Looping through a form and populating from an object - javascript

I have a form and a javascript object.
<form id="myForm">
<input type="text" name="title">
<input type="text" name="image">
</form>
var myObject = {title: 'this is the title', image: 'image.jpg'}
Is there a way to run through the form inputs, and it any of the input names match the keys in the object, set the value?
Please note, I wish to run through the form and not the object, as the object has lots of other data in it which is not relevant to the form (not shown in example).

You can do:
$("#myForm input:text[name]").each(function() {
var name = $(this).attr("name");
for (var key in myObject) {
if (key == name) {
$(this).val(myObject[key])
break;
}
}
});

With this you don't ever loop the object, but you'll have to write an if-clause for every attribute:
var myObject = {title: 'this is the title', image: 'image.jpg'}
$('#myForm input').each(function()
{
if($(this).attr('name') === 'title')
{
$(this).val(myObject.title);
}
});

Related

How can I automatically associate a json object key with a multidimensional form field?

I am trying to dynamically populate form fields based on whether or not a json array key exists with the same name.
This is json returned over an ajax call to the server:
{
"title":"My Item Title",
"product_description":{
"1":{
"name":"My Item",
"description":"My Description"
}
},
"image":"main.jpg",
"additional_image":[
{
"image":"img1.jpg",
"sort":1
},
{
"image":"img2.jpg",
"sort":2
}
],
"model":"123",
"quantity":"1"
}
My html form is like this:
<form>
<input type="text" name="title"/>
<input type="text" name="product_description[1][name]"/>
<input type="text" name="product_description[1][description]"/>
<input type="text" name="image"/>
<input type="text" name="additional_image[0][image]"/>
<input type="text" name="additional_image[0][sort]"/>
<input type="text" name="additional_image[1][image]"/>
<input type="text" name="additional_image[1][sort]"/>
<input type="text" name="model"/>
<input type="text" name="quantity"/>
</form>
And my current javascript is like this. There is probably a better way than using "for ...in" as the "key" only returns the parent "product_description" structure and not the underlying object. I try to check for the object, but it is not dynamic.
$.ajax({
url: 'path/to/callback',
type: 'get',
dataType: 'json',
...
success: function(json) {
for (var key in json) {
if (json.hasOwnProperty(key)) {
if (typeof(json[key]) == 'object') {
var obj = json[key];
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
if (typeof(json[key]) == 'object') {
var obj2 = obj[prop];
for (var prop2 in obj2) {
$('input[name="'+key+'['+prop+']['+obj[prop]+'['+prop2+']"]').val(json.key);
}
}
}
}
} else {
$('input[name="'+key+'"]').val(json.key);
}
}
}
}
});
One way to solve this is to use underscore's template function.
This function allows you to inject values from a JSON object into a prepared string.
For your solution you can extract the appropriate value from the JSON by creating a dummy string and using the template function.
Example Plunkr here
The bit that does all the work is:
var fields = $('form input[type="text"]');
$.each(fields, function(idx, item) {
item.value = _.template('<%=' + item.name + '%>')(json);
});
This code takes an input field:
<input type="text" name="json.object.array[0].value"/>
and creates a template string: <%=json.object.array[0].value%>
Then it passes that string to underscore and you get the value :)
(Don't forget to include underscore in your html page)

Take an input value and see if it equals the defined object

HTML:
<html>
<body>
<input type = "text" name = "name" id = "name"> </input>
<button type = "submit" id = "submit">Find Student </button>
<script type = "text/javascript" src="ObjectTest.js"></script>
</body>
</html>
Javascript:
var Matt = {
GPA: 4.0,
Faculty: "Science",
Year: 1
};
I have an object that I've defined with some values.
What I am trying to do is to allow text to be entered into the textbox.
When the submit button is hit, a javascript function will be run that grabs the value in the textbox and if it equals the object value, then it will console.log the properties.
Here is my better attempt:
function findStudent(){
var student = document.getElementById('name').value;
return student;
}
console.log(student);
Hard to know exactly what you're trying to achieve or where your object is coming from but your object probably needs to look something like:
var student = {
name:'Matt',
gpa:4.0,
faculty:'Science',
year: 1
}
Try something like:
function checkName(){
var name = document.getElementById('name').val();
if(name === student.name){
console.log('same');
}
else{
console.log('different');
}
}
Called in your button, with something like:
<button onclick="checkName()">Check Student</button>
You have to think about the structure. There should be a lot of students. It's not practical to set multiple objects for each student:
var st1 = { ... }
var st2 = { ... }
Instead it's more practical to declare one object with all students. And put the values in an array:
var students = {
"Matt": ["4.0", "science", "1.0"],
"Laura": ["3.0", "comedy", "2.2"],
...
}
You can output the array as an info to the corresponding student:
function findStudent() {
var info = [];
var student = document.getElementById("name").value;
for (name in students) {
if (name === student) {
info = students[name];
}
}
alert(info);
}
JSFiddle
If you want to use a submit button, it should be in a form. This also makes dealing with inputs easier, even if you don't want to submit the form. I've modified the object so that it has a name property.
var Matt = {
name: 'Matt',
GPA: 4.0,
Faculty: "Science",
Year: 1
};
function checkValue(form) {
if (form.studentName.value == Matt.name) {
form.output.value = ('Match');
} else {
form.output.value = ('Not a match');
}
return false;
}
<form onsubmit="return checkValue(this);">
<label for="studentName">Name: <input name="studentName" id="studentName"></label>
<button>Check the name</button>
<br>
<label for="output">Output: <input name="output" id="output"></label>
</form>
The body of the checkValue function could be:
form.output.value = form.studentName.value == Matt.name? 'Match' : 'Not a match';
However the longer version is simpler to understand.

How to pass multiple variables from function to multiple jquery attr

This question is related to:
How to pass multiple variables from funtion to jquery attr
So the link above shows multiple solutions on how to pass multiple variables from a regular JavaScript function into multiple jQuery .attr() function values. But the question is, what if you want to send those variables to more than one jQuery functions?
That might sound strange as a statement, that's why I'll include an example.
$(function() {
function definingVars() {
var ValueOne = "Sucess with the value on input 1";
var IdOne = successWithTheId1;
var ClassOne = sucessWithTheClass1;
var ValueTwo = "Sucess with the value on input 2";
var IdTwo = successWithTheId2;
var ClassTwo = sucessWithTheClass2;
return [ValueOne, IdOne, ClassOne, ValueTwo, IdTwo, ClassTwo];
}
$("div:nth-child(1)").attr({
// var df = definingVars(); Incorrect syntax!!!
value: df.ValueOne,
id: df.IdOne,
class: df.ClassOne
})
$("div:nth-child(2)").attr({
// var df = definingVars(); Incorrect syntax!!!
value: df.ValueTwo,
id: df.IdTwo,
class: df.ClassTwo
})
});
input {
width: 20em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<input type="text" id="noSucessWithTheId1" class="noSucessWithTheClass1" value="No sucess with the value on input 1">
<input type="text" id="noSucessWithTheId2" class="noSucessWithTheClass2" value="No sucess with the value on input 2">
</div>
Please don't ask about context. This is a dummy example.
$(function() {
function definingVars() {
var Value = "Sucess with the value";
var Id = successWithTheId;
var Class = sucessWithTheClass;
return {
value: Value,
id: Id,
class: Class
};
}
$("input").attr(definingVars())
});
This is one of the answers posted in the question related to this one. It looks beautiful, but it looks impossible to apply this same concept to the situation stated at the beginning of this question.
Not sure if that is what you want to do.
You missed the quotes on some string
I stored the attributes in an array
You should be targetting the input not the div
$(function() {
function definingVars() {
var ValueOne = "Sucess with the value on input 1";
var IdOne = "successWithTheId1";
var ClassOne = "sucessWithTheClass1";
var ValueTwo = "Sucess with the value on input 2";
var IdTwo = "successWithTheId2";
var ClassTwo = "sucessWithTheClass2";
return [{value:ValueOne, id:IdOne, class:ClassOne}, {value:ValueTwo, id:IdTwo, class:ClassTwo}];
}
var df = definingVars();
$("input:nth-child(1)").attr(df[0]);
$("input:nth-child(2)").attr(df[1]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<input type="text" id="noSucessWithTheId1" class="noSucessWithTheClass1" value="No sucess with the value on input 1">
<input type="text" id="noSucessWithTheId2" class="noSucessWithTheClass2" value="No sucess with the value on input 2">
</div>
Changed the selector and returning an object instead of an array to simplify variables.
You can invoke the function and access the object property using the required key.
$(function() {
function definingVars() {
console.log("invoked definingVars");
return {
ValueOne: "Sucess with the value on input 1",
IdOne: "successWithTheId1",
ClassOne: "sucessWithTheClass",
ValueTwo: "Sucess with the value on input 2",
IdTwo: "successWithTheId2",
ClassTwo: "sucessWithTheClass2"
};
};
$($("div>input")[0]).attr({
value: definingVars()["ValueOne"],
id: definingVars()["IdOne"],
class: definingVars()["ClassOne"]
});
$($("div>input")[1]).attr({
value: definingVars()["ValueTwo"],
id: definingVars()["IdTwo"],
class: definingVars()["ClassTwo"]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<input type="text" id="noSucessWithTheId1" class="noSucessWithTheClass1" value="No sucess with the value on input 1">
<input type="text" id="noSucessWithTheId2" class="noSucessWithTheClass2" value="No sucess with the value on input 2">
</div>

Adding of users to dropdown list doesn't work

Good evening!
There's a problem with adding a user to dropdown list (ui-grid is used).
I need to push input name by id into dd list after the "addNewPerson" button is clicked, if there's no such name in the list, or to call "alert", if there is.
Here's a code, responsible for the dd list creation in html:
<ui-select ng-model="person.selected" theme="select2" style="min-width:300px;">
<ui-select-match placeholder="Select a person in the list or search by name">{{$select.selected.name}}
</ui-select-match>
<ui-select-choices repeat="person in contacts | filter: {name: $select.search} track by $index">
<div ng-bind-html="person.name | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
Button and input field:
<button type="button" id="addPerson" class="button" ng- click="addNewPerson()">Add New Person</button>
<input id="name" class="form-control" placeholder="Enter your Name">
Array of objects with the "name" field, which needs to be passed into the dd list:
$scope.contacts = [
{name: "Han Solo"},
{name: "ThetaSigma"},
{name: "Ollie Reeder"},
{name: "Amy McDonald"},
{name: "PJ Harvey"},
{name: "Sofie Marceau"},
{name: "Arthur Zimmermann"},
{name: "Michelle Dockery"},
{name: "Xavier Dolan"}
];
And, at last, the notorious function:
$scope.person = {};
$scope.addNewPerson = function () {
var nameInput = document.getElementById("name");
for (var i=0; i <= $scope.contacts.length; i++) {
if ($scope.contacts[i].name == nameInput.value.toLowerCase()) {
alert("Error, the name entered already exists");
}else{
var obj1 = {name: nameInput.value};
$scope.contacts.push(obj1);
}
}
};
I've tried various formations of the function, it either pushes nothing and alerts 10 times, or pushes names correctly, but even already existing ones, or pushes 10 times and alerts 10 times after a single adding.
I'm handicapped. Tried to find similar q/a here, but to no avail.
And sorry for my english, it'snot my native language.
Here's working codepen example.
First Change the html for the input to use scope variable:
<input ng-model="name" class="form-control" placeholder="Enter your Name">
and in the controller:
$scope.name = "";
$scope.addNewPerson = function () {
for (var i=0; i < $scope.contacts.length; i++) {
if ($scope.contacts[i].name.toLowerCase() === $scope.name.toLowerCase()) {
alert("Error, the name entered already exists");
return;
}
}
$scope.contacts.push({name: $scope.name});
};
You ng-model to bind the new user name:
<input id="name" class="form-control" placeholder="Enter your Name" ng-model="new_user_name">
Then in your js, you have to break out of your forloop :
$scope.person = {};
$scope.addNewPerson = function () {
var name = $scope.new_user_name || "";
var match_found = false;
for (var i=0; i <= $scope.contacts.length; i++) {
if ($scope.contacts[i].name == name.toLowerCase()) {
alert("Error, the name entered already exists");
match_found = true;
break;
}
}
if (!match_found) {
var obj1 = {name: name};
$scope.contacts.push(obj1);
}
};
The above answers are fine, I would just like to add the option to use functional programming style as I love to do it and for me it looks cleaner.
View
<input ng-model="name" class="form-control" placeholder="Enter your Name">
Controller
$scope.name = "";
$scope.addNewPerson = function () {
var contactIndex = $scope.contacts.map(function (contact) {
return contact.name.toLowerCase();
}).indexOf($scope.name.toLowerCase());
if (contactIndex === -1)
$scope.contacts.push({name: $scope.name});
else
console.log("Error, the name entered already exists");
}
A few notes:
When working with angular, never access DOM in view controllers, use directives instead
Functional programming style will save you a lot of typing
Using console.log instead of alerting boosts your productivity by approx. 9000%

How to validate form fields with javascript objects?

I am trying to do some simple form validation using javascript object values. I know it's not "ideal", but I'm just working with a simple form that doesn't need to be iron-clad.
Please see my fiddle example: http://jsfiddle.net/6dXd7/3/
I am trying to make sure that each form field has a value. If so, set the value for myObj.fieldID to yes.
Then, when the form is submitted, check every existing myObj.XXX and be sure all their values are yes.
In my example, I am having trouble creating the object, and I don't know how to cycle through all the objects when the submit button is pressed without specifying each one by name.
Here's the code in the jsfiddle example linked to above:
<script>
$(document).ready(function () {
var myObj = {};
$("input.checkblank").blur(function () {
var inputID = $(this).attr("id");
var contents = $("input#" + inputID).val();
if (contents == "") {
$(myObj).data(inputID, "no");
} else {
$(myObj).data(inputID, "yes");
}
});
$("#verify").click(function () {
if (myObj.first && myObj.second == "yes") {
// ***** Trying to get it to scan through ALL existing myObj's and make sure all their values are "yes" *****
$('.results').text('all good');
} else {
$('.results').text('not good');
}
});
});
</script>
<input type="text" name="first" id="first" class="checkblank"><br />
<input type="text" name="second" id="second" class="checkblank">
check<br />
<p class="results"> </p>
​
​
You were storing field info in jQuery DATA and trying to check them later not in the same place...
var obj = {}
$(obj).data('a','1');
console.log(obj.a); //this will log null, cause there's no attribute 'a' in 'obj'
console.log($(obj).data('a')); //this will log '1' :]
instead do this, you should store you data in attributes from native object like this:
var obj = {}
obj['a'] = '1'; //obj.a = '1' work's too
console.log(obj.a); //now it log '1' :]
Also, your verification function is wrong.. it only check if first exists inside myObj and if second exists and is equal to "yes". So your verification function should be something like this:
$("#verify").click(function() {
var allFieldsOK = false;
for ( var field in checkedFields ) {
if ( !(allFieldsOK = checkedFields[field] ) ) break;
}
$('.results').text( allFieldsOK ? 'all good' : 'not good' );
});
Here is an update to you jsFiddle, it is working for you purpose and should work if you add more input fields with the class checkblank :]
http://jsfiddle.net/6dXd7/5/
replace this
$("#verify").click(.........});
with this
$("#verify").click(function() {
var flag=true;
$('.checkblank').each(function(){ //check all elements with class checkblank
if($(this).val().length==0) //set flag false if anyone of them is blank
flag=false;
})
if (flag) {
$('.results').text('all good');
} else {
$('.results').text('not good');
}
});
...it should work

Categories