Use jQuery arguments in JavaScript function - javascript

I want to use a jQuery argument in a JavaScript function. At the moment, my code looks like this:
window.nextGen = function(cell) {
// code...
}
window.prepareNextGen = function() {
nextGen($('#grundtabelle').rows[1].cells[1]);
}
But that doesn't work. Any help?

Simple Fix
To access the table object rows and cells you can simply add an array index like so:
nextGen( $('#grundtabelle')[0].rows[1].cells[1] );
See this previous question for more detail: How to get a DOM Element from a JQuery Selector
Run the snippet to try
nextGen( $('#grundtabelle')[0].rows[1].cells[1] );
function nextGen( cell ) {
console.info( cell.innerHTML ); // displays B1
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<table id="grundtabelle">
<tr>
<td>A0</td>
<td>B0</td>
</tr>
<tr>
<td>A1</td>
<td>B1</td>
</tr>
<tr>
<td>A2</td>
<td>B2</td>
</tr>
</table>

A jQuery object does not have a rows or cells property. Assuming you're trying to get the second td of the second tr (note that the indexes are zero-based, so the item with index of 1 is the second), then you need to use jQuery's DOM traversal methods. In this case, find() and :eq. Try this:
nextGen($('#grundtabelle').find('tr:eq(1) td:eq(1)'));
If the nextGen() function is expecting a DOMElement instead of a jQuery object then you can retrieve that from the jQuery object like this:
nextGen($('#grundtabelle').find('tr:eq(1) td:eq(1)')[0]);
// or:
nextGen($('#grundtabelle').find('tr:eq(1) td:eq(1)').get());

Related

Is there way to parse tr returned by 'this'?

Each row of my table has a button at the end of the row, which has an addEventListener like this,
button.addEventListener ("click", function() {
deleteSummary(this);
});
function deleteSummary(oButton)
{
console.log(oButton.parentNode.parentNode.innerHTML)
}
the console.log shows like this,
<td>966</td><td>TypeA</td><td>1234</td><td>10,000</td><td>9,861</td><td>139</td><td>2021-01-02</td><td>3</td><td>7</td><td>8</td><td>7</td><td>89</td><td>9</td><td>8</td><td>7</td><td>1</td><td><button>delete</button></td>
But I have no idea how to parse(?) it.
I always found answers you use document.getElementById() when googling.
Thanks
You should not aim to parse HTML. You have access to the DOM, so stick with that. You already found the tr element successfully, and then you can for instance use its cells property to get access to all the td elements, and you could map that list of cells to their text content. That way you get a standard array with all the cell texts of that particular row.
let buttons = document.querySelectorAll("td>button");
for (let button of buttons) {
// Your code:
button.addEventListener ("click", function() {
deleteSummary(this);
});
}
function deleteSummary(oButton) {
let tr = oButton.parentNode.parentNode;
let data = Array.from(tr.cells, cell => cell.textContent);
data.pop(); // Optional: get rid of the column with the delete button
console.log(data);
}
<table>
<tr>
<td>966</td>
<td>TypeA</td>
<td>1234</td>
<td>10,000</td>
<td>2021-01-02</td>
<td><button>delete</button></td>
</tr>
<tr>
<td>123</td>
<td>TypeB</td>
<td>9988</td>
<td>29,999</td>
<td>2020-09-20</td>
<td><button>delete</button></td>
</tr>
</table>

How to check whether a html column contains empty cells?

I want to check whether a cells of a certain column of a html table is filled completely. The 5th column of the #mf-table could not be kept unfilled.
I used following function to select the column. It works fine.
$.fn.column = function(i) {
return $('tr td:nth-child('+(i+1)+')', this);
}
I used the following method to pop up a warning if column has empty cells.
if ($('#mf-table').column(5).is(":empty")) {
toastr.error('Fill empty fields');
}
This method does not working. Can any one tell what is wrong here?
edit:
I tried following method. In order to test my code I colored the column 5 and it works fine. Here I have considered a situation where any of the cell is empty in whole table
if ($('#mf-table tr td').is(":empty")) {
$('#mf-table').column(5).css( "background-color", "red" )
}
So in the above method, if at least one cell is empty, the column 5 is colored. I need help to alter this method to check whether at least one cell is empty in column 5.
Try this :
jQuery('table tr').each(function(){
if(jQuery(this).children('td:empty').length > 0){
console.log('Ther is Empty Cell');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>20</td>
<td>20</td>
<td>20</td>
<td></td>
</tr>
</tbody>
</table>
Try to use this function instead (copied from here):
function isEmpty( el ){
return !$.trim(el.html())
}

Is there simple way to get array from td elements on page? (node.js/cheerio/jQuery)

I am using node.js/cheerio (the same as jQuery syntax) to parse the page.
And when I am using:
$ = cheerio.load(body);
console.log($('.td-title a').text());
I have in my console very long string from words "mainaboutcontactusprofile" etc. How can I make an array of td text?
None of the answers provided worked for me, but this did.
let arr = $('.td-title a').toArray().map((x) => { return $(x).text()});
Credit: Github
jQuery's map()
console.log($("td").map(function(){ return this.textContent}).get());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
</tr>
</table>
I suggest using jQuery's $.map() function for this. It creates an array based on a matched set of elements:
var textArray = $('.td-title a').map( function(index, domElement) {
return domElement.innerText; //each element input gets turned into text output
});
console.log( textArray );
See http://api.jquery.com/map/ for more details
in javascript
simply document.getElementsByTagName("td") return an array of all td.
Using jQuery you should use something like $('#table1 td')

JQuery .parent click

The use of "this" and ".parent()" in jquery gets a bit confusing when it goes past simple divs or datatables. I have a table with the following structure: (I can't rename any of the classes or id)
<table class="table1">
<tbody>
<tr>
<div class="detail">
<table>
<thead></thead>
<tbody>
<tr>
<td>
<img class="picture_open" src="../location">
</td></tr></tbody></table></div></tr></tbody></table>
What I'm trying to do is have a click function on that img which will be able to grab the full RowElement.
What I have now:
$(".table1 tbody tr td img.picture_open").live('click', function () {
var overallTable = jQuery(this).parent("table").dataTable();
console.log("overallTable: " + overallTable);
var elementRow = this.parentNode.parentNode;
console.log("elementRow: " + elementRow);
var rowData = overallTable.fnGetData( elementRow );
console.log("rowData: " + rowData);
if ( this.src.match('img_name') )
{
//kills the table that was created if that row is opened
}
else
{
//runs ajax call to create another table since row is NOT opened
}
} );
However the code I have above prints out this:
overallTable: [object Object]
elementRow: [object HTMLTableRowElement]
TypeError: 'null' is not an object (evaluating 'oSettings.aoData')
In my problem is the $(this) incorrect? (Not getting the img with class "picture_open")
Or is my overallTable variable set up incorrectly with the .parent()?
Or is it my elementRow variable set up improperly with the parentNode?
Any help to clarify my errors would be amazing.
Thanks!
parent() in jQuery will parse only one level up the DOM, you should use .parents()/.closest(). This will fix your issue.
NOTE: .live() is turned into .on() in latest jQuery versions. Better to use .on()/.click()
parent() in jQuery only moves one level up the DOM, so what you probably want there is parents('table'). This should fix your overallTable issue.
in jQuery, .parent() only goes up the DOM once. What you should be using it .parents() to look up the DOM until it finds table
You need to use .closest('table') to find the closest table
Similary to find the element row
var elementRow = $(this).closest('tr');
Try this :
$('.table1').on('click', '.picture_open', function(ev) {
this // is .picture_open element
ev.target // is .picture_open element
ev.delegateTarget // is .table1 element
var $row = $(ev.delegateTarget).find('.detail tr').first();
});

jQuery to find all previous elements that match an expression

Using jQuery, how do you match elements that are prior to the current element in the DOM tree? Using prevAll() only matches previous siblings.
eg:
<table>
<tr>
<td class="findme">find this one</td>
</tr>
<tr>
<td>find the previous .findme</td>
</tr>
<tr>
<td class="findme">don't find this one</td>
</tr>
</table>
In my specific case, I'll be searching for the first .findme element prior to the link clicked.
Ok, here's what I've come up with - hopefully it'll be useful in many different situations. It's 2 extensions to jQuery that I call prevALL and nextALL. While the standard prevAll() matches previous siblings, prevALL() matches ALL previous elements all the way up the DOM tree, similarly for nextAll() and nextALL().
I'll try to explain it in the comments below:
// this is a small helper extension i stole from
// http://www.texotela.co.uk/code/jquery/reverse/
// it merely reverses the order of a jQuery set.
$.fn.reverse = function() {
return this.pushStack(this.get().reverse(), arguments);
};
// create two new functions: prevALL and nextALL. they're very similar, hence this style.
$.each( ['prev', 'next'], function(unusedIndex, name) {
$.fn[ name + 'ALL' ] = function(matchExpr) {
// get all the elements in the body, including the body.
var $all = $('body').find('*').andSelf();
// slice the $all object according to which way we're looking
$all = (name == 'prev')
? $all.slice(0, $all.index(this)).reverse()
: $all.slice($all.index(this) + 1)
;
// filter the matches if specified
if (matchExpr) $all = $all.filter(matchExpr);
return $all;
};
});
usage:
$('.myLinks').click(function() {
$(this)
.prevALL('.findme:first')
.html("You found me!")
;
// set previous nodes to blue
$(this).prevALL().css('backgroundColor', 'blue');
// set following nodes to red
$(this).nextALL().css('backgroundColor', 'red');
});
edit - function rewritten from scratch. I just thought of a much quicker and simpler way to do it. Take a look at the edit history to see my first iteration.
edit again - found an easier way to do it!
Presumably you are doing this inside an onclick handler so you have access to the element that was clicked. What I would do is do a prevAll to see if it is at the same level. If not, then I would do a parent().prevAll() to get the previous siblings of the parent element, then iterate through those backwards, checking their contents for the desired element. Continue going up the DOM tree until you find what you want or hit the root of the DOM. This a general algorithm.
If you know that it is inside a table, then you can simply get the row containing the element clicked and iterate backwards through the rows of the table from that row until you find one that contains the element desired.
I don't think there is a way to do it in one (chained) statement.
edit: this solution works for both your original problem, the problem you mention in your first comment, and the problem you detail in the comment after that.
$('.myLinks').click(function() {
var findMe = '';
$(this).parents().each(function() {
var a = $(this).find('.findme').is('.findme');
var b = $(this).find('.myLinks').is('.myLinks');
if (a && b) { // look for first parent that
// contains .findme and .myLinks
$(this).find('*').each(function() {
var name = $(this).attr('class');
if ( name == 'findme') {
findMe = $(this); // set element to last matching
// .findme
}
if ( name == 'myLinks') {
return false; // exit from the mess once we find
// .myLinks
}
});
return false;
}
});
alert(findMe.text() ); // alerts "find this one"
});
this works for your example in the OP as well as a modified example as explained in the comments:
<table>
<tr>
<td class="findme">don't find this one</td>
</tr>
<tr>
<td class="findme">find this one</td>
</tr>
<tr>
<td>find the previous .findme</td>
</tr>
<tr>
<td class="findme">don't find this one</td>
</tr>
</table>
as well as this test case which you added:
<table>
<tr>
<td class="findme">don't find this one</td>
</tr>
<tr>
<td class="findme">don't find this one</td>
</tr>
<tr>
<td class="findme">find this one</td>
</tr>
</table>
find the previous .findme
I usually number elements (1,2,3..) (rel="number"), so then i use this code to give class to all previous elements:
var num = $(this).attr("rel");
for (var i = 1; i<=num; i++)
{
$('.class[rel="'+i+'"]').addClass("newclass");
}
had the same problem, heres what i came up with. my function uses compareDocumentPosition. dont know how it compares to the other solutions in terms of performance though.
$.fn.findNext = function ( selector ) {
var found, self = this.get(0);
$( selector )
.each( function () {
if ( self.compareDocumentPosition( this ) === 4 ){
found = this;
return false;
}
})
return $(found);
}
of course one could change this quite easily to fetch ALL elements following the calling element.
$.fn.nextALL= function ( selector ) {
var found = [], self = this.get(0);
$( selector )
.each( function () {
if ( self.compareDocumentPosition( this ) === 4 )
found.push(this);
})
return $(found);
}
EDIT: streamlined version
$.fn.findNext = function( s ){
var m = this[0], f=function(n){return m.compareDocumentPosition(n)===4;};
return this.pushStack( $(s).get().filter(f) );
}

Categories

Resources