Incrementing the name attribute of cloned inputs in jquery - javascript

I have a specific section of a form(a select box and three checkboxes) that needs to be duplicated upon request. I have the clone of the div working as well as the incrementing of that specific div, but I am having issues incrementing the checboxes itself to make it unique.
Here is my HTML:
<div class="orgboxdupe" style="border: 1px solid lightgrey; padding-left:20px;padding-right:20px;padding-bottom:20px;margin-top:10px; width: 600px;">
<h3>Add user to an organization</h3>
<select id="orggroupadd" class="user_groupadd" name="user_orggroupadd[]">
<option value="none">Select an organization</option>
<option value="152">Test4</option>
<option value="156">test9</option>
</select>
<br><br>Organization Admin (can view uploaded files): <input type="checkbox" name="orgadmincheckbox2"><br><br>c3 Access: <input type="checkbox" name="c3checkbox2"> c4 Access: <input type="checkbox" name="c4checkbox2">
</div>
On button click it creates a new orgboxdupe box with an incrementing ID but for some reason it increments the number on the first div checkboxes and not on the subsequent cloned checkboxes:
Here is my JS
//Portalorgs - add Users
//Vars
let $addnewgroupbutton = jQuery( "#addnewgroup" );
let $mainelement = jQuery("#orguserbox");
let $dupebox = jQuery(".orgboxdupe");
let $selectboxid = jQuery("#orggroupadd");
let $checkboxes = jQuery("input[type='checkbox']");
let $cloneindex = 1;
//Duplicating add organizations box for users - po-addusers.php
$addnewgroupbutton.click(function() {
$cloneindex++;
$dupebox.clone().appendTo($mainelement).attr("id","user_orggroupadd" + $cloneindex).find(':checked').attr('checked', false);
$checkboxes.each(function(){
jQuery(this).attr("name",jQuery(this).attr("name") + $cloneindex);
});
console.log($cloneindex);
});
Thanks for any help that can be provided.

