FormData and checkboxes - javascript

Currently when creating a FormData object, a checked checkbox is added with a value of "on", and an unchecked checkbox is not passed at all.
Do I have to hack in some hidden inputs to properly set checkboxes, or is there some customization I can do with FormData, or pre processing?
I would prefer a checked checkbox to be 1 and an unchecked to be 0. I can already do this myself (ie ugly hack), but I don't see any native way with FormData.
form.addEventListener("submit", function(e) {
e.preventDefault();
const data = new FormData(form);
for (const [name,value] of data) {
console.log(name, ":", value)
}
})
<form id="form">
<input name="normal" type="text" value='example' />
<input id="inpt" name="on" type="checkbox" />
<label for="inpt">on</label>
<br /><button type="submit">submit</button>
</form>

Currently when creating a FormData object, a checked checkbox is added with a value of "on", and an unchecked checkbox is not passed at all.
on is only used if the checkbox is missing a value attribute
Do I have to hack in some hidden inputs to properly set checkboxes
No. That is properly handling checkboxes. It is how they have worked in forms since the form element was added to HTML.
Test for the presence or absence of the checkbox in the code that handles it.

Try this:
var checkbox = $("#myForm").find("input[type=checkbox]");
$.each(checkbox, function(key, val) {
formData.append($(val).attr('name'), this.is(':checked'))
});
It always adds the field to FormData with either a value of true when checked, or false when unchecked.

I took a slightly different approach from the existing answers. I created my form data variable the standard jQuery way inside my form submit event handler:
var form = $(this).get(0);
var formData = new FormData(form);
Based on Quentin's answer, saying that it is only set to 'on' when the value attribute is not available, I just added a document event on change to all checkboxes to set the value when the user checks or unchecks the input.
$(document).on("change", "input[type='checkbox']", function () {
var value = $(this).prop('checked');
$(this).val(value);
});
When my form data object is created in the above way, all checked checkboxes now have the value of 'true' rather than 'on'.
This worked quite nicely for my purposes and seems to me to be a pretty simple fix. Interestingly, having value='false' doesn't do anything as the input is just ignored and not added to the form data object if it is not checked. But obviously that still works.

Related

How to collect a string from a radio input and send it to a useState? (React) [duplicate]

