I have a Website with tables which have informations about work projects. Here's an example:
<tr valign="top" bgcolor="#FFFFA0"><td valign="top" bgcolor="#00CC00"></td>
<td valign="top">1500-779</td>
<td valign="top">140072EAL</td>
<td valign="top">125</td>
<td valign="top">DSQ ABC</td>
<td valign="top">34_FEAT-1234: Object Index: Example</td>
<td valign="top"></td>
<td valign="top">om</td>
<td valign="top">br</td>
<td valign="top"><p title = "individual task is scheduled">edit</p></td>
<td valign="top">9,7</td>
<td valign="top">2,3</td>
<td valign="top">7</td>
<td valign="top">8</td>
<td valign="top">2016 24,4</td>
<td valign="top">2016 35</td>
<td valign="top">0</td>
</tr>
Now I want to construct a dynamic Greasemonkey script which search for dynamic tags like FEAT-1234,WTS-4567,PIDT-7896 etc. and replace it with a direkt dynamic link to the entry of the Bug in the management software. This is my code so far:
var replacementRegexp = /([A-Z]+)-([0-9]{4})/; //defined regular expression
var searchvar = "";
var link = "";
for (var i = 0; i < 2; i++)
{
if(i == 0)
{
$searchvar = "FEAT";
$link = 'https://vmpolarion.dqa-ac.de/FEAT/workitem?id=FEAT-';
}
else if (i == 1)
{
$searchvar = "WTS";
$link = 'https://vmpolarion.dqa-ac.de/WTS/workitem?id=WTS-';
}
else
{
$searchvar = "PIDT";
$link = 'https://www.vpext.dsa-ac.de/PIDT/show_bug.cgi?id=PIDT-';
}
$("table td:contains('"+searchvar+"')").each(function(index, element) //looking for the tag
{
$(element).html($(element).html().replace(replacementRegexp, '$1-$2')); //replaces the text with a link to the Bugzilla entry
});
}
The search function of the tag works but the replacing still makes problems. One problem is that the links are variable and the Number of the tag that should be found must be part of the link. The most tags have their own link structure. I want to an elegant solution, which is not very long, but I think my code is not very suitable. How can I solve the problem?
PS: This is the first time that I have been working with Greasemonkey,Javascript and JQuery.
Okay i made a realy stupid mistake. I have solved the problem now. Here is the Code.
var replacementRegexp = /([A-Z]+)-([0-9]{4})/; //defined regular expression
var query = new Array();
query[0] = new Array("table td:contains('FEAT')",'$1-$2'); //search word|Link
query[1] = new Array("table td:contains('WTS')",'$1-$2');
query[2] = new Array("table td:contains('PIDT')",'$1-$2');
query[3] = new Array("table td:contains('ATH')",'$1-$2');
for (var i = 0; i <= query.length; i++)
{
$(query[i][0]).each(function(index, element) //looking for variable
{
$(element).html($(element).html().replace(replacementRegexp, query[i][1])); //replaces the text with a link to the Database entry
});
}
Related
I'm working on a basic genetic algorithm that guesses the words you type into it. I have all of that working but for some reason, the guesses are not live updating, but rather only using the last iteration. Here's my current updateGuesses function:
function updateGuesses(){
var sortAtt = attempts.sort(cmpFitness);
bestAttempt = sortAtt[0];
GUESS.innerHTML= bestAttempt.sentence;
//Top Guesses from past generations
pastGuesses[5] = pastGuesses[4];
pastGuesses[4] = pastGuesses[3];
pastGuesses[3] = pastGuesses[2];
pastGuesses[2] = pastGuesses[1];
pastGuesses[1] = pastGuesses[0];
pastGuesses[0] = {sentence:bestAttempt.sentence, gen:generation};
document.getElementById("gen1").innerHTML = pastGuesses[0].gen;
document.getElementById("guess1").innerHTML = pastGuesses[0].sentence;
document.getElementById("gen2").innerHTML = pastGuesses[1].gen;
document.getElementById("guess2").innerHTML = pastGuesses[1].sentence;
document.getElementById("gen3").innerHTML = pastGuesses[2].gen;
document.getElementById("guess3").innerHTML = pastGuesses[2].sentence;
document.getElementById("gen4").innerHTML = pastGuesses[3].gen;
document.getElementById("guess4").innerHTML = pastGuesses[3].sentence;
document.getElementById("gen5").innerHTML = pastGuesses[4].gen;
document.getElementById("guess5").innerHTML = pastGuesses[4].sentence;
document.getElementById("gen6").innerHTML = pastGuesses[5].gen;
document.getElementById("guess6").innerHTML = pastGuesses[5].sentence;
}
This function is called in a while loop that updates the array every iteration. The end result that's displaying is correct but for some reason it's not updating each loop. Here's the table structure:
<table id="myTable">
<tr>
<td>Generation</td>
<td>Best Guess</td>
</tr>
<tr>
<td><span id="gen1">1</span></td>
<td id="guess1">N/A</td>
</tr>
<tr>
<td id="gen2">2</td>
<td id="guess2">N/A</td>
</tr>
<tr>
<td id="gen3">3</td>
<td id="guess3">N/A</td>
</tr>
<tr>
<td id="gen4">4</td>
<td id="guess4">N/A</td>
</tr>
<tr>
<td id="gen5">5</td>
<td id="guess5">N/A</td>
</tr>
<tr>
<td id="gen6">6</td>
<td id="guess6">N/A</td>
</tr>
</table>
EDIT: Here's my main method that includes the loops:
function main(){
var string;
var score;
generation = 0;
goal = document.getElementById("goalField").value;
string_length = goal.length
//Populate attempts with random strings
for (let i = 0; i < POPULATION; i++){
string = randomString();
score = stringScore(string);
attempts[i] = {sentence:string, sentenceScore:score};
}
//Retrieve Probabilities for each attempt
fitness()
//Find best Guess
updateGuesses()
while(bestAttempt.sentenceScore != string_length){
repopulate()
generation++;
sortAtt = attempts.sort(cmpFitness)
updateGuesses()
}
The while loop basically checks if the best sentence guessed is correct and if it isn't it creates a new array of guesses. The goal is to update the HTML table with the new guesses each time it runs through the while loops.
Thank you #RobbieD ! I figured it out by using setInterval with an if statement within it instead of a while loop.
var repeat = setInterval(doAgain,100);
}
function doAgain(){
//GUESS.innerHTML=attempts[0].fitness
if(bestAttempt.sentenceScore != string_length){
repopulate()
generation++;
sortAtt = attempts.sort(cmpFitness)
updateGuesses()
}
else{
clearInterval(repeat);
}
}
I am trying to use java-script to export html data into excel. The funny thing is that it DOES work when I use getElementsByTagName instead of getElementById. However, I need to pinpoint id elements and thus 'getElementById' is what I need (I guess). When I debug the below code in IE it gives me:
Object doesn't support property or method 'getElementsById'
Here is what I've got:
HTML (as an idea only):
<body>
<table>
<tr>
<td>content 1</td>
<td>content 2</td>
<td id="R">content I need</td>
<td>some other content</td>
</tr>
</table>
</body>
and accompanying JS
<script type="text/javascript">
function write_to_excel()
{
str="";
var mytable = document.getElementById("R")[0];
var row_Count = mytable.rows.length;
var col_Count = mytable.getElementById("R")[0].getElementById("R").length;
var ExcelApp = new ActiveXObject("Excel.Application");
var ExcelSheet = new ActiveXObject("Excel.Sheet");
ExcelSheet.Application.Visible = true;
for(var i=0; i < row_Count ; i++)
{
for(var j=0; j < col_Count; j++)
{
str= mytable.getElementById("R")[i].getElementById("R")[j].innerHTML;
ExcelSheet.ActiveSheet.Cells(i+1,j+1).Value = str;
}
}
}
</script>
I have the feeling - it's trifle but ... Thanks in advance!)
The getElementById method returns a single DOM element (if you have more than one HTML element with the same ID then your page is buggy but browsers won't complain because 10 years ago it was a common bug that lots of people make). As such the statement:
document.getElementById("R")[0]
Makes no sense whatsoever. Instead, what you want is:
var myTD = document.getElementById("R");
If you have a page structure like this:
<table id='T'>
<tr>
<td>content 1</td>
<td>content 2</td>
<td>content I need</td>
<td>some other content</td>
</tr>
</table>
And want to iterate each column in each row, you'd do it like this:
var mytable = document.getElementById("T");
var table_rows = mytable.getElementsByTagName('tr');
for (var row=0;row<table_rows.length;row++) {
var row_columns = table_rows[row].getElementsByTagName('td');
for (var col=0;col<row_columns.length;col++) {
var item = row_columns[col];
// process item here
}
}
See the documentation of HTMLElement for more info on how to navigate the DOM: https://developer.mozilla.org/en/docs/Web/API/Element
Full documentation of the DOM API: https://developer.mozilla.org/en/docs/DOM
You may also check out the relevant docs on MSDN instead of MDN for IE specific stuff but I prefer MDN because it documents the compatibility level (what other browsers implement a feature) of the API.
IDs must be unique.
Therefore, the function you're looking for is called getElementById (singular)
I am using greasemonkey to change the functionality of an existing web page.. If you aren't familiar with greamonkey it doesn't really matter.. the main information is that the current code for the existing page looks like this:
<div id="sqlDiv" class="sqlBorderDiv" style="display: none;">
<div class="reportBorderDiv">
<table class="reportTable">
<tbody>
<tr>
<tr class="reportRow1">
<tr class="reportRow2">
<td>55555</td>
<td>Bruce Wayne</td>
<td>12456789123</td>
<td>2013-12-17</td>
<td>Batman</td>
<td>Superhero</td>
<td>Menace</td>
<td>123246</td>
<td>12456</td>
<td>123456</td>
<td></td>
</tr>
</tbody>
</table>
</div>
I want to run a script on it that will make the first cell of any reportRow into a hyperlink using the information in that cell. I am trying with a script like below, but something is going wrong and I have no idea what. ( I am really new into javascript). Thank you for any suggestions!!
var anchor = null;
var container;
var rows;
var cells;
var demoNum;
var linkString = "https://somewebsite.com/";
container = document.getElementById('sq1Div');
rows = container.getElementsByTagName("tr");
for (var i = 0; i < rows.length; i++) {
var className = rows[i].getAttribute("class");
if ( className == "reportRow1" || className == "reportRow2" ) {
anchor = rows[i];
cells = anchor.getElementsByTagName("td");
demoNum = cells[0];
linkString = linkString + demoNum;
cells[0] = <a href = linkString > demoNum </a>;
}
}
The problem is in the line
cells[0] = <a href = linkString > demoNum </a>;
That should be in a string, like this:
cells[0]="<a href='"+linkstring+"'>"+demonum+"</a>";
To put that back in the first row of the table, you can do this
row[i].childNodes[0].innerHTML=cells[0];
Also, you have document.getElementById("sq1div"), instead of "sqlDiv"
document.getElementById('sq*1*Div');
incorrect indetifier, you are using number "1" instead of letter "l"
and of course as wrote scrblnrd3 line with new link builds incorrect
It seems to me the HTML has unmatched tags, could this somehow confuse greasemonkey?
In my application i use a framework that generates a table with the id of the cells at Run-Time in ascending order.
So that i have "ElementX1X1" for row1 and column1, "ElementX1X2" for row1 and column2 etcetc...
The HTML structure generated will be:
<tr>
<td class="my_msg" align="left">
<id="ElementX1X1">
what i can set is the class(my_msg) and the content of the cell(of the table).
I want simply make:
var test=document.getElementById("ElementX1X1");
test.onclick=function();
but i'm not able to recognize the cell...
i want to make getElementById only if it is in the class "my_msg" or only if it has a certain content(as i said the only two things i can set)...
Anyone has any idea on how i can solve the problem?!
Thanks in advance!
Update the HTML to:
<td id="ElementX1X1" class="my_msg" >...
Edited - to work around broken framework:
<tr>
<td class="my_msg" align="left">
<id="ElementX1X1">
some content
</td>
<td class="my_msg" align="left">
<id="ElementX1X2">
some content
</td>
</tr>
If you want to find row 1 column 2, you can cheat using a bit of jQuery to inspect the contents of the element:
var row = 1;
var column = 2;
var matched = null;
$(".my_msg").each({
if($(this).html().indexOf('<id="ElementX' + row + 'X' + column + '">')!=-1){
matched = $(this);
}
});
matched will either point to the element you're looking for or null - but if you already know the row and column id's of the cells then why not just walk the DOM?
var row = 1;
var column = 2;
var matched = null;
var table = document.getElementsByTagName("TABLE")[0]; // up to you how your find it
try {
matched = table.getElementsByTagName("TR")[row-1].getElementsByTagName("TD")[column-1];
}
catch(err) {
// not found
}
Or the brute force way (i.e. fix the framework output):
var table = $("#tableid"); // up to you how your find it
table.html(table.html().replace(/">\n<id="/g,'" id="'));
your code is now:
<tr>
<td class="my_msg" align="left" id="ElementX1X1">…</td>
<td class="my_msg" align="left" id="ElementX1X2">…</td>
…
so you can use
$("#ElementX2X1");
to select the first row, second column
Neither is particularly elegant, but should get the job done while you wait for your buggy framework to be fixed ;)
I have a problem in my code. I want to get the b tag that has the style color silver using Javascript. I tried using the tagName === "B" but it didn't work. I figured that the B tags are not children of the rowData class.
<tr class="rowData">
<td style="padding: 0pt;">
<table><tr>
<td>
<b style="font-size: 15px; color: silver;">Mugging</b>
<br />Payout: <b style="color: green;">$200 - $300</b>
<br />Experience: +1 </td>
<td style="text-align: right;">
</td>
</tr></table>
</td>
<td style="padding: 0pt;">
<table><tr>
<td style="width: 100px;">
<b style="color: gray;">Required:</b>
<br />Energy: 1 </td>
<td style="">
</td>
</tr></table>
</td>
</td>
</tr>
I removed some part of it..
Here's some part of the Javascript code:
var jobs = {};
jobs.scan = function() {
var tagHolder = {};
var availJobs = {};
var jobContents = dom.get("app8743457343_content");
var rData = dom.getElementsByClass("rowData", jobContents, "tr");
for(var i = 0; i < rData.length; i++) {
var rChildren = rData[i].childNodes;
for(var j=0; j<rChildren.length; j++) {
if(rChildren[j].tagName === 'B') {
alert(rChildren[j]);
}
}
}
}
jobs.scan();
When I started the script it didn't alert, or responded. Maybe I need to use something to like nextSibling? Please help me figure this out.. I want the b with the style color silver. The Mugging text
You could fight the good fight and try to get that monstrosity working across all browsers....
Or, you could try jQuery! It's fun and easy, and all the cool kids are doing it!
var text = $('tr.rowData').find('b').filter(function() {
return $(this).css('color') == 'silver';
}).text();
alert(text);
Tada!
EDIT: In all seriousness, if you want to do it in raw javascript, this works for me on IE and Firefox:
var text;
var bs = document.getElementsByTagName("b");
for(var x = 0; x < bs.length; x++) {
if(bs[x].style.color == 'silver') {
text = bs[x].innerHTML;
break;
}
}
alert(text);
It is just grabbing all the bold elements in the document and checking to see which one has a color of silver. This is not super efficient, obviously, and I am not sure of your use case. I do see in your code you are first grabbing a reference to a jobContents element. I am not sure where that is coming from as you didn't post that part of the markup, but if the <b> will end up being inside this element, you can change this line:
var bs = document.getElementsByTagName("b");
To this:
var bs = jobContents.getElementsByTagName("b");
Which will then 1) speed it up, 2) make sure you get what you want.
Good luck.
Your code doesn't go down deep enough into the tree. You need at least 4 more levels of childNode "for" loops to get to the "B" tag. If you go this route then you should probably make a recursive function that searches for your "B" tag.