How to create objects from multiple selectors in jquery? - javascript

I have two elements(#list1, #list2 in html). I need to create object and populate it from these two elements.
For example:
$('#list1, #list2').each(function(index,value){
var object =[ {#list1.value, #list2.value} ];
})
Something like that. So it can add these elements to array with each iteration. How it can be done?

it is .val()
you can push OR you can map
You can use a class so you do not need to list
NOTE: If there is no value attribute on the field, using this.getAttribute("value") on the .get examples will result in any field without value attribute to be omitted from the array instead of adding an empty value (Thanks #adz5A)
http://jsfiddle.net/mplungjan/jLsa80m9/7/
var object1 = [];
$('#list1, #list2').each(function() {
object1.push($(this).val())
})
console.log(object1);
// Smarter:
var object2 = $('#list1, #list2')
.map(function(index,$list) {
return $list.value; // or this.value or $(this).val();
})
.get();
console.log(object2);
// EVEN Smarter:
var object3 = $('.list')
.map(function() {
return this.value;
})
.get();
console.log(object3);
// The two following versions were posted by #rmn - I include them here for
// completeness sake. Upvote his answer if you like them
// ES6 with jQuery
var object4 = $('#list1, #list2').get().map(el => el.value)
console.log(object4);
// ES6 without jQuery
var object5 = [...document.querySelectorAll('#list1, #list2')].map(el => el.value)
console.log(object5);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" value="value1" id="list1" class="list" />
<input type="text" value="value2" id="list2" class="list" />

I think you are looking for .get(). It returns as an array the set of matched DOM elements. You can easily combined this with map to retrieve the value of some attribute for instance
$("selector").map(function () { return this.getAttribute("value"); }).get();
Will get you the value attribute for the selection into an array. Note that you can use arrow function inside map as the second argument is the dom node itself, in my example the dom element is bounded to the lexical context this.

With jQuery
$('#list1, #list2').get().map(el => el.value)
Without jQuery
[...document.querySelectorAll('#list1, #list2')].map(el => el.value)

you can create array outside the loop and push it on each iteration
var object =[];
$('#list1, #list2').each(function(){
object.push($(this).val());
});

If you want to have id in your object, this is better:
function getList(){
var list = []
$("#input1, #input2").each(function(){
list.push({id: this.id, value: this.value });
});
console.log(list);
/*
OUTPUT:
[
{
"id": "input1",
"value": "v1"
},
{
"id": "input2",
"value": "v2"
}
] */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="input1" type="text" value="v1" />
<input id="input2" type="text" value="v2" />
<input type="button" onclick="getList()" value="get list" />

Related

how to remember inputs value by using local storage?

I have tried to use local storage to remember the input's value after refreshing page. but my code does not work.
here is the HTML code
<input type="text" name="name" onkeyup="saveValue(event)"/>
<input type="text" name="name" onkeyup="saveValue(event)"/>
<input type="text" name="age" onkeyup="saveValue(event)"/>
and here is javascript
<script type="text/javascript">
var nameArr = ["name"];
var inputs = document.getElementsByName('name');
inputs.forEach(function(el){
el.value = getSavedValue(el);
})
function saveValue(e) {
var name = e.target.name;
var val = e.target.value;
localStorage.setItem(name, val);
}
function getSavedValue(v) {
if (!localStorage.getItem(v)) {
return "";
}
return localStorage.getItem(v);
}
</script>
if there is a way to solve this problem please tell me.
and if there is a way to do that with jquery I will be thankful to tell me that.
Here are couple of things. First instead of onkeyup use onblur so value will be saved in storage only when the focus is removed from the element.
Secondly use a common class inputs in this case and give separate name to each element.
Then get all the elements with same class, iterate through it and get value of name property using getAttribute. Use this value to check if there exist a key in localStorage
var nameArr = ["name"];
var inputs = [...document.getElementsByClassName('inputs')];
inputs.forEach(function(el) {
console.log()
el.value = getSavedValue(el.getAttribute('name'));
})
function saveValue(e) {
var name = e.target.name;
var val = e.target.value;
localStorage.setItem(name, val);
}
function getSavedValue(v) {
if (!localStorage.getItem(v)) {
return "";
}
return localStorage.getItem(v);
}
<input type="text" class='inputs' name="firstName" onblur="saveValue(event)" />
<input type="text" class='inputs' name="lastName" onblur="saveValue(event)" />
<input type="text" class='inputs' name="age" onblur="saveValue(event)" />
On your code you are passing the input object as a parameter instead of its name (or value; you choose). As localStorage only stores String key-value pairs, it won't work as you're trying to find a key that is an object.
in the forEach instead of:
el.value = getSavedValue(el);
set:
el.value = getSavedValue(el.name);
or let the "getSavedValue" function accept an object as parameter, but to access localStorage you must pass a string as the key.

Find duplicate values in form elements by class using javascript

I am trying to use javascript to find duplicate values in form elements (input boxes and select drop downs) based on class. This is what I have, but it is not working. Is there a better way to do this? I am new to javascript and saw this as a solution on a different post.
EDIT: Only the inner functions are not called. If I break them out, they get called. Why is this?
<%# taglib prefix="s" uri="/struts-tags"%>
<s:include value="Header.jsp">
<s:param name="pageScript">
<script type="text/javascript">
function checkForDuplicates() {
var hasDuplicates = false;
$('.class_name').each(function () {
var inputsWithSameValue = $(this).val();
hasDuplicates = $('.class_name').not(this).filter(function () {
return $(this).val() === inputsWithSameValue;
}).length > 0;
if (hasDuplicates){
alert("cannot have duplicates")
}
});
}
</script>
</s:param>
</s:include>
<div id="container-content">
<div id="content">
<s:form action="someAction" theme="simple" method="get" id="theForm">
<s:textfield theme="simple" class="class_name"/>
<s:textfield theme="simple" class="class_name" />
<s:select headerKey="" headerValue="Select Value"
list="values" listKey="value" class="class_name" size="1"/>
<s:submit action="" value="Save" onclick="return checkForDuplicates()"/>
</s:form>
<%-- end content --%>
</div>
<%-- end container-content --%>
</div>
<s:include value="Footer.jsp" />
I am importing these:
<script src="scripts/jquery-1.4-min.js"></script>
<script src="scripts/jquery.maskedinput.min.js" type="text/javascript"></script>
<script src="scripts/jquery.supertextarea.min.js" type="text/javascript"></script>
What is the problem? I put a breakpoint inside the first innerfunction after the .each, but it never goes in there.
Thanks
This is based on ROX's answer, however, i think we can check if the next element's input is inside the array without the need of a second function.
function checkDuplicates() {
// get all input elements
var $elems = $('.class_name');
// we store the inputs value inside this array
var values = [];
// return this
var isDuplicated = false;
// loop through elements
$elems.each(function () {
//If value is empty then move to the next iteration.
if(!this.value) return true;
//If the stored array has this value, break from the each method
if(values.indexOf(this.value) !== -1) {
isDuplicated = true;
return false;
}
// store the value
values.push(this.value);
});
return isDuplicated;
}
You might want to check if the input is empty somewhere in your code but that's up to you.
Edit : https://jsfiddle.net/65ss1cxj/
Your could make your function much better, there is no need to loop all over your elements inside your first loop.
Just store your all inputs values into an array, then make that array unique values, and compare the length of them.
// a function to make an array values unique
// http://stackoverflow.com/a/840849/3971911
function eliminateDuplicates(arr) {
var i,
len=arr.length,
out=[],
obj={};
for (i=0;i<len;i++) {
obj[arr[i]]=0;
}
for (i in obj) {
out.push(i);
}
return out;
}
function checkDuplicates() {
// get all input elements
var $elems = $('.class_name');
// we store the inputs value inside this array
var values = [];
// loop through elements
$elems.each(function () {
// if the value is empty, just pass it
if (this.value == '') {
return true;
}
// store the value
values.push(this.value);
});
// make the values array unique
var uniqueValues = eliminateDuplicates(values);
// return false if the unique array length is not equal to the original array
return uniqueValues.length == values.length;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<div><input type="text" class="class_name" /></div>
<div><input type="text" class="class_name" /></div>
<div><input type="text" class="class_name" /></div>
<div><input type="text" class="class_name" /></div>
<input type="submit" value="Go" onclick="return checkDuplicates()" />
</form>

I need an array of selected checkboxes

Javascript Code:
var simvalue = $('input[name="simnamecbx"]:checked').each(function() {
var sim_name=this.value.split(" ")[0];
console.log("simname:",sim_name);
var sim_list = [{
simulation_name : sim_name,
}];
console.log(sim_list);
});
I need an array of selected checkboxes in sim_list.. currently the array of values are replaced with the same index ie Array[1].. I need values like 1,2,3,4 in 'var simvalue'
Your are not pushing data to array instead you are re initiating array
try like this
var sim_list=[];
var simvalue = $('input[name="simnamecbx"]:checked').each(function() {
var sim_name=this.value.split(" ")[0];
console.log("simname:",sim_name);
sim_list.push({
simulation_name : sim_name,
});
});
console.log(sim_list);
You are reassigning the array instead of adding to it here
var sim_list = [{
simulation_name : sim_name,
}];
Also there should not be any , when setting only one property to an object or on the last property. You can use push to add to an array.
sim_list.push({simulation_name : sim_name});
with sim_list delcared as an empty array BEFORE the loop.
var sim_list = [];
$('input[name="simnamecbx"]:checked').each(function() {
var sim_name = this.value.split(" ")[0];
sim_list.push({
simulation_name : sim_name // comma removed to avoid errors
});
});
See push documentation
As others said, you are reassigning the array in each loop so all of the previous values are lost.
The map function can get all the values you want and put them into an array:
$(function() {
// Call map on your selector
var result = $('input[name="simnamecbx"]:checked').map(function() {
// return the values you want in the array
return { simulation_name: this.value.split(' ')[0] };
}).get(); // get returns the result as an array
// Output result
$.each(result, function(i, val) {
$('#result').append("Simulation name: " + val.simulation_name + "<br />");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" name="simnamecbx" value="test1 1" checked="checked" /> 1 <br />
<input type="checkbox" name="simnamecbx" value="test2 2" /> 2 <br />
<input type="checkbox" name="simnamecbx" value="test3 3" /> 3 <br />
<input type="checkbox" name="simnamecbx" value="test4 4" checked="checked" /> 4 <br />
<input type="checkbox" name="simnamecbx" value="test5 5" /> 5 <br />
<div id="result"></div>

Tricky Javascript logic with Objects, Array and Booleans

I am having a lot of issue trying to figure out this logic. Let me set the stage here:
In the HTML there are some form/input elements type radio. Each of them have an ID assigned to it.
<form>
<input type="radio" name="oneAllowed" id="yesterday" />
<input type="radio" name="oneAllowed" id="today" />
<input type="radio" name="oneAllowed" id="tomorrow" />
</form>
Using Javascript essentially what I am trying to do is loop through the 3 objects, since they all have same name assigned within HTML only a single one can be selected, whichever one is returning true I want grab hold of that result then access the second key:value pair, for example for 'commitYesterday' it would be 'commitYesterday.hasValue();' and dispatch that to a different function for other calculation.
var urgentOrderSelector = function(){
var commitYesterday = {
isChecked: document.getElementById("yesterday").checked,
hasValue: function(){
if (this.isChecked == true) {
return 3;
};
};
};
var commitToday = {
isChecked: document.getElementById("today").checked,
hasValue: function(){
if (this.isChecked == true) {
return 2;
};
};
};
var commitTomorrow = {
isChecked: document.getElementById("tomorrow").checked,
hasValue: function(){
if (this.isChecked == true) {
return 1;
};
};
};
var urgentArray = [commitYesterday.isChecked, commitToday.isChecked, commitTomorrow.isChecked];
for(var i = 0; i <= urgentArray.length-1; i++){
if (urgentArray[i].isChecked == true) {
//This is where I am stuck. I was thinking of doing perhaps the following:
return urgentArray[i].hasValue();
};
}
};
Why don't you change your HTML to this:
<form>
<input type="radio" name="oneAllowed" id="yesterday" value="3" />
<input type="radio" name="oneAllowed" id="today" value="2" />
<input type="radio" name="oneAllowed" id="tomorrow" value="1" />
</form>
And use document.querySelector to get the selected elements:
document.querySelector('[type="radio"][name="oneAllowed"]:checked').value
If you actually need to run specific functions dependend on which radio box is checked you could add an attribute data-fn="fnName" to each input and then create an object with the keys as functions:
var fns = {'fnName1': function () {}, 'fnName2': function() {} …};
And then call the function defined by the Attribute:
fns[document.querySelector('[type="radio"][name="oneAllowed"]:checked').getAttribute('data-fn')]();
Not exactly sure what your end goal is.
But here's a more minified version of your logic. Hope it helps.
var urgentOrderSelector = function(){
var radioDict = {'yesterday':3, 'today':2, 'tomorrow':1};
return radioDict[$('input[name=oneAllowed]:checked').attr('id')];
};
Alternatively, if you wanted to execute some function based on the selection, you could store the function pointers and execute them accordingly, ie:
var funcYesterday = function(){alert('yesterday');};
var funcToday = function(){alert('today');};
var funcTomorrow = function(){alert('tomorrow');};
var funcUrgentOrder = function(){
var radioDict = {
'yesterday' : funcYesterday,
'today' : funcToday,
'tomorrow' : funcTomorrow
};
return radioDict[$('input[name=oneAllowed]:checked').attr('id')]();
};
Or, much simpler, since you are using the 'value' property on your radios:
function urgentOrderSelector = function() {
return $('input[name=oneAllowed]:checked').val();
};

Getting DOM element value using pure JavaScript

Is there any difference between these solutions?
Solution 1:
function doSomething(id, value) {
console.log(value);
//...
}
<input id="theId" value="test" onclick="doSomething(this.id, this.value)" />
...and Solution 2:
function doSomething(id) {
var value = document.getElementById(id).value;
console.log(value);
//...
}
<input id="theId" value="test" onclick="doSomething(this.id)" />
Update: The question was edited. Both of the solutions are now equivalent.
Original answer
Yes, most notably! I don't think the second one will work (and if it does, not very portably). The first one should be OK.
// HTML:
<input id="theId" value="test" onclick="doSomething(this)" />
// JavaScript:
function(elem){
var value = elem.value;
var id = elem.id;
...
}
This should also work.
The second function should have:
var value = document.getElementById(id).value;
Then they are basically the same function.
In the second version, you're passing the String returned from this.id. Not the element itself.
So id.value won't give you what you want.
You would need to pass the element with this.
doSomething(this)
then:
function(el){
var value = el.value;
...
}
Note: In some browsers, the second one would work if you did:
window[id].value
because element IDs are a global property, but this is not safe.
It makes the most sense to just pass the element with this instead of fetching it again with its ID.
Pass the object:
doSomething(this)
You can get all data from object:
function(obj){
var value = obj.value;
var id = obj.id;
}
Or pass the id only:
doSomething(this.id)
Get the object and after that value:
function(id){
var value = document.getElementById(id).value;
}
There is no difference if we look on effect - value will be the same. However there is something more...
Solution 3:
function doSomething() {
console.log( theId.value );
}
<input id="theId" value="test" onclick="doSomething()" />
if DOM element has id then you can use it in js directly
This should also work.
function doSomething() {
yourElement = document.getElementById("yourID);
yourValue = yourElement.value; console.log(yourValue);
console.log(yourValue);
}
<div id="yourID" value="1" onclick="doSomething()">
</div>
function doSomething() {
console.log( theId.value );
}
<input id="theId" value="test" onclick="doSomething()" />

Categories

Resources