How to execute script on every tab changing in RSA Archer GRC? - javascript

I'm trying to change styles of many text fields on a layout of an application in RSA Archer GRC using custom object. I wrote a script and it runs only once, when the application is opened. The problem is that the layout contains multiple tabs. When tab is changed the script isn't working anymore.
So how to execute the script on every tab changing?
var tableId = 'master_DefaultContent_rts_ts3295_s4655_f18821srvgrid_ctl00';
//table with target elements
$(document).ready(function () { //run script when page is loaded
main();
});
function main() {
var table = document.getElementById(tableId).getElementsByTagName("tbody")[0];
var rows = table.getElementsByTagName("tr");
for (var i = 0; i < (rows.length - 1); i++) {
var field = rows[i].getElementsByTagName("td")[1];
var spanElements = field.getElementsByTagName("span"); //target elements
for (var k = 0; k < spanElements.length; k++) { //apply style for each of them
var elem = spanElements[k];
elem.style.fontFamily = "Times New Roman";
elem.style.fontSize = "14pt";
elem.style.color = "black";
}
}
}

Try using this in your custom object instead of $(document).ready({});, it should fire each time a tab is loaded.
function pageLoad(){
//code
}

<tabelement onclick="main()">Tab</tabelement>
Use the onclick event on the tab to execute the main function.

Related

Browser Extension's creating dynamic buttons with dynamic links

I'm trying to create a browser extension popup (in JS) that creates a number of buttons with links that open up different webpages. The function takes a number of parameters, the main one being b_link which is an array of URL's to the website. For some reason, only the last URL in array is applied to all of the buttons that are created.
I'm not entirely sure what the problem is, I could speculate but I don't think that would be productive. One thing I did notice and had to compensate for was using b_link in the lambda function. Just using b_link[i], the lambda function only saw undefined so no webpage opened, but using var tmpLink = b_link[i]; at least gets the link into the function and allows a webpage to open.
How should I make these buttons so that they all have their own links, rather than only the last one in the array?
The function in question:
function createSiteButton(numBtns, b_id, b_class, b_text, b_link, b_bg)
{
// check if the input text is an array
if (Array.isArray(b_text))
{
// create the new set of buttons
for (i= 0; i < numBtns; i++)
{
var newButton = document.createElement('button');
var tmpLink = b_link[i];
newButton.id = b_id;
newButton.class = b_class;
newButton.innerHTML = b_text[i];
newButton.style.background = b_bg;
newButton.addEventListener("click", function()
{
if (tmpLink)
{
window.open(tmpLink, "_blank");
}
});
button_array[i] = newButton;
}
// add the new buttons the screen
for (i= 0; i < numBtns; i++)
{
divID.appendChild(button_array[i]);
}
}
}
I found a way to do this via creating an a element, setting href via a.href = tmpLink and appending the button to the a element as a child. The final function is:
function createSiteButton(numBtns, b_id, b_class, b_text, b_link, b_bg)
{
var outputElem = document.getElementById('output');
// check if the input text is an array
if (Array.isArray(b_text))
{
//var tmpLink = null;
// create the new set of buttons
for (i= 0; i < numBtns; i++)
{
var a = document.createElement('a');
var newButton = document.createElement('button');
var tmpLink = b_link[i];
newButton.id = b_id;
newButton.class = b_class;
newButton.innerHTML = b_text[i];
newButton.style.background = b_bg;
a.href = tmpLink;
a.appendChild(newButton);
divID.appendChild(a);
button_array[i] = newButton;
}
}
}

Code Working in Console BUT NOT From Script

