Get tr element with document.querySelector - javascript

I trying to get a tr element using the document.querySelector sentence, but I get :
TypeError: tempNode.querySelector(...) is null
My selector in Javascript is: document.querySelector("#row-model")
This is working with other element (with a div to be exact) but with it, I tried others selectors (using the datatype, the tr, etc, but always I get the same error)...Then in the browser console I checked the existence of the element, the HTML of the element is as follows:
<table>
<tbody>
<tr class="" id="row-model" data-id="myid" data-type="rowtemplate">
<td class="category">
</td>
<td class="title showTipTip">
<a data-cats="" href="#profile" id="title" aria-controls="profile" role="tab" data-toggle="tab" title="" data-id="" class="spotlink" address="true"></a>
</td>
<td class="comments">
<a class="spotlink" href="#comments" title="" id="commentValue"> commentValue
</a>
</td>
<td class="genre">
catdesc
</td>
<td class="poster">
poster
</td>
<td class="date" id="since"></td>
<td class="filesize" id="filesize">
</td>
<td class="nzb">
NZB
</td>
<td class="multinzb">
<input onclick="multinzb()" name="messageid[]" value="" type="checkbox">
</td>
</tr>
</tbody>
</table>
EDITED:
The JS code inside the function is:
$('#catalog').each(function(){
var tempNode = document.querySelector("#row-model").cloneNode(true); //I clone the element and then append it to another table
tempNode.querySelector("a #category").textContent = "test";
$('#spotsTable tr:last').after(tempNode);
});
Also, I have the table inside a div with hidden class (bootstrap), maybe it can affect it?

Related

Same filter for ng-repeat inside another ng-repeat

Same filter for ng-repeat inside another ng-repeat
I make a table where I need to combinate col from different array's. The first array is the list of same data. The first col is number, when this number is empty, I get another number from second array.
Then a I have search box and for searching I using just this number from the first col. I using ng-model for filter in table, but I can't this filter for both ng-repeat.
search box
<div calss="input-lg">
<input name="value" id="input" type="text" class="input-lg"
placeholder="Search in DM-TEC" ng-model="searchDM" ng-virtual-keyboard="
{size: 9, relative: false}"/>
</div>
html table
<tbody ng-repeat="roll in vykresy | filter: searchDM">
<tr ng-repeat="re in RE | filter: searchDM" ng-if="roll.id === 'RE'">
<td> {{re.num}}</td>
<td> {{roll.name}} </td>
<td rowspan="{{RE.length}}" ng-if="$index===0" style="vertical-align: middle;"> {{roll.numberD}} </td>
<td rowspan="{{RE.length}}" ng-if="$index===0" style="vertical-align: middle;"> <a ng-href=" ./pdf/{{roll.numberD}}.pdf">{{roll.numberD}}.pdf</a> </td>
</tr>
<tr ng-repeat="rel in REL | filter: searchDM" ng-if=" roll.id === 'REL'">
<td> {{rel.numberPN}} </td>
<td> {{roll.name}} </td>
<td rowspan="{{REL.length}}" ng-if="$index===0" style="vertical-align: middle;"> {{roll.numberD}} </td>
<td rowspan="{{REL.length}}" ng-if="$index===0" style="vertical-align: middle;"> <a ng-href=" ./pdf/{{roll.numberD}}.pdf">{{roll.numberD}}.pdf</a> </td>
</tr>
<tr ng-repeat="re_l in RE_L | filter: searchDM" ng-if=" roll.id === 'RE_L'">
<td> {{re_l.numberPN}} </td>
<td> {{roll.name}} </td>
<td rowspan="{{RE_L.length}}" ng-if="$index===0" style="vertical-align: middle;"> {{roll.numberD}} </td>
<td rowspan="{{RE_L.length}}" ng-if="$index===0" style="vertical-align: middle;"> <a ng-href=" ./pdf/{{roll.numberD}}.pdf">{{roll.numberD}}.pdf</a> </td>
</tr>
<tr ng-if="roll.id === 'PVR'">
<td> {{roll.numberPN}} </td>
<td> {{roll.name}} </td>
<td> {{roll.numberD}} </td>
<td> <a ng-href=" ./pdf/{{roll.numberD}}.pdf">{{roll.numberD}}.pdf</a> </td>
</tr>
angular
$scope.search = '';
The filter work just only tbody ng-repeat or just inside, but I need use this filter for both.
Thanks in advance!
Best regards
David
You are using common ng-model on both filter.
As result ,
ng-repeat="roll in vykresy | filter: searchDM"
If the tbody is getting hidden because of the filter result,
your inner filter has no chance to show the result.
The result inner ng-repeat of which is inner DOM will automatically get removed.So,you can not see it.

