I am programmatically populating options to increase and decrease the value of an element and store the same in the DB table. To get a better idea, consider the following example:
<tr>
<td id="name_1">Element 1</td>
<td>increase icon</td>
<td>decrease icon</td>
</tr>
<tr>
<td id="name_2">Element 2</td>
<td>increase icon</td>
<td>decrease icon</td>
</tr>
<tr>
<td id="name_n">Element n</td>
<td>increase icon</td>
<td>decrease icon</td>
</tr>
Whenever I click any among the n increase / decrease icon, I need to access the value of #name_n. For which, I wrote the following function:
$(".increase").click(function(){
var id = $(this).attr('id'); //get the id of the element that was clicked.
console.log(id);
var arr = id.split("_"); //split to get the number
var no = arr[1]; //get the number
var name = $("#name_"+no).text(); //get the required value in name_n
console.log(name);
});
//replica for decrease class as well.
Problem :
Every time I click any increase icon, in my console, I'm getting id as inc_1 only! So, the value of name is Element 1 always. Same happens with click function for .decrease.
I have tried with the following ways to get the id:
var id = this.id;
var id = $(this).get(0).id;
var id = $(this)[0].id;
But nothing changed. The same problem persists. What's wrong and how do I resolve this?
Your code looks correct at first glance. Maybe there is some issue with rendering, perhaps the elements really get the same ID.
However, I would recommend a different approach for this task, without using ID's. You can achieve your goal by referencing the TD element relatively to the clicked increase/decrease button. I mean something like this.
$(".increase").click(function(){
var $td = $(this).closest("tr").children(":eq(0)"); //get the TR's first TD
var name = $td.text(); //get the required value in name_n td
console.log(name);
});
You could add a more generic class on the elements you wish tou target after the click(currently #name_n) and use the .closest and .siblings methods.
html
<tr>
<td id="name_n" class="target">Element n</td>
<td>increase icon</td>
<td>decrease icon</td>
</tr>
js
$(".increase").click(function(){
var name = $(this).closest('td').siblings('.target').text();
console.log(name);
});
Here is a working demo https://jsfiddle.net/0hru2jtx/
Related
I have this code (opt1) to get the text of the cell, which is clicked, but this alerts all of the objects in the table as its in a loop. But when I place it outside the loop I just get a random text from the table and not the one which is clicked (opt2).
I need the textContent of the cell, which is clicked, once, and not any other.
FYI: the cell contains multiple <td> inside <tr>.
The current method gets me the name text either of all cells (opt1) or the last cell (opt2)
HTML:
<table id="table">
<tr class="cell" onclick="RowHandlers()">
<td class="name">Name</td>
<td class="date">Date</td>
<td class="subject">Subject</td>
</tr>
</table>
opt1
function RowHandlers() {
var table = document.getElementById("table");
var name;
for (var i=1;i<table.rows.length;i++) {
name = table.rows[i].cells[0].innerText;
alert(name);
}
}
opt2
function RowHandlers() {
var table = document.getElementById("table");
var name;
for (var i=1;i<table.rows.length;i++) {
name = table.rows[i].cells[0].innerText;
}
alert(name);
}
Your problem seems to be identifying the clicked row after a click has happened.
We can solve this in multiple ways:
In JS, use the event object's target property:
(Preferred) Add handler via addEventListener().
Use a single handler by making use of event propagation.
Add handlers to each row.
(Discouraged) Add handler via onevent property. Only one handler can be added this way.
(Deprecated) Use the global object window.event.
(Discouraged) In HTML, use inline event onclick on each row:
Pass this to the handler function (e.g. <tr onclick="RowHandler(this)">). this in inline events will refer to the clicked element.
Add IDs to each row (e.g. <tr id="row1">). For each row, pass its ID to the function (e.g. onclick="RowHandler('row1')"). Search for the element by the passed ID.
Using addEventListener()
To add a listener, pass the event type and the listener:
const input = document.querySelector("input");
const button = document.querySelector("button");
button.addEventListener("click", clickHandler);
function clickHandler(event) {
console.log(input.value);
input.value = "";
}
<input><button>Click me!</button>
Event propagation
Because events bubble up the DOM, <table>'s listener will also fire when its rows are clicked. We can use event.target to get the event's origin element and find the clicked row:
const table = document.querySelector("table");
table.addEventListener("click", tableClickHandler);
function tableClickHandler(event) {
const row = event.target.closest("tr.cell"); // event.target may be a <td>
const isInRow = Boolean(row);
const isFirstRow = row === table.rows[0];
if (!isInRow || isFirstRow) return;
const name = row.cells[0].textContent;
const date = row.cells[1].textContent;
const subject = row.cells[2].textContent;
console.log("Clicked:", { name, date, subject });
}
table,td{border:1px solid}
<table>
<tr>
<th>Name</th>
<th>Date</th>
<th>Subject</th>
</tr>
<tr class="cell">
<td class="name">Some name</td>
<td class="date">01-01-1999</td>
<td class="subject">Some subject</td>
</tr>
<tr class="cell">
<td class="name">Another name</td>
<td class="date">02-02-2020</td>
<td class="subject">Another subject</td>
</tr>
</table>
Regarding your solutions
You are missing some way of identifying the clicked element; see my suggestions above.
In opt2, you are looping through all rows, but constantly overriding the variable name before using it. Therefore it is the same as only reading the name of the last row.
You may want to use .textContent over .innerText, because it doesn't cause a reflow. If visibility of the content matters, choose .innerText, otherwise .textContent.
A table usually consists of sections (e.g. <thead>, <tbody>, <tfoot>, or an implicit section). Each section consists of rows; each row consists of cells. Therefore, your class name "cell" for a row may be confused with actual table cells (<td>/<th>).
Please check this.
const [row] = document.getElementsByClassName('cell');
row.addEventListener('click', function(event) {
console.log(event.target.innerText);
})
<table id="table">
<tr class="cell">
<td class="name">Name</td>
<td class="date">Date</td>
<td class="subject">Subject</td>
</tr>
</table>
I am generating input fields dynamically, hoping to parse any text entered in a field and process in the keydownFunc later. No text avail in the DOM after the key event occurred.
Here is my code:
for (i = 1; i < 7; i++) {
var element = document.createElement("input");
element.setAttribute("style", "width:33px;");
element.setAttribute("name", i);
element.setAttribute("onkeydown", "keydownFunc(event);");
var tempID = document.getElementById(i)
tempID.appendChild(element);
}
function keydownFunc(event) {
var x = event.keyCode;
if (x == 13 | x == 9) {
path = event.path[1].id
console.log(path);
// process input
}
}
<table id="table">
<tbody>
<td id="1"></td>
<td id="2"></td>
<td id="3"></td>
<td id="4"></td>
<td id="5"></td>
<td id="6"></td>
</tbody>
</table>
You should avoid assigning event handlers using on... attributes. You should use addEventListener instead:
element.addEventListener("keydown", keydownFunc);
Also path is a quite obscure and not a standard property of the Event object. What are you trying to access? If it's the input itself, then use event.target (for example event.target.value to get its value), or if you want to get the table cell, then use event.target.parentNode.
I'm not entirely sure what your question is, but I think you want to access the text someone has entered in the textbox and do something with it. You can access this inside of your keydownFunc as
event.path[0].value
Here event.path[0] will be the input element.
Incidentally you don't need to name the input element, unless you're using the name for something else.
I came across a problem whose solution has led me to post it here so others may make use of it or improvise better than me.
My Problem: I have a table of results with check boxes to select rows. The requirement was to know if I was selecting(using the checkboxes) the same set of one particular column value, if so I had to do something.
HTML code
Considering the below being my html code for the dynamic table(CFML). The tag has to be inside a loop to dynamically create the table content.
<table class="fixedTable">
<thead class="containerbg">
<tr class="listingheader">
<td>StagingID</td>
<td>BatchID</td>
<td>AuditID</td>
<td>Action</td>
<td>File Name</td>
<td>Card No</td>
<td>Card No</td>
</tr>
</thead>
<tbody>
<tr class="cur_row" >
<td>#staging_id#</td>
<td>#batch_import_job_id#</td>
<td>#audit_Id#</td>
<td>#code#</td>
<td class="file_name">#source_filename#</td>
<td>#card_number#</td>
<td class="tblResolve">
<input type="checkbox" class="checkBoxClass cb" name="resolveErrorsCheck" value="#row_no#">
</td>
</tr>
JS Code
//register the click event
$(document).ready(function() {
$(document).on('click', '.cb',enableDisableActions);
});
function enableDisableActions() {
var values = new Array();
$.each($("input[name='resolveErrorsCheck']:checked").closest('td').siblings('.file_name'),
function (){
values.push($(this).text());
});
const initial = values[0];
const result = values.filter(src => src != initial);
if(result.length){
//no duplicate file_name selected
//do something
}else{
//duplicate file_name selected
//do something
}
}
Look at my code, I want to make it like that when a user click the table tr, I will get the first td text, so jquery I use first() and then text(), but it echo out both td 1 and td apple. I only want to get the first td text, what did I do wrong? Appreciate.
var gridtable = $('.gridtable');
gridtable.click(function(){
var name = $(this).first().text();
alert('name');
})
<tr class="gridtable">
<td>1</td>
<td >apple</td>
</tr>
<tr class="gridtable">
<td>2</td>
<td >banana</td>
</tr>
Inside handler this refers to the clicked tr applying first() method will retrieve the same tr itself . Instead, you need to filter out the nested td element. You can use the :first pseudo-class selector to get the first element.
var gridtable = $('.gridtable:first');
gridtable.click(function(){
// get the first element within the context
var name = $('td:first', this).text();
alert(name);
});
var gridtable = $('.gridtable');
gridtable.click(function() {
var name = $('td:first',this).text();
alert(name);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr class="gridtable">
<td>1</td>
<td>apple</td>
</tr>
<tr class="gridtable">
<td>2</td>
<td>banana</td>
</tr>
</table>
Since you are attaching your click handler at the tr level, you'll need to use the find function to select all tds within the tr and then select the first td:
var name = $(this).find('td').first().text();
var gridtable = $('.gridtable');
gridtable.click(function(){
var name = $(this).find('td:first').text();
alert(name);
});
var gridtable is referring to your tr elements, so when $element.click is raised, gridtable.first() is locating the first element with class .gridtable
You could use .gridtable.children() to get the children of gridtable and use the .first() after that
Please have a look to this example: https://jsfiddle.net/gnc9t1p2/1/
Edit 1 -
As #JaromandaX said, you should use var name = $(this)... to get the clicked row.
I think below code will help out you, it's working for me.
var gridtable = $('.gridtable');
gridtable.click(function(){
var name = $(this).find("td:first").text();// for only first td
or
var name = $(this).find("td:eq(0)").text();// you can change index number like eq(0) ,eq(1) for nect td
alert(name);
})
Just looking for the best practise way of doing this.
I have a table listing information and in the last column is a button with "Edit/View". When the user clicks on the button a div area appears with more information which can be edited
Code below with some fragments of jstl
<script type="text/javascript">
//Click on Edit/View on table
$('.viewCustomer').click(function()
{
.......
});
</script>
<tr class="odd">
<td>${customerBean.comName}</td>
<td>${customerBean.comCode}</td>
<td class="noRightPad"> <input type="submit" name="createBut" value="View/Edit" class="viewCustomer" /> </td>
</tr>
So my question would be:
(1) how do i pass a variable to function $('.viewCustomer').click(function()
(2) is this the best way of going about to do this. Is there a more efficient/secure/cleaner of doing this?
Cheers
Alexis
The click function will not be called by you. It is called when the button is clicked, and as such has the event object passed to it:
$('.viewCustomer').click(function(evt){
.......
});
What exactly are you wanting to pass? You can access the DOM element that you are clicking using this and $(this), so maybe it possible to reference what you want from here.
EDIT For comment
if the user clicked on the button that
was in the 4th row of the table and in
that row the another colum had
customer id 1234 i want to pass the
variable 1234.
NOTE: None of the below has been tested, but ought to suffice
Let's assume your 'customer id' column has a classname of 'customerid'. So your HTML might be:
<tr class="odd">
<td>${customerBean.comName}</td>
<td class="customerid">${customerBean.comCode}</td>
<td class="noRightPad"> <input type="submit" name="createBut" value="View/Edit" class="viewCustomer" /> </td>
</tr>
The jQuery might look something like:
$('.viewCustomer').click(function(){
var $buttonCell = $(this).parent(); //the <td> containing the button
var $buttonRow = $buttonCell.parent(); //the <tr> containing the button and your customer id
var $customerIdCell = $buttonRow.find("td.customerid");
var customerId = $customerIdCell.text();
});
The above is proken down into lines to show you how stuff is being retrieved. Using 'chaining' we can express it more concisely:
$('.viewCustomer').click(function(){
var customerId = $(this).parent().parent().find("td.customerid").text();
}
You can also search for the customerid cell as a 'sibling' of the button cell for an even more concise approach (and one less function call).
$('.viewCustomer').click(function(){
var customerId = $(this).parent().siblings("td.customerid").text();
}