I have an element in my page:
<form>
<div data-id="x">
<label>field 1</label>
<input name="field1" type="text" value="Foo" />
<label>field 2</label>
<input name="field2" type="number" value="5" />
</div>
<div data-id="y">
<label>field 1</label>
<input name="field1" type="text" value="Foo" />
<label>field 2</label>
<input name="field2" type="number" value="5" />
</div>
...other 100 inputs...
</form>
I'm looking for a javascript script like that:
var theElement = document.querySelector('[data-id="x"]');
var myObject = theElement.toObject();
And the object must looks like
{"field1":"Foo","field2":5}
I can't use the FormData strategy because I need a very small set of data from a very big form, but it is like a "partial FormData".
I'm asking if exists a standard method to convert the content of an HTMLElement in an object like for the FormData.
PS: i can use also the data-attribute if necessary
Actually there is no standard quicky method to do this task.
The solution is iterate over inputs and selects:
<script>
let myObj = {};
let element = document.querySelector('[data-id="x"]');
element.querySelectorAll('input').forEach(el=> {
// check the type
// the property is : el.name
// the value must be : el.value for text/number/email...
// the value for the type="checkbox" is according to checked attribute
});
element.querySelectorAll('select').forEach(sel=> {
// if multiple choise => create an array of selected options
// if single => check the selected option's value
});
</script>
This is the code i've used (simplified)
Related
I want to store the correct answer(option) and the other 3 options as well. But for the other 3 options I will store those in database saying is_correct(column) 0/no/False. But for that, I'll have to have such logic that will figure out which radio button is for which input field. How do I bind/map a radio input field to a text input field?
I can, extract values out of these elements but can't figure out the logic.
<div id="option" class="form-group">
<input type="radio" name="option" required/><input type="text" name="option_1" required/><br/><br/>
<input type="radio" name="option" required/><input type="text" name="option_2" required/><br/><br/>
<input type="radio" name="option" required/><input type="text" name="option_3" required/><br/><br/>
<input type="radio" name="option" required/><input type="text" name="option_4" required/>
</div>
I just can't figure out the next step! Seen similar types of posts but not so similar tbh despite the concept being same.
First off, I really don't understand why you use radio buttons and a input text. In my opinion, just switch the input text to labels, or if you want the user to type the answer just give him 1 input text.
That being said, keeping the design you've made:
HTML:
<div id="options" class="form-group">
<input type="radio" id="option_text" required/><input type="text" id="option_1" required/><br/><br/>
<input type="radio" id="option_text2" required/><input type="text" id="option_2" required/><br/><br/>
<input type="radio" id="option_text3" required/><input type="text" id="option_3" required/><br/><br/>
<input type="radio" id="option_text4" required/><input type="text" id="option_4" required/>
<button type="submit" id="sub">
Press me
</button>
</div>
<div id="output1">
</div>
<div id="output2">
</div>
<div id="output3">
</div>
<div id="output4">
</div>
Javascript:
$("#sub").on('click',function(){
let eachone=[];
eachone[0]=$("#option_1").val();
eachone[1]=$("#option_2").val();
eachone[2]=$("#option_3").val();
eachone[3]=$("#option_4").val();
$("#output1").html(eachone[0]+" - "+$("#option_text").prop("checked"))
$("#output2").html(eachone[1]+" - "+$("#option_text2").prop("checked"))
$("#output3").html(eachone[2]+" - "+$("#option_text3").prop("checked"))
$("#output4").html(eachone[3]+" - "+$("#option_text4").prop("checked"))
})
If you want to alter something, or test for your exact test case, here is the fiddle
Jfiddle.
Note I'm using jQuery, just for ease of code, you can change most of the jquery references to document.getElementById
Edit:
Updated fiddle with checkboxes: JFiddle
Edit2:
Updated fiddle with single option checkboxes:
Jfiddle2
Warning: the event created might break some other input type checkboxes you have in your code!
First I think you should use the value attribute of the radioButtons instead of the second input, just put the text in a span or a label :
<input type="radio" id="option1" name="option" value="option1">
<label for="option1">8</label>
then you can get the selected value by doing:
var selectedOption = null;
if (document.getElementById('option1').checked) {
selectedOption = document.getElementById('option1').value;
}
After that, you can query the db to see if the selected option is correct or not.
How about instead of submitting the form with form data, you submit a JSON string/object?
So, your object for question can be something like
{
"question" : "How many planets orbit around the sun?",
"options" : [{
"name" : "1",
"value" : "7",
"isAnswer" : false
}, {
"name" : "2",
"value" : "8",
"isAnswer" : true
}]
}
Now, what's left is to create this object when the submit button is clicked.
To do that, you can have ids such as
<input type="radio" id="radio-1" name="option" required/>
<input type="text" id="text-1" required/>
These elements can be created dynamically, or manually if you are making the page just for a single question.
Now, when the button to submit the form, is clicked, you can run the below code which constructs a JSON object.
let question = {};
question.question = $("#question").val(); //Assuming you are using jQuery and id for question input box is question.
question.options = [];
for(i=0; i<4; i++) {
let option = {};
option.name = (i+1); //convert to ascii if you want alphabets
option.value = $("#text-"+(i+1)).val();
option.isAnswer = $("#radio-"+(i+1)).checked;
question.options.push(option);
}
You can now send this question object to your server.
I just want to get all different values using javascript with the same id.
Here is my input code:
<input type="text" id="full" name="full" value="2018-12-06">
<input type="text" id="full" name="full" value="2018-12-14">
<input type="text" id="full" name="full" value="2018-12-18">
When I alert the id of the inputs it show's the 2018-12-06 only. I want to disable the jquery datepicker but the 2018-12-06 is the only one read.
Here is my calendar.
and my javascript code:
var x = (document.getElementById('full').value);
var array = ["2018-12-25", "2019-01-01", x]
I want to disable all value with same id like the mention above,
IDs must be unique. You should add a class to each element and then use getElementsByClassName.
Because the method returns a nodelist to get each input value you need to iterate over it. For both these examples I've used map, but you might find a for/loop or forEach easier to use.
const full = document.getElementsByClassName('full');
const arr = [...full].map(input => input.value);
console.log(arr);
<input type="text" class="full" value="2018-12-06">
<input type="text" class="full" value="2018-12-14">
<input type="text" class="full" value="2018-12-18">
An alternative might be to use querySelectorAll. This uses CSS selectors so you can pinpoint elements by their attributes instead:
const full = document.querySelectorAll('[name="full"]');
const arr = [...full].map(input => input.value);
console.log(arr);
<input type="text" name="full" value="2018-12-06">
<input type="text" name="full" value="2018-12-14">
<input type="text" name="full" value="2018-12-18">
ID is used as an individual identifier. So it is illegal to use same Id for multiple elements. To get values of multiple elements use class instead of id.
You can use getElementsByClassName() function to read values of all elements with same class name
Alternative to getElementsByClassName() using jQuery
var l = $('.full').length;
//Initialize default array
var result = [];
for (i = 0; i < l; i++) {
//Push each element to the array
result.push($('.full').eq(i).val());
}
//print the array or use it for your further logic
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" class="full" value="2018-12-06">
<input type="text" class="full" value="2018-12-14">
<input type="text" class="full" value="2018-12-18">
You can't create an element with the same Id, If you want to get all different values from another element using javascript you can use ClassName
<input type="text" class="full" name="full" value="2018-12-06">
<input type="text" class="full" name="full" value="2018-12-14">
<input type="text" class="full" name="full" value="2018-12-18">
var x = document.getElementsByClassName('full');
I have a form with many text-input-fields and checkboxes. Whenever a checkbox is checked, all text-input fields and all other checkboxes (exept the one that was checked) should be disabled. After unchecking this checkbox, all disabled fields should be enabled again.
This works with the following code (shown are only the first 3 lines):
<form id="myForm">
Checkbox 1: <input type="checkbox" name="checkbox1" id="checkboxOne" onclick="enableDisableAll();" />
<input type="text" id="id1" name="name1" /><br>
Checkbox 2: <input type="checkbox" name="checkbox2" id="checkboxTwo" onclick="enableDisableAll();" />
<input type="text" id="id2" name="name2" /><br>
Checkbox 3: <input type="checkbox" name="checkbox3" id="checkboxThree" onclick="enableDisableAll();" />
<input type="text" id="id3" name="name3" /><br>
</form>
function enableDisableAll() {
cb1 = document.getElementById('checkboxOne').checked;
cb2 = document.getElementById('checkboxTwo').checked;
cb3 = document.getElementById('checkboxThree').checked;
document.getElementById('checkboxOne').disabled = (cb2 || cb3);
document.getElementById('id1').disabled = (cb1 || cb2 || cb3);
document.getElementById('checkboxTwo').disabled = (cb1 || cb3);
document.getElementById('id2').disabled = (cb1 || cb2 || cb3);
document.getElementById('checkboxThree').disabled = (cb1 || cb2);
document.getElementById('id3').disabled = (cb1 || cb2 || cb3);
}
Since the code becomes confusing with many checkboxes (cb1 || cb2 || cb3 || ....... cb(n)), I wonder if there would be a more elegant possibility to do this, e.g.:
function enableDisableAll() {
cb1 = document.getElementById('checkboxOne').checked;
cb2 = document.getElementById('checkboxTwo').checked;
cb3 = document.getElementById('checkboxThree').checked;
var cb_array = [];
cb_array.push("cb1");
cb_array.push("cb2");
var cb_array_imploded = cb_array.join(" || ");
document.getElementById('id1').disabled = (cb_array_imploded);
Unfortunately, this does not work.
Does anyone have a simple solution for my problem?
select all the form elements and loop through and check for id same as clicked element id.if so don't disabled it.
function enableDisableAll(e) {
var own = e;
var form = document.getElementById("myForm");
var elements = form.elements;
for (var i = 0 ; i < elements.length ; i++) {
if(own !== elements[i] ){
if(own.checked == true){
elements[i].disabled = true;
}else{
elements[i].disabled = false;
}
}
}
}
function clearAll(){
document.getElementById("myForm").reset();
}
<form id="myForm">
Checkbox 1: <input type="checkbox" name="checkbox1" id="checkboxOne" onclick="enableDisableAll(this);" />
<input type="text" id="id1" name="name1" /><br>
Checkbox 2: <input type="checkbox" name="checkbox2" id="checkboxTwo" onclick="enableDisableAll(this);" />
<input type="text" id="id2" name="name2" /><br>
Checkbox 3: <input type="checkbox" name="checkbox3" id="checkboxThree" onclick="enableDisableAll(this);" />
<input type="text" id="id3" name="name3" /><br>
</form>
<input class="field button2" type="button" value="Clear form" size="10" onclick="clearAll(this);">
Update : To clear all the form fields
document.getElementById("myForm").reset();
One possible approach is the following; though note that I amended your HTML, wrapping the <input type="checkbox"> elements in a parent <label> element, and removing the unnecessary <br /> elements along with the obtrusive in-line event-handlers in the HTML:
// a named function bound to an element via
// via JavaScript; the 'event' argument
// is passed automatically from the
// EventTarget.addEventListener() method:
function disableIfChecked(event) {
// the event.target node is the node upon which
// the listened-for event was originally triggered:
let target = event.target;
// 'this' is also passed from the
// EventTarget.addEventListener() method; here
// retrieved all <input> elements within the
// <form> (the 'this'), convert that NodeList
// explicitly to an Array and then filter that
// Array using an Arrow function:
Array.from(this.querySelectorAll('input')).filter(
// we retain only those elements ('el') in the Array
// which are not equal to, and therefore are not, the
// changed element:
el => el !== target
// iterating over the filtered collection:
).forEach(
// each <input> element remaining in the collection
// will be disabled if the changed element is clicked,
// or enabled if the changed element is no longer clicked:
el => el.disabled = target.checked
);
}
document.querySelector('#myForm').addEventListener('change', disableIfChecked);
/* Selecting the <label> element that follows
an <input> element: */
input+label::before {
/* Adding a line-feed character using the CSS
'content' property of the pseudo-element
to force each <label> to a new-line: */
content: '\A';
display: block;
}
<form id="myForm">
<!-- the label element associates the text with the enclosed
input, so clicking the text focuses that input element: -->
<label>Checkbox 1: <input type="checkbox" name="checkbox1" id="checkboxOne" /></label>
<input type="text" id="id1" name="name1" />
<label>Checkbox 2: <input type="checkbox" name="checkbox2" id="checkboxTwo" /></label>
<input type="text" id="id2" name="name3" />
<label>Checkbox 3: <input type="checkbox" name="checkbox3" id="checkboxThree" /></label>
<input type="text" id="id3" name="name3" />
</form>
JS Fiddles: commented, uncommented
In order to support browsers without support for ES6, the following is an alternative approach doing the same thing:
// a named function bound to an element via
// via JavaScript; the 'event' argument
// is passed automatically from the
// EventTarget.addEventListener() method:
function disableIfChecked(event) {
// the event.target node is the node upon which
// the listened-for event was originally triggered:
let target = event.target;
// 'this' is also passed from the
// EventTarget.addEventListener() method; here
// retrieved all <input> elements within the
// <form> (the 'this'), convert that NodeList
// explicitly to an Array by treating the NodeList
// as an Array, using Function.prototype.call(),
// and Array.prototype.slice():
Array.prototype.slice.call(
this.querySelectorAll('input')
).filter(function(el) {
// we retain only those elements ('el') in the Array
// which are not equal to, and therefore are not, the
// changed element:
return el !== target;
// iterating over the filtered collection:
}).forEach(function(el) {
// each <input> element remaining in the collection
// will be disabled if the changed element is clicked,
// or enabled if the changed element is no longer clicked:
el.disabled = target.checked;
});
}
document.querySelector('#myForm').addEventListener('change', disableIfChecked);
/* Selecting the <label> element that follows
an <input> element: */
input+label::before {
/* Adding a line-feed character using the CSS
'content' property of the pseudo-element
to force each <label> to a new-line: */
content: '\A';
display: block;
}
<form id="myForm">
<!-- the label element associates the text with the enclosed
input, so clicking the text focuses that input element: -->
<label>Checkbox 1: <input type="checkbox" name="checkbox1" id="checkboxOne" /></label>
<input type="text" id="id1" name="name1" />
<label>Checkbox 2: <input type="checkbox" name="checkbox2" id="checkboxTwo" /></label>
<input type="text" id="id2" name="name3" />
<label>Checkbox 3: <input type="checkbox" name="checkbox3" id="checkboxThree" /></label>
<input type="text" id="id3" name="name3" />
</form>
JS Fiddles.
References:
Array.from().
Array.prototype.filter().
Array.prototype.forEach().
Document.querySelectorAll().
Element.querySelectorAll().
JavaScript Arrow Functions.
It's usually best to use onchange instead of onclick event on inputs such as checkboxes, radiobuttons, or selects.
In order to make a general solution for as many inputs as you need, it's best to use document.querySelectorAll to fetch all inputs within the form. You can then iterate over all inputs and set their disabled property to the checked value of the targeted checkbox.
Solution snippet below:
function enableDisableAll(event) {
var allInputs = document.querySelectorAll('#myForm input');
allInputs.forEach(function(input) {
if (input !== event.target) {
input.disabled = event.target.checked;
}
});
}
<form id="myForm">
Checkbox 1: <input type="checkbox" name="checkbox1" id="checkboxOne" onchange="enableDisableAll(event);" />
<input type="text" id="id1" name="name1" /><br> Checkbox 2: <input type="checkbox" name="checkbox2" id="checkboxTwo" onchange="enableDisableAll(event);" />
<input type="text" id="id2" name="name2" /><br> Checkbox 3: <input type="checkbox" name="checkbox3" id="checkboxThree" onchange="enableDisableAll(event);" />
<input type="text" id="id3" name="name3" /><br>
</form>
An important detail here is that if you want to assign a typical event handler function directly to an HTML attribute, the function must have a single parameter explicitly named event. It is however recommended to assign event handlers in javascript and not in HTML. The syntax for that would be myCheckbox.addEventListener('change', enableDisableAll);
You may want to add listeners to every checkbox, by iterating over a selector of all checkboxes.
I have array element in HTML
<input type="checkbox" value="Value1" name="model[settings][]">
<input type="checkbox" value="Value2" name="model[settings][]">
<input type="checkbox" value="Value3" name="model[settings][]">
I am reading all the HTML input, iterating it and building a hash in the javascript. But this will read the array element and only pick the last model[settings][] element.
var inputs = jQuery(" :input", "#elementID");
Is there a way in jQuery or JavaScript to read and build an array variable in javascript which then can be passed to controller ?
Thank You
If I understand you correctly, you are trying to iterate through all your input elements to get their value and store that as a JS object, correct?
If that's the case, I would add a unique ID to all my inputs, and then create an object with the structure { id : value }:
function getInputObject(sel) {
sel = $(sel);
var out = {};
sel.each(function() {
out[$(this).attr("id")] = $(this).val();
});
return out;
}
$(document).ready(function() {
console.log( getInputObject("input") );
});
input {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="input1" value="value input 1" type="text" />
<input id="input2" value="value input 2" type="text" />
<input id="input3" value="value input 3" type="text" />
I have a website where there are five checkboxes, a div that contains another divs which each div contains five input hidden that have a value 1 or empty. That value comes from DB.
That's an example to represent the div container with the divs:
<input checkbox value="a">
<input checkbox value="b">
<input checkbox value="c">
<input checkbox value="d">
<input checkbox value="e">
<div class="container">
<div class="content" data-name="combine">
<input type="hidden" value="" data-name="a" />
<input type="hidden" value="" data-name="b" />
<input type="hidden" value="" data-name="c" />
<input type="hidden" value="" data-name="d" />
<input type="hidden" value="" data-name="e" />
</div>
<div class="content" data-name="combine">
<input type="hidden" value="1" data-name="a" />
<input type="hidden" value="" data-name="b" />
<input type="hidden" value="" data-name="c" />
<input type="hidden" value="1" data-name="d" />
<input type="hidden" value="" data-name="e" />
</div>
</div>
In the javascript code i have this snippet:
if(elementLength > 0) {
$("[data-name='combine'] div.tagsProds").each(function() {
var element = $(this);
$.each(enabledChecks,function(i, v) {
if(element.find("input[name='"+v+"']").val() == "") {
element.append("<div class='blocked'></div>");
element.unbind("click");
element.addClass("js_noSortable");
}
});
});
}
The javascript first checks if the div.container has childs and if it has childs the code iterates each child. On each child i iterate the five each checkbox (enabledChecks) and i see if the input hidden are empty. What i need if that if the five input are empty then append the `div.blocked'.
As i don't have enough reputation to write a comment i write an answer.
First, i think that your answer is quite interesting if you're looking to find a way using a jQuery function, but as i don't know any function to do this i think that you can create an array() and when you check if the input has empty value push it to the array, when the loop finishes you check the length of the array() and if it matches with the number of your checkboxes then append the .blocked
If I understand the question correctly, you want to find divs matching some selector that have no child input elements with non-empty values. The .filter method seems like a good fit here:
$("[data-name='"+name+"'] div.tagsProds")
.filter(function() {
// assert that at least one child input has a value
var $inputsWithValue = $(this).find("input[name='avail_" + v + "'][value!='']");
return $inputsWithValue.length === 0;
})
.each(function() {
// now act on those value-less divs
$(this)
.append("<div class='blocked'></div>")
.addClass("js_noSortable")
.unbind("click");
});
Another selector-only option might look like:
$("[data-name='"+name+"'] div.tagsProds:not(:has(input[name='avail_" + v + "'][value!='']))")
.each(function() {
// now act on those value-less divs
$(this)
.append("<div class='blocked'></div>")
.addClass("js_noSortable")
.unbind("click");
});
JSFiddle: http://jsfiddle.net/nrabinowitz/vrx2wk8g/
Note that the examples above follow the selectors in your sample code, but won't work against your sample markup.