I' creating a table to add new lines where each line had an input quantity but doesn't work well.
When i add more than a line the quantiy of first input increment more than once.
I want that each input increment 1 time per click.
My html - jade:
table(class=["table","table-hover", 'table-reception'])
thead
tr
th Referência
th Designação
th Quantidade
tbody
My view: (When i read a bar code i add a new tr)
tr(class="item-article", id="#{data.ref}", data-codigo="#{data.codigo}")
td(class="td-ref")
span #{data.ref}
td(class="td-design")
span #{data.design}
td(class="td-qtt")
<input type='button' value='-' class='minus' />
<input type='text' size='10' class='value' value='0' />
<input type='button' value='+' class='plus' />
my jquery:
function btnPlusMinus()
{
$('.minus, .plus').click(function (e) {
e.preventDefault();
var $input = $(this).siblings('.value');
var val = parseInt($input.val(), 10);
$input.val(val + ($(this).hasClass('minus') ? -1 : 1));
$( ".barCode" ).val('');
$( ".barCode" ).focus();
});
}
Jquery - loading bar code:
function receptionArticle()
{
$('.barCode').change(function ()
{
barCode = $(this).val();
//alert($(this).val());
document.getElementById('scrollToReception').scrollIntoView();
$.get("/warehouse-reception-getArticle/"+encodeURIComponent(barCode), function(data)
{
if(data == 'false')
{
$.get("/warehouse-reception-popup/", function(data)
{
$(".popup").html('');
$(".popup").append(data);
$('.opacity').show();
$('.popup').show();
closeWarehousePopup();
});
}
else
{
$(".table-reception tbody").append(data);
$(".table-reception tbody tr:last").hide();
$('.table-reception tbody tr:last').css( "background-color", "#2ecc71" ).fadeIn(1000);
$( ".table-reception tbody tr:last" ).animate({
'background-color': "initial"
}, 5000);
$("#reception-message").hide();
$( ".barCode" ).val('');
$( ".barCode" ).focus();
btnPlusMinus();
}
});
});
}
Html:
If i add five row and increment the first input the result was 5 and not 1. If i in second row increment the result was 4 and 1. etc...
Thank you
The problem is that you are calling btnPlusMinusInit() every time you add a row - and with each call you are binding an extra event on it. So after adding 3 rows the events for the buttons in the first row are called 3 times.
It's better to use jQuery's on event handler with a selector. By using a selector (in your case '.minus, .plus') the event is delegated and affects new elements added to the DOM, too.
So try this instead:
$('#add-row').click(function() {
var row = '<tr><td>'+
'<input type="button" value="-" class="minus" />'+
'<input type="text" size="10" class="value" value="0" />'+
'<input type="button" value="+" class="plus" />'+
'</td></tr>';
$(".table-reception tbody").append(row);
});
$(document).on('click', '.minus, .plus', function (e) {
e.preventDefault();
var $input = $(this).siblings('.value');
var val = parseInt($input.val(), 10);
$input.val(val + ($(this).hasClass('minus') ? -1 : 1));
$( ".barCode" ).val('');
$( ".barCode" ).focus();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table-reception">
<tbody></tbody>
</table>
<button id="add-row">Add row</button>
First at all, its not a nice solution to handle a function with the class.
function btnPlusMinusInit()
{
$('#plusBtn').click(btnPlus); //use id selector, for unique elements
$('#minusBtn').click(btnMinus); //use id selector, for unique elements
};
btnPlusMinusInit();
function btnPlus(e){
var $input = $(this).siblings('#value'); //use id selector, for unique elements
var inputValue = $input.val();
inputValue = inputValue.trim() != "" ? inputValue : 0; //check for empty input or add readonly
var val = parseInt(inputValue);
$input.val(val + 1);
$( "#barCode" ).val(''); //use id selector, for unique elements
$( "#barCode" ).focus(); //use id selector, for unique elements
}
function btnMinus(e){
var $input = $(this).siblings('#value'); //use id selector, for unique elements
// var $input = $('#value'); would be the same for a unique value element.
var inputValue = $input.val();
inputValue = inputValue.trim() != "" ? inputValue : 0; //check for empty input or add readonly
var val = parseInt(inputValue);
$input.val(val - 1);
$( "#barCode" ).val(''); //use id selector, for unique elements
$( "#barCode" ).focus(); //use id selector, for unique elements
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="minusBtn" type='button' value='-' class='minus' />
<input id="value" type='text' size='10' class='value' value='0' />
<input id="plusBtn" type='button' value='+' class='plus' />
<div id="barCode">HERE IS A BARCODE</div>
Related
I have a jquery function to show or hide divs when certain checkboxes are checked or unchecked and work fine using the "change" function. Therefore, if the checkbox has already been previously checked the corresponding div is not shown. How can I change this code to work?
My code is here:
<script>
jQuery(document).ready(function($) {
$('.my_features').change(function() {
var checkbox = $(this);
if( checkbox.is(':checked') ) {
$( '#' + checkbox.attr('data-name') ).show();
} else {
$( '#' + checkbox.attr('data-name') ).hide();
}
});
});
</script>
This is pretty canonical.
I would use data-id instead of data-name though:
$(function() {
$('.my_features').on("change",function() {
$(`#${this.dataset.id}`).toggle(this.checked);
}).change(); // trigger the change
});
.toggleDiv { display:none}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label><input type="checkbox" class="my_features" data-id="div1">Div 1</label>
<label><input type="checkbox" checked class="my_features" data-id="div2">Div 2</label>
<div id="div1" class="toggleDiv">Div1 div</div>
<div id="div2" class="toggleDiv">Div2 div</div>
If you do not like mixing DOM and jQuery access then
$(`#${$(this).data('id')}`).toggle($(this).is(':checked'));
I am assuming your question was how to show/hide the divs for checkboxes that are already checked/unchecked upon loading the page.
You can do this by passing in the same function you are using for change() into the each() method, which will iterate over each checkbox and run the function.
jQuery(document).ready(function($) {
$('.my_features').each(function(){
var checkbox = $(this);
//you can use data() method to get data-* attributes
var name = checkbox.data('name');
if( checkbox.is(':checked') ) {
$( '#' + name ).show();
} else {
$( '#' + name ).hide();
}
});
});
Demo
function update(){
var checkbox = $(this);
var name = checkbox.data('name');
if( checkbox.is(':checked') ) {
$( '#' + name ).show();
} else {
$( '#' + name ).hide();
}
}
//just setup change and each to use the same function
$('.my_features').change(update).each(update);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<input class="my_features" type="checkbox" data-name="first" />
<input class="my_features" type="checkbox" data-name="second" checked />
<input class="my_features" type="checkbox" data-name="third" checked />
<input class="my_features" type="checkbox" data-name="fourth" />
</div>
<div id="first">First</div>
<div id="second">Second</div>
<div id="third">Third</div>
<div id="fourth">Fourth</div>
You can use the following to get the data and then show or hide the div based on the checkbox value
$(document).ready(function() {
$('.my_features').on('click', function() {
var checkbox = $(this);
var div = checkbox.data('name');
if (checkbox.is(':checked')) {
$('#' + div).show();
} else {
$('#' + div).hide();
}
});
})
You can see a working fiddle
$(document).ready(function(){
$('.my_features').change(function(){
if(this.checked)
$('#data-name').hide();
else
$('#data-name').show();
});
});
Try this way.
<script>
jQuery(document).ready(function($) {
$('.my_features').each(function() {
$(this).change(function() {
var checkbox = $(this);
if( checkbox.is(':checked') ) {
$( '#' + checkbox.attr('data-name') ).show();
} else {
$( '#' + checkbox.attr('data-name') ).hide();
}
});
});
});
I was going to use jQuery mobile for this one to get the mobile theme http://jsfiddle.net/hhken790/
HTML
<input type="button" value="-" class="qtyminus" />
<input type="text" name="myInputs[qty][]" value="0" class="qty" />
<input type="button" value="+" class="qtyplus" />
jQuery
$("#dynamic").on("click", ".qtyplus", function (e) {
e.preventDefault();
var $input = $(this).prev("input");
var currentVal = parseInt($input.val());
if (!isNaN(currentVal)) {
$input.val(currentVal + 1);
} else {
$input.val(0);
}
});
However, the plus and minus wont work here. Any idea what causing this?
When you add jQM, it enhances/styles many DOM elements by adding container divs and other DOM elements. This means that your buttons and text inputs are no longer siblings in the DOM and prev() will not work. Instead traverse up the DOM and then down:
var $input = $(this).closest("div#dynamic").find(".qty");
e.g:
$("#dynamic").on("click", ".qtyplus, .qtyminus", function (e) {
e.preventDefault();
var $input = $(this).closest("div#dynamic").find(".qty");
var currentVal = parseInt($input.val());
if (!isNaN(currentVal)) {
$(this).hasClass("qtyplus") ? $input.val(currentVal + 1) : $input.val(currentVal - 1);
} else {
$input.val(0);
}
});
Updated FIDDLE
I have a js function that adds a tr to a table:
function AddData() {
var rows = "";
var product_id = $('input[name="product_name"]').val();
var product_price = $('input[name="product_price"]').val();
rows += "<td><input type='hidden' name='item_id[]' value='" + product_id + "'><p>" + name + "</p></td><td><input type='hidden' name='price[]' value='" + product_price + "' class='price'></td><td>£<span id='amount' class='amount'>0</span></td><td><div class='btn btn-circle' onclick='RemoveData()' value='" + curtainid + "'>Delete</div></td>";
var tbody = document.querySelector("#myTable tbody");
var tr = document.createElement("tr");
tr.innerHTML = rows;
tbody.appendChild(tr)
update_amounts();
}
Within the <td> is a RemoveData() call. I want this to remove the selected tr from the table. I have tried to use:
function RemoveData() {
var elements = document.getElementById('tr');
last = elements[elements.length-1];
last.parentNode.removeChild(last);
}
but with no success.
getElementById gets a single element, by its id. You're passing in a tag name and expecting it to return a list.
If your goal is to remove the last tr element anywhere on the page, you can use querySelectorAll instead:
function RemoveData() {
var elements = document.querySelectorAll('tr'); // <== Main change
var last = elements[elements.length-1]; // <== Note I added `var`
last.parentNode.removeChild(last);
}
querySelectorAll works on all modern browsers, and IE8.
I added var to the last line because your code was falling prey to The Horror of Implicit Globals without it.
Re your comment below:
How would I remove a selected element...
I'd probably have a single event handler on the table and then trigger removal based on the event's target (e.g., delegated handling). That looks something like this:
"use strict";
var tbody = document.getElementById("the-tbody");
// Add rows when the button is clicked
document.getElementById("btn-add").addEventListener("click", addRow, false);
function addRow(e) {
var row = document.createElement('tr');
row.innerHTML = '<td>Hi there ' +
Math.floor(Math.random() * 1000) +
' <span class="remove">[x]</span></td>';
tbody.appendChild(row);
}
// Remove rows when their ".remove" span is clicked
tbody.addEventListener("click", removeRow, false);
function removeRow(e) {
var elm;
for (elm = e.target; elm !== this; elm = elm.parentNode) {
if (/\bremove\b/.test(elm.className)) { // On modern browsers you could use `classList`
// It's a remove link, remove its parent tr and we're done
removeElement(elm.parentNode);
e.stopPropagation();
return;
}
}
}
function removeElement(elm) {
elm.parentNode.removeChild(elm);
}
.remove {
cursor: pointer;
}
<table>
<tbody id="the-tbody"></tbody>
</table>
<input type="button" id="btn-add" value="Add Row">
There I'm using addEventListener. If you need to support older browsers, you can use the hookEvent function in this other answer instead.
I prefer the jQuery function .closest() to delete the selected row so you don't need to work with an Row-ID...because the threadstarter has already jQuery...try this:
$(document).ready(function(){
$('button[name=deleteTR]').click(function(){
$(this).closest('tr').remove();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr><td><button type="button" name="deleteTR">Delete</button></td><td>Row 1</td></tr>
<tr><td><button type="button" name="deleteTR">Delete</button></td><td>Row 2</td></tr>
<tr><td><button type="button" name="deleteTR">Delete</button></td><td>Row 3</td></tr>
<tr><td><button type="button" name="deleteTR">Delete</button></td><td>Row 4</td></tr>
</table>
Greetings from Vienna
The following code runs on a page that gives you the ability to add and delete rows from a table of input fields. It works for existing fields, but when I add new rows and try to delete them in an order that requires replacing the ID and name attributes it doesnt work - it will not replace the ID and name attributes. Any ideas what's going on?
The following function is supposed to decrement the remaining rows after the current row that is going to be deleted has been passed in the loop, and replace the number in the ID and name attributes. Then delete the row.
$("#tblData").delegate("button", "click", function()
{
var id1 = $(this).closest('tr').find('td input').attr('id');
id1 = parseInt(id1.match(/\d+/));
var count = 0;
var ID;
var name;
var str;
var str2;
var n1, n2;
$('#tblData > tbody > tr').each(function() {
$(this).find('td').each(function(){
//do your stuff, you can use $(this) to get current cell
if ($(this).children().children().next().prop("tagName") == "INPUT")
{
if (count > id1){
// get id and name attributes
ID = $(this).children().children().next().attr("id");
name = $(this).children().children().next().attr("name");
// match number and replace number in ID
str=ID;
n1=parseInt(str.match(/\d+/));
n1 = n1-1;
ID = ID.replace(/\d+/,n1);
// match number and replace number in name
str2=name;
n2=parseInt(str2.match(/\d+/));
n2 = n2-1;
name = name.replace(/\d+/,n2);
$(this).children().children().next().attr("id",ID);
$(this).children().children().next().attr("name",name);
}
} else if ($(this).children().children().next().prop("tagName") == "SELECT") {
if (count > id1){
ID = $(this).children().children().next().attr("id");
name = $(this).children().children().next().attr("name");
// match number and replace number in ID
str=ID;
n1=parseInt(str.match(/\d+/));
n1 = n1-1;
ID = ID.replace(/\d+/,n1);
// match number and replace number in name
str2=name;
n2=parseInt(str2.match(/\d+/));
n2 = n2-1;
name = name.replace(/\d+/,n2);
$(this).children().children().next().attr("id",ID);
$(this).children().children().next().attr("name",name);
}
}
});
count = count + 1;
});
$(this).closest('tr').remove();
}
);
Append row function
function Add(){
var id = $( "#tblData tbody tr:last-child td input" ).attr('id');
id = parseInt(id.substring(12, 13)) + 1;
//alert(id);
$("#tblData tbody").append(
"<tr>"+
"<td><label for='BookingRoom_Room_No'>Room No</label><select single='single' size='1' name='BookingRoom["+id+"][roomId]' id='BookingRoom_"+id+"_roomId'><option value='1'>1</option><option value='2'>2</option></select></td>"+
"<td><label for='BookingRoom_startDate' class='required'>Start Date <span class='required'>*</span></label><input name='BookingRoom["+id+"][startDate]' id='BookingRoom_"+id+"_startDate' type='text' /></td>"+
"<td><label for='BookingRoom_endDate' class='required'>End Date <span class='required'>*</span></label><input name='BookingRoom["+id+"][endDate]' id='BookingRoom_"+id+"_endDate' type='text' /></td>"+
"<td><label for='BookingRoom_adults' class='required'>Adults <span class='required'>*</span></label><select single='single' size='5' name='BookingRoom["+id+"][adults]' id='BookingRoom_"+id+"_adults'><option value='1'>1</option><option value='2'>2</option><option value='3'>3</option><option value='4'>4</option><option value='5'>5</option></select></td>"+
"<td><label for='BookingRoom_children' class='required'>Children <span class='required'>*</span></label><select single='single' size='5' name='BookingRoom["+id+"][children]' id='BookingRoom_"+id+"_children'><option value='1'>1</option><option value='2'>2</option><option value='3'>3</option><option value='4'>4</option><option value='5'>5</option></select></td>"+
"<td><button type='button'>Delete</button></td>"+
"</tr>");
};
Don't use delegate, use on instead :
$("#tblData").on("click", "button", function()
By the way, you'll prefer use double quote character instead of single quote character to wrap HTML attributes.
And you're encapsulating too many time this with jquery in your function... a good practice is to never call twice the same element with jquery, store it in a variable instead :
var $that = $(this); // put a $ before your var to remember that it is a jquery element
I want to make input type text refer to user input, if input 3 it shows 3 new input type text
I try this
<input type='text' id='how_many'><input type='button' id='add' value='add'>
<script>
function add(){
var total=$('#how_many).val();
for(var x=0;x<=total;x++){
//HOW TO ADD INPUT TYPE TEXT BELOW
}
}
</script>
Probably you are missing '
var total=parseInt($('#how_many').val());
for(var x=0;x<=total;x++){
$("#mainContainer").append("<input type='text'/>");
}
There you go:
<div class="container">
<input type='text' id='how_many' />
</div>
<input type='button' id='add' value='add' />
<script type="text/javascript">
$(document).ready(function() {
$("#add").click(function(e) {
var $el = $('#how_many'),
total = $el.val();
for (var x=0;x<=total;x++){
$(".container").append($el.val("").clone().attr("id", "total_" + x));
}
});
});
</script>
Where '.clone()' is a jQuery method which clones the DOM node, '.append()' is a jQuery method to append the newly cloned node to another node.
Remember to parse your input, then just create:
var total= parseInt($('#how_many').val());
for(var x=0;x<=total;x++){
$("yourcontainer").append("<input type='text' />");
}
Trigger the add() function on a blur
$("#how_many").blur(add);
$('#add').click(function () {
for (i=0;i<$('#how_many').val();i++) {
$(this).after('<div><input type="text" /></div>')
}
})
jsFiddle example