Accessing html elements from a div tree with javascript - javascript

I need to access title value from some img elements but these elements are deeply implemented in a div tree and after that into some tables.
Let me explain why I need them:
I use a portal where I have information regarding circuits from a network. This portal contains some locations with a few rows (2-3 usually -> circuits for that location). Each row starts with an img element and it can have a few values on title attribute. If the title value is != "No alarms" then I have to take all data from that row and I want to show them via a pop up notification on the bottom right corner near clock.
Below you have a screenshot for how are the html elements organized (for all locations).
http://imageshack.com/a/img661/962/ErjQOt.png
Below you have a screenshot for how is a location organized:
http://imageshack.com/a/img661/7453/QAP5oM.png
If title attribute == "Warning", for example, I have to take the data from the next td's in the same table. Each td has another div without id. Firsts 2 td's on each table have another element inside div: img on first one and a href on the second one.
I'm drawing the tree to show you exactly how are the html elements organized.
<table class="x-grid3-row-table">
<tbody>
<tr>
<td> <!--first td, this contains div->img-->
<div class="x-grid3-cell-inner x-grid3-col-0">
<img .... title="No alarms">
</div>
</td>
<td> <!--second td, this contains div->a href-->
<div class="x-grid3-cell-inner x-grid3-col-1">
<a href...>
</div>
</td>
<td> <!--3rd td, this contains div->string:Text1-->
<div class="x-grid3-cell-inner x-grid3-col-2">Text1</div>
</td>
<td> <!--4th td, this contains div->string:Text2-->
<div class="x-grid3-cell-inner x-grid3-col-2">Text2</div>
</td>
...
</tr>
</table>
Location-1 has 3 circuits, this means 3 tables. The above table is inserted in a div (div class="x-grid3-row x-grid3-row-first" from screenshot2). There are 2 more tables after this one on another div's (div class="x-grid3-row x-grid3-row-alt" & div class="x-grid3-row" from screenshot2) and I have to check the title attribute for each table.
Now my question is how to get the title attribute from each table on the same location? and if the title is != "No alarms" how can I get data from the next td's in that table?
Maybe I can use a loop for all 12 locations or maybe I can get them one by one. This is no big deal because there are only 12 locations but the nasty thing is inside each location to get info from each circuit.
I think there should be a syntax like this to reach each html elements and to get the right value.
var title = $('#ext-gen15-gp-location-1-bd table[0] td[0] img').attr('title');
var title = $('#ext-gen15-gp-location-1-bd table[0] td[1] div[0]').attr('innerHTML');
....
var title = $('#ext-gen15-gp-location-1-bd table[1] td[0] img').attr('title');
var title = $('#ext-gen15-gp-location-1-bd table[1] td[1] div[0]').attr('innerHTML');
...
var title = $('#ext-gen15-gp-location-9-bd table[0] td[0] img').attr('title');
var title = $('#ext-gen15-gp-location-9-bd table[0] td[1] div[0]').attr('innerHTML');
...
...and so on. I'm sure that this syntax is not correct but I think there should be a way to get that data.
I hope that now is explained better then the first time.
EDIT
Guys, thank you very much. You help me a lot. Your codes are working.
Anyway, I just want to ask you something else.
After 3 minutes the whole table is refreshing and I can't find a way to reload the function after that. When the content is refreshing, div ext-gen24 remains empty and after that is refilled with the content:
When is refreshing:
<div class="x-grid3-body" style="width: 1877px;" id="ext-gen24"></div>
After refresh is completed
<div class="x-grid3-body" style="width: 1877px;" id="ext-gen24">content</div>
Can you help me with a function you think it should work in this case ?

You'll need loop through multiple stages of the html: groups, tables, and columns:
var groups = $('.x-grid-group-body'); //hopefully all the '#ext-gen15-gp-location-X-bd' div have 'x-grid-group-body' as the class
groups.each(function () {
var tables = $(this).find('table');
tables.each(function () {
var columns = $(this).find('td');
var image = $(columns[0]).find('img');
var title = image.attr('title');
if (title !== 'No alarms') {
var allInnerHtml = '';
for (var i = 1; i < columns.length; i++) {
allInnerHtml += $(columns[i]).find('div').html() + '\n';
}
alert(allInnerHtml);
}
else {
//just to show that titles with 'No alarm' are skipped
alert('skipped');
}
});
});
See updated JSFiddle
Hope that helps! =)

