Is my third day with Javascript and jQuery and I´m playing a little with Literal Object structure to make the code more legible and modificable. ok. The problem…
I have written a script to insert dinamically inputs to a form and a button to display the content of inputs. Example:
jQuery('#add').click(function(){
jQuery('#opts').append('<li><input type="text" name="i" value="i" /></li>');
});
jQuery('#view-list').click(function(){
$itemsList = jQuery('#opts :input');
console.log('there are ' + $itemsList.length + ' items');
$itemsList.each(function(){
console.log(jQuery(this).val());
});
});
It works correctly, the “add” button inserts items and click button displays items.
The problem is when I take an approach to Literal Object. For example in a big app, this script it will be a little part of it. In this case i make it like this:
var sidebarManager = {
init : function(){
sampleFunction0();
sampleFunction1();
sampleFunction2();
},
sampleFunction0 : function(){
jQuery('#add').click(function(){
jQuery('#opts').append('<li><input type="text" name="insert" value="insert" /></li>');
});
jQuery('#view-list').click(function(){
$itemsList = jQuery('#opts :input');
console.log('there are ' + $itemsList.length + ' items');
$itemsList.each(function(){
console.log(jQuery(this).val());
});
});
},
sampleFunction1 : function(){ //code },
sampleFunction2 : function(){ //code }
}
jQuery(document).ready(function(){
sidebarManager.init();
});
But in this case the list button only display the items who are on the list when the function is called via init function. If added new items, these are not displayed.
I’m interested in the use of literal objects and encapsuled solutions but I´m littel confused 😛
Any advice, sugestion, WTF, or whatever… 🙂
Thanks.
Edited
what happens in the situations with 2 ambiguous this? For exampe:
sampleFunction0 : function(){
jQuery('#add').click(function(){
jQuery('#opts').append('<li><input type="text" name="insert" value="insert" /></li>');
});
jQuery('#view-list').click(function(){
var $itemsList = jQuery('#opts input');
console.log('there are ' + $itemsList.length + ' items');
$itemsList.each(function(){
console.log(jQuery(this).val());
var test = this.sampleFunction1(); //conflict
});
});
},
In this case is necesary call fuction1 like this:
sidebarManager.sampleFunction1();
First, you have to fix the javascript error in the
init()function by adding this:sampleFunction0,sampleFunction1, andsamplefunction2only exist as properties on thesidebarManagerobject so you have to reference them as properties on that object. This should have been easy for you to find if you were looking in your browser’s error console or debug console (where javascript interpreter errors are displayed).Then, I see a couple other issues that should be cleaned up. First, you are using undeclared variables like
$itemsList. That makes them global variables by default. I don’t think you want that and it could potentially cause issues in your code (conflict with other code also doing that). You should preface their first use inside your function withvarto make them local variables. Implicit global variables are a frequent source of accidental bugs and are a bad thing. Avoid them.Second, I don’t think your selector is ideal. Instead of
'#opts :input', I think you want this'#opts input'which will fetch any input tags that are contained in the#optsobject. Both will work in some cases, but I think the second better represents what you want here and is probably a little faster. The resulting code with both fixes would look like this: