Check box value does not change after submission - javascript

What I am trying to do is to populate my input fields based on JSON object. Below are the fields with their default values:
<input type="hidden" name="id"/>
<input id="enabled1" name="enabled" type="checkbox" value="true"> // not sure why value="true" here, by default it should be false
The JSON object has the following format:
[{enabled:false, id:184}]
Based on the JSON object, I will iterate its properties and assign the value to the field accordingly. The iterate function is as follows:
for ( var propertyName in aData) {
if (aData.hasOwnProperty(propertyName)){
// check if field exist
var elem = $("input[name="+propertyName+"]");
var exist = elem.size() == 1;
// if exist, update field with selected info
if (exist){
elem.val(aData[propertyName]);
}
}
}
After the iterate function runs the fields are shown like below:
<input type="hidden" name="id" value="184">
<input id="enabled1" name="enabled" type="checkbox" value="false">
Now if I tick the checkBox and submit the information to server, I want the value to be true but somehow the value is still false. What did I miss out here ?

But that's very much expected. Since, selecting a checkbox does not have any effect on the value of the html element it changes the checked status from unchecked to checked. When you try to get the value on the server side it would return you with the overridden value.
Check it out here

I'm not sure, but I think input tag should have close tag (slash /) in itself:
<input type="hidden" name="id" value="184"/>
<input id="enabled1" name="enabled" type="checkbox" value="false"/>
Please check. -Han-

Related

Assign value from endpoint to checkbox

I am trying to assign values I get from an endpoint to a checkbox
Here is the object
{sendOtpEmail: true}
I had to do some searching inside the endpoint response to differentiate whether an email value comes back or a cell phone value comes back
Here is my code
TS
otpCellValue: any;
otpEmailValue: any;
getOTPChannel() {
this._loader.start();
this._subscriptions.push(this._corpService.getOTPChannel().subscribe((resp) => {
//get endpoint object
console.log(resp);
//get endpoint object parameter name
let keyNames = Object.keys(resp);
console.log(keyNames[0]);
//check for email keyword
if(keyNames[0].includes('Email')) {
console.log(resp.sendOtpEmail);
//get value
if(resp.sendOtpEmail == true) {
//email value is true so the otpEmailValue checkbox should be checked however it is not
this.otpEmailValue = 1;
this.otpCellValue = 0;
} else {
this.otpEmailValue = 0;
this.otpCellValue = 0;
}
}
this._loader.stop();
}, (error) => {
this._loader.stop();
this._errorService.openErrorPopup('Failed to get OPT channel.');
}));
}
HTML
<input type="radio" name="1" id="1" class="with-gap" [(ngModel)]="otpCellValue" [(value)]="otpCellValue">
<input type="radio" name="2" id="2" class="with-gap" [(ngModel)]="otpEmailValue" [(value)]="otpEmailValue">
I added comments to say what I am doing in the code above
So now I am stuck with why the email checkbox is not checked. Any ideas?
Those are not checkboxes but radio buttons. Assuming that you do want the radio buttons (which in your case it looks like it, because it would be one or the other), there are a few things that needs to be done.
Rather than having 2 properties to indicate which option is selected, you could have 1 property for that purpose.
So
this.otpEmailValue = 1;
this.otpCellValue = 0;
Becomes
this.contact = 'email'; // This line is now equivalent to the ones above
In the template, the radio button inputs, need to have the same name for them to behave as 1 input instead of 2, because after all, we only want 1 option selected. The ngModel directive now points to the value we want to bind, in our case, contact. And lastly, the value should be static. When the value of the property bound with ngModel matches the value of one of the radio buttons, it will select it.
So, after all those changes we get the following.
<input type="radio"
name="contact-option"
id="1"
class="with-gap"
[(ngModel)]="contact"
value="cell"> Cell
<input type="radio"
name="contact-option"
id="2"
class="with-gap"
[(ngModel)]="contact"
value="email"> Email
Demo

Get object sent to function with this.value

Is there a way to get the object itself when a function receives a value from it?
Example:
<input id="field1" onblur="testFunction(this.value)" />
<input id="field2" onblur="testFunction(this.value)" />
<script>
function testFunction(x){
field_value_length = x.length;
field_object = ????;
}
</script>
When I blur the field, I apply it's length to "field_value_length" in testFunction(). Ok!
Is there a way to get the object itself (the input) where data in "x" came from, so I can get other properties from the form field that has sent data value to the function, like the "id" etc. just like it was sending testFunction(this) instead testFunction(this.value)?
What is sent to the function is the value from the input... Only.
But nothing prevents you from sending the input element, using just this.
<input id="field1" onblur="testFunction(this)" />
<input id="field2" onblur="testFunction(this)" />
<script>
function testFunction(x){
field_value_length = x.value.length;
field_id = x.id;
}
</script>

jQuery - serializeArray() is not getting the value of the checked checkbox

