jQuery: Inconsistent behavior of find between div and tbody - javascript

I am using the find selector in jQuery by Id. It is behaving differently in case of a div vs tbody. This is a bigger problem - for the sake of clarity here is the reduced version of my original issue
HTML
<div id='iamdiv'>HELLO</div>
<table>
<tbody id='iamtbody'>
<tr><td>HELLO TOO</td></tr>
</tbody>
</table>
<input type='text' id='div'/>
<input type='text' id='tbody'/>
JS
$(document).ready(function() {
var allcontent = $($('body').html()); // I am deliberately doing this to input a HTML String.
var $divcontent = allcontent.find('#iamdiv');
$('#div').val($divcontent.html());
var $tbodycontent = allcontent.find('#iamtbody');
$('#tbody').val($tbodycontent.html());
});
Fiddle: https://jsfiddle.net/bragboy/Lt8nua10/1/
I want to display the raw html in the input text boxes, however only the tbody one is getting displayed and not the div. If I use a filter method instead of find - it works for div but not the tbody.
My objective is to have one consistent way of fetching for both tbody and div.

Two issues:
find looks for descendant elements, but #iamdiv is a top-level entry in your allcontents jQuery object.
You're duplicating the elements in the
var allcontent = $($('body').html());
line, which I'm fairly sure isn't what you want to do. (You've said that's on purpose, to simulate parsing HTML from elsewhere.)
You've said your goal is to use find in both use case (rather than using filter in one and find in the other). To do that, you need to have something else as the root of your allcontent.
You've also said that for some reason you can't change the
var allcontent = $($('body').html());
line, even just to
var allcontent = $("<body>").append($('body').html());
That's okay, you can still add a new root element by adding a line after it, like this:
allcontent = $("<body>").append(allcontent);
Live example:
$(document).ready(function() {
var allcontent = $($("body").html()); // You've said we can't change this
// The added line:
allcontent = $("<body>").append(allcontent);
var $divcontent = allcontent.find('#iamdiv');
$('#div').val($divcontent.html());
var $tbodycontent = allcontent.find('#iamtbody');
$('#tbody').val($tbodycontent.html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='iamdiv'>HELLO</div>
<table>
<tbody id='iamtbody'>
<tr><td>HELLO TOO</td></tr>
</tbody>
</table>
<input type='text' id='div'/>
<input type='text' id='tbody'/>

Use var allcontent = $('body'); instead of var allcontent = $($('body').html());
$(document).ready(function() {
var allcontent = $('body');
var $divcontent = allcontent.find('#iamdiv');
$('#div').val($divcontent.html());
var $tbodycontent = allcontent.find('#iamtbody');
$('#tbody').val($tbodycontent.html());
});
input {
width: 100%; /* just to show the whole content */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='iamdiv' class='somthing1'>
HELLO
</div>
<table>
<tbody id='iamtbody' class='somthing2'>
<tr>
<td>HELLO TOO</td>
</tr>
</tbody>
</table>
<input type='text' id='div' />
<br/>
<input type='text' id='tbody' />
After update in question :
You can use .closest() to achieve this. Because the cose that you picked when using $($(body).html()) has the div as on its node.
$(document).ready(function() {
var allcontent = $($('body').html());
var $divcontent = allcontent.closest('#iamdiv');
$('#div').val($divcontent.html());
var $tbodycontent = allcontent.find('#iamtbody');
$('#tbody').val($tbodycontent.html());
});
input {
width: 100%; /* just to show the whole content */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='iamdiv' class='somthing1'>
HELLO
</div>
<table>
<tbody id='iamtbody' class='somthing2'>
<tr>
<td>HELLO TOO</td>
</tr>
</tbody>
</table>
<input type='text' id='div' />
<br/>
<input type='text' id='tbody' />

Related

How can i get two input field values based on onclick function

I have a div in that div I have two input fields and update button like this:
<button type = "button" id = "add-botton" >Add Element </button>
<div id = "trace-div1" class = "trace">
<h4><span>Trace 1</span></h4>
<form>
<table>
<tbody>
<tr>
<td><label>X Axis: </label></td>
<td><input type="text" name="t_x_axis" class = "t_x_axis" id="x_axis_t1" size="50">
</td>
</tr>
<tr>
<td><label>Y Axis: </label></td>
<td><input type="text" name="t_y_axis" class = "t_y_axis" id="y_axis_t1" size="50"></td>
<td><button type = "button" name = "update-button-trace" class = "update-trace" id =
"update-botton-trace1" onclick="updatebtn(this)">Update </button></td>
</tr>
</tbody>
</table>
</form>
</div>
<script>
$(document).ready(function(){
$('#add-botton').click(function(){
var $div = $('div[id^="trace-div"]:last');
var num = parseInt( $div.prop("id").match(/\d+/g), 10 ) +1;
var $trace1div = $div.clone(true).prop('id', 'trace-div'+num );
$trace1div.find('span').text('Trace ' + num);
$trace1div.find("input[name='t_x_axis']").attr("id", "x_axis_t"+num).val("");
$trace1div.find("input[name='t_y_axis']").attr("id", "y_axis_t"+num).val("");
$trace1div.find("button[name='update-button-trace']").attr("id", "update-button -
trace"+num);
$div.after( $trace1div);
});
});
function updatebtn(el){
var id = $(el).attr('id');
}
}
</script>
Here I am cloning my div multiple times with diff.id's ,my problem is when I click update button i need those respective two input values.
I tried like this but here I am getting all input value like if I have add 3 divs those respective all values coming here each div has 2 input fields :
<script>
function updatebtn(el){
var id = $(el).attr('id');
$('input[type=text]:visible').each(function(){
console.log($(this).val());
})
})
</script>
Thanks
You need to use DOM traversal to find the input elements related to the button which was clicked. The simplest way to do that, given that you're already using jQuery, would be to use a delegated event handler for the dynamic button elements along with closest() and find().
It's also worth noting that your use of id attributes within the dynamic content is creating a lot more problems than it solves. I'd strongly suggest you remove them all and use common classes on all elements. That way you don't have the headache of having to manually update all the incremental ids when adding new content.
Try this:
jQuery(function($) {
var $traceContainer = $('#traces');
$('#add-button').click(function() {
var $div = $traceContainer.find('.trace:last').clone()
$div.find("input[name='t_x_axis']").val("");
$div.find("input[name='t_y_axis']").val("");
$traceContainer.append($div);
$div.find('span').text('Trace ' + ($div.index() + 1));
});
$traceContainer.on('click', '.update-trace', function() {
var $container = $(this).closest('table');
var xAxis = $container.find('input[name="t_x_axis"]').val();
var yAxis = $container.find('input[name="t_y_axis"]').val();
console.log(xAxis, yAxis);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="add-button">Add Element</button>
<div id="traces">
<div class="trace">
<h4><span>Trace 1</span></h4>
<form>
<table>
<tbody>
<tr>
<td><label>X Axis:</label></td>
<td><input type="text" name="t_x_axis" class="t_x_axis" size="50">
</td>
</tr>
<tr>
<td><label>Y Axis:</label></td>
<td><input type="text" name="t_y_axis" class="t_y_axis" size="50"></td>
<td><button type="button" name="update-button-trace" class="update-trace">Update </button></td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
Finally, note that I added a div container around each .trace to make appending them and retrieving their index simpler. Also note that the form within each .trace seems redundant and can probably be removed.
You can use find value as $div.find('.t_y_axis').val()
$(document).ready(function(){
$('#add-botton').click(function(){
var $div = $('div[id^="trace-div"]:last');
var num = parseInt( $div.prop("id").match(/\d+/g), 10 ) +1;
var $trace1div = $div.clone(true).prop('id', 'trace-div'+num );
$trace1div.find('span').text('Trace ' + num);
$trace1div.find("input[name='t_x_axis']").attr("id", "x_axis_t"+num).val("");
$trace1div.find("input[name='t_y_axis']").attr("id", "y_axis_t"+num).val("");
$trace1div.find("button[name='update-button-trace']").attr("id", "update-button-trace"+num);
$div.after( $trace1div);
console.log( 'last t_y_axis => ' , $div.find('.t_y_axis').val());
console.log( 'last t_x_axis => ' , $div.find('.t_x_axis').val());
});
});
function updatebtn(el){
var id = $(el).attr('id');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type = "button" id = "add-botton" >Add Element </button>
<div id = "trace-div1" class = "trace">
<h4><span>Trace 1</span></h4>
<form>
<table>
<tbody>
<tr>
<td><label>X Axis: </label></td>
<td><input type="text" name="t_x_axis" class = "t_x_axis" id="x_axis_t1" size="50">
</td>
</tr>
<tr>
<td><label>Y Axis: </label></td>
<td><input type="text" name="t_y_axis" class = "t_y_axis" id="y_axis_t1" size="50"></td>
<td><button type = "button" name = "update-button-trace" class = "update-trace" id =
"update-botton-trace1" onclick="updatebtn(this)">Update </button></td>
</tr>
</tbody>
</table>
</form>
</div>
try using the following function.since both the input text boxes have their id you can use the same to get the value of the inputs.
Hope it helps!
function updatebtn(el) {
var x1 = document.getElementById('x_axis_t1');
var y1 = document.getElementById('y_axis_t1');
alert('x-axis is ',x1.value, ' and y-axis is', y1.value)
}
you need to develop your updatebtn().
function updatebtn(el){
var element = $(el),
parent_table = element.parentsUntil('table');
x_axis = parent_table.find('.t_x_axis').val();
y_axis = parent_table.find('.t_y_axis').val();
}

Jquery adding only one row not 4

Hi there can someone please help me with this code:
So this is the blade
<table class="optionsForm" style="width:100%">
<thead>
<tr >
<th><button type="button" class="add">Add</button></th>
#for($c = 1; $c<=4; $c++)
<th id="column{{ $c}}">
<input type="text" name="columns[{{ $c }}]"
class="form-control" placeholder="Column {{ $c }} ">
</th> #endfor
<th><button type="button" style="width: 100px; height: 25px" class="addColumn">Add Column</button></th>
</tr>
</thead>
<tbody> #for($r = 1; $r<=4; $r++)
<tr class="prototype">
</tr> #endfor
</tbody>
</table>
and this one is the js code, I need to be able to add only one row, here it is adding 4 rows, I need first to be shown 4 rows, but than when I click add I need to be added only one row how can I achieve this can someone please help me with this thing I am stuck, thank you so much for any efforts.
$(document).ready(function () {
var id = 0;
// Add button functionality
$("table.optionsForm button.add").click(function () {
id++;
var master = $(this).parents("table.optionsForm");
// Get a new row based on the prototype row
var prot = master.find(".prototype").clone();
prot.attr("class", "")
prot.find(".id").attr("value", id);
master.find("tbody").append(prot);
});
// Remove button functionality
$("table.optionsForm button.remove").on("click", function () {
$(this).parents("tr").remove();
});
$("table.optionsForm button.addColumn").click(function () {
var $this = $(this), $table = $this.closest('table')
$('<th><input type="text" name="options" class="form-control" placeholder="Column"></th>').insertBefore($table.find('tr').first().find('th:last'))
var idx = $(this).closest('td').index() + 1;
$('<td><input type="radio" name="col' + idx + '[]" value="" /</td>').insertBefore($table.find('tr:gt(0)').find('td:last'))
});
});
The add button code is creating a collection of four elements with class "prototype" and then cloning four elements:
var prot = master.find(".prototype").clone()
To add a single element, try selecting the first DOM element from the collection and converting it to a JQuery object before applying clone:
var prot = $(master.find(".prototype")[0]).clone()
As a minimal test/demonstration case (not using blade)
var master = $("#master");
var prot = $(master.find(".prototype")[0]).clone();
master.append(prot);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="master">
<span class="prototype">proto 1</span><br>
<span class="prototype">proto 2</span><br>
<span class="prototype">proto 3</span><br>
<span class="prototype">proto 4</span><br>
</div>

Is using <div> inside a <table> valid? Select all option inside a table row

I've got some trouble building a select all checkbox inside a table. Originally the table has several rows and the first checkbox should be used to select all options.
I built a small example, but still could not figure out my mistake.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "httpd://www.w3.org/TR/html4/loose.dtd">
<html><head>
<script language="JavaScript">
function allClicked(clickedId)
{
var divId = "div-" + clickedId.substring(4);
var child = document.getElementById( divId );
var tdChildren = child.getElementsByTagName("td"); // appears to be empty
var allCheckBox = document.getElementById( clickedId );
var setTo = allCheckBox.checked ? true : false;
for (var i=0; i<tdChildren.length; ++i) {
tdChildren[i].elements.checked = setTo;
}
}
</script>
</head><body>
<div id="div-a">
<table>
<tr>
<td><input id="all-AP" onClick="javascript:allClicked('all-AP')" type="checkbox">Select All</td>
<div id="div-AP">
<td><input id="AP_A1K" checked="checked" type="checkbox"></td>
<td><input id="AP_A2K" checked="checked" type="checkbox"></td>
<td><input id="AP_A3K" type="checkbox"></td>
</div>
</tr>
</table>
</div>
</body></html>
During debugging the div with id="all-AP" is retrieved but appears to be empty. I expected it to have three td-elements in it.
Is a div separating the td's valid?
What should I fix?
You don't need a div either to perform a "select all".
Have a look on this fiddle.
First :
<body>
<table id="checkboxtable">
<tr>
<td>
<input onClick="javascript:allClicked()" type="checkbox" />Select All</td>
<td>
<input id="AP_A1K" checked="checked" type="checkbox" />
</td>
<td>
<input id="AP_A2K" checked="checked" type="checkbox" />
</td>
<td>
<input id="AP_A3K" type="checkbox" />
</td>
</tr>
</table>
</body>
Each input has its own id (you CANNOT affect one id to more than one element).
Then allClicked() :
function allClicked() {
var checkBoxTable = document.getElementById("checkboxtable");
var checkBoxes = checkBoxTable.getElementsByTagName("input");
for (var i = 0; i < checkBoxes.length; ++i) {
// if (/^AP_.*/.test(checkBoxes[i].id)) // getting them by regular expression
if (checkBoxes[i].getAttribute("type") == "checkbox") // getting them by type
checkBoxes[i].checked = true;
}
}
The code retrieve the table element by its id. Then it gets all its <input type="checkbox"> elements. Depending on your needs, you can also catch them by their id with a [Regexp][2].test() method (here it catches element whose id begins with "AP_").
This is just one example implementation. You can achieve it in many ways.
No it isn't. You can either put another table inside the second cell or have some javascript to hide/display the other cells.
My final result and working example looks like this:
<!DOCTYPE HTML>
<html><head>
<meta charset="utf-8" />
<title>Testpage</title>
<script type="text/javascript">
function allClicked(clickedId)
{
var divId = "div-" + clickedId.substring(4);
var child = document.getElementById( divId );
var children = child.getElementsByClassName("AP");
var allCheckBox = document.getElementById( clickedId );
var setTo = allCheckBox.checked ? true : false;
for (var i=0; i<children.length; ++i) {
children[i].checked = setTo;
}
}
</script>
</head><body>
<table>
<tr id="div-AP">
<td><input id="all-AP" onClick="javascript:allClicked('all-AP')" type="checkbox">Select All</td>
<td><input class="AP" checked="checked" type="checkbox"></td>
<td><input class="AP" checked="checked" type="checkbox"></td>
<td><input class="AP" type="checkbox"></td>
</tr>
</table>
</body></html>
I used a validator to check the document. (http://validator.w3.org/check)
Using a class feature allows me to place the select all inside the same row.
The div doesn't work across table elements. Try this for your allClicked function instead:
function allClicked(clickedId)
{
var prefix = clickedId.substring(4);
var allCheckBox = document.getElementById( clickedId );
var setTo = allCheckBox.checked ? true : false;
var checkboxes = document.getElementsByTagName("input");
for (var i=0; i<checkboxes.length; ++i) {
var boxid = checkboxes[i].id;
if (boxid.indexOf(prefix)===0) {
checkboxes[i].checked = setTo;
}
}
}
This assumes your grouping of checkboxes have a common prefix. Just remove your div lines from the table entirely and rely on the id prefix of the input fields.

Unhide hidden objects from a website

I would like to make a javascript code that can unhide (reveal) some unhidden objects of a website.
Let me explain you more deeply.
There is one box with some items inside.
Lets say all the items that are being load to this box are 2000 but the website hide the 800.
Could i do something to reveal them?
The code that the website use (as i can see in the "inspect element" of chrome) is the following
<div class="_3hqu" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532">
<table class="_2x_v uiGrid _51mz" cols="3" cellspacing="0" cellpadding="0" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0">
<tbody data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0">
<tr class="_51mx" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2">
<td class="_51m- vMid" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$image">
<div class="_4b2j" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$image.0">
<img class="_2x_w img" src=" IMAGE LINK" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$image.0.0">
</div>
</td>
<td class="_2x_x _51m- vMid" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$text">
<div class="_2x_y" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$text.0">NAME</div>
<div class="_2x_z" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$text.1"></div>
<div class="_2x_z" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$text.2"></div>
</td>
<td class="_51mw _51m- vMid" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$widget">
<a aria-checked="true" aria-labelledby="100000533954532-name" aria-describedby="100000533954532-subtitle" class="_3hqy _3hqz" href="#" role="checkbox" tabindex="0" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$widget.0">
</a>
</td>
</tr>
</tbody>
</table>
</div>
So this is the code for only one element.
the $100000533954532 is the value of this element (without the $ )
and after 1200 of this elements with same code but different values
there is this code that "hides" the other 800 elements.
<input type="hidden" name="at_limit" value="false" data-reactid=".ih.1">
<input type="hidden" name="session_id" value="1326941442" data-reactid=".ih.2">
<input type="hidden" name="profileChooserItems" value="{ "000001":1, "000002":1, etc...
data-reactid=".ih.3">
Is it possible with javascript code to reveal the hidden values (elements) of this table???
what you need is remove property from collection of DOM elements
try this:
document.querySelector('input[type="hidden"]').removeAttribute("type");
Example on JsFiddle
Similar question on StackOverflow
Here's a simple example of grabbing an input element and using the attributes and values contained therein to dynamically create a more complex set of HTML nodes:
JSFiddle it here.
<input type="hidden" name="at_limit" value="false" data-reactid=".ih.1">
<script>
var at_limit = document.querySelector('input[name="at_limit"]');
var reactid = at_limit.getAttribute('data-reactid');
var toggle = (at_limit.value === "true");
var div = document.createElement("DIV");
var tbl = document.createElement("TABLE");
var tbdy = document.createElement("TBODY");
var tr = document.createElement("TR");
var td = document.createElement("TD");
var anc = document.createElement("A");
anc.href = "page.html?reactid=" + reactid;
anc.className = ( toggle )? 'yes': 'no';
var txt = document.createTextNode(reactid);
anc.appendChild(txt);
td.appendChild(anc);
tr.appendChild(td);
tbdy.appendChild(tr);
tbl.appendChild(tbdy);
div.appendChild(tbl);
document.body.appendChild(div);
</script>
<style>
.no { color: red; }
.yes { color: green; }
table { border: solid blue 1px; }
</style>
That's the concept, now it's a matter of mapping the input elements to the targeted div/table structure.

Using Javascript How to loop through a div containing checkboxes and get the value checked from each check box

I have a table with each row containing a cell that has 8 check boxes(Column4)
Here is an example
<table id="enc-assets" class="table">
<thead>
<tr><th>Column1</th><th>Column2</th><th>Column3</th><th>Column4(CONTAINS OPTIONS)</th>
</thead>
<tbody>
<tr>
<td id="sc-isrc"></td>
<td id="sc-filename"></td>
<td id="sc-path" hidden></td>
<td id="sc-platforms">
<div id="sc-inline" style="display: inline-block;">
<div >
<div ng-repeat="p in products ">
<label id="enc"><input id="Platform" ng-checked="prod[p.name]" ng-model="prod[p.name]" ng-init="prod[p.name] = true" type="checkbox"/></label>
</div>
</div>
</div>
</td>
<td>
</td>
<td><br/><br/><button id="enqueuebtn" type="button" ng-click="Show(test)" class="btn-primary"></button></td>
</tr>
</tbody>
</table>
I am trying to loop through each row and assign values from each cell into an object .
I am having problems getting the value checked from the cell that contains the 8 check boxes. I can get values from the other cells just fine.
I have tried the following:
$("#enc-assets tbody tr").each(function() {
var message;
message = new Object();
message.isrc = $(this).find('#sc-isrc').text();
message.path = $(this).find('#sc-path').text();
$("#sc-platforms div div").each(function() {
var platform, selected;
selected = $(this).find('#Platform div label input').checked;
if (selected === true) {
platform = $(this).find('#enc').text();
This is the part that I am not sure if works:
selected = $(this).find('#Platform div label input').checked;
Do I have the correct nesting here to get the values from the check boxes?
Try this:
jsFiddle here
$("#enc-assets tbody tr").each(function() {
var message;
message = new Object();
message.isrc = $(this).find('#sc-isrc').text();
message.path = $(this).find('#sc-path').text();
$("#sc-platforms>div>div").each(function() {
alert( $(this).attr('id') );
var platform, selected;
selected = $(this).find('#Platform');
if(selected.is(':checked')) {
alert('Checked');
}
platform = $(this).find('#enc').text();
alert(platform);
}); //END each #sc-platforms>div>div
}); //END each #enc-assets tbody tr

Categories