As noted by #Taplar $checkboxes references the original checkboxes. So they are the ones being updated each time there's a click.
You need to reference the checkboxes in the just copied clone; you can use chaining like so:
....
.end().find(':checkbox').attr('name', function() {
return this.name + $cloneindex;
});
//Portalorgs - add Users
//Vars
let $addnewgroupbutton = jQuery( "#addnewgroup" );
let $mainelement = jQuery("#orguserbox");
let $dupebox = jQuery(".orgboxdupe");
let $selectboxid = jQuery("#orggroupadd");
let $checkboxes = jQuery("input[type='checkbox']");
let $cloneindex = 1;
//Duplicating add organizations box for users - po-addusers.php
$addnewgroupbutton.click(function() {
$cloneindex++;
$dupebox.clone().appendTo($mainelement).attr("id","user_orggroupadd" + $cloneindex).find(':checked').attr('checked', false)
//operate on the close via method chaining
.end().find(':checkbox').attr('name', function() {
return this.name + $cloneindex;
});
/*$checkboxes.each(function(){
jQuery(this).attr("name",jQuery(this).attr("name") + $cloneindex);
});*/
//console.log($cloneindex);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="addnewgroup">Add New Group</button>
<div id="orguserbox">
<div class="orgboxdupe" style="border: 1px solid lightgrey; padding-left:20px;padding-right:20px;padding-bottom:20px;margin-top:10px; width: 600px;">
<h3>Add user to an organization</h3>
<select id="orggroupadd" class="user_groupadd" name="user_orggroupadd[]">
<option value="none">Select an organization</option>
<option value="152">Test4</option>
<option value="156">test9</option>
</select>
<br><br>Organization Admin (can view uploaded files): <input type="checkbox" name="orgadmincheckbox2"><br><br>c3 Access: <input type="checkbox" name="c3checkbox2">
</div>
</div>

Related

How do I retrieve the value from a checkbox that was created from a Javascript?

I was following the sample code provided by another post (source: How to display multiple list of checkboxes dynamically on dropdown list), as it has the function that was exactly what I was trying to do for my webpage. However, I am having trouble retrieving the value of the checkbox that the user has selected, as the checkbox was dynamically created from the javascript. I tried debugging by inserting an alert function, and I was return with a "[Object NodeList]".
How can I retrieve the individual value(s) base on the checkbox that the user has selected?
For example, if user has selected "apple", I want to retrieve the value "apple". But if the user has selected "apple" and "Orange", I want to retrieve the value "apple" and "orange".
UPDATE
Thank you everyone for your comments and sample codes. I have edited the code below to retrieve the user-selected checkbox.
HTML:
<form id="product_form">
<div class="row" id="row1">
<div class="col-8">
<label><strong>FoodCategory:</strong></label>
<select id="model" name="model" onchange="populate(this.id, 'food')">
<option value="select">--Select Category--</option>
<option value="Fruit">Fruit</option>
<option value="vegetable">Vegetable</option>
</select>
</div>
<div class="col-8">
<label><strong>Outcome:</strong></label>
<div id="food"></div>
</div>
</div>
</form>
<button onclick="getResult()">Get Result</button>
Javascript:
var mappingData = {
"fruit": {
"destination": ["Apple", "Orage"]
},
"vegetable": {
"destination": ["Cabbage", "Carrot"]
}
};
function populate(model, food) {
var mod = document.getElementById('model');
var scenario = document.getElementById('food');
scenario.innerHTML = "";
mappingData[mod.value].destination.forEach(function(item) {
createCheckBox(item, scenario)
});
}
function createCheckBox(value, parent) {
var checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.name = "food";
checkbox.value = value;
var label = document.createElement('label')
label.htmlFor = value;
label.appendChild(document.createTextNode(value));
parent.appendChild(checkbox)
parent.appendChild(label)
parent.appendChild(document.createElement("br"))
}
function getResult() {
let checkboxes = document.querySelectorAll('input[name="food"]:checked');
let values = [];
checkboxes.forEach((checkbox) => {
values.push(checkbox.value)
});
alert(values);
}
Write this code when all javascript code done...
<script>
if (document.getElementById('youid').checked) {
alert(document.getElementById('youid').value);
}</script>
Assuming you have an attribute to select those checkboxes, this code would work:
function do_submit(form) {
var result = [];
var checkboxes = form.querySelectorAll(".my-checkbox").forEach(function(elem) {
if (elem.checked) {
result.push(elem.value);
}
});
form.querySelector("[name=chekboxes]").value = result.join(",");
// to cancel:
return false
// to submit:
// form.submit();
}
<form onsubmit="return do_submit(this); ">
<label><input type="checkbox" class="my-checkbox" value="apple"> apple </label><br>
<label><input type="checkbox" class="my-checkbox" value="banana"> banana </label><br>
<label><input type="checkbox" class="my-checkbox" value="cabbage"> cabbage </label><br>
<!-- should be hidden: -->
<input type="text" name="chekboxes" value="">
<input type="submit">
</form>

How can I prevent a console error with the following code? (It says the given id is not a function)

I keep getting an error because my javascript says that the element declaring my ID is not a function. Thank you in advance to anyone that can help. I am sure it is a simple solution. My goal is to hide one form while the "single" radio button is clicked. (Ignore the "arm all" text, I'm not sure how it got there or how to take it off).
EDIT: I have changed the function names but it seems i am still having the same issue.
// This links form1/form2 to hide & display - onclick for group or single radio buttons
function single(id, text, btn) {
var groupForm = document.getElementById('form2');
var singleForm = document.getElementById('form1');
groupForm.style.visibility = 'hidden';
singleForm.style.visibility = 'visible';
}
function group() {
var groupForm = document.getElementById('form2');
var singleForm = document.getElementById('form1');
singleForm.style.visibility = 'hidden';
groupForm.style.visibility = 'visible';
}
<div>
<div style="position: relative; width: 100%;">
<div id="form2" class="form">
<select name="sendingfrom" class="click-op">
<option value="group-select">arm</option>
<option value="group-select">all</option>
</select>
</div>
<div id="form1" class="form">
<select name="sendingfrom" class="click-op2">
<option value="group-select">waist</option>
<option value="group-select">shoulder</option>
<option value="group-select">elbow</option>
<option value="group-select">wrist_angle</option>
<option value="group-select">wrist_rotate</option>
<option value="group-select">left_finger</option>
</select>
</div>
</div>
<!--onclick value links to javascript-->
<input class="radio-group" type="radio" id="group" name="group-or-single" value="group" onclick="group()">
  <label class="text-group" style="color: black; padding-left: 0px;" for="group">Group</label>
<!--onclick value links to javascript-->
<input class="radio-single" type="radio" id="single" name="group-or-single" value="single" onclick="single()">
  <label class="text-single" style="color: black; padding-left: 0px;" for="single">Single</label>
</div>
You can use the try catch finally statement, but first in the HTML is the names of the function wrong written. This porblem you cannot solve with the solution i mentioned, only if you using eventlisteners in the javascript code.
In this snippet I corrected the misspeled function names, and i made the try catch blocks for you as an exmaple.
// This links form1/form2 to hide & display - onclick for group or single radio buttons
function single(id, text, btn) {
try {
var groupForm = document.getElementById('form2');
var singleForm = document.getElementById('form1');
groupForm.style.visibility = 'hidden';
singleForm.style.visibility = 'visible';
}
catch {
console.log("does not work");
}
}
function group() {
try {
var groupForm = document.getElementById('form2');
var singleForm = document.getElementById('form1');
singleForm.style.visibility = 'hidden';
groupForm.style.visibility = 'visible';
}
catch {
console.log("does not work");
}
}
<div id="form3" class="form">
<select name="sendingfrom" class="click-op2">
<option value="group-select">waist</option>
<option value="group-select">shoulder</option>
<option value="group-select">elbow</option>
<option value="group-select">wrist_angle</option>
<option value="group-select">wrist_rotate</option>
<option value="group-select">left_finger</option>
</select>
</div>
<!--onclick value links to javascript-->
<input class="radio-group2" type="radio" id="group2" name="group-or-single" value="group" onclick="group()">
<label class="text-group2" style="color: black; padding-left: 0px;" for="group">Group</label>
<!--onclick value links to javascript-->
<input class="radio-single2" type="radio" id="single2" name="group-or-single" value="single" onclick="single()">
<label class="text-single2" style="color: black; padding-left: 0px;" for="single">Single</label>
javascript
html
Use Try Catch statement. Mozilla

Selecting current html div and appending to list n amount of times using jQuery

I have written a script that allows a user to add user input into a sample analysis and to add additional samples with a button id="addsmplbtn". However it has come to my attention that in some cases a user would want to fill in one sample and then multiply it for various samples that require the same analyses an n amount of times.
The script below is a very simple version of the actual script. Adding various samples one-by-one is achieved, however I am struggling with adding multiple samples at the same time:
var variable = 1;
$("#addsmplbtn").click(function() {
var element = $(".samplesinfo.hidden").clone(true);
element.removeClass("hidden").appendTo(".paste:last");
$(".panel").hide();
});
$(document).ready(function() {
$("#samplebtn").click(function(){
$(this).next(".panel").slideToggle();
});
$("#addsmplbtn").trigger("click");
});
.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="addsmplbtn">Add Sample</button>
<div id="samplesinfo" class="samplesinfo hidden">
<button type="button" id="samplebtn" class="samplebtn"></i>Sample</button>
<div class="panel">
<input type="text" name="input1">Input1
<input type="text" name="input2">Input2
<select>
<option value=""></option>
<option>Option1</option>
<option>Option2</option>
</select>
<input type="checkbox" name="checkbox">Check1
<input type="checkbox" name="checkbox">Check2
<input type="text" name="batch_count" id="batch_count" placeholder="enter batch count">
<button type="button" id="add_batch" class="add_batch">Add batch samples</button>
</div>
</div>
<form>
<div>
<h3>No hidden content</h3>
</div>
<div id="paste" class="paste">
</div>
</form>
The following section is the jQuery I am struggling with, to select a single sample, fill in <input> and then to append that element an n amount of times:
$("#add_batch").on("click", function() {
var times = $(this).current("#batch_count").val();
for(var i=0; i < times; i++) {
$(this).current("#add_batch").click(function() {
var element = $(this).current(".samplesinfo").clone(true);
element.appendTo(".paste:last");
$(".panel").hide();
});
}
});
Can anybody please help me adjust the code so that it could achieve my goal?
function addSample(source, target, howMany) {
for(var i=0; i < howMany; i++) {
console.log("adding "+$(source).attr("id")+" to "+target);
var element = $(source).clone(true);
element.removeClass("hidden").appendTo(target);
$(".panel").hide();
}
}
function getInputValue(sender, inputName) {
return $(sender).parent().children('input[name="'+inputName+'"]').val();
}
$("#addsmplbtn").click(function() {
addSample($("#samplesinfo"), $(".paste:last"), 1);
});
$(document).ready(function() {
$("#samplebtn").click(function(){
$(this).next(".panel").slideToggle();
});
addSample($("#samplesinfo"), $(".paste:last"), 1);
});
$("#add_batch").on("click", function() {
var times = getInputValue(this, "batch_count");
addSample($(this).parent().parent().get(0), $(".paste:last"), times);
});
Please don't use the same id attribute on multiple elements. This causes many problems.
This fiddle can be a possible solution.
Never use multiple id-s on HTML elements, this is what classes for!
Use:
$(document).on('{event}', '{selector}', function(){})
on dynamically added elements.
// Add sample click event listener
$(document).on('click', '#add-sample', function() {
var element = $(".samples-info.hidden").clone(true);
element.removeClass("hidden").appendTo(".paste:last");
$(".panel").hide();
});
// Add batch click event listener
$(document).on('click', ".add_batch", function() {
var times = $(this).siblings('.batch_count').val();
var element = $(".samples-info.hidden").clone(true);
for(var i=0; i < times; i++) {
$(".paste:last").append("<div class='.samples-info'>" + element.html() + "</div>");
}
$(".panel").hide();
});
// Toggling the sample's panel
$(document).on('click', '.sample-btn', function() {
$(this).next(".panel").slideToggle();
});
$(document).ready(function() {
// Triggering the first sample on ready
$("#add-sample").trigger("click");
});
.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="add-sample">Add Sample</button>
<div class="samples-info hidden">
<button type="button" id="sample-btn" class="sample-btn">
Sample
</button>
<div class="panel">
<input type="text" name="input1">Input1
<input type="text" name="input2">Input2
<select>
<option value=""></option>
<option>Option1</option>
<option>Option2</option>
</select>
<input type="checkbox" name="checkbox">Check1
<input type="checkbox" name="checkbox">Check2
<input type="text" class="batch_count" placeholder="enter batch count">
<button type="button" class="add_batch" class="add_batch">
Add batch samples
</button>
</div>
</div>
<form>
<div>
<h3>No hidden content</h3>
</div>
<div id="paste" class="paste">
</div>
</form>

Applying javascript rules to cloned element [duplicate]

This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 7 years ago.
Each time the user clicks the 'add pizza' button, I would like the page to produce another pizza form and add any costs of the additional pizza. I have been able to add a pizza form, but none of the adding up rules are being applied to the cloned element. Any ideas?
HTML:
<div id="pizzaForm">
<fieldset>
<form class="pure-form">
<legend>Pizza</legend>
<label><b>Pizza Type: </b></label>
<select id="pizza">
<option name="margarita">Margarita</option>
<option name="deep-pan">Deep Pan</option>
<option name="stuffed-crust">Stuffed Crust</option>
</select>
<span style="float:right">
<label><b>Pizza Size: </b></label>
<select id="pizzaSize">
<option name="e-small" id="4.99">Extra Small - £4.99</option>
<option name="small" id="5.99">Small - £5.99</option>
<option name="medium" id="6.99">Medium - £6.99</option>
<option name="large" id="8.99">Large - £8.99</option>
<option name="e-large" id="9.99">Extra Large - £9.99</option>
<option name="f-size" id="10.99">Family Size - £10.99</option>
</select>
</span>
</form>
</fieldset>
<fieldset style = "border-top:0px">
<form class="pure-form">
<legend><b>Toppings (99p Each): </b></legend>
<input type="checkbox" name="onions" id="0.99">Onions</input>
<input type="checkbox" name="mushrooms" id="0.99">Mushrooms</input>
<input type="checkbox" name="peppers" id="0.99">Peppers</input>
<input type="checkbox" name="olives" id="0.99">Olives</input>
<input type="checkbox" name="garlic" id="0.99">Garlic</input>
<input type="checkbox" name="peperoni" id="0.99">Peperoni</input>
<input type="checkbox" name="cheese" id="0.99">Pesto</input>
</form>
</fieldset>
<br>
</div>
<div id="extraPizza"></div>
<center><button id="addPizza"> Add Pizza </button></center>
JavaScript:
var pizzaCost = 0.00;
var toppingCost = 0.00;
var sideCost = 0.00;
var drinkCost= 0.00;
var desertCost = 0.00;
var desertSizeCost = 0.00;
var drinkSizeCost = 0.00;
var sideSizeCost = 0.00;
$("#pizzaSize").prop('disabled', true);
$("#pizza").change(function() {
$("#pizzaSize").prop('disabled', false);
})
$( "#pizzaSize" ).change(function() {
$("input[type='checkbox']").prop('disabled', false);
var selectionPrice = $('option:selected', this).attr('id');
var selectionInt = parseFloat(selectionPrice, 10);
pizzaCost = selectionInt;
calculateCost(pizzaCost, toppingCost, sideCost, drinkCost, desertCost, desertSizeCost, drinkSizeCost, sideSizeCost);
});
$('input[type=checkbox]').change(function(){
var checked = $(":checkbox:checked").length;
toppingCost = 0.99 * checked;
calculateCost(pizzaCost, toppingCost, sideCost, drinkCost, desertCost, desertSizeCost, drinkSizeCost, sideSizeCost);
});
function calculateCost(pizzaCost, toppingCost, sideCost, drinkCost, desertCost, desertSizeCost, drinkSizeCost, sideSizeCost) {
var total = pizzaCost + toppingCost + sideCost + drinkCost + desertCost + desertSizeCost + drinkSizeCost + sideSizeCost;
$("#totalPrice").text(total.toFixed(2));
}
$( "#addPizza" ).click(function() {
$("#pizzaForm").clone().appendTo("#extraPizza");
});
You should use jQuery on delegation when registering your events so that it will work for the dynamically created and injected form elements.
$(document).on("change","#pizzaSize", function() {
$("input[type='checkbox']").prop('disabled', false);
var selectionPrice = $('option:selected', this).attr('id');
var selectionInt = parseFloat(selectionPrice, 10);
pizzaCost = selectionInt;
calculateCost(pizzaCost, toppingCost, sideCost, drinkCost, desertCost, desertSizeCost,
drinkSizeCost, sideSizeCost);
});
Also, I see a few issues with your code. First of you should not keep Id's on your form elements because you are making a clone. Also you should not bind your events by using jQuery selection using Id. No more than one element should have the same Id. Keep some css class on the element which you can use to register your click event code. Also do not keep the price in the id property values. What if 2 items has same price ? Same Id ? That is not correct. You should keep the price in HTML 5 data attribute.
You can use closest() method to get to the parent container and then use find to get a reference to the relative size dropdown.
$(document).on("change", ".pizza", function () {
var _this = $(this);
_this.closest("fieldset").find(".size").prop('disabled', false);
});
Here is a working sample with the changes i mentioned.

Make a NG-Options value select in same function as populating list

I am having some difficulties with selecting a value from an array in the same function that I populate the select using ng-options. I am trying to dynamically load a select list full of options and at the same time there is a default value from the last time the user chose something that I want to already be selected. when console.logging I can see that this works and is added to machineProfile.input but the select does not reflect what the ng-model has as a current value. I did confirm that they are both the same. I have some code below.
$scope.getMachineProfile = function(object) {
var count = 0;
var keepGoing = true;
$scope.machineProfile.machineName = object.Name;
$scope.machineInputs = object.Hardware;
/*angular.forEach(object.Hardware, function(inputs, key) {
console.log($scope.machineInputs);
});*/
//var foundMachine = 0;
angular.forEach($scope.machineProfiles, function(machine, key) {
if (keepGoing) {
if (machine.remoteAddr === object.Address) {
keepGoing = false;
/*$timeout(function(){
}, 500);*/
/*console.log($scope.machineProfiles[count].input);
console.log($scope.machineProfile.input);*/
$scope.machineProfile.input = $scope.machineProfiles[count].input;
$scope.machineProfile.workType = $scope.machineProfiles[count].workType;
$scope.machineProfile.workPeriod = $scope.machineProfiles[count].workPeriod;
$scope.machineProfile.counterRate = $scope.machineProfiles[count].counterRate;
$scope.machineProfile.timerRate = $scope.machineProfiles[count].timerRate;
console.log($scope.machineProfile);
//console.log('Awesome select: ' + count);
//console.log($scope.machineProfiles[count].input);
}
++count;
}
});
HTML
<ul class="nav sidebar-menu">
<li ng-repeat="machine in machineObj" class="">
<a ng-click="getMachineProfile(machine)">
<span class="fa fa-cogs"></span>
<span class="sidebar-title">{{machine.Name}}</span>
</a>
</li>
</ul>
Below is once a item is selected from the code above:
<div class="col-sm-4">
<div class="form-group">
<label for="chooseInput" class="control-label">Choose Input</label>
<!-- <select name="chooseInput" class="form-control" ng-model="machineProfile.input">
<option ng-selected="machine.input === machineProfile.input" ng-repeat="machine in machineInputs" value="machine.input">
{{machine.input === machineProfile.input}}
</option>
</select> -->
<select name="chooseInput" class="form-control" ng-model="input" ng-change="awesome(machineProfile.input)" ng-options="machine.input for machine in machineInputs track by machine.input"></select>
<!-- <input disabled="true" name="machineName" type="text" class="form-control" placeholder="Machine Name"> -->
</div>
</div>
Any help is appreciated as this is driving me nuts. The $scope object machineProfile.input is updated but nothing appears on screen.
Looks like your ng-model is not correct. Try this.
<select name="chooseInput" class="form-control" ng-model="machineProfile.input" ng-change="awesome(machineProfile.input)" ng-options="machine.input for machine in machineInputs track by machine.input"></select>

Categories

Resources