Button no longer fires function after being used once - javascript

I have a table / tbody / row that, when a user clicks on "Add Product", I want that row to be cloned and pasted underneath the previous row. In other words, the user is adding journal entry items.
What I want, is that when they first click on the "Add Product" button, I want the row to be cloned and inserted underneath. I then want that first "Add Product" button to be disabled, however, the next button has to be enabled in order to allow yet another entry to be inserted, so on and so forth.
So far, I can get the button to clone and insert the row below, and disable the first button. However, the second button, although not disabled, no longer fires the function. It is just an "empty" button.
<table id="sales-journal">
<tbody>
<tr class="sales-journal-row">
<td class="grid-40">
<select id="sales-product-id" name="sales-product-id" required="required">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
</td>
<td class="grid-20">
<input type="number" step="1" id="sales-sold-qty" name="sales-sold-qty" />
</td>
<td class="grid-20">
<input type="number" step="1" id="sales-spill-qty" name="sales-spill-qty" />
</td>
<td class="grid-20">
<button class="sales-journal-add" id="sales-journal-add" />Add Product</button>
</td>
</tr>
</tbody>
</table>
And the jquery
$('.sales-journal-add').click(function() {
var clone = $('#sales-journal > tbody:last').clone()
clone.insertAfter('#sales-journal > tbody:last');
$(this).removeAttr('id').attr('disabled', 'disabled').addClass('disabled');
});

You would need to use event delegation for the new buttons. The click events are bound initially only to the buttons that existed in DOM, but not for the ones that were cloned. SO bind the event to the container for delegation to the buttons so that it gets applied for the buttons that are created in the future when you clone your new tbody.
$('#sales-journal').on('click', '.sales-journal-add' , function() {
var clone = $('#sales-journal > tbody:last').clone()
clone.insertAfter('#sales-journal > tbody:last');
$(this).removeAttr('id').prop('disabled', true).addClass('disabled');
});
You can use .on() for jquery >=1.7 or live for older versions (deprecated).
Also as my suggestion try using prop instead of attr to set the disabled property.
Fiddle

Here, try this:
<table id="sales-journal">
<tbody>
<tr class="sales-journal-row">
<td class="grid-40">
<select id="sales-product-id" name="sales-product-id" required="required">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
</td>
<td class="grid-20">
<input type="number" step="1" id="sales-sold-qty" name="sales-sold-qty" />
</td>
<td class="grid-20">
<input type="number" step="1" id="sales-spill-qty" name="sales-spill-qty" />
</td>
<td class="grid-20">
<button class="sales-journal-add" id="1" />Add Product</button>
</td>
</tr>
</tbody>
</table>
JS:
var cur_id = $(".sales-journal-add").attr('id');
var next_id = parseInt(cur_id) + 1;
$('#sales-journal').on('click',"#" +cur_id,function() {
var clone = $('#sales-journal > tbody:last').clone();
clone.insertAfter('#sales-journal > tbody:last');
$(this).attr('disabled', 'disabled').addClass('disabled');
clone.find('.sales-journal-add:last').attr('id', next_id);
cur_id = next_id;
});
$('#sales-journal').on('click',"#" +next_id,function() {
var clone = $('#sales-journal > tbody:last').clone();
clone.insertAfter('#sales-journal > tbody:last');
$(this).attr('disabled', 'disabled').addClass('disabled');
clone.find('.sales-journal-add:last').attr('id', next_id);
});
Fiddle.

Related

How can I add/remove select boxes from DOM when all select boxes have one name so that upon Submit I get value from active select box?

