In my code, I can get the object but not the value. How can I get the value of the .cups textbox? Thanks.
HTML:
<tr id="20">
<td class="description">CHEESE,FONTINA</td>
<td><input type="text" class="cups" value=""></td>
<td><input type="checkbox" class="breakfast"></td>
<td><input type="checkbox" class="lunch"></td>
<td><input type="checkbox" class="dinner"></td>
<td><input type="checkbox" class="snack"></td>
<td><input type="checkbox" class="favorites"></td>
<td><label class="addFood"><input type="button" class="input_text_custom input_button" value="Add"></label></td>
</tr>
JS:
$(document).ready(function () {
$('.addFood').click(function () {
var tr = $(this).parents('tr');
var foodId = tr.attr('id'); // works
var servings = tr.children('.cups'); // returns [object Object]
var servings = tr.children('.cups').val(); // returns undefined
alert(servings);
});
});
The <input> is a grandchild of <tr>, not a child, so it won't be selected by .children and you get a jQuery object which has no members when you try it (this is akin to an empty array).
Use .find instead, that operates on descendants.
I always find that it is best to be as verbose as you can with jQuery selectors. Especially when it comes to classes as there can be more than one element or types of elements that could be matched. Id's are unique so tr#20 is overkill (IMO).
I would use something like this -
var cupsValue = $("#20 input.cups").val();
If you still want to use a derivative of your code, I would also suggest that you use closest() and not parents() (unless there is something I'm missing from your markup). You are only looking for one parent object, the closest tr that is a parent of the current element.
Related
I have a form under a . I want to clone this and append dynamically in another and so on dynamically. Also I need to assign auto incremented id to all form elements too. Apart from pure javascript I can not use any jQuery or any other library.
Here is my HTML
<tr id="repeat">
<td><input type="text" id="fieldName" /></td>
<td>
<select name="fieldType" id="fieldType">
<option value="string">String</option>
</select>
</td>
<td><input type="radio" id="mandatory" name="mandatory" value="true" /><input type="radio" id="mandatory" name="mandatory" value="false" /></td>
<td>Delete Button</td>
</tr>
Here is my JavaScript
var i = 0;
this.view.findById("start").addEventHandler("click", function () {
var original = document.getElementById('repeat');
var clone = original.cloneNode(true);
original.parentNode.appendChild(clone);
})
Presently I can cloned the form elements in <tr id="repeated1"> dynamically and so on, but unable to assign auto incremented id to input box and select box . Also unable to assign auto incremented name to the radio buttons dynamically
You can change Id or another attribute as you want.
but for your code my solution is using querySelectorAll to get element and change it's Id, something like below code, it is tested and works nice:
Based on this HTML design code and JS function:
function MakeElementsWithDifferentId() {
for (var i = 1; i < 10; i++) {
var original = document.getElementById('repeat');
var clone = original.cloneNode(true);
clone.id="repeat"+i;
clone.querySelectorAll('[id="fieldName"]')[0].id ="fieldName"+i;
clone.querySelectorAll('[id="fieldType"]')[0].id ="fieldType"+i;
clone.querySelectorAll('[id="mandatory"]')[0].id ="mandatory"+i;
clone.children[2].children[0].name="mandatoryName"+i; //To change the radio name also
original.parentNode.appendChild(clone);
}
}
MakeElementsWithDifferentId();
<table>
<tr id="repeat">
<td><input type="text" id="fieldName" /></td>
<td>
<select name="fieldType" id="fieldType">
<option value="string">String</option>
</select>
</td>
<td><input type="radio" id="mandatory" name="mandatory" value="true" /> </td>
<td>Delete Button</td>
</tr>
</table>
the MakeElementsWithDifferentId() function make 10 batch elements with different Ids.
the JSFiddle Test
after run you can right click on element that you want and see the Id by inspect element.
Note:
Instead of clone.querySelectorAll('[id="fieldName"]')[0] it's better to get element by querySelector like clone.querySelector('[id="fieldName"]')
Hope will help you.
I am trying to get the element inside of the dynamically created ID, to alert. So far i've this.
<tr>
<td class="td-input">
<input id="WILL GENERATE DYNAMICALLY IP" type="checkbox"
onchange="toggleSelect(this,event)" class="update-select-widget">
</td>
<td>127.0.0.1</td>
<td></td>
<td>
<div onclick="singleLaunch(this)"><i class="fa fa-gear"></i></div>
</td>
</tr>
function:
var nestedId = $(this).parent().parent().children(".td-input").attr("id");
alert(nestedId);
there is plenty of tables with different values, ill have to showcase, i tried using .each and .map in the past but still not luck. Best Regards
this cannot be used if you are calling this using onclick attribute.
function singleLaunch(div){
alert($(div).closest('tr').find(".td-input input").attr("id"));
}
function singleLaunch(x){
var nestedId = $(x).closest("tr").find(".td-input input").attr("id");
alert(nestedId);
}
Try this
$(document).on('click', '.td-input input', function(){
alert($(this).attr('id'));
});
I am trying to build up a table by adding values from textbox fields in the tfoot of the same table. The eventual goal is to be able to then inline edit previously added rows while still leaving the capability to add more rows.
I have the following markup:
<table>
<thead>
<tr>
<th>Service</th>
<th>Protocol</th>
<th>Source Port</th>
<th>Destination Port</th>
<th>Action</th>
</tr>
</thead>
<tfoot>
<tr>
<td>
<input type="text" data-function="service" value="foo" />
</td>
<td>
<input type="text" data-function="protocol" value="bar" />
</td>
<td>
<input type="text" data-function="sourcePort" value="baz" />
</td>
<td>
<input type="text" data-function="destPort" value="fob" />
</td>
<td>
<button id="addBtn" type="button">Add</button>
</td>
</tr>
</tfoot>
</table>
The below script stores all of the input[type=text] elements in the tfoot in an inputs variable. From there I am trying to use .index() to identify and then retrieve the value of each textbox:
$(document).ready(function () {
$('#addBtn').click(function (e) {
var inputs = $(this).closest('tfoot').find('input[type=text]');
console.log(inputs);
var serviceIndex = inputs.index('[data-function="service"]');
console.log(serviceIndex);
console.log(inputs[serviceIndex].value);
// the remaining indexes all return -1
var protocolIndex = inputs.index('[data-function="protocol"]');
console.log(protocolIndex);
console.log(inputs[protocolIndex].value);
var sourcePortIndex = inputs.index('[data-function="sourcePort"]');
console.log(sourcePortIndex);
console.log(inputs[sourcePortIndex].value);
var destPortIndex = inputs.index('[data-function="destPort"]');
console.log(destPortIndex);
console.log(inputs[destPortIndex].value);
});
});
Unfortunately the selector data-function="X" selector only works for service. All of the other selectors return -1 indicating that a value was not found. The above code is from this jsFiddle which illustrates the problem. I am not wedded to using index, but cannot use the element's id as I need a more general solution.
Why does the jQuery .index() method only work for the first element in the collection, when a selector is specified?
From the docs:
If .index() is called on a collection of elements and a DOM element or
jQuery object is passed in, .index() returns an integer indicating the
position of the passed element relative to the original collection.
So this should work:
inputs.index($('[data-function="protocol"]'));
...
Demo: http://jsfiddle.net/Dfxy9/2/
In the context you are using it .index is only called on the first element in the jQuery collection. jQuery does this for any non-iterative method (for example .html, .attr, .text) -- .index is no different.
Instead of using the collection, use the selector: http://jsfiddle.net/4kLqb/
I have a table with some td elements with the same class. But i want to change claas only in specified area .selected.
I make this:
<tr>
<td>--</td>
<td class="mcost"></td>
</tr>
<tr class="selected">
<td><input type="radio" name="work" onclick="selone('.selected','#sel1','m');" checked="checked" /></td>
<td id="sel1" class="mcost"></td>
</tr>
<tr class="selected">
<td><input type="radio" name="work" onclick="selone('.selected','#sel2','m');" /></td>
<td id="sel2" class="mcost"></td>
</tr>
<tr>
<td>--</td>
<td class="mcost"></td>
</tr>
And try this:
function selone(g,f,n){
$(g).each(function(){
$('.'+n+'cost').removeClass().addClass(n+'cost_dis');
});
$(f).removeClass().addClass(n+'cost');
}
But it's change class to all mcost elements =( Not only in specified area. How to improve it?
in your .each, you requery the entire dom for .mcost cells. You need to do the following:
function selone(g,f,n){
$(g).each(function(){
$(this).find('.'+n+'cost').removeClass().addClass(n+'cost_dis');
});
$(f).removeClass().addClass(n+'cost');
}
This will only change the .mcost items inside of your $(g) element. This should work. Let me know.
$(".selected td").each( function() { $(this).addClass("whatever"); } );
You could use a better, and unobtrusive approach:
remove the onclick-events in the html.
Use the script to this:
$(function () {
$(".selected :radio").click(function () {
var selected = $(this).parents(".selected:first");
selected.removeClass().addClass('mcost_dis');
selected.find('.mcost').removeClass().addClass('mcost');
});
});
(However the last line doesn't add much)
The problem is in the part $('.'+n+'cost')
this does not consider the context it is called in. It will allways select all .mcost elements in the page.
if you change it to:
$(this).find('.'+n+'cost')
it will search only in the context of g. Do the same for f.
However, it all depends on what g and f are. Using .selected in this case it should give you what you want.
I don't think you need the each loop at all if you change your selector a bit. Wouldn't this work:
function selone(g,f,n) {
// find elements that already have the class, and change them
$(g + " ." + n + 'cost').removeClass().addClass(n+'cost_dis');
// add class to newly selected item
$(f).removeClass().addClass(n + 'cost');
}
Assuming you call it with
selone('.selected','#sel1','m');
Then within the function $(g + " ." + n + 'cost') evaluates as $(".selected .mcost") - which means "find elements of class 'mcost' that are descendents of elements with class 'selected'".
I have the following HTML dinamically generated:
...
<tr>
<td><input type="text" class="q" value="5" name="q[]" /></td>
<td><input type="text" class="p" value="20" name="p[]" /></td>
</tr>
...
Ok, so what I want to do is the following: when an input with class q changes, I want to obtain the product between p and q (p*q) that are in the same row, so in this example I would obtain 100.
Is that possible? Thanks!
$('.q').change(function() {
result = $(this).val() * $(this).next('.p').val()
});
You can get the other element with:
// this references the `q` element
$(this).parent().children('.p')
// or
$(this).next('.p')
// or
$(this).closest('tr').find('.p') // <- least prone to structure changes
// or
$(this).siblings('.p')