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.
Related
I am trying to create a list of names an user could chose from to select a object with multiple hidden values. I work with a PHP backend.
The code I wrote works but I think it is probably not the right way to approach the problem and could be written alot better, but I can't seem to find a better way.
Right now I print a <div> for every object which are clients in my case. Within the div I have four checkboxes that are hidden, which I check and uncheck on the background with a javascript function. The values of those checkboxes is what I need in javascript for an API call after the user choses the client.
I select and deselect the with a javascript function.
foreach($clients as $client) {
echo '<div class="'.$client->name.'-'.$client->id.' client-style" name="'.$client->name.'">
<input type="checkbox" class="'.$client->id.'" name="client_id" value="'.$client->id.'">
<input type="checkbox" class="'.$client->id.'" name="client_fb" value="'.$client->facebook.'">
<input type="checkbox" class="'.$client->id.'" name="client_insta" value="'.$client->instagram.'">
<input type="checkbox" " class="'.$client->id.'" name="client_wb" value="'.$client->website.'"></div>';
}
For every element I create an on click event handler
for (var i = 0; i < clientList.length; i++) {
const {name, id} = clientList[i];
$(`.${name}-${id}`).on('click', function() {
selectClientFromList({name, id});
});
}
I am trying to get a list of clickable "names". When a "name" is clicked, you want to get the "name" but also "id", "facebook", "instagram", "website".
Might be useful to use the <select> tag with multiple values like this but I don't want a dropdown. I need a scrollable list, because I also have use searchbar for this list.
With a lot of clients the html would grow fast. How do I clean my php code and keep the information about a client that the user selected?
Thanks in advance!
A good approach can be to use a hidden input. Give your div a class and then
foreach($clients as $client) {
echo '
<div class="'. $client->name.'-'.$client->id.' client-style" name="'.$client->name.'">
<input type="hidden" class="aclass '.$client->id.'" name="client_id" value="'.$client->id.'">
<input type="hidden" class="aclass '.$client->id.'" name="client_fb" value="'.$client->facebook.'">
<input type="hidden" class="aclass '.$client->id.'" name="client_insta" value="'.$client->instagram.'">
<input type="hidden" class="aclass '.$client->id.'" name="client_wb" value="'.$client->website.'"></div>';
}
And then instead of creating a click handler everytime. One works too.
$(`.aclass`).on('click', function() {
let type = $(this).attr('name'); // client_id or client_fb
let client_id = $(this).attr('class').replace("aclass",""); // $client->id's value is here
let value = $(this).val(); // credentials
});
I have two forms,In form1 when user select radio button,enter value in text box and clicks on add to list button the (text of radio button+value of text box) should get added to a listbox in form2.
I wrote javascript function to add items and included the script in both forms i.e in form1 the function gets triggered for onclick event of add to list button and in form2 in body tag onload event.
But it is not working,can anyone help in this regard as i am new to javascript.
Form1:
<form name="orderform">
Category:
<input type="radio" name="category" id="category" value="0">Apple</input>
<input type="radio" name="category" id="category" value="1">Orange</input>
<input type="radio" name="category" id="category" value="2">Banana</input>
<input type="radio" name="category" id="category" value="3">Guava</input>
<br>
Item: <input type="text" length="30" name="item" id="item"/>
<br>
<input type="button" name="add" value="Add to List" onClick="addItem_list()"/>
</form>
Form2:
<body onload="addItem_list()">
<form name="items">
Items <SELECT name="item_list" id="item_list">
<option value="">Select item</option>
</SELECT>
Javascript:
function addItem(selectbox,text,value )
{
var item = document.createElement("OPTION");
item.text = text;
item.value = value;
selectbox.options.add(item);
}
function addItem_list(){
var it=document.orderform.item.value; //getting item value from textbox
//To determine which radio button has been selected:
for (var i=0; i<document.orderform.category.length; i++)
{
if (document.orderform.category[i].checked==true)
{
var y = orderform.category[i].value;
}
}
var val=y+" "+it;
addItem(document.items.item_list,val,val);
}
Your script does work as intended. However, your HTML is very invalid. This could break correct parsing in some browsers dependend on doctype and subsequently the correct execution of JavaScript. When use IDs then define them unique. <input> is a void tag, that means it must not have a closing tag! When you use an XHTML doctype, mark the open tag as self closing <input />. Use <label for="the-input-id">My Label</label> to get a clickable label connected to the input element.
Don't rely on name mapping to document and form objects. Other scripts can overwrite this names, e.g. a JS-framework could define items as a document property/method. Use document.getElementById() or document.querySelector() / document.querySelectorAll() or some similar method instead.
I assume the <body> in the second code fragment appears in your code only once at the top of page.
Your not properly retrieving the 'orderForm' or the 'categories'. You need to grab those items correctly. You cannot navigate through the document just based on tag name, although that would be cool if you could. Here's the JS.
function addItem(selectbox,value )
{
var item = document.createElement("OPTION");
item.text = value;
item.value = value;
selectbox.options.add(item);
}
function addItem_list(){
var item =document.getElementById('item');
var it = item.value;
if(!it)
it = 'blank';
var categories = document.getElementsByTagName('category');
//To determine which radio button has been selected:
for (var i=0; i<categories.length; i++)
{
if (categories[i].checked==true)
{
var y = categories[i].value;
}
}
var val;
if(y)
val = y + ' ' + it;
else
val = it;
var item_list = document.getElementById('item_list');
addItem(item_list,val);
}
And now it works great! Hope that's what you were looking for!
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());
}
);
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-
I have N number of radio button groups in the page with auto generated names.
I want to call a javascript function as the value of the checked property. THIS LINE EXCLUDED AFTER EDIT ( Depending on the return value, the radio button needs to be checked or unchecked.)
<input type="radio" name="auto_generated_name" value="some_value" checked="test_check(args);" />
and the javascript function is
function test_check(params) {
if(conditions){
return true;
}
else
return false;
}
But that does not work. Whatever value I assign to 'checked' property, be it any javascript function or any string etc, the radio button becomes checked.
How can I achieve my goal?
EDIT:
<input type="radio" name="auto_generated_name" value="somevalue" onclick="test_check(args)"/>
4 radio buttons make a group. such N radio groups have html class names in this way : button_group_1, button_group_2, button_group_3, button_group_4 etc.
The 'args' need to be these class (i.e. radio button group) names and the corresponding values (from value="1", value="2", value="3" and value="4" ).
Cookies with the class names and values will be created inside the javascript function.
On page refresh, cookies matching with the class names will be checked and depending on the existence of the corresponding cookies, the radio button will be checked or unchecked.
How to achieve the goals/
Assuming you are using jQuery, use the change event: http://api.jquery.com/change/
The checked attribute is simply a boolean value to indicate whether the radio button should be checked, it cannot contain script, or a reference to a scripting function. Any value in the attribute will cause the radio button to be checked.
Without knowing what mechanism you are using to check each radio button - I can see an args variable but don't know what type this is - it's going to be tricky to write some code for you.
If you can make args into an array of values, then something along the lines of the following should work for you:
var args = new Array(true,false,true)
$.each(args, function(index, value) {
$("INPUT[type=radio]").eq(index).attr("checked", value)
});
Here's a fiddle to show what I mean more clearly
check this output, valid args is 'aa'.
http://jsfiddle.net/X7rcC/1
html:
<input type="radio" name="auto_generated_name" value="some_value1" checked="bb" />
js:
$(function() {
var radios = $("input[type='radio']");
$.each(radios, function(index, value){
var args = value.attributes[1].nodeValue;
test_check(args, value);
})
});
function test_check(params, value){
if(params == "aa"){
$(value).attr("checked",true);
}else
$(value).attr("checked",false);
}
try this:
Here I user a custom attribute to input named groupname. In OP's case groupname="<?php echo $radio_button_group_name; ?>". Then checking the value of this attribute OP can assign checked attribute value.
<input type="radio" name="r1" groupname="gr1"/>
<input type="radio" name="r2" groupname="gr2"/>
$('input:radio').each(function() {
if ($(this).attr('groupname') == 'gr1') {
$(this).attr('checked', true);
} else {
$(this).attr('checked', false);
}
});
Your question really boils down to:
How can I set the value of a checkbox when the page first loads? (Using a parameter stored with the checkbox)
The key insights are:
you can't store a function inside a parameter and expect it to automatically evaluate on load
you can store the data about an object inside data- properties
you can set the value of objects on page load in jQuery using the $(document).ready() event
.
<script type="text/javascript">
$(document).ready( function() { // this code runs when the page is first loaded
var radios = $("input[type='radio']"); // find all of your radio buttons
$.each(radios, function(){
var radio = $(this);
var param = radio.attr('data-param'); // retrieve the param from the object
radio.attr('checked', test_check(param) ); // set the value of the radio button
})
});
function test_check(params) {
if(conditions){
return 'checked';
}
else
return '';
}
</script>
You cannot use a checked attribute this way, because anything as the value will be the same as checked=true Even just checked checks a radio button. What you should do is use a custom attribute which will create the checked attribute:
<input type="radio" name="auto_generated_name" value="some_value" needs_check="param">
<script>
// Do test_check on param for each input
$('input:radio').each(function()
{
var radio = $(this);
var param = radio.attr('needs_check');
var condition = test_check(param);
radio.attr('checked', condition);
});
function test_check(param)
{
return true or false based on param
}
</script>
I was facing same problem and my conclusion is that don't use " " to contain a function.
Correct:
<input type="radio" name="im" id="b1" onclick=alert("hello"); />
Incorrect:
<input type="radio" name="im" id="b1" onclick="alert("hello");" />