I've a page with two input fields. I've a JS object (info) containing 'reference' and a 'value' field of each item. For each item, there's a corresponding 'input' field with matched by 'class' attribute. When a user updates a matching input field, I want to add it's 'value' in the info object.
The problem I'm experiencing is that it's putting the value in the last item in the array (location.value
) for either input.
Can anyone help me with where I'm going wrong please? (I could see solutions using 'each' where data for all inputs needs to be added to an array/object. I'm stuck on getting the data for matched fields.)
$(document).ready(function() {
var info = {
name: {
ref: "a2350",
value: ""
},
location: {
ref: "a2351",
value: ""
}
};
for (var p in info) {
if (info.hasOwnProperty(p)) {
$('input.' + p).focusout(function() {
var val = $(this).val();
info[p].value = val; // Only setting value on the last item in array!
//console.log(p); /// p = always location!
out();
})
}
}
function out() {
console.log(info);
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<input type="text" class="name" />
<input type="text" class="location" value="" />
Your issue is because p
will be location
when the loop ends. Therefore all the click handlers will update the location
object, regardless of which element they are attached to.
To fix this you can use a closure to retain the scope of the p
at the point the event handler logic was created. Also note that hasOwnProperty()
is moot when you're looping through the properties of the object; it has to exist for the iteration to happen. Try this:
$(document).ready(function() {
var info = {
name: {
ref: "a2350",
value: ""
},
location: {
ref: "a2351",
value: ""
}
};
for (var p in info) {
(function(p) {
$('input.' + p).focusout(function() {
var val = $(this).val();
info[p].value = val;
out();
})
})(p);
}
function out() {
console.log(info);
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<input type="text" class="name" />
<input type="text" class="location" value="" />
Alternatively, you can avoid the loop and associated closure by using the class
on the input
to retrieve the required object:
$(document).ready(function() {
var info = {
name: {
ref: "a2350",
value: ""
},
location: {
ref: "a2351",
value: ""
}
};
$('input').focusout(function() {
var className = $(this).attr('class');
if (info.hasOwnProperty(className))
info[className].value = this.value;
out();
});
function out() {
console.log(info);
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<input type="text" class="name" />
<input type="text" class="location" value="" />
You can simply use the class attribute to update the object by key:
$(document).ready(function(){
var info = {
name: {
ref: "a2350",
value: ""
},
location: {
ref: "a2351",
value: ""
}
};
$('input').focusout(function() {
var className = $(this).attr('class');
var inputValue = $(this).val();
if (info.hasOwnProperty(className)) {
info[className].value = inputValue;
} else {
// If you want to add unknown inputs to the object
info[className] = {ref: "", value: inputValue};
}
console.log(info);
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="name" />
<input type="text" class="location" value="" />
<input type="text" class="not_exists" value="" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With