aaSorting in datatables not working properly

I have the following html in my first column. It shows a icon and an anchor tag.
<tr class="even">
<td class=" sorting_1">
<span data-sortvalue="0">
<img title="icon" src="icon.png">
0
</span>
</td>
</tr>
<tr class="odd">
<td class=" sorting_1">
<span data-sortvalue="1">
<img title="icon" src="icon.png">
1
</span>
</td>
</tr>
<tr class="even">
<td class=" sorting_1">
<span data-sortvalue="2">
<img title="icon" src="icon.png">
2
</span>
</td>
</tr>
....................
...................
...................
I am using aaSorting[0, 'asc']
In chrome, the 0 value is always staying at the top if the column is sorted either ascending or descending. All the remaining values are getting sorted accordingly.
In firefox, the sorting is completely broken.
The data attributes for sorting on your span tags need to be on the td tag. They should also be changed to just 'data-sort' or 'data-order'.
Check out DataTables data-attributes docs here
<tr class="even">
<td class=" sorting_1" data-sort="0">
<span>
<img title="icon" src="icon.png">
0
</span>
</td>
</tr>
...
...

Scroll to element in modal div

I'm using JQuery load() to place a page into a modal div set to overflow-y:auto; At the top of the loaded page inside the modal div, I want to click on an element (actually a table cell...) that will scroll the page down to a specific div:
<div id='haematopoietic_section' class='cap_h2'>Haematopoietic</div>
The code in the loaded page contains:
$('#haematopoietic').click(function(){
$(document).scrollTop($('#haematopoietic_section').offset().top);
});
The above code isn't doing anything. I can throw an alert in the click event, but it won't scroll. Any ideas?
See example at https://jsfiddle.net/z7m4c38d/3/ Note that this fiddle does not use JQuery load, but instead has code fixed inside the div...problem remains...
use the below code, in your click event
var container = $('body'),
scrollTo = $('#haematopoietic_section');
container.scrollTop(
scrollTo.offset().top - container.offset().top + container.scrollTop()
);
Since the div is contained in <div id = 'cap_module_holder'> .... </div>
so your container variable should be:
var container = $('#cap_module_holder');
i have added an extra div in middle to increase height so that you can see the scroll effect.
<div id='module_container'>
<div id='cap_module_holder'>
<p class='cap_h1'>Bone Tumours</p>
<p>Introduction</p>
<p>
<br>In the first three decades of life, benign tumours are the most frequent. In the elderly, a bone tumour is likely to be malignant, either primary or a metastasis.</p>
<p class='cap_h2'>Primary tumours involving bone</p>
<p>These are all derived from tissue of mesodermal origin.</p>
<table width="auto" border="0" align="center" cellspacing="3">
<tr>
<td width="208" valign="top">
<p align="center"><strong>Histological classification</strong>
</p>
</td>
<td width="208" valign="top">
<p align="center"><strong>Benign</strong>
</p>
</td>
<td width="208" valign="top">
<p align="center"><strong>Malignant</strong>
</p>
</td>
</tr>
<tr>
<td id='haematopoietic' class='cap_t2' width="208" valign="top">
<p>Haematopoietic</p>
</td>
<td class='cap_t3' width="208" valign="top">
<p>Haemangioma</p>
</td>
<td class='cap_t3' width="208" valign="top">
<p>Myeloma
<br>Malignant  lymphoma</p>
</td>
</tr>
<tr>
<td class='cap_t2' width="208" valign="top">
<p>Chondrogenic</p>
</td>
<td class='cap_t3' width="208" valign="top">
<p>Osteochondroma
<br>Chondroma
<br>Chondromyxoid fibroma</p>
</td>
<td class='cap_t3' width="208" valign="top">
<p>Chondrosarcoma
<br>Dedifferentiated -Chondroblastoma</p>
</td>
</tr>
<tr>
<td class='cap_t2' width="208" valign="top">
<p>Osteogenic</p>
</td>
<td class='cap_t3' width="208" valign="top">
<p> Osteoma                           Osteoid osteoma
<br>Osteoblastoma</p>
</td>
<td class='cap_t3' width="208" valign="top">
<p>Osteosarcoma</p>
</td>
</tr>
<tr>
<td class='cap_t2' width="208" valign="top">
<p>Fibrogenic</p>
</td>
<td class='cap_t3' width="208" valign="top">
<p>Fibrous cortical defect
<br>Non-ossifying fibroma</p>
</td>
<td class='cap_t3' width="208" valign="top">
<p>Fibrosarcoma</p>
</td>
</tr>
<tr>
<td class='cap_t2' width="208" valign="top">
<p>Neuroectodermal</p>
</td>
<td width="208" valign="top">
<p> </p>
</td>
<td class='cap_t3' width="208" valign="top">
<p>Ewing’s sarcoma</p>
</td>
</tr>
<tr>
<td class='cap_t2' width="208" valign="top">
<p>Notochordial</p>
</td>
<td class='cap_t3' width="208" valign="top">
<p>Benign notochordal cell tumour      </p>
</td>
<td class='cap_t3' width="208" valign="top">
<p>Chordoma</p>
</td>
</tr>
<tr>
<td class='cap_t2' width="208" valign="top">
<p>Odontogenic</p>
</td>
<td class='cap_t3' width="208" valign="top">
<p>Giant cell tumour</p>
</td>
<td class='cap_t3' width="208" valign="top">
<p>Ameloblastoma
<br>
</p>
</td>
</tr>
<tr>
<td class='cap_t2' valign="top">Unknown origin</td>
<td class='cap_t3' valign="top">Unicameral cyst
<br>Aneurysmal bone cyst</td>
<td valign="top"> </td>
</tr>
</table>
<div style = "height:500px;" >ok </div>
<div id='haematopoietic_section' class='cap_h2'>Haematopoietic</div>
</div>
</div>
A more recent solution using only JavaScript:
var element = document.getElementById("scroll-here")
element.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' })
See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
Late to the party here, but I am posting this in the hopes that it helps someone else who is beating their heads against the wall about scrolling inside modals.
In my case I had multiple modals that could be opened (but just one at a time), and within each modal was a form that needed to be validated on submission. I wanted it to scroll to the first invalid form input on submission.
The key thing here is that you want to scroll the contents inside the modal, not the page behind the modal, nor the position of the modal itself against the background page. So to do this you need to do the following:
1) Structure your modals correctly. Put an id into the div that has the class='modal fade' and then make sure the 'modal-body' has its own id, in this case 'newExpenseForm18'. (note I use a 'key' attribute to tell me which modal is open).
<div class="modal fade uploadExpense in" key="18" id="uploadExpense18" role="dialog" >
<div class="modal-dialog text-left">
<div class="modal-content" id="modalcontent18">
<div class="modal-header">
</div>
<div class="modal-body" id="newExpenseForm18">
..... etc followed by (at some point)
<div id = 'myExpense18'>
..... etc
2) Now you need to get three ids: the whole modal ( in this case "uploadExpense18"), the container div ( in this case "theform18"), and the target div to which you want to scroll, in this case "myExpense18". You can get these thus:
var modalId = $('.modal:visible').attr('id');
var key = $('.modal:visible').attr('key');
var bodyId = 'newExpenseForm'+key;
var targetId = 'myExpense'+key;
3) Now you find out the distance you need to scroll. To do this, find the offset of the target div, relative to the top of the page, and also the offset of the modal-body, relative to the top of the page
var position = $('#'+targetId).offset().top;
var position2 = $('#'+bodyId).offset().top;
4) subtract one from the other to get the offset of the target relative to the container div.
var distance = position-position2;
5) and, finally, scroll the body of the modal inside the modal div, so that the target is now at the place where the top of the container used to be:
$('#'+modalId).animate({ scrollTop: distance }, "slow");
Hope that helps someone!

