here's a demo table
<table id="table1">
<tr>
<td><label>name</label><input type="text" id= "name1"/></td>
<td><label>age</label><input type="text" id= "age1"/></td>
<td><input type="button" id= "addRow"style="background-image:url("images/addicon.png");"/></td>
</tr>
and jquery code m trying is
$("#addRow").live("click", function (e, index) {
var val = ("#table1 tr").length();
val++;
$('#table1 tbody > tr:last').after('<tr><td><label>name</label><input type="text" id= "name"'+val+'/></td><td><label>age</label><input type="text" id= "age"'+val+'/></td><td><input type="button" id= "addRow"style="background-image:url("images/addicon.png");"/></td><td><input type=button id="deleteRow" style="background-image:url("images/removeicon.png");"></td>');
});
$("#deleteRow").live("click",function(e,index){
$(this).parent().closest("tr").remove();
});
Now problem comes when somebody add a row 2 times and delete a row
i.e val will be name2, name3
suppose name2 is deleted
then again adding row no. of rows is 2 so val++
result in 3
and new row will have name3 as id, this is creating problem for me.
What actually i want is, I should maintain the row count
1 2 3 ... like this irrespective what row is deleted.
Can anyone help me out with this, I have gone through loads of tutorial but none of them have maintained a uniform rowcount that's y i have put up this question.
You can use input names like name[] to have an array of values in the form. This is easier than using things like name1, name2, etc. If your concern is the labels, you can wrap an input in a label and skip the for, like so:
<label>String: <input></label>
Clicking String: focuses the input.
If you want to stick with what you have, just store val one scope outside of .click and increment it every time. Don't rely on the length.
By the way, you should also switch from .live to .on assuming it's available.
Related
I have a table with lots of rows
I have a filter to hide these rows based on the content of a child element (an input field) several levels down within the row
The input field within the row is wrapped several times. I can't manage to hide the row based on that inputs value.
Here's how a row looks:
<tr class="acf-row" data-id="row-13">
<td class="acf-field acf-field-date-picker acf-field-5de02ec006a2e" data-name="datum" data-type="date_picker" data-key="field_5de02ec006a2e">
<div class="acf-input">
<div class="acf-date-picker acf-input-wrap" data-date_format="dd.mm.yy" data-first_day="1">
<input type="text" class="input hasDatepicker" value="24.03.2020" id="dp1582735317447">
</div>
</div>
</td>
</tr>
Please note that there are more siblings on each level than I've put in here for readability. But the hierarchy is as displayed here.
Then I've got this input field to define what we want to filter:
<input placeholder="Datum filtern" type="text" id="datefilter" style="padding:5px; width:150px;">
And last but not least the jquery:
$( "#datefilter" ).change(function() {
var filterdate = $("#datefilter").val();
jQuery('.input.hasDatepicker').each(function() {
var currentElement = $(this);
var dateinfield = currentElement.val();
if( dateinfield !== filterdate){
$(this).closest('.acf-row').hide();
}
});
});
Currently it hides all the rows, not just those with a different value. What should happen is that only the rows get hidden where the value of #datefilter is different from the value of .input.hasDatepicker
I tried a few things like trying to use .parent().parent()... but didn't get it to work. Help would be greatly appreciated.
Here's a jsfiddle with the whole table including all siblings:
https://jsfiddle.net/59by3w7o/
UPDATE:
I think I can now say for sure the issue is 2 instances of the input element in each row. Here's a jsfiddle with only that and no noise:
https://jsfiddle.net/8k41xy6u/
How could I solve that? I tried playing with :first but couldn't get it to take the first within each .acf-row and not the very first in the whole document.
From the updated JSFiddle, a table row looks something like:
<tr class="acf-row">
<td>
<div class="acf-input">
<div>
<input class="input hasDatepicker" type="text" value="26.03.2020">
<input class="input hasDatepicker" type="text" value="10:00">
</div>
</div>
</td>
</tr>
And now the problem becomes clear. In the JS, .each() iterates over everything with the classes .input and .hasDatepicker. Both your inputs match that, so it will test both of them. If the value of the either one does not match your filterdate that row will be hidden. But the 2nd input value is a time, and that will never match a date, no matter what the date is - so every row will always be hidden.
There are 2 obvious ways to tackle this - 1) make the inputs distinguishable, so you can target just the date input in your filter comparison, OR 2) somehow target just the first input in the set of 2.
The first option (make them distinguishable) is by far the best, as the second relies on the layout of the HTML. It could happen in future that you'll do a redesign and the inputs won't be in the same order, or even in the same <div>, and then your JS will break. That might even happen without you doing it or even knowing about it if the HTML is autogenerated by some 3rd-party library (eg ACF/Wordpress), and a plugin update changes things. But if you can distinguish the inputs then you can target the right ones no matter where they are on the page.
To make them distinguishable, you could add a class, eg:
<input class="input hasDatepicker date" type="text" value="26.03.2020">
Then update your JS to target only those:
$('.input.hasDatepicker.date').each(function(i) {
If changing the HTML isn't an option, then you'll have to rely on and make use of position. Iterate instead over all div.acf-inputs, and find the first input in each:
$('div.acf-input').each(function(i) {
var dateinfield = $(this).find('input.input.hasDatepicker').first().val();
// ...
Working JSFiddle (of option 2).
I have the following situation I can not solve. I would be very thankful if anyone had an idea:
My webpage contains a table of players. Each line (player) contains two checkboxes: One that selects if the player is active (checked) or not, the other which team he/she belongs to (checked=Team 1; unchecked=Team 2).
So each line looks sth like this:
<tr>
<td><input id="plyr2_active" type="checkbox" name="plyr_active[]" value="2"></td>
<td><input type="checkbox" id="plyr2_team" name="plyr_team[2]" data-on-color="danger" data-off-color="success" data-on-text="RED" data-off-text="GREEN" checked value="1"></td>
</tr>
I'd like to add a button that, when clicked, will run a function that randomizes the teams of the ACTIVE players. Meaning that the players will be shuffled and half of them belong to one, the other half to the other team.
What I tried: Get all checkbox states in an array, then shuffle() the array and try to change the checked-state via bootstrap. Miserably failed :-(
Any help will be much appreciated. Thanks!!
Okay, this should help to get you started. It shows how to pull a list of active players (using jQuery) from your table.
Assuming you have a button with an id of 'shuffleBtn':
<button id="shuffleBtn">Shuffle<button>
and a table with id 'players':
<table id='players'>
:
</table>
-
$("#shuffleBtn").click(function() {
var newPlayerArray = [],
id = 1;
$("#players tr td:first-child").each(function() {
if ($(this).find('input:first').prop('checked')) {
newPlayerArray.push(id);
}
id++;
});
console.log(newPlayerArray);
});
This will display an array of the active players (assuming the first row is player 1, the second player 2, etc.) on the console.
Example: [1,3,4]
It then iterates each row () and grabs the first column (). Then for each of those it finds the first <input> and checks if the 'checked' property is present (this means the checkbox has been clicked).
I am just pushing the row index (starting at 1) so you may need to change how you interpret the associated player.
I'm using JQuery to dynamically create table rows. Each row contains 3 text fields. As users type into a text field, the table row is cloned and multiple rows are added as required. All that works fine.
Numerical values are entered into the first 2 fields, which are multiplied. The output automatically appears in the 3rd text box. As the input fields are clones, I can't use getElementById to run the function & multiply the values.
I was told to use onchange using parent siblings, but I don't know how to do that. Can someone give me an example?
Here is a sample of my code in JS Fiddle: https://jsfiddle.net/mzctb778/
Since you are adding things dynamically you should use event delegation to listen for change events. Do this by attaching it to the table. So listen for a change on an input. Once you detect the change, get the row by looking up the DOM and select the inputs you need to multiply. Since you can not use ids since they need to be unique, use classes to reference the elements.
$("table").on("change", "input", function () { //use event delegation
var tableRow = $(this).closest("tr"); //from input find row
var one = Number(tableRow.find(".one").val()); //get first textbox
var two = Number(tableRow.find(".two").val()); //get second textbox
var total = one * two; //calculate total
tableRow.find(".three").val(total); //set value
});
$("button.add").on("click", function() {
var tbody = $("table tbody");
tbody.find("tr:eq(0)").clone().appendTo(tbody).find("input").val("");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td><input class="one" /></td>
<td><input class="two" /></td>
<td><input class="three" readonly="readonly"/></td>
</tr>
</tbody>
</table>
<button class="add">Add</button>
Add this to your script and it will do the calculations you want:
$("table select").on("change", function(){
var x=$(this).find(":selected").val();
var y=$(this).closest("td").siblings().find(":selected").val();
$(this).closest("td").siblings().find("input").val(x*y);
});
New JS Fiddle
I have an html table called #DimensionAttributes whose columns are as follows:
<td><input type="text" name="txtLEName" value="#attribute.Key" /></td>
I intentionally wanted to maintain the name of the input element static. There can be multiple rows bound to this table. How do I loop through each row and find out the input elements value using the ID. The reason I wanted to use ID is because there can be multiple columns that would come soon in this table. Please help
Use selector, perhaps:
$("input[name='txtLEName']")
Well, first all, an ID must be unique, instead used class. Or if you eagerly wanted to use ID, try selecting by this :
Suppose you have this two element with same ID name :
<td><input type="text" name="txtLEName" value="#attribute.Key" id="hello"/></td>
<td><input type="text" name="txtLEName" value="#attribute.Key" id="hello"/></td>
Then your selector should be :
$('[id="hello"]')
Or another way, if you want to increment the ID name like :
<td><input type="text" name="txtLEName" value="#attribute.Key" id="hello1"/></td>
<td><input type="text" name="txtLEName" value="#attribute.Key" id="hello2"/></td>
As you dont know how many of element since the element created dynamically, then you can select it using this :
$('[id^="hello"]') // find the element ID name start with `hello`
If you want to loop thru each row, why not write something like this:
$("#DimensionAttributes tr input[name='txtLEName']").each(function(){
//Your code here:
//$(this).val()
});
var $rows = $('#table').find("tr:not(:eq(0))");
$rows.each(function () {
var $tds = $(this).find('td');
var val = $tds.find(':text').val();
console.log(val);
})
Assuming you have 1 input text each row you can select the table id find the tr and iterate and find td with input and get the value
DEMO
I'm dynamically creating and appending into a table, a <tr> and a <td> with the following code:
$("#table1").append(
'<tr>'+
'<td style="cursor:pointer" onclick="pass.data.carregar(this.parentNode.rowIndex-2);">'+$("#DRVR_NAME").val()+'</td>'+
'</tr>');
It's Ok so far: I can load the Td data into another fields that I want and there's no problem on creating it.
But beyond creating it I must allow the user to remove the <td> dynamically, but as you can see, there's no ID to look for. What's the better way to allow the user to remove the <td> ?
Im trying the following code:
$("#table1>tbody>td>tr."+teste+"").remove();
But no success! The test variable is a number that I automatically define for the register.
Any help?
If test is the 0-based index of the row you want to remove...
$("#table1>tbody>tr:eq("+test+")").remove();
Set a unique id attribute when you dynamically create each cell.
<tr id="uniqueID"><td>Cell Content</td></tr>
Then use simple jquery to remove the row by id.
$('#uniqueID').remove();
Your remove code assumes there is a class on the TD. You'll have to target it with :eq() by referencing the value in your hidden field. If the value in the hidden field is a number (the index of the td the user selected = your counter), you could try something like this:
var hiddenFieldValue = $('input.hiddenFieldClassName').val();
$("#table1>tbody>tr>td:eq("+hiddenFieldValue+")").remove();
You could add a little x next to each driver name that will delete that td by changing your code a bit:
$("#table1").append('<tr>'+'<td style="cursor:pointer" onclick="pass.data.carregar(this.parentNode.rowIndex-2);">'+$("#DRVR_NAME").val()+'<span onclick="$(this.parentNode).remove()">x</span></td>'+'</tr>');
Or you could add another function to the click handler that you are binding to each <td> that will display a message in a predefined <div> asking the user if s/he wants to delete that element:
$("#table1").append('<tr>'+'<td style="cursor:pointer" onclick="pass.data.carregar(this.parentNode.rowIndex-2);askDelete(this);">'+$("#DRVR_NAME").val()+'</td>'+'</tr>');
and then define a message area (id = 'messageArea') somewhere in your HTML and the following function in your code:
askDelete(el){
var MA=$('#messageArea');
MA.empty();
MA.html('Do you want to delete ' + el.innerHTML + '?<br>').append('<span id="confirmDelete">delete</span> <span id="cancelDelete">cancel</span>')
MA.find('#confirmDelete').click(function(){$(el).remove();});
MA.find('#cancelDelete').click(function(){MA.empty();})
}
then style your delete and cancel buttons as you wish.