How to read multiple checkboxes(and data associated with it)? - javascript

I have a form with multiple checkboxes and each checkbox as an input field associated with it that'll activate once you check the checkbox.
I've got the frontend working just fine, but I was wondering how can I read in my PHP which checkboxes were checked along with their respective input fields (and some have a radio button too in addition to the input field)
Here's what each individual checkbox in my form looks like:
<!-- Option1 -->
<div class="form-row">
<div class="form-group col-md-8">
<div class="form-check">
<input class="form-check-input showman" type="checkbox" onchange="showqt()" value="Button Chicken Amritsari" id="c1">
<label class="form-check-label" for="c1">
Button Chicken Amritsari<i><br>(Boneless) Serves 2<br>INR 290</i>
</label>
</div>
</div>
<div class="form-group col-md-4" id="ifYes" style="display: none; float:right;">
<!-- <label for="qtcounter">Quantity:</label> -->
<div class="input-group" id="qtcounter">
<input type="button" value="-" class="button-minus" data-field="quantity">
<input type="number" step="1" max="" value="1" name="quantity" class="quantity-field">
<input type="button" value="+" class="button-plus" data-field="quantity">
</div>
</div>
</div>
<!-- Option 1 ends -->
I haven't wrapped my head around the PHP yet but previously to read multiple checkboxes I put them all in an array in the name field and read that array in PHP. However, that was without the added complication of each checkbox having input field.
Does anyone have any idea how to do this?

You want to use an associative array for both the inputs and the checkboxes.
<!-- Option1 -->
<div class="form-row">
<div class="form-group col-md-8">
<div class="form-check">
<input class="form-check-input showman" type="checkbox" name="items[1][chosen]" onchange="showqt()" value="Button Chicken Amritsari" id="c1">
<label class="form-check-label" for="c1">
Button Chicken Amritsari<i><br>(Boneless) Serves 2<br>INR 290</i>
</label>
</div>
</div>
<div class="form-group col-md-4" id="ifYes" style="display: none; float:right;">
<!-- <label for="qtcounter">Quantity:</label> -->
<div class="input-group" id="qtcounter">
<input type="button" value="-" class="button-minus" data-field="items[1][quantity]">
<input type="number" step="1" max="" value="1" name="items[1][quantity]" class="quantity-field">
<input type="button" value="+" class="button-plus" data-field="items[1][quantity]">
</div>
</div>
</div>
<!-- Option 1 ends -->
For option 2 use items[2][chosen] and items[2][quantity], etc.
Note that must specify the index and can't use []. Otherwise, the index of quantity will not match the chosen item.
In php you can loop through the items and ignore the items that aren't chosen.
foreach ($_POST['items'] as $item) {
if (!isset($item['chosen'])) continue; // Skip items that aren't chosen.
echo $item['quantity'] . ' ' . $item['chosen'] . "\n";
}

Related

Jquery: limit user to select only two radio options at once and display values inside divs