I have a script that I'm running to detect a line break in a flex-wrapped UL.
I have this javascript function at the top of my scripts.js file outside of the $(document).ready call.
var detectWrap = function(className) {
var wrappedItems = [];
var prevItem = {};
var currItem = {};
var items = document.getElementsByClassName(className);
for (var i = 0; i < items.length; i++) {
currItem = items[i].getBoundingClientRect();
if (prevItem && prevItem.top < currItem.top) {
wrappedItems.push(items[i]);
}
prevItem = currItem;
};
return wrappedItems;
}
Inside of a $(document).ready call, I have this:
$( ".menu-item-has-children" ).click(function() {
var wrappedItems = detectWrap('menu-item-object-practice-area');
for (var k = 0; k < wrappedItems.length; k++) {
wrappedItems[k].className = "wrapped";
}
});
If I load the page and click the "Practice Areas", I get nothing. If I open up the console and drop in the following it works fine:
var wrappedItems = detectWrap('menu-item-object-practice-area');
for (var k = 0; k < wrappedItems.length; k++) {
wrappedItems[k].className = "wrapped";
}
I'm assuming this has something to do with the timing and/or what is loaded up but I'm not adding content into the DOM...I'm just adding a class.
For reference, here is the site: https://myersbrierkelly.djykrmv8-liquidwebsites.com/
When you click the drop-down menu, two separate event handlers respond:
Yours, to measure for wrapped items
The library you're using, to toggle the display of the submenu
However, as there is nothing to manage the order of these, what ends up happening is that your wrap-detector runs before the submenu is shown, and if the submenu isn't shown yet then you can't measure getBoundingClientRect() since it doesn't exist. A simple console.log(currItem) would have revealed this.
If you can't guarantee the order of events (which may well be the case when using a library), then you should delay your code by a frame.
$(".menu-item-has-children").click(function() {
requestAnimationFrame(function() {
var wrappedItems...
});
});

html table selected cell using javascript

I have generated a dynamic html table using java script. Now I need to get the css class of the cell clicked by the user.
How am I supposed to do this?
Here is the code:
function generateSeatMatrix() {
var rows = parseInt(document.getElementById('txtRows').value);
var cols = parseInt(document.getElementById('txtCols').value);
if (!validateMatrixInput(rows, cols)) {
// TODO display error message
return;
}
var matrixTable = document.getElementById('tblMatrix');
if (matrixTable.rows.length > 0) {
for (var k = matrixTable.rows.length - 1; k >= 0; k--) {
matrixTable.deleteRow(k);
}
}
for (var i = 0; i < rows; i++) {
matrixTable.insertRow(i);
for (var j = 0; j < cols; j++) {
matrixTable.rows[i].insertCell(j);
matrixTable.rows[i].cells[j].className = 'matrix-cell';
matrixTable.rows[i].cells[j].setAttribute('onclick', 'hello()');
}
}
}
The 'hello()' function is supposed to handle the required logic. Right now, the function is called properly but I have no idea how to get the selected cell css class. Actually, i tried to send the position as declaring the event (using setAttribute), but then an error raised.
I see you are trying to add a onclick as you built but if you create some jquery like so you can do it. But you would have to have jQuery loaded. Although if you are building this dynamically you may need to use $('document').find('td'). This may not be the solution you are looking for but will get the job done.
$('td').on('click', function(){
var myClass = this.className;
})
Tried adding in comment but wouldn't show code view.
Here is how easily this could be handled..
matrixTable.rows[i].cells[j].setAttribute('onclick', 'hello(' + i + ',' + j + ')');
Well done!

Inserting CSS-linked HTML in HTML page code via JS