TL;DR: I want to be able to make a selection using currently-active HTML select box, when I have multiple select boxes with the same name, but only one of them is to be active at any one time.
--
My question is this - I have multiple filename select boxes, that upon submit, always send the value of the last select box that is at the bottom of HTML that has filename name in HTTP Request. I want to find a way to send only the filename that is associated with the currently-active a_XX_row box, and not any others.
i.e. I select id of 40, I should only see the box that says "A-40 Designer and Specs", and not the 800 box. When I press submit I want POST['filename'] to have the "A-40 Designer and Specs", but instead I always get the "A-800 Designer E.xlsm", because it is the last select in the HTML file.
$('#modelid').on('change', function() {
if (this.value == 40)
$('.a_40_row').show();
else
$('.a_40_row').hide();
if (this.value == 800)
$('.a_800_row').show();
else
$('.a_800_row').hide();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form><table>
<tr>
<td>
<select name="id" id="modelid">
<option value="0">--select--
<option value="40">40
<option value="800">800
</select>
</td>
</tr>
<tr class="a_40_row" style="display: none;">
<td>Version</td>
<td>
<select name="filename">
<option selected>A-40 Designer and Specs B.xlsm</option>
<option>A-40 Designer and Specs A.xlsm</option>
</select>
</td>
</tr>
<tr class="a_800_row" style="display: none;">
<td>Version</td>
<td>
<select name="filename">
<option>A-800 Designer E.xlsm</option>
</select>
</td>
</tr>
<tr>
<td><input type="submit"></td>
</tr>
</table></form>
don't show/hide selects form.
you just need to update the second select when the first is changed
the way to do that:
const
myForm = document.forms['my-form']
, filenames =
[ { model: '40', cod: 'A-40-B', fn:'A-40 Designer and Specs B.xlsm' }
, { model: '40', cod: 'A-40-A', fn:'A-40 Designer and Specs A.xlsm' }
, { model: '800', cod: 'A-800-E', fn:'A-800 Designer E.xlsm' }
]
myForm.modelid.onchange = () =>
{
myForm.filename.innerHTML = ''
filenames
.filter(x=>x.model===myForm.modelid.value)
.forEach( filename=>
{
myForm.filename.add( new Option(filename.fn,filename.cod))
}
)
}
select,
button {
display : block;
float : left;
clear : left;
margin : .3em;
}
select {
min-width : 8em;
padding : 0 .3em;
}
<form name="my-form">
<select name="modelid" >
<option value="" selected disable >--select--</option>
<option value="40" > 40 </option>
<option value="800" > 800 </option>
</select>
<select name="filename"></select>
<button type="submit">submit</button>
</form>
Two options,
Enable/disable the element as you show it.
Populate one field with what you need.
Option 1 :
$('#modelid').on('change', function() {
//Set visibility
$('.a_40_row').toggle(this.value == 40);
//Toggle disabled
$('.a_40_row [name=filename]').prop("disabled", this.value != 40);
$('.a_800_row').toggle(this.value == 800)
$('.a_800_row [name=filename]').prop("disabled", this.value != 800);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form><table>
<tr>
<td>
<select name="id" id="modelid">
<option value="0">--select--</option>
<option value="40">40</option>
<option value="800">800</option>
</select>
</td>
</tr>
<tr class="a_40_row" style="display: none;">
<td>Version</td>
<td>
<select name="filename" disabled>
<option selected>A-40 Designer and Specs B.xlsm</option>
<option>A-40 Designer and Specs A.xlsm</option>
</select>
</td>
</tr>
<tr class="a_800_row" style="display: none;">
<td>Version</td>
<td>
<select name="filename" disbled>
<option>A-800 Designer E.xlsm</option>
</select>
</td>
</tr>
<tr>
<td><input type="submit"></td>
</tr>
</table></form>
Option 2 : - This uses HTML 5 which has issues in IE 10 and less
$('#modelid').on('change', function() {
$(".row").show();
var selVal = $(this).val();
//Go through the options
$("[name=filename] option").each(function(){
//Dont use jquerys data here, it will convert to a number when it can
//Get array of values where can display from the data attribute
var arrDisplay = this.dataset.display.split(",");
//Add the hidden property if not contained in array -- wont work in IE 10 and older
$(this).prop("hidden", !arrDisplay.includes(selVal));
//Set a default
$(this).prop("selected", $(this).data("optiondefault") && !arrDisplay.includes(selVal) )
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form><table>
<tr>
<td>
<select name="id" id="modelid">
<option value="0">--select--</option>
<option value="40">40</option>
<option value="800">800</option>
</select>
</td>
</tr>
<tr class="row" style="display: none;">
<td>Version</td>
<td>
<select name="filename">
<option data-display="40" data-optiondefault="true">A-40 Designer and Specs B.xlsm</option>
<option data-display="40">A-40 Designer and Specs A.xlsm</option>
<option data-display="800" data-optiondefault="true">A-800 Designer E.xlsm</option>
<option data-display="40,800">Hybrid</option>
</select>
</td>
</tr>
<tr>
<td><input type="submit"></td>
</tr>
</table></form>

How can i do event listener for a custom select in the table?

I have table it contains columns from database and I have custom select on the column and also have button update. Now I need when I click on the button make event listener in custom select and get what the user selected and print the value selected on console using JavaScript ….How can I do this please any one help me...
#foreach ($bookinghalls as $item)
<tr>
<td>{{$item->id}}</td>
<td>{{$item->name}}</td>
<td >{{$item->hall_name}}</td>
<td>{{$item->from_date}}</td>
<td>{{$item->to_date}}</td>
<td>{{$item->type_booking}}</td>
<td ><select class="custom-select mr-sm-2" name="intervel" >
#if ($item->pay==0)
<option value="0" >Not paid</option>
<option value="1" >paid </option>
#else ($item->pay==1)
<option value="1" >paid </option>
<option value="0" >Not paid</option>
#endif
</td>
<td id="stauts"> <?php
if($item->stauts==0)
print_r("available");
elseif($item->stauts==1)
print_r("it's Processing ");
elseif($item->stauts==2)
print_r("booking done");
?></td>
<td><button type="submit" class="btn btn-primary but_update" name="imagaid" >update</button>
</td>
for set event listener for a <select> tag and get value of <option value="any-value" selected>text</option>, do as following:
document.querySelector('.custom-select').addEventListener('change', function () {
let selectedValue = this.value;
console.log(selectedValue);
});

How do you reference a checkbox array name value?

I have a sequence of checkboxes and associated select lists. If the checkbox is checked I need to take the value of the corresponding select option and then change the total, but I can't seem to reference this value. Here is a simplified version of the HTML code:
<table>
<tr>
<td>
<input type="checkbox" name="checkboxCK[]" id="checkboxAR1" class="check" />
</td>
<td>
<select name="addonR[]" class="select-colour">
<option value="50">1 ($50)</option>
<option value="100">2 ($100)</option>
<option value="150">3 ($150)</option>
<option value="200">4 ($200)</option>
</select>
</td>
</tr>
<tr>
<td>
<input type="checkbox" name="checkboxCK[]" id="checkboxAR2" class="check" />
</td>
<td>
<select name="addonR[]" class="select-colour">
<option value="50">1 ($50)</option>
<option value="100">2 ($100)</option>
<option value="150">3 ($150)</option>
<option value="200">4 ($200)</option>
</select>
</td>
</tr> <tr>
<td>
<input type="checkbox" name="checkboxCK[]" id="checkboxAR3" class="check" />
</td>
<td>
<select name="addonR[]" class="select-colour">
<option value="50">1 ($50)</option>
<option value="100">2 ($100)</option>
<option value="150">3 ($150)</option>
<option value="200">4 ($200)</option>
</select>
</td>
</tr>
<table>
$<span id="theTotalAmount">150</span>
And the javascript code:
$("input.check:checkbox").click(function(){
//run through allcheckboxes that are checked and pull corresponding select option value
for (var i = 0; i < document.getElementsByName('checkboxCK[]').length; i++)
{
//get the value of the selected option
var s = document.getElementsByName('addonR['+i+']');
var theAmount = s.options[s.selectedIndex].value;
console.log(theAmount);
//check the checkbox is checked and if so add the corresponding select value
if(document.getElementsByName('checkboxCK['+i+']').checked)
{
totalCost = totalCost+document.getElementsByName('addonR['+i+']').value;
}
}
//rewrite the html for total amount
document.getElementById("theTotalAmount").innerHTML = totalCost;
});
I am struggling to reference the s variable.. It keeps being undefined. Can anyone see why?
Or is there a better way to achieve what I am trying to do?
The names of the checkboxes don't have a number between the square brackets in the HTML. You shouldn't put one there with your JavaScript.
document.getElementsByName('addonR[]') will give you an (array-like) HTML Collection of all the elements with that name.
Write
var s = document.getElementsByName('addonR[]')[i];

jQuery - Adding another row

I have a table on which I have a button then when I click on that button I insert a new row. But after inserting a row I cannot insert another.
For more clearance see this fiddle.
HTML:
<table id="sales-journal">
<tbody>
<tr class="sales-journal-row">
<td class="grid-40">
<select id="sales-product-id" name="sales-product-id" required="required">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
</td>
<td class="grid-20">
<input type="number" step="1" id="sales-sold-qty" name="sales-sold-qty" />
</td>
<td class="grid-20">
<input type="number" step="1" id="sales-spill-qty" name="sales-spill-qty" />
</td>
<td class="grid-20">
<button class="sales-journal-add" id="1" />Add Product</button>
</td>
</tr>
</tbody>
</table>
JS:
var cur_id = $(".sales-journal-add").attr('id');
var next_id = parseInt(cur_id) + 1;
$("#" +cur_id).click(function() {
var clone = $('#sales-journal > tbody:last').clone();
clone.insertAfter('#sales-journal > tbody:last');
$(this).attr('disabled', 'disabled').addClass('disabled');
alert(cur_id);
clone.find('.sales-journal-add:last').attr('id', next_id);
cur_id = next_id;
});
$("#" +next_id).click(function() {
alert("lepa");
var clone = $('#sales-journal > tbody:last').clone();
clone.insertAfter('#sales-journal > tbody:last');
$(this).attr('disabled', 'disabled').addClass('disabled');
clone.find('.sales-journal-add:last').attr('id', next_id);
});
use event delegation -
$('#sales-journal').on('click','.sales-journal-add', function () {
var clone = $('#sales-journal > tbody:last').clone();
clone.insertAfter('#sales-journal > tbody:last');
$(this).attr('disabled', 'disabled').addClass('disabled');
alert(cur_id);
clone.find('.sales-journal-add:last').attr('id', next_id);
cur_id = next_id;
});
$('#sales-journal').on('click','.sales-journal-add', function () {
alert("lepa");
var clone = $('#sales-journal > tbody:last').clone();
clone.insertAfter('#sales-journal > tbody:last');
$(this).attr('disabled', 'disabled').addClass('disabled');
clone.find('.sales-journal-add:last').attr('id', next_id);
});
Demo ---> http://jsfiddle.net/g2UwK/5/
http://learn.jquery.com/events/event-delegation/
Maybe you could try something like this:
JSFiddle
I reduced the code by half by creating a single Event Function which is re-binded to each newly added button after each click.
<script type="text/javascript">
$(function(){
//Click event
$(".sales-journal-add").click(function(){
addRow();
$(this).hide();
});
});
//Event function
function addRow(){
//Get clicked button ID
var cur_id = $(".sales-journal-add:last").attr('id');
//Substring ID
var cur_id = cur_id.substring(3);
//Parse to int
var next_id = parseInt(cur_id) + 1;
//Clone row
var clone = $('#sales-journal > tbody:last').clone();
clone.insertAfter('#sales-journal > tbody:last');
//Change the ID of the newly added button
clone.find('button').attr('id', "btn"+next_id);
//Clear each newly added number input
clone.find('#sales-sold-qty,#sales-spill-qty').val('');
//Bind Click Event to newly added button
$(".sales-journal-add").on('click', addRow);
//Hide the last button
$(this).hide();
}
</script>
I also hide the last button clicked to prevent spam and whatnot.
I didn't changed the HTML to much, i only added a "btn" to the button IDs
<table id="sales-journal">
<tbody>
<tr class="sales-journal-row">
<td class="grid-40">
<select id="sales-product-id" name="sales-product-id" required="required">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
</td>
<td class="grid-20">
<input type="number" step="1" id="sales-sold-qty" name="sales-sold-qty" />
</td>
<td class="grid-20">
<input type="number" step="1" id="sales-spill-qty" name="sales-spill-qty" />
</td>
<td class="grid-20">
<button class="sales-journal-add" id="btn1"/>Add Product</button>
</td>
</tr>
</tbody>
Is this what you were looking for? I hope this will help :)

cloned form fields not submitting (no $_POST data)

I have a form in a table with the option to duplicate a certain row (thus allowing users to add more fields as needed). The cloning works fine and the events data and handlers work fine. However when the form is submitted, the cloned form field data does not post. Below is my code for cloning the fields which works fine and solves any issue of duplicate IDs. Any suggestions/help as to why the cloned field do not submit would be absolutely appreciated.
$('#btnAddNewField').click(function() {
var currLength = $('.cloneInput').length;
var newID = new Number(currLength + 1);
var clonedField = $('#field_id' + currLength).clone(true);
clonedField[0].setAttribute('id', 'field_id' + newID);
clonedField.find(':text').each(function() {
this.setAttribute('id', this.getAttribute('id') + newID);
this.setAttribute('name', this.getAttribute('name') + newID);
});
$('#field_id' + currLength).after(clonedField);
HTML:
<tr id="field_id_1">
<td>
<table>
<tr>
<td>Pick option</td>
<td>
<select name="choice_1" id="choice_1" parent="true">
<option value="null" selected="selected">Select</option>
<option value="1">option 1</option>
<option value="2">option 2</option>
<option value="3">option 3</option>
</select>
</td>
</tr>
<tr>
<td>Pick next option</td>
<td>
<select name="next_choice_1" id="next_choice_1">
<option value="null" selected="selected">Select next</option>
</select>
</td>
</tr>
<tr>
<td>Image:</td>
<td><input type="file" name="image_1" id="image_1"/></td>
</tr>
</table>
</td>
</tr>
<tr>
<td></td>
<td>
<input type="button" value="Add New" id="btnAddNewField" />
<input type="button" value="Remove" id="btnDelField" />
</td>
</tr>
I don't see anywhere where you are changing the name property of the cloned form fields. You will need to change this in order to not have the posted data just overwritten by the additional fields.
I think you are mistaken by how post works. You should actualy create a new name for the cloned field, as that is what is used for posting the variables. Creating a new id is only nessecary to produce valid html, but has nothing to do with the actual posting.

Categories

Resources