How do I get the content of a <td> using JavaScript? - javascript

My HTML
<tr class="g1">
<td id="saveursqte_box[]">
<div class="t">
xxxxxxxxxxxxx
<div class="r">
<div class="a">
</div>
<img src="images/saveurs/saveur_test.jpg" width="125" border=0>
</div>
</div>
</td>
<td class="i">
<input type="text" name="saveursqte[]" alt="2.95" value="" size="3" onBlur="__sumform();">
</td>
</tr>
What I'm trying to do
I want to get the contents of: <td id="saveursqte_box[]"> using javascript.
which is:
<div class="t">
xxxxxxxxxxxxx
<div class="r">
<div class="a">
</div>
<img src="images/saveurs/saveur_test.jpg" width="125" border=0>
</div>
</div>
I tried this javascript:
var saveursqte_box = document.getElementsById('saveursqte_box[]');
and then
htmltotal = htmltotal + saveursqte_box[i].innerHTML;
but javascript doesn't seem to like me :-(

It is document.getElementById no "s".
This document.getElementById('saveursqte_box[]'); returns a single dom element not an array like jQuery.So the code to get the innerHTML would be:
htmltotal += saveursqte_box.innerHTML;

In addition to #scrappedcola's note about there being no 's' in getElementById, you may also be having problems using square brackets in the element id.
I ran your example in Firefox 4 with <td id="saveursqte_box"> and it worked, whereas using <td id="saveursqte_box[]"> I got NULL as the result of getElementById().

Also:
saveursqte_box[i]
i is not defined. Just use saveursqte_box

Thanks to all! I know my Javascript skills are low but by combining your answers together I came with this and it works perfectly :
htmltotal += document.getElementById('saveurmoisqte_box_' + i).innerHTML;
As per your answer, I removed the "s" of getElementById. My bad: I copied getElementsByName and then replaced the Name by Id... This is why there was a "s" there. The kind of mistake that can waste you a week to debug... 
After that, I rename my <td id="extrasqte_box[]"> with <td id="extrasqte_box_0">. I thought you could write ids arrays like you do with names (ex: name="xxxx[]") and then iterate but I was wrong.
With that in place it works perfectly! Not bea-u-tiful but it works.
What I'm actually doing with this is:
I have an order form with many items and when you fill an input (quantity), an hover image of the product appears to its right... and when you move away (onBLur), the form total is updated, AND using the function here above, I get the content of the <td> (including the hover image) and put a summary of the items chosen in the "checkout section". The result is super-clean for the user and user-friendly. The inconvenient is I hope this makes sense to you.

Related

JQuery - Find values of elements based on other relative elements?