I am developing a product comparator where user have to select only two products within a universe with 4 products for example.
In this case, the user would select two products within this universe with 4 products and the information of these selected products would appear inside columns (column 1 and column 2).
I tried to research some similar questions here, but unfortunatly i didn't find a correct way to do that:
Get two values from select option at once
Select and Radio options to show div
Two radio buttons are selecting at once
My question is: How can i select only two radio options, always limiting only two selections? Also, how can i display radio values from selected options inside column 1 and the second selected product inside column 2?
Below is the code that i'm using:
HTML structure that display 4 products with their respective radio buttons:
<h2 class="mb-3">Produtos</h2>
<div class="row justify-content-center">
<div class="col-2">
<img src="https://assets.adidas.com/images/h_840,f_auto,q_auto,fl_lossy,c_fill,g_auto/cde9362a09ba4dd38c9ead6600ac074e_9366/Tenis_Duramo_SL_2.0_Preto_GW8336_01_standard.jpg" width="100px"/>
<input class="form-check-input radio" type="radio" name="produto1" id="1" value="Tênis preto">
<label class="form-check-label" for="1"></label>
</div>
<div class="col-2">
<img src="https://assets.adidas.com/images/h_840,f_auto,q_auto,fl_lossy,c_fill,g_auto/7ed0855435194229a525aad6009a0497_9366/Tenis_Superstar_Branco_EG4958_01_standard.jpg" width="100px"/>
<input class="form-check-input radio" type="radio" name="produto2" id="2" value="Tênis branco">
<label class="form-check-label" for="2"></label>
</div>
<div class="col-2">
<img src="https://assets.adidas.com/images/h_840,f_auto,q_auto,fl_lossy,c_fill,g_auto/9326e8db8d8e4e509e42ad26010cf693_9366/Tenis_adidas_4DFWD_Pulse_Preto_Q46451_01_standard.jpg" width="100px"/>
<input class="form-check-input radio" type="radio" name="produto3" id="3" value="Tênis verde">
<label class="form-check-label" for="3"></label>
</div>
<div class="col-2">
<img src="https://assets.adidas.com/images/h_840,f_auto,q_auto,fl_lossy,c_fill,g_auto/7a80a0e74201457eb1e5adcb00ff92f8_9366/Tenis_Dropset_Trainer_Azul_GZ2941_01_standard.jpg" width="100px"/>
<input class="form-check-input radio" type="radio" name="produto4" id="4" value="Tênis azul">
<label class="form-check-label" for="4"></label>
</div>
</div>
<div id="coluna1"></div>
<div id="coluna2"></div>
Below is jquery code that takes the values ​​of the selected items and display their information in respective columns. These code not allow to select more than two products:
$('.radio').change(function(){
var shoes = $(this).val();
var count = $("input[type='radio']:checked").length;
if(count > 2){
alert("you just have to select only two shoes.");
$(this).prop('checked', false);
return false;
}
$('#column1').text(shoes);
$('#column2').text(shoes);
//
});
In this case, how could i improve my code to reach the correct result? As a practical example, i I made a draft on JSFidle: https://jsfiddle.net/kg51Lvzx/
To do what you require I would suggest using checkboxes instead of radio controls. This allows the user to deselect an option.
From there you can loop through the selected items to output their text in the relevant divs.
Also, a couple of notes on the HTML. Firstly, I changed the repeated elements to use the same classes instead of incremental ids, as it makes selection much easier. Secondly, the label elements now wrap the relevant content. This means that the checkbox control and the image are clickable to make the selection.
let $output = $('.output');
let updateSelections = () => {
$output.text('');
$products.filter(':checked').each((i, el) => {
$output.eq(i).text(el.value);
});
}
let $products = $('.product').change(function() {
if ($products.filter(':checked').length > 2) {
$(this).prop('checked', false);
alert("you just have to select only two shoes.");
} else {
updateSelections();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/css/bootstrap.min.css" />
<h2 class="mb-3">Products - shoes</h2>
<div class="row justify-content-center">
<div class="col-2 ms-2">
<label class="form-check-label">
<img src="https://assets.adidas.com/images/h_840,f_auto,q_auto,fl_lossy,c_fill,g_auto/cde9362a09ba4dd38c9ead6600ac074e_9366/Tenis_Duramo_SL_2.0_Preto_GW8336_01_standard.jpg" width="100px" />
<div>
<input class="form-check-input product" type="checkbox" name="product1" id="1" value="Black shoes">
</div>
</label>
</div>
<div class="col-2 ms-2">
<label class="form-check-label">
<img src="https://assets.adidas.com/images/h_840,f_auto,q_auto,fl_lossy,c_fill,g_auto/7ed0855435194229a525aad6009a0497_9366/Tenis_Superstar_Branco_EG4958_01_standard.jpg" width="100px" />
<div>
<input class="form-check-input product" type="checkbox" name="product2" id="2" value="White shoes">
</div>
</label>
</div>
<div class="col-2 ms-2">
<label class="form-check-label">
<img src="https://assets.adidas.com/images/h_840,f_auto,q_auto,fl_lossy,c_fill,g_auto/9326e8db8d8e4e509e42ad26010cf693_9366/Tenis_adidas_4DFWD_Pulse_Preto_Q46451_01_standard.jpg" width="100px" />
<div>
<input class="form-check-input product" type="checkbox" name="product3" id="3" value="Green shoes">
</div>
</label>
</div>
<div class="col-2 ms-2">
<label class="form-check-label">
<img src="https://assets.adidas.com/images/h_840,f_auto,q_auto,fl_lossy,c_fill,g_auto/7a80a0e74201457eb1e5adcb00ff92f8_9366/Tenis_Dropset_Trainer_Azul_GZ2941_01_standard.jpg" width="100px" />
<div>
<input class="form-check-input product" type="checkbox" name="product4" id="4" value="Blue shoes">
</div>
</label>
</div>
</div>
<div class="output" id="column1"></div>
<div class="output" id="column2"></div>

Pass value from one field to another

Got a 3 selection radio button options and also a number field, in case somebody wants to select more than radio buttons can offer. And i'm trying to pass a radio button value to the number field when radio value is changed.
Here is my html code for it
<!-- this is main add to cart form -->
<form>
<!-- and this is secondary form for radio buttons, so, only one could be selected -->
<form class="quanform">
<div class="pricelinewrap">
<div class="priceline">
<div class="pricelinecellval">
<input type="radio" id="quanlineradio1" value="1" name="quanline" />
</div>
</div>
</div>
<div class="pricelinewrap">
<div class="priceline">
<div class="pricelinecellval">
<input type="radio" id="quanlineradio2" value="2" name="quanline" />
</div>
</div>
</div>
<div class="pricelinewrap">
<div class="priceline">
<div class="pricelinecellval">
<input type="radio" id="quanlineradio3" value="3" name="quanline" />
</div>
</div>
</div>
</form>
<div class="newquanfield tablecell almiddle">
<input type="number" min="1" size="2" class="quantity" name="quantity" id="quantity" value="2" />
</div>
</form>
And this is my jquery code for it
$("form.quanform .pricelinewrap .priceline .pricelinecellval input[type=radio]").each(function(){
$(this).click(function(){
var quanval = $(this).val();
$(this).parents().find(".newquanfield input[type=number]").val(quanval);
});
});
Nothing happens and there are no errors in the console
The problem lies purely in your selector:
$("form.quanform) won't work, as your <form class="quanform"> is wrapped inside another <form>, which is invalid markup; <form> cannot be nested inside another <form>.
Because the 'desired' markup is invalid, it actually never gets added to the DOM. You can confirm this by viewing the source yourself with CTRL + U - <form class="quanform"> doesn't exist. Thus, you cannot target it with jQuery.
You can validate your markup with the W3 Validation service to ensure that your HTML is indeed valid, ensuring that your jQuery selectors work the way you expect.
As for your current structure, you can omit the .quanform component, and simply use $("form .pricelinewrap .priceline .pricelinecellval input[type=radio]"), which will work based off of the outer <form> element (which does indeed exist in the DOM).
This can be seen working in the following example:
$("form .pricelinewrap .priceline .pricelinecellval input[type=radio]").each(function() {
$(this).click(function() {
var quanval = $(this).val();
$(this).parents().find(".newquanfield input[type=number]").val(quanval);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- this is main add to cart form -->
<form>
<!-- and this is secondary form for radio buttons, so, only one could be selected -->
<form class="quanform">
<div class="pricelinewrap">
<div class="priceline">
<div class="pricelinecellval">
<input type="radio" id="quanlineradio1" value="1" name="quanline" />
</div>
</div>
</div>
<div class="pricelinewrap">
<div class="priceline">
<div class="pricelinecellval">
<input type="radio" id="quanlineradio2" value="2" name="quanline" />
</div>
</div>
</div>
<div class="pricelinewrap">
<div class="priceline">
<div class="pricelinecellval">
<input type="radio" id="quanlineradio3" value="3" name="quanline" />
</div>
</div>
</div>
</form>
<div class="newquanfield tablecell almiddle">
<input type="number" min="1" size="2" class="quantity" name="quantity" id="quantity" value="2" />
</div>
</form>
Hope this helps! :)

Only one radio button must be selected at a time

I want to select one radio button out of two radio button using Javascript here is my html code I have
<div class="row">
<div class="form-group">
<label class="control-label col-sm-6">Feel Of The Cards : </label>
<div class="col-sm-6">
<input type="radio" value="NonEmbossed" name="feel_of_card" /> Non Embossed/Smooth Finished<br>
<input type="radio" value="Embossed" name="feel_of_card1" /> Embossed/Linen Finished/Textured Cards
</div>
</div>
</div>
I want to make a separate function in which a one radio button will be selected out of two radio button?
what is the possible way to write javascript function ?
<div class="row">
<div class="form-group">
<label class="control-label col-sm-6">Feel Of The Cards : </label>
<div class="col-sm-6">
<input id="_1234" type="radio" value="NonEmbossed" name="feel_of_card" /> Non Embossed/Smooth Finished<br>
<input id="_1235" type="radio" value="Embossed" name="feel_of_card" /> Embossed/Linen Finished/Textured Cards</div>
</div>
</div>
Why do you use all instead of id value?
Also do not mix CSS syntax (# for identifier) with native JS
Native JS solution:
document.getElementById("_1234").checked = true;
JQuery solution:
$("#_1234").prop("checked", true);
You don't need JavaScript to do that. Just give same name to both checkboxes
<div class="row">
<div class="form-group">
<label class="control-label col-sm-6">Feel Of The Cards : </label>
<div class="col-sm-6">
<input type="radio" value="NonEmbossed" name="feel_of_card" />
Non Embossed/Smooth Finished<br />
<input type="radio" value="Embossed" name="feel_of_card" />
Embossed/Linen Finished/Textured Cards
</div>
</div>
</div>

Enabling multiple textboxes with a corresponding multiple checkbox using a single jQuery function

I have 4 multiple check boxes which each one of them is specifically correspondent to 4 text-boxes. I need to enable the disabled texbox when the corresponding checkbox is checked. I wrote a same function for each checkbox's onclick event in html tag itself as onclick="document.getElementById('txtLrgPrc').disabled=!this.checked;" .
But I need to automate this by calling a function only once by sending the parameters of textboxes and heckboxes(i.e. id or name,,) to my js file using jQuery. Can anyone help me for refining this please?
Here is the code which I am currently using and it works finely.
jsp page:
<div class="row item-tbl-row" id="addItmChkbxReg">
<div class="col-xs-5">
<label class="checkbox-inline">
<form:checkbox value="regular" class="checkbox sizechkbx" path="size" label="Regular" id="chkReg" onclick="document.getElementById('txtRegPrc').disabled=!this.checked;"/>
</label>
</div>
<div class="col-xs-7">
<form:input type="text" class="form-control price" path="price" id="txtRegPrc" disabled="true"/>
</div>
</div>
<div class="row item-tbl-row" id="addItmChkbxMed">
<div class="col-xs-5">
<label class="checkbox-inline">
<form:checkbox value="medium" class="checkbox sizechkbx" path="size" label="Medium" onclick="document.getElementById('txtMedPrc').disabled=!this.checked;"/>
</label>
</div>
<div class="col-xs-7">
<form:input type="text" class="form-control price" path="price" id="txtMedPrc" disabled="true"/>
</div>
</div>
<div class="row item-tbl-row" id="addItmChkbxLrg">
<div class="col-xs-5">
<label class="checkbox-inline">
<form:checkbox value="large" class="checkbox sizechkbx" path="size" label="Large" onclick="document.getElementById('txtLrgPrc').disabled=!this.checked;"/>
</label>
</div>
<div class="col-xs-7">
<form:input type="text" class="form-control price" path="price" id="txtLrgPrc" disabled="true"/>
</div>
</div>
You can automate like the following.
<script type="text/javascript">
$(document).ready(function () {
$(".checkbox").click(function () {
$(this).parent().parent().next().find(".form-control").prop("disabled", !$(this).prop("checked"));
});
});
</script>
Also, remove the click event of the checkboxes.
Another solution:
<script type="text/javascript">
function C(t, textBoxId) {
$("#" + textBoxId).prop("disabled", !$(t).prop("checked"));
}
</script>
<form:checkbox value="regular" id="chkReg" onclick="C(this, 'txtRegPrc')"/>

finding last child div in nested fieldset

Within a jquery mobile page I have a page with a nested fieldset.
I need to dynamically add an input and button field anytime a certain button is clicked.
My first step has been trying to find the id of the last dynamically added control group.
That is where I am stuck.
I have tried a lot of different ways to get to the div but haven't had any luck so I was hoping I could get some help from the experts.
My latest attempt...
$('#ServicePage #ServiceArticle #ServiceList #collapse #btnaddOther').on('click', function () {
var ct = $('#ServicePage #ServiceArticle #ServiceList #collapse');
getLastId(ct);
});
function getLastId(ct) {
var id = $(ct.last).attr('id');
addOtherItem(id);
}
Below is an example of the page. The div i'm trying to reach is below the 2nd fieldset and has an id of collapse. I need to get the last child div within the collapse div i.e. I need to return the id= addOther_1.
I hope that makes sense.
<div id="ServicePage" data-role="page" class="ui-page-theme-a">
<article id="ServiceArticle" data-role="content" class="ui-content">
<form>
<br />
<div id="ServiceList" class="ui-corner-all custom-corners">
<div class="ui-bar ui-bar-b">
<h3>Color Services</h3>
</div>
<div class="ui-body ui-body-a">
<fieldset data-role="controlgroup">
<legend>Select Color Services</legend>
<input type="checkbox" name="service" id="serviceHiLight" value="HiLight" />
<label for="serviceHiLight">Highlights</label>
<input type="checkbox" name="service" id="serviceLoLight" value="LoLight" />
<label for="serviceLoLight">Low-Lights</label>
<input type="checkbox" name="service" id="serviceRetouch" value="Retouch" />
<label for="serviceRetouch">Retouch</label>
<input type="checkbox" name="service" id="serviceHiLightRetouch" value="HiLightRetouch" />
<label for="serviceHiLightRetouch">Highlight Retouch</label>
<input type="checkbox" name="service" id="servicePainting" value="Painting" />
<label for="servicePainting">Painting like Ombre or Balayage</label>
<input type="checkbox" name="service" id="serviceAllOver" value="AllOver" />
<label for="serviceAllOver">All over color</label>
*<fieldset data-role="collapsible">
<legend>Other</legend>
<div id="collapse" data-role="controlgroup">
<div id="addOther_1" data-role="controlgroup" data-type="horizontal">
<input id="txtaddOther_1" type="text" name="service" data-wrapper-class="controlgroup-textinput ui-btn" placeholder="Enter Service Name" />
<button id="btnDeleteOther_1" style="background-color: transparent; border-style: none;" class="ui-btn-b ui-shadow ui-btn ui-icon-delete ui-btn-inline ui-btn-icon-notext ui-corner-all">Delete</button>
</div>
<a id="btnaddOther" href="#" class="ui-btn ui-shadow ui-btn-icon-left ui-icon-plus">Add</a>
</div>
</fieldset>
</fieldset>
</div>
</div>
</form>
</article>
</div>
How would I go about accessing this nested div?
Thanks
function getLastId() {
var $x = $('fieldset:last-of-type > div:first-of-type > div:first-of-type')
// addOtherItem($x.attr("id"));
// Just to show we got the id, I am putting it in a div.
// Remove when done and un-comment line 3
$('#tmpDiv').html($x.attr("id"))
}
$('#btn').on('click', function(){
getLastId();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- TMP -->
<div id="tmpDiv"></div>
<button id="btn">Click Me</button>
<!-- / TMP -->
<div id="ServicePage" data-role="page" class="ui-page-theme-a">
<article id="ServiceArticle" data-role="content" class="ui-content">
<form>
<br />
<div id="ServiceList" class="ui-corner-all custom-corners">
<div class="ui-bar ui-bar-b">
<h3>Color Services</h3>
</div>
<div class="ui-body ui-body-a">
<fieldset data-role="controlgroup">
<legend>Select Color Services</legend>
<input type="checkbox" name="service" id="serviceHiLight" value="HiLight" />
<label for="serviceHiLight">Highlights</label>
<input type="checkbox" name="service" id="serviceLoLight" value="LoLight" />
<label for="serviceLoLight">Low-Lights</label>
<input type="checkbox" name="service" id="serviceRetouch" value="Retouch" />
<label for="serviceRetouch">Retouch</label>
<input type="checkbox" name="service" id="serviceHiLightRetouch" value="HiLightRetouch" />
<label for="serviceHiLightRetouch">Highlight Retouch</label>
<input type="checkbox" name="service" id="servicePainting" value="Painting" />
<label for="servicePainting">Painting like Ombre or Balayage</label>
<input type="checkbox" name="service" id="serviceAllOver" value="AllOver" />
<label for="serviceAllOver">All over color</label>
*<fieldset data-role="collapsible">
<legend>Other</legend>
<div id="collapse" data-role="controlgroup">
<div id="addOther_1" data-role="controlgroup" data-type="horizontal">
<input id="txtaddOther_1" type="text" name="service" data-wrapper-class="controlgroup-textinput ui-btn" placeholder="Enter Service Name" />
<button id="btnDeleteOther_1" style="background-color: transparent; border-style: none;" class="ui-btn-b ui-shadow ui-btn ui-icon-delete ui-btn-inline ui-btn-icon-notext ui-corner-all">Delete</button>
</div>
<a id="btnaddOther" href="#" class="ui-btn ui-shadow ui-btn-icon-left ui-icon-plus">Add</a>
</div>
</fieldset>
</fieldset>
</div>
</div>
</form>
</article>
</div>
I like the "last-of-type" and "first-of-type" selectors
$('fieldset:last-of-type > div:first-of-type > div:first-of-type')
http://api.jquery.com/last-of-type-selector/
The above will select the last fieldset, then the first direct child div, then the first div after that (which is the one you want).
Why not keep track of the last one using an id.. For example: id = 'LastOne', now, when you add a new item, remove the attribute from the actual last one, and then just place it on the one you're about to add. Basically, something like this:
$(document).ready(function(){
$('.add').click(function(){
var nvar = $('#lo').removeAttr('id').clone();
nvar.attr('id','lo');
nvar.insertAfter($('.mydiv').last());
});
});
You click on an ADD button (with the class .add) and then it looks for the LasOne (LO for short), removes it attr, makes a clone of it and then places it below the last one. Of course, you can also remove the attr AFTER you insert. That way, you wouldn't need to use "LAST".. since you don't really know what the last one is.
Check the fiddle working here: http://jsfiddle.net/lrojas94/v26fk8yd/
I was making this wayyyyy to difficult. I got the answer by trying something that charlietfl said "Since it has an ID just use that $('#collapse') since by definition ID's are unique – charlietfl"
Because I am using jquery mobile I did have to include the page name so it was simply
$addOther = $('#ServicePage #collapse');
The name of the jquery mobile page and the id of the div I need to look into.
Thanks everyone for your help.
I forgot to add how I found the last div within that div...
$('#ServicePage #collapse').find('.a').last();
This found the last div withing a div. The div I would looking in has the id #collapse.

Categories

Resources