My html
<tr id="uniqueRowId">
<td>
<input class="myChk" type="checkbox" />
</td>
<td class="from">
<textarea class="fromInput" ...></textarea>
</td>
<td class="to">
<textarea ...></textarea>
</td>
</tr>
I have a table where each row is similar to the above with only one exception: not all rows will have textreas. I need to grab all rows that have textareas AND checkbox is not "checked".
Then I need to leaf through them and do some stuff.
I tried something like:
var editableRows = $("td.from .fromInput");
for (s in editableRows)
{
$s.val("test value");
}
but it didn't work.
1) how do I grab ONLY the rows that have checkboxes off AND have fromInput textareas?
2) how do I leaf through them and access the val() of both textareas?
I am sure this could be optimized, but I think it will work.
$("tr:not(:has(:checked))").each(function(i, tr) {
var from = $(tr).find("td.from textarea").val();
var to = $(tr).find("td.to textarea").val();
//now do something with "from" and "to"
});
See it working on jsFiddle: http://jsfiddle.net/RRPqb/
You can use this to select the rows:
$('tr', '#yourTable').has('input:checkbox:not(:checked)').has('textarea')
Live demo: http://jsfiddle.net/simevidas/Zk5EH/1/
As you can see in the demo, only the row that has a TEXTAREA element and a unchecked checkbox will be selected.
However, I recommend you to set classes to your rows: the TR elements that contain TEXTAREA elements should have a specific class set - like "directions". Then you could select those rows easily like so:
$('tr.directions', '#yourTable').each(function() {
if ( $(this).find('input:checkbox')[0].checked ) return;
// do your thing
});
$("tr:not(:has(:checked)):has(input.fromInput)")
Should be what you need. All the rows that don't have anything checked but that do have an input with the class 'fromInput'
If you want to loop through them to get the value of any textarea just extend your selector:
$("tr:not(:has(:checked)):has(textarea.fromInput) textarea")
Or as above if you want to be able to distinguish them:
$("tr:not(:has(:checked)):has(textarea.fromInput)")
.each(function() {
var from = $(this).find("td.from textarea").val();
var to = $(this).find("td.to textarea").val();
})
I don't know how much performance is a concern here, but if it is, then rather then writing a selector to find rows that contain a textarea you may find it helps to add a class to the row itself.
<tr class="hasTextarea">
Then you could alter your JQuery as so:
$("tr.hasTextarea:not(:has(:checked))")
Related
<table>
<tr id="tr1">
<td id="td1"> test1 </td>
<td id="td2"> test2 </td>
<td id="td3"> test1 </td>
<td id="td4"> test3 </td>
</tr>
</table>
Here I have a table with a tr in it and 4 td's.
Now, my question is, how can I compare the td.text() with the other one?
For example:
a loop that takes the text of first td and then compare it with other td's.
If it is the same, then give that td a class.
HERE: td id="td1" should get a class
BUT:
When I'm at the 3e td, the 3e td should get a class.
This code should work for you:
var tds;
$('tr').each(function(i, item){
tds = $(this).find('td');
tds.each(function(j, elem1){
tds.each(function(k, elem2){
if($(elem1)[0] != $(elem2)[0] && $(elem1).text() == $(elem2).text()){
$(elem1).addClass('cl');
}
});
});
});
FIDDLE: https://jsfiddle.net/lmgonzalves/cqa6m6va/1/
You can use this code:
function setClasses(word) {
var tds = $("tr td");
for(var i = 0; i < tds.length; i++) {
if(tds.eq(i).text() === word) {
tds.eq(i).addClass('red');
}
}
}
setClasses("test1");
jQuery selectors will be your friend here. :)
var $container = $("#tr")
$container.children().each(function() {
if (!($(this).hasClass("td")) {
var sTextVal = $(this).text();
var $currTextGroup = $container.children(":contains('" + sTextVal + "')");
if ($currTextGroup.length > 1) {
$currTextGroup.addClass("td");
}
}
});
I'll explain the logic, and then touch on one issue to be aware of . . .
Basically, this code:
Collects all of the the children of the <tr> and loops through them one at a time
If the current child does not already have a class of "td" (if it already has a "td" class, then this text has already been checked for duplicates), it retrieves the text from inside the element and searches for all of the children of the <tr> that contain that same text value
If more than one of the children in the <tr> contain that text, all of those children are given the class of "td"
The one potential issue that this solution could run into is if the text in the current element is present as part of the text in one of its siblings. For example, if the text in one sibling is "the", and it has some siblings that have text values of "then" and "there" and "the end", they will be found by :contains.
If your text values are sufficiently "patterned" (as they are in your example), though, this should not be an issue. If it is an issue, there is a more complex way to do that "common text" selection, but I won't bother with that, unless it is necessary.
If I understand correctly, you want to select the first 'td' in a 'tr' and compare it against the other 'td' in your table. Please try the below code and let me know if it works for you.
HTML (provided by OP)
<table>
<tr id="tr1">
<td id="td1"> test1 </td>
<td id="td2"> test2 </td>
<td id="td3"> test1 </td>
<td id="td4"> test3 </td>
</tr>
</table>
CSS
.color--red { color: red; }
jQuery
$(document).ready(function(){
var first = $("#tr1 :first-child").html();
$('#tr1 :not(:first-child)').each(function() {
if(first == $(this).html()){
$(this).addClass("color--red");
}
});
});
I tried to keep it as simple as possible. The variable first pertains to that first 'td' that you want to use for comparison. Note how the each function operates on 'all elements except the first child in the tr', which clearly will omit the first variable we declared initially. From there it's all about comparing using $(this).html() to grab the value of the currently selected element, against the value obtained from the first variable.
Once this succeeds, simply add a class of your choice. For simplicity's sake, I added my own color--red class to the mix, which should show red color text for the third 'td' element as you suggested in your question post. Enjoy! Let me know if you need anything further.
I'm writing some JavaScript to clone a table row containing form elements.
It's working well so far but there's one piece I can't quite figure out.
The element names have a number which increases with every row.
E.g:
<table>
<tbody>
<tr>
<td><input type="text" name="name[0][abc]" /></td>
<td><button class="add-row-button">+</button></td>
</tr>
<tr>
<td><input type="text" name="name[1][abc]" /></td>
<td><button class="add-row-button">+</button></td>
</tr>
</tbody>
</table>
I need the cloned row to update the number. There are multiple fields in each row which need this updated number so I can't just include the new name in the jQuery code. What I think has to happen is I need get the name, use a regex replace, then update the attribute.
Here's my current (simplified for the example) jQuery:
// Current num of elements. Names are 0 based so this will be the number used
// for the new name.
var formRowCount = $('table tr').length;
$('.add-row-button').click(function() {
// Clone the last row.
$(this).closest('tr').last().clone().insertAfter($(this).closest('tr'));
// Set the new field selector.
var $newRow = $(this).closest('tr').next();
$newRow.find('input[type="text"]').val('');
formRowCount++;
});
Can someone point me in the right direction. Before formRowCount++; I need to get the current element name and update the number with formRowCount.
Yeah, you can use regex if you want.
var formRowCount = $('table tr').length;
$('.add-row-button').click(function() {
// Clone the last row and insert it.
$(this).closest('tr').last().clone().insertAfter($(this).closest('tr'));
// Select the input field
var $newInput = $(this).closest('tr').next().find('input[type="text"]');
// Update the input value and name attribute
var newName = $newInput.attr('name').replace(/^(name\[)\d+(\].+)$/, '$1' + formRowCount + '$2');
$newInput.val('').attr('name', newName);
// Update the number
formRowCount++;
});
I have a table which has input checkboxes.
When user selects checkbox I'm saving this value attribute to an array...so the user is clicking, checking and unchecking and after some time he will press the button.
In the button click event I'm trying to iterate through each of the records and check if the each input[type="checkbox"] has the same value as the one in the array, so if the values are the same then I will read all the td values from that row.
This is my code:
$('#something').click(function(){
$( "tr td input" ).each(function(index) {
//selected is an array which has values collected from the checked checkboxes..for example [2,3]
for(var i=0;i<selected.length;i++)
{
if($(this).val()==selected[i][0].value)
{
alert($('tr').eq(index).find('td').eq(1).text());
}
}
});
});
And html code:
<table>
<tbody>
<tr>
<td><input type="checkbox" value="on"></td>
<td>ID</td>
<td>Name</td>
</tr>
<tr>
<td><input type="checkbox" value="0"></td>
<td>1</td>
<td>John</td>
</tr>
<tr>
<td><input type="checkbox" value="1"></td>
<td>2</td>
<td>Steve</td>
</tr>
</tbody>
</table>
So for example if I have value [1] in the array. How can I get all the row information from that? My code is not working. Any idea?
I created a plunk that iterates over each input, reads the values and writes them to an array:
var checkBoxCollection = new Array();
var cb = {};
$("button").click(function(){
$("input").each(function(index, el){
id = $(el).attr("id");
val = $(el).val();
isChecked = $(el).is(':checked');
console.log(index, id, val);
checkBoxCollection.push({'id': id, 'val': val, 'isChecked': isChecked});
}); // each
console.log(checkBoxCollection);
}); // button.click
You could use this way to select the cell value as soon as the button is clicked and would only have to test if the box was checked. To learn how to use the console and the chrome dev tools you may take a look at this 7 minute video
Update with one checkbox for all
In my updated plunk you can see that i use two different selectors
// using different selector - see my comment and tell me if you can not do that
Select all <input class="cbAll" type="checkbox" id="cbAll" value="on">
// and each checkbox like this
<input class="cb" type="checkbox" id="cb0" value="0">
And the javascript
$("input.cbAll").click(function(){
$("input.cb").each(function(index, el){
// javascript ternary operator is optional this switches each checked state
$(el).is(':checked')
? $(el).prop('checked', false)
: $(el).prop('checked', true);
}); // each
});
Update including the copy of the text inside the <td>
In this plunk the text from the cells in the same tablerow of the checbox is copied into the array. The relevant code are these lines
isChecked = $(el).is(':checked');
if(isChecked){
var cells = $(el).parent().parent().children();
var cellId = cells.eq(1).text();
var cellName = cells.eq(2).text();
checkBoxCollection.push({'id': id, 'val': val
, 'isChecked': isChecked
, 'cellId': cellId
, 'cellName': cellName});
console.log(index, id, val, cellId, cellName);
}
In the screenshot you can see that the values of each checked textbox are copied.
As far as i can tell i solved all your questions:
use of jquery each to iterate over checkboxes
copy the text of cells within a tablerow into an array if the checkbox of that row is checked
If i understood your questions not fully please clarify what you would like to know.
It appears that the condition if($(this).val()==selected[i][0].value) is not true.
If it is a simple array, you don't need .value in the end. Simply compare with selected[i][0]
if($(this).val()==selected[i][0])
I have a datatable containing a list of Cars. each row in the html contains a Car ID. I have added checkbox column to the first cell in my datatable - if it is checked the row is highligted to indicate to the user they have selected that row. What I waht to do is get all the IDs of all the cars a user has selected on clicking a button on the page. (also there are other columns in the table row where I have checkboxes (i.e - a Manual column or an Automatic column which will somtime be checked - like in column 5 ot 6 in the table)
so this is part of the cshtml for my page..
#foreach (var car in Model.Cars)
{
<tr carId="#Html.DisplayFor(modelItem => car.CarID)">
<td class="table-data">
<input id="SelectIndividual" name="Select" type="checkbox" />
</td>
//more stuff set in other tds in table
Then this is the JS I have for the page so far.
$('#GetSelectedCars').click(function (event) {
var cars= new Array();
carsListTable.find("tr").each(function (index, para) {
$('tr').find('td:input:checked:first').each(function () {
var car= new Object();
alert($(this).parent().parent().attr("carId"));
car.ID = $(this).parent().parent().attr("carId");
cars.push(car);
});
});
var jsonString = $.toJSON(cars);
I want to then return the json string to my controller (I do this by passing the value into a hidden field on my model and then deserialize - but at the minute I am getting it as empty. My problem is getting the best way to get the id from the row if it is checked?
You can use the selectors :checkbox:checked and use the jQuery.map to convert the array. The jQuery.closest() method will give the closest ancestor matching the given selector.
var cars = carsListTable.find('.table-data :checkbox:checked').map(function(i, v){
return {
ID : $(v).closest('tr').attr('carId')
}
});
Demo Fiddle
Note: The id of elements should be unique in a document so the id of the checkbox should be removed or has to be suffixed or prefixed by a dynamic value like the car id.
First, you should use class instead id for elements that will be present more than once. I suggest change #SelectIndividual for .SelectIndividual on the checkbox input). Another thing you should change is the carId attribute, because is not semantic valid. You should use custom data attributes instead. This is how your code should look like:
HTML
#foreach (var car in Model.Cars)
{
<tr data-carID="#Html.DisplayFor(modelItem => car.CarID)">
<td class="table-data">
<input id="SelectIndividual" name="Select" type="checkbox" />
</td>
Jquery
$('#GetSelectedCars').click(function (event) {
var cars= new Array();
$('SelectIndividual:checked').each(function () {
var car= new Object();
car.ID = $(this).parent().parent().data('carID');
cars.push(car);
});
});
//keep doing things
I would suggest to use the data-* attributes that are valid HTML5 as well as the jQuery.data() methods for the id of the car.
Can you assign a class to all checkboxes in first column and then try this
$('.cbClass:checked').each(function () {
tr = $(this).closest('tr');
// use the row
})
I'm developing a table in html. Every rows have a checkbox with the same attribute name as tag tr. So I want to color the row selected in yellow if that raw is the unique selected, otherwise color in blue all the rows selected. So I was developing this:
var checked = $("input[#type=checkbox]:checked");
var nbChecked = checked.size();
if(nbChecked==1){
var row = $('tr[name*="'+checked.attr("name")+'"]');
row.style.backgroundColor="#FFFF33";
}
But color doesn't change :( can you tell me why? can you help me?
<TR valign=top name="<?php echo $not[$j]['name'];?>">
<TD width=12 style="background-color:#33CCCC">
<div class="wpmd">
<div align=center>
<font color="#FF0000" class="ws7">
<input type="checkbox" name="<?php echo $not[$j]['name'];?>" onchange="analizeCheckBox()"/>
</div>
.
.
.
.
.
.
Although this code doesn't get you all they way to the funcitonality, it does do the row updating.
http://jsfiddle.net/4QKe9/5/
HEre is the Javascript:
function updateRows() {
var checked = $("input:checked");
var nbChecked = checked.size();
if (nbChecked == 1) {
checked.parent().parent().css("background", "#FFFF33");
}
}
$(function () { $("input:checkbox").click(updateRows)});
Firstly, you have got the background color on the cell not the row. You need to move it.
Here's your fixed html:
<table>
<tr style="vertical-align:top; background-color:#33CCCC">
<td style="width:12px">
<div class="wpmd">
<div class="ws7" style="text-align:center; color:#FF0000">
<input type="checkbox" />
</div>
</div>
</td>
</tr>
</table>
and then this script will work
$("td .ws7 input[type=checkbox]").bind({
click: function()
{
if ($(this).is(":checked"))
{
$(this).closest("tr").css("background-color", "#ffff33");
}
else
{
$(this).closest("tr").css("background-color", "#33CCCC");
}
}
});
change the "td .ws7" selector to match your needs.
Example.
When you call the jQuery function $() with a selector string it will return a jQuery object that is like an array even when only 1 or 0 elements matched. So your code:
row = $('tr[name*="'+checked.attr("name")+'"]');
row.style.backgroundColor="#FFFF33";
Doesn't work because row is not a DOM element with a style property, it's a jQuery object that's like an array with lots of extra methods. The individual DOM elements that matched can be accessed with array-style notation, so:
row[0].style.backgroundColor = "#FFFF33";
Will work to update the first matching DOM element. If nothing matched then row[0] will be undefined and you'll get an error. row.length will tell you how many elements matched.
In your code:
var checked = $("input[#type=checkbox]:checked");
You don't need the # symbol to match attribute names, so "input[type=checkbox]:checked" is OK, but "input:checkbox:checked" is simpler.
So getting at last to your actual requirement, which is when a single row has a checked box to set that row's background to yellow, but if multiple rows have checked checkboxes to set all those rows' backgrounds to blue, you can do this with only three lines of code:
// reset all trs to default color
$("tr").css("background-color", "yourdefaultcolorhere");
// select the checked checkboxes
var checked = $("tr input:checkbox:checked");
// set the checked checkboxes' parent tr elements' background-color
// according to how many there are
checked.closest("tr").css("background-color",
checked.length===1 ? "yellow" : "blue");
Notice that you don't need to select by the name attribute at all, because jQuery's .closest() method will let you find the tr elements that the checked checkboxes belong to.
WORKING DEMO: http://jsfiddle.net/FB9yA/