I’ve been teaching my self JavaScript and jQuery for a few months, but I’m still getting confused with JavaScript objects and jQuery objects.
In the following example I assigned a jQuery object to the variable $target. The $target should consist of an array of two objects.
My question is why I have to wrap the value variable again into the jQuery object in .each() function ?
$('select.to_append').change(function(){
var $target = $('select.to_append');
var $form = $('#anotherForm');
$.each($target, function(key, value){
$form.append('<input name="' + $(value).attr('name') + '" type="hidden" value="' + $(value).val() + '"></input>');
});
});
The sample code I use to append values from selects which are not parts of the form being submitted;
because $target is a jQuery object, but when you iterate you will get a dom element reference in your iteration handler not a jQuery object. So if you want to access jQuery methods on that object you need to wrap the object again.
By the way to iterate over a jQuery object you can use .each() instead of jQuery.each()
$('select.to_append').change(function () {
var $target = $('select.to_append');
var $form = $('#anotherForm');
$target.each(function (index, el) {
$form.append('<input name="' + $(el).attr('name') + '" type="hidden" value="' + $(el).val() + '"></input>');
});
});
Related
Why is this not working with JQuery?
The property wont be checked to true so or with asnyc function... I tried everything, but it only will working if i set the attribute checked true in browser at console. Not even with outsourced async callback functions.
for (var i = 0; i < user.benutzer.length; i++)
{
var user_var = user.benutzer[i].benutzer;
user_rep = user_var.replace(/ /g, '_');
$('#div_buttongroup').append('<label for="' + user_rep + '" class="btn btn-primary" id="label_'+user_rep+'"><input type="radio" class="user_radio" id="' + user_rep + '" value="' + user_var + '" name="radio" autocomplete="off"></input>' + user_var + '</label>');
if (i === 0)
{
t = user_rep;
$('#label_'+user_rep).addClass("btn btn-primary active");
$('#'+user_rep).prop("checked",true);
}
}
The difference between attributes and properties can be important in specific situations. Before jQuery 1.6, the .attr() method sometimes took property values into account when retrieving some attributes, which could cause inconsistent behavior. As of jQuery 1.6, the .prop() method provides a way to explicitly retrieve property values, while .attr() retrieves attributes.
$('#'+user_rep).attr("checked");
I think it was a JQuery bug in combination with radiobuttons. I used a selectbox and everything was working
I am running a loop which is appending input fields. Now, as I am using a loop, all the attributes are similars. So, when I need to grab any one of the then I am grabbing more than one field.
How do I dynamically change the attributes according to the index, so that I can grab the correct input field ?
ebs_no = data.number_ebs;
for(i=0;i<ebs_no;i++){
$('form.ebs').append("<br>EBS"+(i+1)+"</br>");
$('form.ebs').append('<br> SNAPSHOTNO <input type="text" name="'+i+'"></br>');
$('form.ebs').append('<input type="submit" name="submit">');
$('[name='+i+']').on('submit',function(){
alert($('[name='+i+']').val());
});
}
Replace this:
alert($('[name='+i+']').val());
by this:
alert($(this).val());
The code $(this) refers to the element being treated
Your are looking for event delegation.It is used for created Dynamically DOM elements and use class instead of iterare i in the loop
ebs_no = data.number_ebs;
for (i = 0; i < ebs_no; i++) {
$('form.ebs').append("<br>EBS" + (i + 1) + "</br>");
$('form.ebs').append('<br> SNAPSHOTNO <input type="text" class="someClass" name="' + i + '"></br>');
$('form.ebs').append('<input type="submit" name="submit">');
$('[name=' + i + ']').on('submit', function () {
alert($('[name=' + i + ']').val());
});
}
$(document).on('submit', '.someClass', function () {
alert($(this).val());
});
var div_raw_id = 'acf-download-link';
var div_id = '#' + div_raw_id;
var chapter_index = 1;
var chapter = 'chapter-' + chapter_index;
$('button[name=addnewchapter]').click(function(chapter, div_id ,div_raw_id){
$(div_id).append('<div class="acf-input-wrap"><input id="' + div_raw_id +'" class="text" name="fields[field_55951fb44c1d6][' + chapter + '][]" value="" placeholder="" type="text"><span class="remove_btn"></span></div>');
return false;
});
The problem is I cannot pass div_id, chapter_index, chapter as a parameter to the anonymous function inside the click event. I used the debugger and the debugger represents them as undefined values even though they are defined in above code. It seems there is a variable scope problem, however, I cannot figure out any other way to pass the defined variables as a parameter to the anonymous function inside the click event.
You don't need to pass the variables defined at the beginning as parameters, simply use it inside the function:
var div_raw_id = 'acf-download-link';
var div_id = '#' + div_raw_id;
var chapter_index = 1;
var chapter = 'chapter-' + chapter_index;
$('button[name=addnewchapter]').click(function(){
$(div_id).append('<div class="acf-input-wrap"><input id="' + div_raw_id +'" class="text" name="fields[field_55951fb44c1d6][' + chapter + '][]" value="" placeholder="" type="text"><span class="remove_btn"></span></div>');
return false;
});
You can pass anything (no string as it would be used as selector, preferable an object) you want to your event handler.
See the documentation of .on( events [, selector ] [, data ], handler ) for further infos on the data parameter
var eventData = {
"div_id": "acf-download-link"
,"chapter": 1
};
$('button[name=addnewchapter]').on("click", eventData, function(e){
$("#" + e.data.div_id)
.append('<div class="acf-input-wrap"><input id="' + e.data.div_id + '"'
+ ' class="text" name="fields[field_55951fb44c1d6][chapter-' + e.data.chapter + '][]"'
+ ' value="" placeholder="" type="text"><span class="remove_btn"></span></div>');
return false;
});
Thanks to JS Closures Your click handler is defined at the same level as the variables div_raw_id, div_id, div_raw_id, chapter_index, chapter.
This means that if you give the callback function arguments with the same name the callback function can no longer see the external ones with the same name.
So chapter_index Should still be defined. The first argument chapter will be the first parameter that jQuery passes through (The Event Object) the last 2 will be set to undefined.
In one of the jsp pages from my project, I have to work with this json lists:
var obj_tipo = jQuery.parseJSON( "{"Tipo":[{"id":3,"nome":"gerente"},{"id":4,"nome":"supervisor"},{"id":5,"nome":"analista"},{"id":6,"nome":"tecnico"},{"id":7,"nome":"secretaria"},{"id":8,"nome":"seguranca"}]}" );
var obj_campo = jQuery.parseJSON( "{"Key":[{"id":1,"nome":"e-mail"},{"id":2,"nome":"cidade"}]}" );
I try read each item of the list this way:
for(var item in obj_tipo.Tipo)
select.append('<option value="'+item.nome+'">'+item.nome+'</option>');
and
for(var item in obj_campo.Key)
$("table.cadastro").append('<tr> <td> '+item.nome+' : </td> <td> <input type="text" name="'+item.nome+'" size=20 maxlenght=40> </td> <tr>');
But I am getting the text 'undefined' when I display the page, instead of the corret text, despite the fact that the right amount of itens are being displayed.
Someone knows how to fix that? What the right way to access each item from my json list? the list is well formed, right?
As #Oleg said, it should be more like:
var obj_tipo = jQuery.parseJSON( '{"Tipo":[{"id":3,"nome":"gerente"},{"id":4,"nome":"supervisor"},{"id":5,"nome":"analista"},{"id":6,"nome":"tecnico"},{"id":7,"nome":"secretaria"},{"id":8,"nome":"seguranca"}]}' );
var obj_campo = jQuery.parseJSON( '{"Key":[{"id":1,"nome":"e-mail"},{"id":2,"nome":"cidade"}]}' );
I basically just changed the wrapping quotes, to '
Also, you may want to consider looping through the JSON using $.each, if you are using jQuery. See this question here for some clarification: jquery loop on Json data using $.each
Using for in on arrays is not a good idea. Either use for (var i = 0; i < arr.length; i++) {... or native forEach or jQuery's each...
var obj = $.parseJSON('{"Tipo":[{...},{...},{...}]}'); // mind the quotes
$.each(obj.Tipo, function (index, item) {
select.append('<option value="' + item.nome + '">' + item.nome + '</option>');
});
Use
for(var item in obj_tipo.Tipo) {
var nome= obj_tipo.Tipo[item].nome;
select.append('<option value="'+nome+'">'+ nome +'</option>');
}
instead of
for(var item in obj_tipo.Tipo)
select.append('<option value="'+item.nome+'">'+item.nome+'</option>');
For more info visit for...in
variable: A different property name is assigned to variable on each iteration.
I don't have any idea about Java language. But you can get the Nome and id field by using below code snippet.
Please try with the below code snippet. Let me know if any concern.
var tipo = obj_tipo.Tipo;
for(var i = 0; i < tipo.Length; i++)
{
select.append('<option value="'+tipo[i].id+'">'+tipo[i].nome+'</option>');
}
The item in your code returns the index of the array. I updated your code to get to a solution. Please find the fiddle here
$("table.cadastro").append('<tr> <td> '+obj_campo.Key[item].nome+' : </td> <td> <input type="text" name="'+obj_campo.Key[item].nome+'" size=20 maxlenght=40> </td> <tr>');
or
for(var item in obj_tipo.Tipo)
$('select').append('<option value="'+obj_tipo.Tipo[item].nome+'">'+obj_tipo.Tipo[item].nome+'</option>');
I am building a form in HTML out of a javascript object that I've imported from a JSON file.
I use a recurisve algorithm to build HTML tables, and respective elements (labels, text boxes, etc.)
The fields load with the value of the current node.
The idea is to edit the values in the textboxes; which in turn updates the javascript object. When
changes have been made, the editor will send the JSON object to the server and update the file.
The puzzling question, is how do I reference the node that has been changed? I have tried several
approaches to no avail.
EDIT:
This is a basic idea of what I'm doing:
function build_tree(obj, depth) {
for (key in obj) {
if (typeof(obj[key]) == 'object') {
print(key + "<input type="text" value='" + obj[key] + "'>");
build_tree(obj[key], depth + 1);
} else
print(key + "<input type="text" value='" + obj[key] + "'>");
}
Now, how do I bind the value of obj[key] to the text boxes, so that when I change the
value it updates the Javascript object?
document.getElementById('name').changed = true;
So now the DOM element has the property 'changed'. You can also use any other value (dates, arrays, etc)
First off you need a way to individually identify the input so, i would add a data-key attribute.
function build_tree(obj, depth) {
for (key in obj) {
if (typeof(obj[key]) == 'object') {
print(key + "<input type="text" value='" + obj[key] + "' data-key= '"+key+"'>");
build_tree(obj[key], depth + 1);
} else
print(key + "<input type="text" value='" + obj[key] + "' data-key= '"+key+"'>");
}
Then i would attach a change event handler to each text input, after the tree is built.
$('input[type="text"]').on('change',function(){
var key = $(this).data('key');
obj[key] = $(this).val();
});
obj would be a global array. Hope this makes sense.
An approach I have seen many others use is a special attribute with data- prefixed.
For example:
<div id="pie" data-like-pie="true">I do like pie.</div>
Then, to find the attribute with JavaScript:
likesPie = document.getElementByID("pie").getAttribute("data-like-pie");
Or with jQuery:
likesPie = $("#pie").data("like-pie");
As you can see, jQuery's data method automatically prepends data- to the front of the attribute.
You should take a look at knockoutjs. It has an entire binding engine that updates values between html and object model automatically. So all you need to do is to send back your JSON model whenever the right values has been entered into your textboxes or whatever you use to update your values.
This will update your original model (global obj) when the generated textboxes change.
When using your print function:
print(key + "<input type="text" value='" + obj[key] + "'>");
update it to something like:
print(key + "<input type="text" value='" + obj[key] + "' data-object-key='" + key + "' >");
And in your JS, if using JQuery you want to listen to all changes on your input elements.
Add a class if necessary.
$("input[type='text']").change(function()
{
var key = $(this).data("object-key");
obj[key] = $(this).val();
});