Using checkboxes to update a total row based on images

I am working on code which updates a total row based on when a checkbox is checked based on whether or not an image in that row is the correct image.
Here is the HTML:
<table border="1">
<tr> <!-- Table Header -->
<td>
Checkbox
</td>
<td>
Items
</td>
<td>
Area 1
</td>
<td>
Area 2
</td>
<td>
Area 3
</td>
</tr>
<tr id="checkRow"> <!-- Row 1 -->
<td>
<form>
<input type="checkbox" name="Row1" value="Row1" onchange="onCheck(this);">
</form>
</td>
<td>
Item 1
</td>
<td class="imageBox">
<img id="image1" src="yes.png" alt="Needed">
</td>
<td class="imageBox">
<img id="image2" src="yes.png" alt="Needed">
</td>
<td class="imageBox">
<img id="image3" src="no.png" alt="Needed">
</td>
</tr>
<tr> <!-- Row 2 -->
<td>
<form>
<input type="checkbox" name="Row2" value="Row2" onchange="onCheck(this);">
</form>
</td>
<td>
Item 2
</td>
<td class="imageBox">
<img src="yes.png" alt="Needed">
</td>
<td class="imageBox">
<img src="yes.png" alt="Needed">
</td>
<td class="imageBox">
<img src="no.png" alt="Needed">
</td>
</tr>
<tr> <!-- Row 3 -->
<td>
<form>
<input type="checkbox" name="Row3" value="Row3" onchange="onCheck(this);">
</form>
</td>
<td>
Item 3
</td>
<td class="imageBox">
<img src="yes.png" alt="Needed">
</td>
<td class="imageBox">
<img src="yes.png" alt="Needed">
</td>
<td class="imageBox">
<img src="yes.png" alt="Needed">
</td>
</tr>
<tr> <!-- Row 4 -->
<td>
<form>
<input type="checkbox" name="Row4" value="Row4" onchange="onCheck(this);">
</form>
</td>
<td>
Item 4
</td>
<td class="imageBox">
<img src="yes.png" alt="Needed">
</td>
<td class="imageBox">
<img src="yes.png" alt="Needed">
</td>
<td class="imageBox">
<img src="no.png" alt="Needed">
</td>
</tr>
<tr id="outputRow"> <!-- Table Bottom -->
<td>
<!--Empty-->
</td>
<td>
Summation
</td>
<td id="total1">
0
</td >
<td id="total2">
0
</td>
<td id= "total3">
0
</td>
</tr>
</table>
Here is the Javascript (using jQuery)
//Numbers in the total row (Summation)
var total1=0;
var total2=0;
var total3=0;
function onCheck(cb)
{
var $box = $(cb);
var imageBoxes = $box.parents('td.imageBox');
if(cb.checked===true)
{
//Checks the image in the row. If it is yes.png, it adds 1 to to the total
//for that column and displays that total variable in the total row.
/*if(document.getElementById('image1').src.toString().indexOf('yes')>0){
total1++;
document.getElementById('total1').innerHTML=total1;
} */
if(imageBoxes[0].children().attr('src').toString().indexOf('yes')>0){
total1++;
document.getElementById('total1').innerHTML=total1;
}
/*else
{
document.getElementById('total1').innerHTML=no;
} */
if(document.getElementById('image2').src.toString().indexOf('yes')>0){
total2++;
document.getElementById('total2').innerHTML=total2;
}
/* else
{
document.getElementById('total2').innerHTML=no;
} */
if(document.getElementById('image3').src.toString().indexOf('yes')>0){
total3++;
document.getElementById('total3').innerHTML=total3;
}
/*else
{
document.getElementById('total3').innerHTML=no;
} */
}
//If the checkbox is unchecked, this checks for
//if the image in each box in that row is
//yes.png. If it is, then 1 is subtracted from the
//column's total and the new total is shown.
else
{
if(document.getElementById('image1').src.toString().indexOf('yes')>0){
total1--;
document.getElementById('total1').innerHTML=total1;
}
if(document.getElementById('image2').src.toString().indexOf('yes')>0){
total2--;
document.getElementById('total2').innerHTML=total2;
}
if(document.getElementById('image3').src.toString().indexOf('yes')>0){
total3--;
document.getElementById('total3').innerHTML=total3;
}
}
}
I built this in Fiddle, so all the Script imports are not shown.
EDIT: Here is the link to the Fiddle: hhttp://jsfiddle.net/GGxpX/62/
EDIT: It was pointed out that my Id's were repeating. I fixed this in the new fiddle, but this did not fix the problem.
EDIT3: Fixed more problems including using a td element as its image child. The link points to the updated Fiddle now.
EDIT4: Updated Fiddle again.
If I understand what you want, I think you are making this more complicated than it needs to be. (Correct me if I'm wrong.) I would have the handler for the checkboxes re-calculate the totals each time.
The JavaScript could be this short:
function onCheck() {
var totals = [0, 0, 0];
$('tr.checkRow').each(function () {
var $row = $(this);
if ($row.children('td:first').find('input:checkbox').prop('checked')) {
$(this).find('td.imageBox').each(function (index) {
var $imageBox = $(this);
if ($imageBox.children('img:first').attr('src').indexOf('yes') >= 0) {
++(totals[index]);
}
});
}
});
$('#total1').text(totals[0]);
$('#total2').text(totals[1]);
$('#total3').text(totals[2]);
}
Notice how the onCheck() function doesn't even take a parameter. That's because it doesn't matter what checkbox was changed, or if it was checked or unchecked.
This loops through each row, and if its checkbox is checked, it loops through each image box.
In order for the code above to work, you must put the class "checkRow" on the proper <tr> elements. (You previously had it as an "id" on those elements.)
jsfiddle
There were several things I saw wrong with your code. Here's a few:
"id" attributes must be unique.
When checking the result of calling .indexOf() use >= 0, not > 0.
imageBoxes[0] returns a DOM element, not a jQuery object.
There is no need for the calls to toString() because the src attribute is a string.
You could also attach your event handlers with jQuery, rather than use "onchange" attributes, but I left it your way in the jsfiddle.

Getting the 'co-ordinates' of a <TD> cell using jQuery

I'm building somewhat of a different website, below is my HTML markup and my question. Please don't be put off by this wall of text, I'm sure it's really not a difficult problem for someone who know's their stuff but it takes some explaining.
<div id="0" class="cell" style="top: 0px; left: 0px;">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tbody>
<tr id="0">
<td id="0"> </td>
<td id="1"> </td>
<td id="2"> </td>
<td id="3"> </td>
<td id="4"> </td>
<td id="5"> </td>
<td id="6"> </td>
<td id="7"> </td>
<td id="8"> </td>
<td id="9"> </td>
<td id="10"> </td>
<td id="11"> </td>
<td id="12"> </td>
<td id="13"> </td>
<td id="14"> </td>
<td id="15"> </td>
</tr>
<tr id="1">
<td id="0"> </td>
<td id="1"> </td>
<td id="2"> </td>
<td id="3"> </td>
<td id="4"> </td>
<td id="5"> </td>
<td id="6"> </td>
<td id="7"> </td>
<td id="8"> </td>
<td id="9"> </td>
<td id="10"> </td>
<td id="11"> </td>
<td id="12"> </td>
<td id="13"> </td>
<td id="14"> </td>
<td id="15"> </td>
</tr>
</tbody>
</table>
</div>
This markup is repeated in a tiling sort of pastern in order to fill the entire page. A similar DIV might be:
<div id="1" class="cell" style="top: 144px; left: 0px;">
<!-- The rest of the table code here... -->
</div>
If you can't see it already, I'm creating a load of cells across the entire page sorted into DIVs. Now, when a user clicks into a cell (one of the <td>'s), I want to get it's co-ordinates represented by: 0, 1, 5.
In this example, 0, 1, 5 is the DIV with id of 0, the TR element inside that DIV with the ID of 1, and lastly the cell inside that TR element with an ID of 5. I wanted to write a javascript function to get these co-ordinates, but I am at a complete loss on what parameters to pass, and little idea how I can get out the co-ordinates.
From as far as I can think once I can pass a click event(?) to the function I can look at the <td>'s parent elements and get their IDs?
If anyone can provide a solution to this problem or provide any input, it'd be greatly appreciated.
Since it is not valid to begin an ID with a number, I'll offer a different solution.
Since your IDs are basically index numbers, you can use jQuery's .index() method to get what you need.
Test it here: http://jsfiddle.net/hBarW/
$('td').click(function(){
var $th = $(this);
var td_idx = $th.index();
var tr_idx = $th.closest('tr').index();
var div_idx = $(this).closest('div').index();
alert(td_idx + ' ' + tr_idx + ' ' + div_idx);
});
Use the closest jQuery function, which returns the parent element that you specify.
Like this:
$("td").click(function () {
var parentDIVId = $(this).closest("div").attr("id");
var parentTRId = $(this).closest("tr").attr("id");
var myId = $(this).attr("id");
}
try
$('td').click(function(){
var td = this.id;
var tr = $(this).closest('tr').attr('id');
var div = $(this).closest('div').attr('id');
});
you can test it here.
more on .closest() here
the easy thing would be
$('td').click(function(){
$this = $(this);
alert( $this.closest('div').attr('id') + ',' + $this.closest('tr').attr('id') + ',' + $this.attr('id'));
});
But you have some issues..
you cannot have numbers as IDs
IDs should be unique inside the DOM ...

Categories