How do I get all the inputs in a element with jQuery? - javascript

I'm new to jQuery. I'm trying to get all inputs inside a div element. Here is what I have coded so far:
$(".pros_earnings_delete_annual_earning").click(function(e) {
e.preventDefault();
var target = $(e.target);
var parent = target.parent(".total-for-earnings");
var inputs = parent.children(":input");
console.log(inputs);
$.each(inputs, function(index, value) {
console.log(value);
});
});
When I click I get this:
[prevObject: v.fn.v.init[0], context: button.pros_earnings_delete_annual_earning, selector: ".parent(.total-for-earnings).children(:input)", constructor: function, init: function…]
The each method does not seem to output anything.
HTML:
<div class="total-for-earnings" style='background-color:#ccc;padding:10px;overflow:hidden;'>
<div style='width:160px;float:left;'><strong>Total for 2013:</strong>
<input type='hidden' name='pros_earnings_annual_year[]' value='2013'>
</div>
<input type='text' name='pros_earnings_annual_amount_mul[]' placeholder='0' value='10' size='8' style='width:80px;' />
<select name='pros_earnings_annual_amount_sup[]' style='width:110px;'>
<option value='Thousand'>Thousand</option>
<option value='Million' selected>Million</option>
<option value='Billion'>Billion</option>
</select><span>USD</span>
<div style="float:right;">
<button class="pros_earnings_save_annual_earning" style="margin-left:15px; width:auto; height:25px;">Save</button>
<button class="pros_earnings_delete_annual_earning" style="margin-left:15px; width:25px; height:25px;">-</button>
</div>
</div>

Change
var target = $(e.target);
var parent = target.parent(".total-for-earnings");
var inputs = parent.children(":input");
to,
var parent = $(this).closest(".total-for-earnings");
var inputs = parent.find(":input"); //Unlike children(), find() will go any depth to match.

Simply put:
var $inputs = $(':input',parent)
Will match all inputs in the context of the parent element.
You're console.log is outputting the jQuery object which represents each item in this collection, if you want the value of the input, just ask:
$inputs.each(function(){
console.log($(this).val());
})
Also, there was one other bug - target.parent(..) should have been target.parents(..) (plural)
Live example: http://jsfiddle.net/3aJuZ/

the problem is in this line
var parent = target.parent(".total-for-earnings");
change to
var parent = target.parents(".total-for-earnings");

Related

I am trying to make a checklist where I can click on the button attributed to each "task" and the single line is removed when it is clicked.