I'm attempting to find the value of an element (input element) based on a nearby element, specifically in my example I'm looking to return 'Complete' based on it being next to the 'Contract Review Status' field. I cannot use any unique identifier, as my source system will randomise the unique identifier.
<td class=" FieldLabel ml-FldLbl ml-BrdRight lo_51395 ml-BrdBottom" style="width:15%;">
<span id="loitem51395">
<img id="22508requiredImg" class="required-icon" src="/BackgroundImageGenerator.axd?className=Bullet&classProperties=bulletShape:RequiredIndicatorWidget;baseColor:%23B80000" alt="Required" style="display:none;">
Contract Review Status:
</span>
</td>
<td class="ml-FldCnt lo_51395 ml-BrdBottom" style="width:35%;">
<div id="master_DefaultContent_rts_s8307_f22508c" class="ArcherTreeView DisabledTree">
<ul class="rtUL rtLines">
<li id="" class="rtLI rtFirst rtLast">
<div class="rtMid">
<div data-valueslistvalueid="81019" style="color:#000000;">
<input name="master$DefaultContent$rts$s8307$ctl10" type="hidden" class="readOnly" value="81019">
Complete
</div>
</div>
</li>
</ul>
</div>
</td>
I'll be looking to store the 'Complete' in a variable so that I can display conditional graphics, depending on the current status.
Thanks in advance!
As it seems you can find the "Contract Review Status", I'd suggest you go up from there to the parentNode's in turn until you find the first td (check jQuery's "closest" method). From there take the next td (check jQuery's "next" method) and down until you find your input element (check jQuery's "find" method).
I hope this is enough information to help you solve your issue.
select the column based on the type of the input type;
$('tr > td').find('input[type=hidden]').val()
Hope this helps

Trying to pull a value out of a kendo popup window using Excel VBA

I'm trying to pull a value out of a kendo popup window but can't seem to get the right combo/syntax.
Im looking for 9070009 in the "dipatchIdentLablel"
I have tried:
.Document.getElementById("AddSucessWindow").Value 'I know, too broad, too many possibilities
.Document.getElementById("AddSucessWindow").Text
.Document.getElementById("AddSucessWindow").getElementById("dispatchIdentLablel").Value
.Document.getElementById("AddSucessWindow").getElementById("dispatchIdentLablel").Text
.Document.getElementById("dispachIdentLablel").Value
.Document.getElementById("dispachIdentLablel").Text
.Document.getElementById("dispachIdentLablel").getElementsByName("dispatchIdentLablel").Value
.Document.getElementById("dispachIdentLablel").getElementsByName("dispatchIdentLablel").Text
.Document.getElementById("dispachIdentLablel").getElementsByName("dispatchIdentLablel").innerText
.Document.getElementById("dispachIdentLablel").getElementsByName("dispatchIdentLablel").HTML
.Document.getElementById("AddSucessWindow").getElementsByTagName("span").Value
.Document.getElementById("AddSucessWindow").getElementsByTagName("span").Text
No errors on any, but the result is"empty" on all
Here is a portion of the web page code. I've removed a bunch of unneccessary stuff for ease of reading.
<div tabindex="0" class="k-window-content k-content" id="AddSucessWindow" role="dialog" aria-labelledby="AddSucessWindow_wnd_title" data-role="window">
<div>
<table>
<tbody>
<tr>
<td class="columnLabel">
<label for="Dispatch_Load_Id:">Dispatch Load Id:</label>
</td>
<td class="columnData">
<span id="dispatchIdentLablel" name="dispatchIdentLablel"></span>
9070009 '<<--Shows as element (text)
</td>
</tr>
</table>
</div>
<div class="divCenter">
<button Type="Button" id="AddSucessWindowClose">Close</button><script>
jQuery(function(){jQuery("#AddSucessWindowClose").kendoButton({});});
</script>
</div>
I can get the button to close the window using this
.Document.getElementById("AddSucessWindowClose").Click
I know I'm overlooking something or have the syntax wrong. Any insight appreciated !!
You should be able to use querySelector() looking for the columnData class:
.Document.querySelector(".columnData").innerText
Note that this worked for me when testing with just the HTML in the OP. If there are other elements with the same class on the page, may have to tweak it.

Nested ng-repeat with dynamic input

I am trying to display a JSON response in a table using ng-repeat. The problem is that not all objects recieved are the same. All of them have a date, short message and long message. There are also ones with an additional value list, differing in length. This list should be diplayed underneath the long message within its own table or list. I use the alert.slice().reverse() because I want the newest entries to be on top. The new objects are inserted using .push({values}).
<tbody class="AlTbody" ng-repeat="alerts in alerts.slice().reverse()" ng-class="className">
<tr class="Altr Aldate">
<td ng-show="{{alerts.Date}}"><b>{{alerts.Date}}:</b>
</td>
</tr>
<tr class="Altr Alshort " ng-click="toggleDetail($index)">
<td>{{alerts.S}}</td>
</tr>
<tr class="Altr " ng-show="activePosition == $index">
<td class="msgL">{{alerts.L}}
<!-- 1) <p ng-show="{{item.List}}"><br><ul><li>Previous values:</li> <li ng-repeat="vals in ValueList">{{vals.value}}</li></ul> </p>-->
<!-- 2) <p ng-show="{{List.txt}}"> <br><ul><li>Previous values:</li> <li ng-repeat="List in alerts.List">{{List.txt}}</li></ul> </p>-->
</td>
</tr>
</tbody>
I already tried two approaches as seen in the code. The first one displayed the list correct however it was displayed underneath every long message instead of only the one it belongs to. I used a new variable.
var l=valList.length;
scope.List=true;
while(l>-1){
scope.ValueList.push({value: valList[l]});
l--;
}
The second approach did not work at all because I could not find an index.
var l=valList.length;
var indexV= jQuery.inArray(currdate,scope.alerts.Date);
while(l>-1){
scope.alerts[indexV].List.push({txt: valList[l]});
l--;
}
edit:
This is the current output. There you can see two objects( date, short message and long message) and both of them have the previous values section. However only the upper object is supposed to diplay the list of previous values.
What you are trying to achieve is entirely possible, my advice is to start at a known point and work from there.
I have put together a jsfiddle to show you how nested ng-repeats will work. try and work from that point. As a side note it looks like your JSON structure is overly complex, if you can simplify that down I would.
https://jsfiddle.net/roscorcoran/wyu7tgxm/
<div ng-app="App" ng-controller="Ctrl1">
<div ng-repeat="alert in alerts">
<a ng-if="alert.Date">{{alert.Date}}</a>
<p ng-repeat="val in alert.L.vals">
<a ng-if="val && val.value">{{val.value}}</a>
</p>
<p ng-repeat="item in alert.List">
<a ng-if="item && item.txt">{{item.txt}}</a>
</p>
</div>
</div>
You can try to add a ng-if statement inside the ng-repeat loop:
<p ng-if="{{values.list}}"><br><ul><li>Previous values:</li> <li ng-repeat="vals in values.list">{{vals.value}}</li></ul> </p>-->
Okay so this works for me now. It still always displays "Previous Values:" but the values only display when they actually belong to the message.
<ul ng-if="alerts.List.vals"><li>Previous values:</li> <li ng-repeat="val in alerts.List.vals" >{{val.value}}</li></ul>
This might not be the best and most elegant solution but it works.
if(valList){
scope.alerts.push({Date:currdate,S:msgSn,L:msgLn, List:{ vals:[{value:valList[0]},{value:valList[2]},{value:valList[4]},{value:valList[6]}] } });
}else{
scope.alerts.push({Date:currdate,S:msgSn,L:msgLn });
}
I only display the even indexes of the value array because the list of values was a string which I split and every uneven entry is "):" which I don't need to display.