I do not have access to the HTML of the pages (they are program-built dynamically).
I do have access to the JS page it is linked to.
For example I can do somethin like this and it works:
window.onload=function(){
var output = document.getElementById('main_co');
var i=1;
var val="";
while(i<=1)
{ if(!document.getElementById('timedrpact01'+i))
{
var ele = document.createElement("div"); ele.setAttribute("id","timedrpact01"+i);
ele.setAttribute("class","inner");
ele.innerHTML=" Hi there!" ;
output.appendChild(ele);
I would like to use this basis insert a button that would allow to switch from one CSS set (there are several files invoked) to another _another path.
Many thanks
The external stylesheets are referenced using link, as in:
<link rel="stylesheet" href="http://example.com/path-to-css">
So, get hold of the appropriate link element using:
var css = document.getElementsByTagName("link")[0];
Here, we got hold of the first link available by specifying the [0] index.
Then, overwrite the href attribute to point it to the new path.
css.setAttribute("href", "http://example.com/path-to-css");
window.onload=function(){
var output = document.getElementById('main_co');
var i=1;
var val="";
//switch all the href's to another path
var switchStyleSheet = function() {
var links = document.getElementsByTagName("link");
for(var i=0; lkC = links.length; i < lkC; i++)
links[0].href = links[0].href.replace('path_to_file', '_path_to_file');
};
while(i<=1) //while is not required here, if i is 1
{
if(!document.getElementById('timedrpact01'+i)) {
var ele = document.createElement("div"); ele.setAttribute("id","timedrpact01"+i);
ele.setAttribute("class","inner");
ele.innerHTML=" Hi there!" ;
var button = document.createElement('button');
if(button.addEventListener) {
button.addEventListener('click', switchStyleSheet);
}
else {
button.attachEvent('click', switchStyleSheet);
}
output.appendChild(button);
output.appendChild(ele);
}
}
}

obj is null, javascript

function init()
{
alert("init()");
/**
* Adds an event listener to onclick event on the start button.
*/
xbEvent.addEventListener(document.getElementById("viewInvitation"), "click", function()
{
new Ajax().sendRequest("31260xml/invitations.xml", null, new PageMaster());
xbEvent.addEventListener(document.getElementById("declinebutton"), "click", function ()
{
declineInvitation();
});
});
ok so what I have here is a event listerner function, the case is when viewInvitation is clicked , the program will fetch my xml file and run page master function where I created my decline button with id="declinebutton", however this does not work, the error message that i get is obj=null or the program could not find id = declinebutton, why is it so? I have created it when I called page master using dom. any help will be appreciated.
function PageMaster()
{
this.contentDiv = document.getElementById("content");
}
/**
* Builds the main part of the web page based on the given XML document object
*
* #param {Object} xmlDoc the given XML document object
*/
var subjectList;
var i;
PageMaster.prototype.doIt = function(xmlDoc)
{
alert("PageMaster()");
alert("Clear page...");
this.contentDiv.innerHTML = "";
if (null != xmlDoc)
{
alert("Build page...");
//create div Post
var divPost = document.createElement("div");
divPost.className = "post";
//create h1 element
var h1Element = document.createElement("h1");
var headingText = document.createTextNode("Invitations");
h1Element.appendChild(headingText);
//insert h1 element into div post
divPost.appendChild(h1Element);
subjectList = xmlDoc.getElementsByTagName("subject");
var groupList = xmlDoc.getElementsByTagName("group");
for (i = 0; i < subjectList.length; i++) //for each subject
{
var divEntry = document.createElement("div");
divEntry.className = "entry";
var subjectNum = subjectList[i].attributes[0].nodeValue;
var subjectName = subjectList[i].attributes[1].nodeValue;
var groupId = groupList[i].attributes[0].nodeValue;
var groupName = groupList[i].attributes[1].nodeValue;
var ownerId = groupList[i].attributes[2].nodeValue;
//set up the invitation table attributes
var table=document.createElement("table");
table.width = 411;
table.border = 3;
table.borderColor = "#990000"
var input=document.createElement("p");
var inputText=document.createTextNode("You are invited to join " + groupName + "(groupId : " + groupId +")");
input.className="style11";
var blank=document.createElement("nbps");
input.appendChild(inputText);
var acceptButton=document.createElement("input");
acceptButton.type="button";
acceptButton.id="acceptbutton";
acceptButton.value="accept";
var declineButton=document.createElement("input");
declineButton.type="button";
declineButton.id="declinebutton";
declineButton.value="decline";
table.appendChild(input);
table.appendChild(acceptButton);
table.appendChild(declineButton);
divEntry.appendChild(table);
var blankSpace = document.createElement("p");
divEntry.appendChild(blankSpace);
divPost.appendChild(divEntry);
}
//insert div post into div content
this.contentDiv.appendChild(divPost);
}
};
/**function getValueOf()
{
return i;
}**/
function declineInvitation()
{
alert("decline");
}
function acceptInvitation()
{
alert("hello");
/**var pos=getValueOf();
alert(subjectList[pos].attributes[0].nodeValue);**/
}
That's my page master function, and I definitely have created the button. but it does not work.
Try calling your function like this:
window.onload=init;
The javascript runs as the page loads. At that point, the element does not yet exist in the DOM tree. You'll need to delay the script until the page has loaded.
The example you gave doesn't create the "Decline" button, as your question suggests it should. If it should, you might want to look at that.
Of course, if the button already exists, please disregard this answer.
You have a listener inside a listener. Is that right?
What about this?:
function init(){
alert("init()");
/** * Adds an event listener to onclick event on the start button. */
xbEvent.addEventListener(document.getElementById("viewInvitation"), "click", function()
{
new Ajax().sendRequest("31260xml/invitations.xml", null, new PageMaster());
}
xbEvent.addEventListener(document.getElementById("declinebutton"), "click", function ()
{
declineInvitation();
});
As far as I understand, you create button with id="declinebutton" for each entry from xml, is that right?
If yes, I'd suggest you to generate different id's for each button (for example, append line index to 'declinebutton', so you have buttons 'declinebutton0', 'declinebutton1' an so on), and assign event listener to buttons separately in the loop.

Categories