If your Div tree has classes in the same format is now you can use something like this.
var title = $('.x-panel-bwrap').find('img').attr('title');
Or if the div class dependency is not confirmed, then assuming that img tag will always have a class name starting with 'tick', you can use this.
var title = $('img *[class^="tick"]').attr('title');
EDIT
Now that you have explained your problem more clearly, i've included a fiddle with the solution you need. Now you will have to expand it to suit your code more closely.
For example if you want to log each location separately, start looping through the locations first and then find tables inside them.
Basically you can use Jquery .find and .each to go through your comeplete html and do whetever you want.
var tableList = $('.x-grid3-row-table');
tableList.each(function() {
var imgTitle = $(this).find('img').attr('title');
alert(imgTitle);
if (imgTitle == 'Warning') {
infoTd = $(this).find('td:nth-child(3)');
text = infoTd.find('div').text();
alert(text);
}
});
FIDDLE

Related

How to update some portion of a td title jquery

on ajax success, I have to update some portion of the title.
I am extracting the current td title as:
//with this I could get the current td title
let tdTitle = $('.amenity-review-table').find("td[data-unitid='"+resp.unit.id+"']").attr('title');
and consoling this tdTitle gives:
<div class='unit-title'><strong>Unit: 101</strong></div><span class=''>Washer/Dryer = <span>1</span></span></br><div class='sm-box unit-note-color d-inline-block'></div><span class='unit-note-popup'>note added 3</span>
Now, on ajax success I will receive the new updated title and this can be accessed via:
resp.unit.unit_note, now once I receive the update I have to update the note shown on the title of td. So, in above case:
I have to update the text inside unit-note-popup class to new note which could be received on resp.unit.note. So the final title looks like:
<div class='unit-title'><strong>Unit: 101</strong></div><span class=''>Washer/Dryer = <span>1</span></span></br><div class='sm-box unit-note-color d-inline-block'></div><span class='unit-note-popup'>"+resp.unit.unit_note+"</span> //my syntax could be wrong here, but this is what I needed
Update:
Here, is the jsfiddle to reproduce the scenario:
http://jsfiddle.net/a3t7yfe2/1/
You'll need to parse the HTML in the title attribute into something you can work with (like a jQuery object).
Then you can manipulate the .unit-note-popup text and write the HTML back into the attribute
// Mock data
const resp = {
unit: {
id: 1,
note: "Note added 4!"
}
}
const td = $(`.amenity-review-table td[data-unitid="${resp.unit.id}"]`)
const title = td.attr("title")
const titleEl = $(`<div>${title}</div>`) // parse into an element
titleEl.find(".unit-note-popup").text(resp.unit.note)
td.attr("title", titleEl.html())
/* Make the title attribute visible */
td[data-unitid]:after {
display: block;
color: red;
content: attr(title);
margin: 1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="amenity-review-table">
<tr>
<td data-unitid="1" title="<div class='unit-title'><strong>Unit: 101</strong></div><span class=''>Washer/Dryer = <span>1</span></span><br/><div class='sm-box unit-note-color d-inline-block'></div><span class='unit-note-popup'>note added 3</span>">
Check out my super awesome HTML title
</td>
</tr>
</table>
Here I've wrapped the title HTML text in a <div> so that it's encapsulated in a single parent element. That way, you can get the inner HTML back for writing the new value.

Getting top five rows from a populated table element

I have a table (called mytbl - see below) consisting of 100 rows. From this table, I want to take only the first five rows (assume a user presses "Show Top Five")
This is what I have tried, however, the alert gives me 'empty'
var $updatedtable = $("#mytbl");
$updatedtable.empty();
for ( var i = 0; i < 5; i++ )
{
$updatedtable.append(document.getElementById("mytbl").rows.item(i).innerHTML)
}
alert($updatedtable);
$updatedtable.appendTo( $( "#rbl" ) );
This was the code used to create the html page
<div class="tab-pane" id="rbl">
<div id="rbldiv">
<div class="bs-example voffset-10px">
<form>
<div class="form-group">
<label for="inputText" style="float:left;margin-right:5px;">Show top </label>
<div class="col-xs-1">
<input type="text" class="form-control input-normal" id="ben-count-set" placeholder="100">
</div>
<label for="inputText"> beneficiaries by cost increase</label>
</div>
</form>
</div>
<table id="mytbl" class="table table-striped table-hover"></table>
</div>
</div>
Also, if, after I successfully manage to get the top five and appendTo rbl which has mytbl, won't this get overwritten? If later the user wants to See Top 30, aren't the values gone? How can I take care of this?
EDIT:
I was able to get the display of the top rows thanks to charlietfl and Tatermelon. But my rows get sliced off, and I haven't completely understood how to handle a case where user selects top 10 first and then top 11.
This is what I have tried.
In the function where I'm making the (entire) table for the first time, I saved the table as follows
function makeTable() {
//code to make table rbltbl
//code to make table rbltbl
//code to make table rbltbl
//code to make table rbltbl
//below line saves the table to $rows, so I can use it inside the click function below
$rows = $('#rbltbl tr').clone();
}
This is my function. Assume 'ben-count-set' is the number of values, the user wants to see. I think I should change var $table to read from $rows instead of rbltbl. But $rows gives empty here.
$("#ben-count-submit").click(function (event) {
event.preventDefault();
console.log("clicked on the update button");
var reqcount = document.getElementById('ben-count-set').value;
var $table = $("#rbltbl");
var $mystring = '#rbltbl tr:gt('+parseInt(reqcount)+')';
$($mystring).remove();
console.log($mystring);
$table.appendTo( $( "#rbl" ) );
}
Please advise.
If you want an array of the first 5 rows can get it right in a jQuery object using several different selectors
$('#mytbl tr:lt(5)');
You can can cache all the rows into a variable and still have access to them later regardless of what you do to the table...just clone them
var $rows = $('#mytbl tr').clone();
Want to remove all but top 5
$('#mytbl tr:gt(4)').remove();
then change out for another selection of rows clone the clone, filter them and insert
$('#mytbl').html( $rows.clone().slice(5, 10) );
If you are using jquery, then you can use the :lt selector:
var $firstRows = $('#mytbl').find('tr:lt(5)');
Then, you can clone them to append in your new table so that they will not be removed from your original table:
$( "#rbl" ).append($firstRows.clone());

Replacing divs that can be replaced in html/javascript

Hi i'm trying to replace some divs with other divs, this works fine but when i try to replace the second load of divs they don't change anymore.
Basicaly I'm trying to create a "winetour" that lets a user choose some options and generates the perfect wine to go along with it.
You get presented with a couple of options (img links) and if you click one the div's content changes and presents another set of clickable images taking you deeper in your process of choosing a great wine.
HTML:
<div id"Gelegenheid">
<img src="Images/Ontbijt.jpg" id="ontbijt" alt="Ontbijt">
<img src="Images/Borrel.jpg" id="borrel" alt="Borrel">
<img src="Images/Dinner.jpg" id="feest" alt="Diner">
<img src="Images/Feest.jpg" id="diner" alt="Feest">
</div>
<div id"Ontbijt" style="display: none"> Some content that shows trough the "tour"</div>
<div id"Borrel" style="display: none"> Some content that shows trough the "tour"</div>
<div id"Dinner" style="display: none">
<img src="Images/White.jpeg" id="ontbijt-licht" alt="ontbijt-licht">
</div>
<div id"Dinner-detail-voor" style="display: none"> Some content that shows trough the "tour"</div>
<div id"Dinner-detail-head" style="display: none"> Some content that shows trough the "tour"</div>
JavaScript:
function continueTour(i) {
if (i==1) {
document.getElementById("Gelegenheid").innerHTML = document.getElementById("Ontbijt").innerHTML;
} else if (i==2) {
document.getElementById("Gelegenheid").innerHTML = document.getElementById("Borrel").innerHTML;
} else if (i==3) {
document.getElementById("Gelegenheid").innerHTML = document.getElementById("Diner").innerHTML;
} else if (i==4) {
document.getElementById("Gelegenheid").innerHTML = document.getElementById("Feest").innerHTML;
} else {
document.getElementById("Dinner").innerHTML = document.getElementById("Dinner-detail-voor").innerHTML;
}
}
So basically if you click on a link that's inside the "Gelegenheid" div you will be taken to for example Dinner, but the problem is, inside dinner there are some more links and i want to link them for example to "Dinner-detail-voor"
I want to make this working with core JavaScript (so no JQuery) but i don't know what's going on?
Thanks in advance!
Found the answer.
Added
document.getElementById("from").style.display = "none" ;
document.getElementById("to").style.display = "table" ;
to each of the javscript index functions, now it works where 'from' is the father and 'to' is the child that is being linked to, not very neat but it works,
If someone has a shorter or alternative solution feel free to post!
first we create an array for all the content, array is base 0 so we start from function myFunction(0); next we create a tag with updated variable in them. the if statement is use to reset the variable when hit max. hope this help.
http://jsfiddle.net/xgay3f83/3/
function continueTour(i) {
var content = ['content 1', 'content 2', 'content 3', 'content 4'];
var target = document.getElementById('target');
var next = i + 1;
var end = content.length;
if(next>end) {
i = 0;
next = 1;
}
var openTag = '<a href="#" class="hvr-grow" onClick = "continueTour('+next+')">';
var closeTag = '</a>';
target.innerHTML = openTag+content[i]+closeTag;
}

split a big HTML page to pages on client side

I have a huge HTML page which is mainly a form which is mostly like this:
<FIELDSET id= '1'>
<TABLE>
<TR> </TR>
</FIELDSET>
</TABLE>
.
.
.
<FIELDSET id= 'n'>
<TABLE>
<TR> </TR>
</TABLE>
The number of fieldsets are generated by dynamically on the server.
Question: On the client side I want to do a pagination for this huge page, so that only say,3 fieldset appear per page on the client.
I don't want to change the way page is loading or form is being submitted currently.
Well just a little tips you may use
$('fieldset')
document.querySelectorAll('fieldset')
will return you fields
in order to get show only i .. i+3 fieldsets you can use
var i = 3
$('fieldset').hide().each(function ( index, el) {
if (index >= i && index < i+3) $(el).show()
})
var fieldsets = [].slice(document.querySelectorAll('fieldset'))
for (var index in fieldsets) {
var display = index < i && index >= i+3 ? 'none' : ''
fieldsets[index].style.display = display
}
Pagination won't really help you in any way other than visual if done on the client side (no speed increases, load reductions, etc), but if that's what you want you can do it with DOM manipulation. Something like the following might work for you:
var i=0,sets=document.getElementsByTagName('fieldset'),len=sets.length;
for(;i<len;i+=3) {
// wrap sets[i] through sets[i+2], as long as they exist, in a div
// if i !== 0, hide or minimize the div
}
// add controls to unhide/unminimize each div

Problems extracting parts from rendered HTML tables with jQuery

I need to grab certain parts from many tables, save them and finally generate a new table using a jQuery template. But I am having problems collecting the first value.
HTML
<table>
<tr><td colspan="7">atext1 atext2 - stuff 2 - <img src="img/icon_1.gif" class="icon" title="icon1" />12 - <img src="img/icon_2.gif" class="icon" title="icon2" />4 - <span title="long title"><img src="img/icon_3.gif" class="icon" /> stuff 5 </span></td></tr>
<tr><th><span title="title1">th1</span></th><th title="title2">th2</th><th title="title3">th3</th><th title="title4">th4</th><th title="title5">th5</th><th title="title6">th6</th><th title="title7">th7</th></tr>
<tr><td class="own" style="width:10px;"> </td><td>text</td><td><img src="img/icon_4.png" class="icon link" title="icon4" onclick="dothis(118965,[1324,1835,2296,2443,2960,2961,2962,2964,2976,3186,4901,4974]);" /> text</td><td>text</td><td class="right">24 (9)</td><td class="right">827</td><td class="right">11</td></tr>
MORE SIMILAR TRs HERE
</table>
JS
var savedData = [];
tbl = $('#table_1'); // Grab all content within div, which is a whole html table
var data = [];
$('tr', tbl).each(function(i, tr) {
// Begin the process to grab needed parts
if (i == 0) { // first row is special. it is colspan'ed
row = $('td', tr).html().split(' - '); // Splitting seems like the only way to get smaller html parts to work with
var a_href = $(row).find('a').attr('href'); // returns undefined
var a_href = $(row[0]).find('a').attr('href'); // returns undefined
var a_href = $('a', row).attr('href'); // returns undefined
var a_href = $('a', row[0]).attr('href'); // returns undefined
// Grab id only. I thought this would work
data['id'] = $('a', row[0]).attr('href').match(/view=page&id=([0-9]+)/)[1];
// Grab the other parts
} else {
// do stuff for other rows
}
});
savedData.push[data];
1) Why am I getting undefined ? 'row' becomes an array when splitting the inner html
2) I also have at least 1 tr with only th cells. Would it faster those rows where excluded from the .each(), like with a sub selector, or just ignore it (like if ($('td', tr).length > 0) { // do stuff }) ?
3) If I just grab all text() from all td in all tr then using jQuery.map() is about 3-4 times faster than jQuery.each(i,v). Any idea why ?
I can use $('td[colspan], tr) to grab first row, but jQuery.each() is easy to understand and thus to work with
4) When I need to use the collected parts in the template, can I then use savedData[0].id ?
I got my answer here How to extract multiple parts from a html string with jQuery?

Categories