Like the question says. I have been able to rid the entire list with a click of a single button (not what I want), I have been able to click a button and rid just the button but not the text - this is what is giving me the biggest issue.
Any help would be greatly greatly appreciated.
//create the initial todocount variable
var toDoCount = 0;
window.onload = function() {
//user clicked on the add button in the to-do field add that text into the to-do text
$('#add-to-do').on('click', function(event) {
event.preventDefault();
//assign variable to the value entered into the textbox
var value = document.getElementById('to-do').value;
//test value
console.log(value);
var todoitem = $("#to-dos");
todoitem.attr("item-");
//prepend values into the html and add checkmark, checkbox, and line break to make list
var linebreak = "<br/>";
var todoclose = $("<button>");
todoclose.attr("data-to-do", toDoCount);
todoclose.addClass("checkbox");
todoclose.text("☑");
//prepend values to html
$("#to-dos").prepend(linebreak);
$("#to-dos").prepend(value);
$("#to-dos").prepend(todoclose);
toDoCount++;
//to remove item from checklist
$(document.body).on("click", ".checkbox", function() {
var toDoNumber = $(this).attr("data-to-do");
$("#to-dos").remove();
});
});
HTML below
<div class ="col-4">
<!-- To Do List -->
<form onsubmit= "return false;">
<span id = "todo-item" type = "text">
<h4>Add your Agenda Here</h4>
<input id ="to-do" type = "text">
<input id ="add-to-do" value = "Add Item" type = "submit">
</span>
</form>
<div id="to-dos"></div>
</div>
This should work.
//create the initial todocount variable
var toDoCount = 0;
$(function() {
//user clicked on the add button in the to-do field add that text into the to-do text
$('#add-to-do').on('click', function(event) {
event.preventDefault();
//assign variable to the value entered into the textbox
var value = document.getElementById('to-do').value;
//test value
console.log(value);
var todoitem = $("#to-dos");
todoitem.attr("item-");
//prepend values into the html and add checkmark, checkbox, and line break to make list
var linebreak = "<br/>";
var todoclose = $("<button>");
todoclose.attr("data-to-do", toDoCount);
todoclose.addClass("checkbox");
todoclose.text("☑");
//prepend values to html
$("<div/>", {
"class": "to-do-item"
})
.append([todoclose, value, linebreak])
.appendTo($("#to-dos"));
toDoCount++;
//to remove item from checklist
$(document.body).on("click", ".to-do-item", function() {
var toDoNumber = $('.checkbox', this).attr("data-to-do");
$(this).remove();
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col-4">
<!-- To Do List -->
<form onsubmit="return false;">
<span id="todo-item" type="text">
<h4>Add your Agenda Here</h4>
<input id ="to-do" type = "text">
<input id ="add-to-do" value = "Add Item" type = "submit">
</span>
</form>
<div id="to-dos"></div>
</div>
I found the root issue to be related to how you remove the item. If it is based on the button click, then $(this).remove() simply removes the button.
Consider the following code.
$(function() {
function makeTask(todo) {
var c = $("#to-dos .todo-item").length + 1;
console.log(c, todo);
var item = $("<div>", {
class: "todo-item",
id: "todo-item-" + c
});
$("<button>", {
class: "checkbox todo-item-close",
id: "todo-item-close-" + c
}).html("☑").click(function(e) {
console.log("Remove", $(this).parent().attr("id"));
$(this).parent().remove();
}).appendTo(item);
item.append(todo);
return item;
}
$('form').submit(function(e) {
e.preventDefault();
var task = makeTask($("#to-do").val());
task.appendTo("#to-dos");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col-4">
<!-- To Do List -->
<form>
<h4>Add your Agenda Here</h4>
<input id="to-do" type="text" />
<input id="add-to-do" value="Add Item" type="submit" />
</form>
<div id="to-dos"></div>
</div>
Here we add the button and assign a click event to that button. Since the button is inside the <div> we need to traverse to the parent element and then remove the entire element.
Since it is in a form, and many users may try to submit the data with Enter, I prefer to use .submit() callback.
Hope that helps.

get an element id and then use it in a getElmentByID to trigger a function on click

function getId(e){
var xid = e.target.id;
console.log(xid);
}
<form onclick="getId(event)">
<label for="name" id="I am an Span">Nombre</label><br>
<input type="text" name="name" id="tbx_nombre"> <br>
<span id="nombre"></span> <br>
</form>
<div id="result"></div>
When the user click on a texbox the function gets the id of the element, then the deleteSpan method is call with the splitted id of the textbox which is now the id of the span to be changed to an emply string.
I get this error Cannot set property 'onclick' of null at getId
<form onclick="getId(event)">
<input type="text" name="name" id="tbx_name"><br>
<span id="name"></span>
...MORE INPUTS AND SPAN TAGS...
</form>
JS
function getId(e){
var xid = e.target.id; // => tbx_name
var spanId = xid.split("_").pop(); // =>name
document.getElementById(xid).onclick = function(){deleteSpan(spanId)};
}
function deleteSpan(spanId){
document.getElementById(spanId).innerHTML = "";
}
You are getting that error because when you try to set the click handler on the span by ID, you don't currently have the correct ID. It's null, because the click target is currently the form (which doesn't have an ID) instead of the input.
As others mentioned, the click event listener should be attached to the input.
But you also don't need to set a separate click handler within getId--you can just call deleteSpan in the getId function. In fact, if you set it inside another handler like you have, it won't work the first time (unless that's your desired outcome).
function getId(e){
var xid = e.target.id; // => tbx_name
var spanId = xid.split("_").pop(); // =>name
deleteSpan(spanId);
}
function deleteSpan(spanId){
document.getElementById(spanId).innerHTML = "";
}
<form>
<input onclick="getId(event)" type="text" name="name" id="tbx_name"><br>
<span id="name">Span</span>
</form>
onclick attribute event handler should be at input instead of form
<form>
<input type="text" name="name" id="tbx_name" onclick="getId(event)"><br>
<span id="name"></span>
</form>
or even better, use addEventListener for the inputs which have id format as tbx_{{value}}
var allInputs = document.querySelectorAll("input[id^='tbx_']");
allInputs.forEach( s => s.addEventListener( "click", e => getId ));
You can invoke above code when the form has loaded (at document load or window load).
You have to set the attribute onclick in input instead of form to get the expected id. Otherwise you have to check if the target node is INPUT or not:
function getId(e){
if(e.target.nodeName == 'INPUT'){
var xid = e.target.id; // => tbx_name
var spanId = xid.split("_").pop(); // =>name
deleteSpan(spanId);
}
}
function deleteSpan(spanId){
document.getElementById(spanId).innerHTML = "";
}
<form onclick="getId(event)">
<input type="text" name="name" id="tbx_name"><br>
<span id="name">Span</span>
</form>

Javascript - prevent onclick event from being attached to all elements with same class

I'm working on a simple form that includes an input field where the user will fill in the required amount by clicking the incrementor/decrementor. The form is created based on data pulled dynamically from the database
Below is the problematic part: html and the jquery handling it:
The incrementor, decrementor and the input field:
-
<input type="text" id="purchase_quantity" class = "purchase_quantity" min="1" max="6" delta="0" style = "width: 32px;" value="1">
+
and the jquery handling the above:
jQuery(function ($) {
$('.addItem').on('click', function () {
var inputval = $(this).siblings('.purchase_quantity').val();
var num = +inputval;
num++;
if(num>6)num=6;
console.log(num);
$(".purchase_quantity").val(num);
return false;
});
$('.removeItem').on('click', function () {
var inputval = $(this).siblings('.purchase_quantity').val();
var num = +inputval;
num--;
if(num<1)num=1;
console.log(num);
$(".purchase_quantity").val(num);
return false;
});
});
Now, what's happening is: onclick of the incrementor/decrementor (+ and -) the value on the input field changes across all the fields in the page instead of the one clicked only. Have spent quite some time on this with no success and will appreciate some help
The line
$(".purchase_quantity").val(num);
says, literally, to change the value on all the fields. Earlier you used
$(this).siblings('.purchase_quantity').val()
to get the value, so why not also use
$(this).siblings('.purchase_quantity').val(num)
to set it?
That's because siblings will get you all items on the same level.
Get the siblings of each element in the set of matched elements,
optionally filtered by a selector.
Place them in separate div elements, and adjust your setter to actually only update the siblings inside that div.
jQuery(function ($) {
$('.addItem').on('click', function () {
var inputval = $(this).siblings('.purchase_quantity').val();
var num = +inputval;
num++;
if(num>6)num=6;
console.log(num);
$(this).siblings('.purchase_quantity').val(num);
return false;
});
$('.removeItem').on('click', function () {
var inputval = $(this).siblings('.purchase_quantity').val();
var num = +inputval;
num--;
if(num<1)num=1;
console.log(num);
$(this).siblings('.purchase_quantity').val(num);
return false;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
-
<input type="text" id="purchase_quantity2" class = "purchase_quantity" min="1" max="6" delta="0" style = "width: 32px;" value="1">
+
</div>
<div>
-
<input type="text" id="purchase_quantity1" class = "purchase_quantity" min="1" max="6" delta="0" style = "width: 32px;" value="1">
+
</div>
you should change $(".purchase_quantity").val(num) to $("#purchase_quantity").val(num)

Read dynamically updated attribute value jquery

I have a situation over here. I'm writing this situation in a chronology.
Assume that there are an input[type=number] and a button.
When the button is clicked, it will change the attribute value (data-oldval="") to the current value of the input number.
The next time I click the button, it supposed to add the current value in the input with the number in the data-oldval attribute.
But the problem is, I can't read the newly updated attribute value.
To make the situation clearer, I included the code snippet below. I hope that anybody here can help me with this.
var response = $('.response');
$('body').on('click', '.btn', function() {
var btn = $(this),
t = btn.parent('.dummy'),
n = t.find('input[type=number]'),
val = n.val(),
oldval = n.data('oldval');
n.attr('data-oldval', val+oldval);
response.text(n.data('oldval'));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dummy">
<input type="number" value="1" data-oldval="0">
<button class="btn" type="submit">Add</button>
</div>
<div class="response"></div>
Two issues; you need to retrieve the value using data('oldval'), not attr(), and you also need to convert val() to an integer so it can be added to the old value. Try this:
var response = $('.response');
$('body').on('click', '.btn', function() {
var btn = $(this),
t = btn.parent('.dummy'),
n = t.find('input[type=number]'),
val = parseInt(n.val(), 10),
oldval = n.data('oldval');
n.data('oldval', val + oldval);
response.text(n.data('oldval'));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dummy">
<input type="number" value="1" data-oldval="0">
<button class="btn" type="submit">Add</button>
</div>
<div class="response"></div>
You need to parse the number entered into the input or it will be returned as a string and concatenated when setting val + oldval
console.log(typeof(val)) // string
val = parseInt(n.val());
You can also set the attribute by using the jQuery data method, the same way you're retrieving it to update the response element.
n.data('oldval', val + oldval);
See https://jsfiddle.net/aso1s0xz/
There is already a great answer but here is solution without data-oldval as I don't see why is it needed in this case.
$('body').on('click', '.btn', function() {
var response = parseInt($('.response').text());
if(isNaN(response))response=0;
var val = parseInt($('input').val());
var sum = val+response;
$('.response').text(sum);
})
To get dynamic Value Try JS, It will work perfectly
document.getElementById('element-id').getAttribute('data-oldval');
Use the Data() method in jQuery to set the value too:
var response = $('.response');
$('body').on('click', '.btn', function() {
var btn = $(this),
t = btn.parent('.dummy'),
n = t.find('input[type=number]'),
val = n.val(),
oldval = n.data('oldval');
n.data('oldval', parseInt(val)+parseInt(oldval));
response.text(n.data('oldval'));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dummy">
<input type="number" value="1" data-oldval="0">
<button class="btn" type="submit">Add</button>
</div>
<div class="response"></div>

calculate the product of two input fields in javascript using jQuery

I have an input field that I want to populate with the product of two input fields that appear earlier in the form.
<div class="form-group">
<label for="item_name" class="col-lg-2 control-label">Item:</label>
<div class="col-lg-2">
<input type="text" name="item_name[]" placeholder="Name">
</div>
<div class="col-lg-2">
<input type="text" name="item_qty[]" placeholder="Quantity">
</div>
<div class="col-lg-2">
<input type="text" name="item_price[]" placeholder="Price">
</div>
<div class="col-lg-2">
<input type="text" name="item_total[]" placeholder="Total">
</div>
</div>
These input fields can occur multiple times, so I'm attempting to loop over the item_total[] arrray and attach a listener to the focus event.
$.each($("[name='item_total[]']"), function( index, value ) {
$(this).focus(function() {
var value = ?
//not sure how to select the value of the two previous input fields
// var value = $("item_qty[index]") * $("item_price[index]");
console.log(value);
});
});
You can do like this
$('input[name="item_qty[]"],input[name="item_price[]"]').on("change",function (){
var $container = $(this).closest('.form-group');
qty = Number($('input[name="item_qty[]"]',$container).val())||0,
price = Number($('input[name="item_price[]"]',$container).val())||0;
$('input[name="item_total[]"]',$container).val(qty * price);
})
Another solution starts with selector:
$('input[name^="item_qty"],input[name^="item_price"]').on("change",function (){
var $container = $(this).closest('.form-group');
qty = Number($('input[name^="item_qty"]',$container).val())||0,
price = Number($('input[name^="item_price"]',$container).val())||0;
$('input[name^="item_total"]',$container).val(qty * price);
})
Following assumes that you have [] in input names due to repeating rows and will isolate values within repeated row instances
You can traverse to the nearest wrapping container which would be form-group using closest(), then look within that container using find()
I think what you want is to apply change handler to the user inputs and calculate total when they change
$("input[name=item_qty\\[\\]], input[name=item_price\\[\\]]").change(function(){
var $container = $(this).closest('.form-group');
var qty = $container.find('[name=item_qty\\[\\]]') || 0;
var price = $container.find('[name=item_price\\[\\]]') || 0;
$container.find('[name=item_total\\[\\]]').val( qty * price );
});
jQuery requires escaping special characters in selectors which is why there are so many \\ above.
See escaping rules in selectors API Docs
Something like the following would work.
var quantityEl = $('input[name="item_qty[]"]'),
priceEl = $('input[name="item_price[]"]'),
totalEl = $('input[name="item_total[]"]')
;
var calculateTotal = function() {
var quantity = +quantityEl.val().trim(),
price = +priceEl.val().trim(),
total = quantity * price
;
if (!isNaN(total)) {
totalEl.val(total);
}
};
priceEl.on('change keyup paste', calculateTotal);
quantityEl.on('change keyup paste', calculateTotal);
You can do soemthing like this
input1 = $(this).closest($("[name='item_price']")).val()
Or like this
input1 = $("[name='item_price']")[index]).val()

Categories

Resources