I have the following html which is basically a parent table with some child tables inside it,
<table id="roottable" class="tablemain" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td></td>
<td>
<table class="intable" align="center" border="0">
<tbody>
<tr>
<td class="chn" colspan="2" align="center">
<div>
<div class="mparent">
<div class="checkbox">
<input type="checkbox" id="ch243" name="ch243" value="243">
<label for="ch243"></label>
</div>
<div class="chtext">Category</div>
</div>
</div>
</td>
</tr>
<tr>
<td>Param two</td>
<td>
<div class="checkbox">
<input type="checkbox" id="ch244" name="ch244" value="244">
<label for="ch244"></label>
</div>
</td>
</tr>
</tbody>
</table>
......
......
<table class="intable" align="center" border="0">
......
......
What I need to do is access all checkboxes of the nested table, for each table. That is get the checkboxes inside the first nested table, perform some operations with it, move to the next nested table do the same with the checkboxes inside it.
I can access individual tables like below with their id,
$('#tableid').find('input[type="checkbox"]').each(function () {
});
This works, but the tables are auto generated from db and the id is not known beforehand, also, the number of tables may vary, so I have no option other than selecting the parent table and then look for every child tables inside it one by one ... I have tried this ...
$('table').each(function(){
$(this).find('input[type="checkbox"]').each(function () {
// DO STUFFS WITH CHECKBOXES
});
But it doesn't work... How do I go about this? Thanks.
$('table tr td').each(function(){ // this line is for main outer table
$(this).children('table').each(function () { //this will iterate all the child table
$(this).find('input:checkbox').each(function(){ //this will find checkbox inside each table
//Your Stuff
});
});
});
NOTE :- I m not using id selector here because questioner mentioned that he doesn't know id's beforehand.
Working Demo
Working Demo
Your final code block looks acceptable, except that you haven't prevented the table selector from also selecting the outer table. As written, this would cause each set of checkboxes to be considered twice - once as part of its own table and again (actually first) as descendants of the outer table.
Try a more specific selector:
$('#roottable .intable').each(...)
I would do something like this:
$('#roottable').find('.intable').each(function(index, elt) {
// operate now on each "child table"
var $childTable = $(elt);
$childTable.find('input[type="checkbox"]').each(function(i, cb){
// Do your stuff with the checkoxes of the current ".intable" table
});
});
Just use:
var tableInputs = {};
$('#roottable input[type="checkbox"]').each(function () {
var id = $(this).closest('table').attr('id');
var name = $(this).attr('name');
tableInputs[id] = {};
tableInputs[id][name] = $(this).val();
});
This will select all checkboxes that are a child of a table.
EDIT if you need to group just find the id of the closest parent table and use that as an index for an object. You end up with one large object with all the id's as properties, while using only one each loop.
Related
I have a table which contains a combination of plain text, input textboxes, selects, and spans. I need to iterate through the table row by row and pull out the value in each cell. Within my table all <tr> have a particular css class.
$(".gridBody").each(function(rowindex){
$(this).find("td").each(function(cellIndex){
var cell = $(this).first()
})
In my debugger I can see what kind of object is being returned by $(this).first() but I can't find out how to get into its attributes. I have tried using jqueries html parser to turn it back into a dom element, but instead of getting, for example, a textbox, I get something like [[html inputtextbox]]. Most of the methods that work on regular dom elements are not working for me.
If I use $(this)[0].innerText it returns the correct value when the contents of the cell are plain text, but not when they are a form of input or nested in a span element. What I would really like to be able to do is get a regular html dom element back that I can then check the type of with $.is() and then vary much logic from there.
How do I get the first child element in a table cell as an html dom element that I can manipulate with jquery like any other dom element?
var collected = $("#myTable td").find("input, textarea, span").map(function(){
return this.value || this.textContent;
}).get();
console.log( collected ); // an array holding values or text
http://jsbin.com/zewixe/2/edit?html,css,js,console,output
If you want only the immediate children than use the right > selector
(">input, >textarea, >span")
Heres how I would do it:
<table>
<tr>
<td>
<h1>Some stuff.</h1>
</td>
</tr>
<tr>
<td>
<input type="text" value="1"/>
</td>
<td>
<input type="text" value="2"/>
</td>
</tr>
<tr>
<td>
<input type="text" value="3"/>
</td>
</tr>
<tr>
<td>
<input type="text" value="4"/>
</td>
</tr>
</table>
$(function() {
function getFormData(selector){
'use strict';
var formTypes = {
text: 'text',
radio: 'radio',
select: 'select'
},
values = [];
$(selector).children().each(function(idx, childNode) {
if (childNode.getAttribute('type') && formTypes[childNode.getAttribute('type')]) values.push(childNode.value);
});
return values;
}
alert(
getFormData('table tr td.someClass')
);
})();
http://codepen.io/nicholasabrams/pen/RaKGjZ
I have two columns. The column on the left loads with rectangular divs, which inside of these divs are 5 input elements that are loaded via PHP with data. The user can drag a div from the left column over to the right column. This will clone it and the user can begin to edit the input elements. I have been able to change the ID of the parent div once its cloned but am running into trouble changing the class names of the input elements inside the cloned div. Im going to save them via ajax and will build an array of all values that belong to each classname. The cloned class names must be different from the original as not to capture the original data.
This is an example of one of the divs that a user can drag and clone. No PHP yet.
<div class='pcaccount' draggable="true" id='account' data-id='accountid' ondragstart="drag(event)" >
<table class='tablesorter'>
<thead id='accountrow'>
<th align='center'>
<input type='text' value='hello' class='owner' >
</th>
<th align='center'>
<input type='text' value='hello' class='custodian' >
</th>
<th align='center'>
<input type='text' value='hello' class='type' >
</th>
<th align='center'>
<input type='text' value='hello' class='tax' >
</th>
<th align='center'>
<input type='text' value='hello' class='accvalue' >
</th>
</thead>
</table>
</div>
This is my current JS. It works fine for dragging, dropping, cloning, and changing the ID of the parent DIV but i can't seem to be able to change the class of the input elements within the div.
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("div", ev.target.id);
var i = 0;
}
function drop(ev) {
var newId = 'newaccount';
ev.preventDefault();
var data=ev.dataTransfer.getData("div");
var nodeCopy = document.getElementById(data).cloneNode(true);
nodeCopy.id = newId+i;
nodeCopy.class = 'newaccount';
ev.target.appendChild(nodeCopy);
i++;
}
Iv neglected to include any code I have tried to make to accomplish this as its rubbish. Any help on this would be greatly appreciated. Also it would be necessary to change the ID of the "thead" as I want to append another table header to it once it is cloned.
Many thanks in advance.
Since you tagged the question with jQuery, here is a jQuery snippet which should allow you to modify child elements of the cloned node:
$('input', nodeCopy).each(function () {
$(this).removeClass(...).addClass(...);
});
$('thead', nodeCopy).each(function () {
$(this)[0].id = ...;
});
Without jQuery, you can achieve something similar using nodeCopy.querySelector or nodeCopy.querySelectorAll.
I am having a table structure like this
<table>
<c forEach var="item" items="${manyItems}">
<tr>
<td id="item1"> ${item.data1} </td>
<td id="item2"> ${item.data2} </td>
<td> <button id="deleteButton"/> </td>
</tr>
</c:forEach>
</table>
Now I want to add a click event to the deleteButton
In my jquery is like this:
$(function() {
$('#deleteButton').click(function() {
var ele = $(this).parent();
/* fetch the other <td> siblings of the #deleteButton */
/* delete code goes here having an ajax query*/
});
});
This code is only deleting the 1st row of the table, but does not work on any other row.
I believe this is because we need to have distinct id's?
Kindly guide me to a good solution.
You are creating duplicate IDs, Identifiers in HTML must be unique and this is the expected behavior.
Use class, Here In example below I have converted deleteButton in to a CSS class so that we can use Class Selector (".class")
<button class="deleteButton"/>
Script
$('.deleteButton').click(function() {
var ele = $(this).parent();
});
Issue is the same ids for multiple elements in a single page. When this happens browser only looks for first instance of it and never goes ahead to look for another one, This is the reason one should understand that IDs should be unique per element.
change to class name instead:
<table>
<c forEach var="item" items="${manyItems}">
<tr>
<td class="item1"> ${item.data1} </td>
<td class="item2"> ${item.data2} </td>
<td> <button class="deleteButton"/> </td>
</tr>
</c:forEach>
</table>
and jquery:
$(function() {
$('.deleteButton').click(function() {
var ele = $(this).parent();
/* fetch the other <td> siblings of the .deleteButton */
/* delete code goes here having an ajax query*/
});
});
First think that, id is known unique, if u need to have click event for two button, u can use class for selecting the button, so try to follow the standards, id is unique selector and class is multiple selector.
What makes something a sibling for jquery requests?
I want the content within all cells of my table to act as siblings for my jquery requests. Currently only the td values in the same row act as siblings of each other. The next row of td's act as a different "family" if you will.
i.e <table>
<tr>
<td> content here </td>
<td> more content </td>
</tr>
<tr>
<td> content here </td>
<td> more content </td>
</tr>
</table>
$("td").click(function () {
$(this).siblings().addClass('fadeClick');
$(this).siblings().removeClass('noFade');
}
See jfiddle for full code: https://jsfiddle.net/nsn3bpep/7/
(I want all boxes, in both rows, aside from the one hovered/clicked on to be half opaque out)
You need to select all td elements and use this collection instead of siblings. Something like this:
var $td = $("td");
$td.click(function () {
$("#content").html($(this).find(".hover-content").html());
$('img[class*="wp-image-"]').removeClass('myClickState');
$(this).find('img[class*="wp-image-"]').addClass('myClickState');
divContent = $("#content").html();
$td.not(this).addClass('fadeClick').removeClass('noFade');
$(this).removeClass('fadeClick');
});
$td.hover(function () {
$("#content").html($(this).find(".hover-content").html());
$(this).addClass('noFade');
$td.not(this).removeClass('noFade').addClass('fade');
}, function () {
$("#content").html(divContent);
$td.not(this).removeClass('fade');
$(this).removeClass('noFade');
});
Demo: https://jsfiddle.net/nsn3bpep/8/
I have a table with few rows. Each rows has header, data and hidden field. Data column can have either text or textarea.
<table id="knowledgeTreeTable" class="custom">
<tbody>
....................
<tr>
<th class="">What is the name of the party?</th>
<td class="">
<textarea id="ktField_7" class="ktEdit" type="text"></textarea>
</td>
<input id="ktField_7H" type="hidden" value="Unique contested">
</tr>
<tr>
<th class="">What is the name of the opposing party?</th>
<td class="">
<input id="ktField_8" class="ktEdit" type="text" style="width: 97%;">
</td>
<input id="ktField_8H" type="hidden" value="Query">
</tr>
......................
</tbody>
</table>
I am able to read the content of header and hidden field but not sure how to read data column as it can have two different types of element.
$("#knowledgeTreeTable tr").each(function() {
alert($('th', this).text());//OK
//alert($('td > [input, textarea]', this).val()); // This is not OK.
alert($('input', this).val());//OK
});
You can't group selectors like
td > [input, textarea]
Instead, use
td > input, td > textarea
Just as you would in a CSS selector, look for both:
alert($('td > input, td > textarea', this).val());
Although since you're using the same class for both, I'd be inclined to use:
alert($('td > .ktEdit', this).val());
Whenever you're trying to access a child element in a loop like this, you need to establish what the common factors between each element is. In this case they are different tags with different names, but they both have the ktEdit class, and both have type="text" (which I don't believe is actually applicable to textareas).
In this case, the common variable is the class name, so you can use that as your selector. As long as you target your parent loop correctly, it won't matter if you use that class on other elements throughout the page:
$("#knowledgeTreeTable tr").each(function() {
alert($('.ktEdit', this).val());
});