I have a checkbox in a form that acts as a flag.
In order to do it, I added a hidden input element so that if the checkbox is not checked, something will still be saved
<form action="">
...
<input type="hidden" name="foo" value="no" />
<input type="checkbox" name="foo" value="yes">
...
</form>
The problem I am having is that when I
check the checkbox
then run jQuery.serializeArray() on the form
the value set for the foo element is "no"
Object { name="foo", value="no"}
Shouldn't serializeArray() emulate browser behaviour? If so, shouldn't it return "yes" if checkbox is checked?
I am using jQuery v1.10.2
In a short word: No. The serializeArray method only returns the checkbox in the case it is checked. Thus, it will ignore it as long as it remains unchecked.
In case you checked it, though, it wiill return the value of your input directly.
Check out the demo at http://api.jquery.com/serializearray/ .
Using serializeArray on a form with multiple inputs of the same name returns more than one object for each element (if checked). This means that the following HTML will return the following object. So the data in question is there and is available. Because of this I'm assuming that you're attempting to either manipulate the data to be in 1 object or you're posting it to a server which is only taking into account the data from the first value with that key. You just need to make sure that any checkbox element takes precedence.
Returned Object:
[
{
name:"foo",
value:"no"
},
{
name:"foo2",
value:"no"
},
{
name:"foo2",
value:"yes"
}
]
HTML:
<form>
<input type="hidden" name="foo" value="no" />
<input type="checkbox" name="foo" value="yes" />
<input type="hidden" name="foo2" value="no" />
<input type="checkbox" name="foo2" value="yes" checked />
</form>
JS:
console.log($('form').serializeArray());
DEMO
Another way you can do this is get rid of the hidden fields and before you submit the form go through each unchecked checkbox and check if there is any data in the serializeArray with the same name. If not just add it in there as a off.
$('#submit').on('click', function(){
var arr = $('form').serializeArray(),
names = (function(){
var n = [],
l = arr.length - 1;
for(; l>=0; l--){
n.push(arr[l].name);
}
return n;
})();
$('input[type="checkbox"]:not(:checked)').each(function(){
if($.inArray(this.name, names) === -1){
arr.push({name: this.name, value: 'off'});
}
});
console.log(arr);
});
DEMO
Using the same name for multiple fields is problematic at best and there is no standardized way that front end systems, or back end systems, will handle it.
The only reason to use the same name is if you are trying to pass some kind of a default value, like you are in the case below, where you are doing a simple yes/no.
What you want, to emulate the browser, is serialize method, not the serializeArray.
I added the form to a page -- from my console:
JSON.stringify(f.serializeArray());
"[{"name":"foo","value":"no"}]"
NO checkmark
JSON.stringify(f.serialize());
""foo=no""
Checkmark
JSON.stringify(f.serialize());
""foo=yes&foo=no""
If your back end system gets confused and is picking up the wrong value, reverse the order of your checkmark and hidden element.
FACT: jQuery serializeArray() does not include unchecked checkboxes that probably we DO need them sent to server (no problem for radios though).
SOLUTION: create a new serialize:
//1. `sel` any collection of `form` and/or `input`, `select`, `textarea`
//2. we assign value `1` if not exists to radios and checkboxes
// so that the server will receive `1` instead of `on` when checked
//3. we assign empty value to unchecked checkboxes
function serialize(sel) {
var arr,
tmp,
i,
$nodes = $(sel);
// 1. collect form controls
$nodes = $nodes.map(function(ndx){
var $n = $(this);
if($n.is('form'))
return $n.find('input, select, textarea').get();
return this;
});
// 2. replace empty values of <input>s of type=["checkbox"|"radio"] with 1
// or, we end up with "on" when checked
$nodes.each(function(ndx, el){
if ((el.nodeName.toUpperCase() == 'INPUT') && ((el.type.toUpperCase() == 'CHECKBOX') || (el.type.toUpperCase() == 'RADIO'))){
if((el.value === undefined) || (el.value == ''))
el.value = 1;
}
});
// 3. produce array of objects: {name: "field attribute name", value: "actual field value"}
arr = $nodes.serializeArray();
tmp = [];
for(i = 0; i < arr.length; i++)
tmp.push(arr[i].name);
// 4. include unchecked checkboxes
$nodes.filter('input[type="checkbox"]:not(:checked)').each(function(){
if(tmp.indexOf(this.name) < 0){
arr.push({name: this.name, value: ''});
}
});
return arr;
}
The reason we assigned empty string to unchecked checkboxes is because a checked one will submit it's value to server which is set in html and can be a zero!!!
So, an empty value denotes a unchecked checkbox.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<form url="http://application.localdev/api/v1/register" method="post" id="formReg" accept-charset="utf-8">
<input type="email" placeholder="email" name="email"><br>
<input type="text" placeholder="firstname" name="firstname"><br>
<input type="text" placeholder="lastname" name="lastname"><br>
<input type="number" placeholder="zip_code" name="zip_code"><br>
<input type="checkbox" name="general" value="true"> general<br>
<input type="checkbox" name="marketing" value="true"> marketing<br>
<input type="checkbox" name="survey" value="true"> survey<br>
<button type="submit">save</button>
</form>
<script>
$(document).ready(function() {
$('#formReg').on('submit', function(e){
// validation code here
e.preventDefault();
var values = {};
$.each($('#formReg').serializeArray(), function(i, field) {
values[field.name] = field.value;
});
$('input[type="checkbox"]:not(:checked)').each(function(){
if($.inArray(this.name, values) === -1){
values[this.name] = $(this).prop('checked')
}
});
console.log(values)
});
});
</script>
serializeArray doesn't return unchecked checkbox. I try this instead of serializeArray:
$('input, select, textarea').each(
function(index){
var input = $(this);
alert('Type: ' + input.attr('type') + 'Name: ' + input.attr('name') +
'Value: ' + input.val());
}
);