Why does this Javascript only run once per page?

I have this Try-it-Yourself section to my website but for some reason when I am wanting to have more than one Try-it-Yourself section it will only work for the one at the top of the page. So if I had three of them on a page the top one would work in the way I want but the next two would do nothing.
I have the following HTML:
<div class="tryit">
<table>
<tr>
<td>Try It Yourself</td>
</tr>
<tr>
<td><textarea id="input" rows="10" cols="47"></textarea></td>
</tr>
<tr>
<td><input onclick="update();" type="button" value="Update"></td>
</tr>
<tr>
<td><iframe id="output" name="output" width="600" height="300" ></iframe></td>
</tr>
</table>
</div>
And the following Javascript:
function update()
{
var tryitoutput = document.getElementById('input').value;
window.frames['output'].document.documentElement.innerHTML = tryitoutput;
}
Thank you.
As others mentioned, this is happening because there can't be more than one HTML element with same value of ID attribute. In your case javascript only finds the first element, that's why it doesn't work on later Update buttons. The simplest approach would be to set different ID attribute values for different "Try it yourself" boxes:
Slightly modify your JS, see following jsFiddle example
function update(tryItIndex) {
var tryItOutput = document.getElementById('input-' + tryItIndex).value;
window.frames['output-' + tryItIndex].document.documentElement.innerHTML = tryItOutput;
}
That's because you are referring to the textarea and the output by id which means it will always just retrieve the first one. A quick fix would be having unique id's for these fields and send the names as parameters to the update function like update(inputId, outputId)

AND/OR Conditions in jQuery

In jQuery space denotes AND condition "," denotes OR condition, Is that right? But I am facing issues in that. Here is my sample html code
<td id="4">
<div id="test1" class="test1"></div>
<div id="test2" class="test2"></div>
</td>
<td id="5">
<div id="test1" class="test1"></div>
<div id="test2" class="test2"></div>
</td>
If I use the following query, it works
jQuery('#4 [id*=test1]')
it selects the correct div. However, if I use this query,
jQuery('#4 #test1')
it doesn't work. Any Idea?
It is not valid to have duplicate ids within the same document.
If you are building this dynamically then try prepending the parent id to the child so it would be like:
<td id="r4">
<div id="r4_test1" class="test1"></div>
<div id="r4_test2" class="test2"></div>
</td>
<td id="r5">
<div id="r5_test1" class="test1"></div>
<div id="r5_test2" class="test2"></div>
</td>
Note, starting an ID with a number is also invalid, so I took the liberty to prepend "r" to your row ids.
I would recommend using the selector:
$('#r5 .test1')
Space isn't strictly an 'and' condition.
In your own example, jQuery('#4 #test1') space means to get children of #4 called #test1 if you see what I mean
The jquery docs for this explain it better than I do!
jQuery('ancestor descendant')
Selects all elements that are descendants of a given ancestor.
Thinking of selectors in terms of "AND" and "OR" probably isn't the most helpful way to go about things. If a space actually meant "AND", then these two statements would be identical:
$('.parent_class .child_class')
$('.child_class .parent_class')
If a selector was a simple "AND", then these statements would select all items that meet both criteria.
In reality, these statements are very different. A space in jQuery and CSS selectors actually shows inheritance. When you have two separate classes, as in my example, you're always saying "select the class that is second in the list, only if it is contained by an element with the first class in the list."
You could say that a comma means "OR", but really it just separates two selecting statements from each other, so that you can select two completely separate items or groups of items.
The jQuery selector syntax borrows from CSS, so this group of tutorials on w3schools.com might be a helpful place to start.
I think you ought to drop the ids off the div tags and just work with classes.
use $('#d5 .test1') or
$('#d5').find('.test1')
I usually use the latter because it's just easier to read when I go back a month later to look at the code.
<td id="d4">
<div class="test1">w</div>
<div class="test2">x</div>
</td>
<td id="d5">
<div class="test1">y</div>
<div class="test2">z</div>
</td>

Categories