I have a MVC3 app using Project Awesome (http://awesome.codeplex.com/), but I am getting a weird behaviour on checkboxes. I have the following simple Html within a Modal popup <input type="checkbox" class="check-box" name="IsDeleted">
When I submit the form containing this element, its post value is 'on' instead of the expected 'true' (when element is checked).
Does anybody know why this is? I am assuming there may be some javascript somewhere messing with the form data, but wanted to check whether there isn't some HTML I am missing.
Thanks
Set the checkboxes value attribute to true and you will get true in your post value.
It's browser specific, I suppose, what to send when value is undefined. You need to defined value attribute on your radios/checkboxes to be sure what will be passed back to you. I would suggest value="1"
set data-val="true" and value="true" by deafult...
if checkbox is checked then returns true
Check Checkbox is checked or not if checked set Hidden field true else set hidden field false.
$('#hiddenFieldId').val($('#CheckBoxId').attr('checked')=='checked')
Surely you should just check if it is set - the value that it sends across is irrelevant, if it's not checked, then nothing at all gets sent when you POST.
Nothing worked!
I ended up on a hacky way after seeing the serialised form object just before posting to controller/action. Its not safe in case if anyone would have any textboxes inside that may contain ampersands. In my case, i had an array of checkboxes, so I did this hack after I am very sure, i won't have problems.
var formData = $("#form").serialize();
formData = formData.replaceAll('=on&','=true&');
if (formData.endsWith('=on'))
{
formData = formData.substring(0, formData.length - 3) + "=true";
}
Hope it helps to those 'someone' with my scenario. Happy hacking.
Use jQuery for cross-browser decision. And it will return true or false anyway.
$('#check-box-id').attr('checked' ) == true
if your checkbox has an id check-box-id. For your current version use the next (select by class name):
$('.check-box').attr('checked' ) == true
Use jQuery
var out=$('.check-box').is('checked')
If checkbox is checked out=true
else out=false
In HTML, add a input type="hidden" above checkbox:
<input name="active" id="activeVal" type="hidden">
<input id="active" type="checkbox">
Then, add a script as below:
$('#activeVal').val($('#active').is(':checked'));
$('#active').change(function() {
$('#activeVal').val($('#active').is(':checked'));
});
When you do eg. $('#your-form').serialize() in jQuery, you will get value of checkbox when checked active: true or uncheck active: false

Checkbox checked not passing an actual value?

My code checks the value of 2x checkboxes to equal true/false depending on a radio field. I see the checkboxes being ticket on the web page.
However, once they are passed over a HTML POST form, they have no values and always equal false.
If I give the checkboxes a value "TRUE" then of course they have only that value.
What am I missing here?
<script>
$(function() {
var MAIN= $("input[type='radio']");
var marketingPhone = $("input[type='checkbox'][name='marketingPhone']");
var marketingRobo = $("input[type='checkbox'][name='marketingRobo']");
MAIN.on('change', function()
{
if ($(this).val() == "TRUE") {
marketingPhone.prop('checked',true);
marketingRobo.prop('checked',true);
} else {
marketingPhone.prop('checked',false);
marketingRobo.prop('checked',false);
}
});
});
</script>
The fields are as follows:
<input type="checkbox" name="marketingPhone" value=""/>
<input type="checkbox" name="marketingRobo" value=""/>
Checkboxes, if not checked, do not get posted at all with the form.
So if you post a form with checkboxes even if they have some value but they are not checked, you can not get checkbox's values in $_POST or $_GET arrays.
You need to specify a value in the HTML. If a checkbox is checked, that value is posted. These values can be anything and are definitely not the same as the true/false that are used for the prop()-call (those just mean 'set or clear the check mark').
Example:
<input type="checkbox" name="marketingPhone" value="yes"/>
<input type="checkbox" name="marketingRobo" value="absolutely"/>
When both are checked, this is posted:
marketingPhone=yes&marketingRobo=absolutely
When not all are checked, the corresponding name=value are omitted from the posted data.
If you really want to post a value (e.g. "true" or "false") for every checkbox all the time, then the only way to do so is by adding hidden fields (one for each checkbox) that you control yourself, setting the value of the hidden field to "true" or "false" using script. You might as well then not set the checkbox value to prevent confusion on the receiving end.
Also be aware that form fields always post strings, so either treat them as literal strings or parse them into booleans on the receiving end.

How to disable enable a checkbox based on another checkbox?

Following code is generated by a for loop.
<form action="saveresponse.php" method="POST" name="mainForm">
<input class="cbox_yes" type="checkbox" name="yes[]" value="01.jpg"
onclick="spenable()" /> OK
<input class="cbox_sp" type="checkbox" name="sp[]" value="01.jpg" disabled />Special<br />
<input class="cbox_yes" type="checkbox" name="yes[]" value="02.jpg"
onclick="spenable()" /> OK
<input class="cbox_sp" type="checkbox" name="sp[]" value="02.jpg" disabled />Special<br />
etc etc upto n times...
Now, what I want is that on page load, all the sp[] checkboxes should be disabled and enabled only if their corrosponding yes[] checkbox is checked by user.
Javascript code I am using: (Just to check if JS is capturing the states of yes[] checkbox?
function spenable(){
var yes = document.mainForm.yes[].value;
if (yes == true)
//alert("true");
document.mainForm.yes[].value = checked;
else
//alert("false");
document.mainForm.yes[].value = checked;
};
};
But I am not getting any alert (Neither Yes, Nor No).
So, is yes[] (Square brackets) in second line is incorrect? Or my if/else condition is wrong in JS?
P.S. All the questions here at SO or on Google deal with only one case/pair.
P.S. If required, I can change yes[] to yes1, yes2, yes3 etc and corresponding sp1, sp2, sp3 where 1,2,3 is $i of For loop, but then how will I capture/refer to it in JS?
_UPDATE:_
The flow/conditions are(Clarification):
Initially Special checkbox will be disabled and OK checkbox will be unchecked.
Then if user checks Ok, Special gets enabled.
If user want, he can tick Special.
If, later, user changes mind and untick the OK, Special should be unticked as well as disabled again.
I used jQuery here for the sake of simplicity.
$("input[name='yes[]']").change(function() { //When checkbox changes
var checked = $(this).attr("checked");
$(this).next().attr("disabled", !checked); //The next checkbox will enable
});​ // or disable based on the
// checkbox before it
Demo: http://jsfiddle.net/DerekL/Zdf9d/
Pure JavaScript: http://jsfiddle.net/DerekL/Zdf9d/1/
Update
It will uncheck the first checkboxes when the Special checkbox is checked.
Pure JavaScript: http://jsfiddle.net/DerekL/Zdf9d/2/
More Updates
Here's the demo:
Pure JavaScript: http://jsfiddle.net/DerekL/Zdf9d/3/
jQuery: http://jsfiddle.net/DerekL/Zdf9d/4/
Little note: document.querySelectorAll works on all modern browsers and IE8+ including IE8. It is always better to use jQuery if you want to support IE6.
You can't use yes[] as an identifier in the Javascript, so you have to access the field using the name as a string:
document.mainForm["yes[]"]
This will not return a single element, it will return an array of elements. Use an index to access a specific element:
document.mainForm["yes[]"][0]
The value of the checkbox will always be the value property, regardless of whether the checkbox is selected or not. Use the checked property to find out if it's selected:
function spenable() {
var yes = document.mainForm["yes[]"][0].checked;
if (yes) {
alert("true");
} else {
alert("false");
};
}
To access the specific checkbox that was clicked, send the index of the checkbox in the event call:
<input class="cbox_yes" type="checkbox" name="yes[]" value="01.jpg" onclick="spenable(0);" /> OK
Use the index in the function:
function spenable(idx) {
var yes = document.mainForm["yes[]"][idx].checked;
var sp = document.mainForm["sp[]"][idx];
sp.disabled = !yes;
}
If you are open to using jQuery:
$('input[type="checkbox"]').click(function(){
var obj = $(this);
obj.next('.cbox_sp').attr({'disabled':(obj.is(':checked') ? false : 'disabled')});
});
This solution will assign an onclick event handler to all checkboxes and then check to see if the corresponding "special" checkbox should be disabled or not. It also sets the default checked state to true.
Working Example: http://jsfiddle.net/6YTqC/

Check if a checkbox is checked in JS

I am new to js and jquery. Currently, I have a form at form.php which contains a checkbox. When the user clicks submit, the form variables are sent to a form.js file where each value is checked to be null or not.
The form.js file works perfectly, however, for the checkbox nothing seems to happen. I have a feeling this is due to the way I have declared the variable.
The following is the code for the js file:
var email = $('#email').val();
var website = $('#website').val();
var CHECKBOX = $('CHECKBOX').val();
...
...
if (CHECKBOX.checked == FALSE){
var error = true;
$('#notchecked_error').fadeIn(500);
}else{
$('#notchecked_error').fadeOut(500);
}
Try using:
if ( $('#CHECKBOX').prop("checked") )
or:
if ( $('#CHECKBOX').is(":checked") )
Also, be sure your selector for the checkbox is correct.
I see two problems in your code. The first one is that the selector in your CHECKBOX assignation is faulty. It should be
var CHECKBOX = $('#CHECKBOX').val();
or
var CHECKBOX = $('input[type=checkbox]').val();
the second problem is that you are reading CHECKBOX.checked from the val() function, you need to read it from the checkbox itself.
if(CHECKBOX.checked)
$('input[type=checkbox]:checked') // If you have multiple checkboxes you can use this and loop through them to get additional info
$('#checkboxID:checked').length // To get one specific checkbox
`$('CHECKBOX').val();`
Will try to find an element with a tagname of CHECKBOX and return it's value. Presumably you want to reference the checkbox with an ID of CHECKBOX:
var CHECKBOX = $('#CHECKBOX');
To see if it's checked:
if (!CHECKBOX[0].checked) {
// CHECKBOX is not checked
}
You really should learn basic javascript before using jQuery. Usually validation is initiated from a form submit, which can give you are reference to the form. You can then reference all of the form elements as properties of the form, you don't need to create all of those jQuery objects. e.g. if you form is something like:
<form ... onsubmit="validate(this)"... >
<input type="checkbox" name="checkbox">
</form>
Then in your validate function:
function validate(form) {
if (!form.checkbox.checked) {
// the checkbox isn't checked
}
}
You can attach the listener dynamically if you wish.

JavaScript: True form reset for hidden fields

Unfortunately form.reset() function doesn't reset hidden inputs of the form.
Checked in FF3 and Chromium.
Does any one have an idea how to do the reset for hidden fields as well?
Seems the easiest way of doing that is having <input style="display: none" type="text"/> field instead of <input type="hidden"/> field.
At this case default reset process regularly.
This is correct as per the standard, unfortunately. A bad spec wart IMO. IE provides hidden fields with a resettable defaultValue nonetheless. See this discussion: it's not (alas) going to change in HTML5.
(Luckily, there is rarely any need to reset a form. As a UI feature it's generally frowned upon.)
Since you can't get the original value of the value attribute at all, you would have to duplicate it in another attribute and fetch that. eg.:
<form id="f">
<input type="hidden" name="foo" value="bar" class="value=bar"/>
function resetForm() {
var f= document.getElementById('f');
f.reset();
f.elements.foo.value= Element_getClassValue(f.elements.foo, 'value');
}
function Element_getClassValue(el, classname) {
var prefix= classname+'=';
var classes= el.className.split(/\s+/);
for (var i= classes.length; i-->0;)
if (classes[i].substring(0, prefix.length)===prefix)
return classes[i].substring(prefix.length);
return '';
}
Alternative ways of smuggling that value in might include HTML5 data, another spare attribute like title, an immediately-following <!-- comment --> to read the value from, explicit additional JS information, or extra hidden fields just to hold the default values.
Whatever approach, it would have to clutter up the HTML; it can't be created by script at document ready time because some browsers will have already overridden the field's value with a remembered value (from a reload or back button press) by that time that code executes.
Another answer, in case anyone comes here looking for one.
Serialize the form after the page loads and use those values to reset the hidden fields later:
var serializedForm = $('#myForm').serialize();
Then, to reset the form:
function fullReset(){
$('#myForm').reset(); // resets everything except hidden fields
var formFields = decodeURIComponent(serializedForm).split('&'); //split up the serialized form into variable pairs
//put it into an associative array
var splitFields = new Array();
for(i in formFields){
vals= formFields[i].split('=');
splitFields[vals[0]] = vals[1];
}
$('#myForm').find('input[type=hidden]').each(function(){
this.value = splitFields[this.name];
});
}
You can use jQuery - this will empty hidden fields:
$('form').on('reset', function() {
$("input[type='hidden']", $(this)).val('');
});
Tip: just make sure you're not resetting csrf token field or anything else that shouldn't be emptied. You can narrow down element's specification if needed.
If you want to reset the field to a default value you can use(not tested):
$('form').on('reset', function() {
$("input[type='hidden']", $(this)).each(function() {
var $t = $(this);
$t.val($t.data('defaultvalue'));
});
});
and save the default value in the data-defaultvalue="Something" property.
I found it easier to just set a default value when the document is loaded then trap the reset and reset the hidden puppies back to their original value. For example,
//fix form reset (hidden fields don't get reset - this will fix that pain in the arse issue)
$( document ).ready(function() {
$("#myForm").find("input:hidden").each(function() {
$(this).data("myDefaultValue", $(this).val());
});
$("#myForm").off("reset.myarse");
$("#myForm").on("reset.myarse", function() {
var myDefaultValue = $(this).data("myDefaultValue");
if (myDefaultValue != null) {
$(this).val(myDefaultValue);
}
});
}
Hope this helps someone out :)
$('#form :reset').on('click',function(e)({
e.preventDefault();
e.stopImmediatePropagation();
$("#form input:hidden,#form :text,#form textarea").val('');
});
For select, checkbox, radio, it's better you know (hold) the default values and in that event handler, you set them to their default values.
Create a button and add JavaScript to the onClick event which clears the fields.
That said, I'm curious why you want to reset these fields. Usually, they contain internal data. If I would clear them in my code, the post of the form would fail (for example after the user has entered the new data and tries to submit the form).
[EDIT] I misunderstood your question. If you're worried that someone might tamper with the values in the hidden fields, then there is no way to reset them. For example, you can call reset() on the form but not on a field in the form.
You could think that you could save the values in a JavaScript file and use that to reset the values but when a user can tamper with the hidden fields, he can tamper with the JavaScript as well.
So from a security point of view, if you need to reset hidden fields, then avoid them in the first place and save the information in the session on the server.
How I would do it is put an event listener on the change event of the hidden field. In that listener function you could save the initial value to the DOM element storage (mootools, jquery) and then listen to the reset event of the form to restore the initial values stored in the hidden form field storage.
This will do:
$("#form input:hidden").val('').trigger('change');
You can reset hidden input field value using below line, you just need to change your form id instead of frmForm.
$("#frmForm input:hidden").val(' ');

Categories

Resources