Iterating through mutiple checkbox values and matching them against a single text input box's value with jQuery

I am trying to check if the value string of a text input field contains any matches that correspond with the values of multiple checkbox inputs. If a checkbox's value is found as a match within the text input's value string, that checkbox should be checked, while any unmatching checkbox should remain unchecked. With the code below, all of the checkboxes show up checked, while only one of the checkbox's value is a match for the text input's value string.
jQuery
$("input[type='checkbox'][name='hello']").each(function(){
var value = $(this).attr('value');
var id = $(this).attr('id');
if ($("input[type='text'][name='goodbye']:contains("+value+")")) {
$("input[id="+id+"]").prop('checked', true);
}
});
HTML
<input type="checkbox" name="hello" id="1" value="1"><label for="1">one</label>
<input type="checkbox" name="hello" id="2" value="2"><label for="2">two</label>
<input type="checkbox" name="hello" id="3" value="3"><label for="3">three</label>
<input type="text" name="goodbye" id="goodbye" value="1">
If you just want to do a text compare the following should work
$("input[type='checkbox'][name='hello']").each(function () {
var value = $(this).val();
if ($('#goodbye').val().indexOf(value) >= 0) {
$(this).prop('checked', true);
}
});
I'm not sure why you were going overly complicated to get the goodbye input, since you had an id and the id is always unique (or you'll have other issues).
$('#goodbye').val()
will give you the value in the input box. using indexOf will return -1 if the value is not found, a number 0 or greater if it is, so we can use that to figure out if the value exists.
example: http://jsfiddle.net/X74NK/1/

JQuery add hidden element to form programmatically

This is really getting to me now.I have a form that loads when the page loads.In my jquery
'ready' function I append a hidden to that form like so :
$("<input id='thehidden' type='hidden' name='thehidden' value='hiddenval'>").appendTo("#MenuForm")
When I check the form content with firebug i can see the element is added.
["$(\"#MenuForm\").children()"] is [div, input#thehidden hiddenval]
All good so far.When I submit this form and try and read the elemet again,i can't get the value of the new hidden val I added.
alert($('#thehidden').val())
is undefined
Any help would be appreciated
When exactly are you trying to read the value from #thehidden div? When the submit button is pressed or when the page reloads after submit? If you don't create the input every time on page load, it's not going to be there the next page load.
I tested your code with just creating the input and reading the value back in an alert and it works fine for me. Check it out for yourself.
try
$('#someid').append($('<input></input>').attr('id','hidden1').attr('type','hidden').attr('value','some val'));
You can create a jQuery function to do most of the work for you. I use this function to add hidden inputs programatically:
jQuery Function:
// This must be applied to a form (or an object inside a form).
jQuery.fn.addHidden = function (name, value) {
return this.each(function () {
var input = {};
if (Object.prototype.toString.call(value) === '[object Array]') {
var r = /\[\]/;
// Pass an array as a series of separate hidden fields.
for (var i = 0; i < value.length; i++) {
input = $("<input>").attr("type", "hidden")
.attr("name", name.replace(r, '[' + i + ']'))
.val(value[i]);
$(this).append($(input));
}
} else {
input = $("<input>").attr("type", "hidden")
.attr("name", name)
.val(value);
$(this).append($(input));
}
});
};
Usage:
For standard form items or simple parameters in MVC theHidden as String:
$('#myform').addHidden('theHidden', 'jam');
=> <input type="hidden" name="theHidden" value="jam">
For list parameters in MVC ID As List(Of Integer):
$('#myform').addHidden('ID', [1,2,5]);
=> <input type="hidden" name="ID" value="1">
<input type="hidden" name="ID" value="2">
<input type="hidden" name="ID" value="4">
For complex types in MVC which have a List property model As ComplexType:
$('#myform').addHidden('Customer[].CustomerID', [1,2,5]);
=> <input type="hidden" name="Customer[0].CustomerID" value="1">
<input type="hidden" name="Customer[1].CustomerID" value="2">
<input type="hidden" name="Customer[2].CustomerID" value="5">
Class ComplexType
Property Customer As List(Of CustomerDetail)
End Class
Class CustomerDetail
Property CustomerID As Integer
End Class
You need to insert the input ELEMENT into the DOM, not just inject HTML into the page. When it comes for form fields, there is a difference.
Use var field = $(document.createElement('input')), then set the attributes of the field.

Categories