Hi Michael, It is working fine. Thank You Very Much.
Just one final question. This is part of a form. When the form is submitted but not validated on the server I rebuild the themes list. There is only one problem: when I delete a theme all disappear. I think it is because themes is being initialized as follows: themes = []; Well, that is fine if initially the list is empty ... but if not then I should get all themes. So I am trying to create a function named InitThemes that initialize themes. <li class="Themes"> Economia<br/> Secundário e Universitário<br/> Note 1<br/> <a class="Remove" href="#Remove">Remover</a> <input type="hidden" name="Themes[0].Subject" value="Economy"/> <input type="hidden" name="Themes[0].LevelsCsv" value="Secondary,College"/> <input type="hidden" name="Themes[0].Note" value="Note 1"/> </li> <li class="Themes"> Matemática<br/> Universitário<br/> Note 2<br/> <a class="Remove" href="#Remove">Remover</a> <input type="hidden" name="Themes[1].Subject" value="Mathematics"/> <input type="hidden" name="Themes[1].LevelsCsv" value="College"/> <input type="hidden" name="Themes[1].Note" value="Note 2"/> </li> So basically in InitThemes I need to parse all this back to themes. The values and text. Maybe the inputs are easy but not the rest ... I think ... Is there a better approach to accomplish this? Thanks, Miguel On Feb 24, 9:39 pm, mkmanning <michaell...@gmail.com> wrote: > The problem is t[1] is now an array of objects, so you have to access > the text and value attributes of the objects by their array index. > Here are the buildThemesList function and the friendlyLevels functions > rewritten to account for that. > > function buildThemesList(){ > ol.empty(); > //more string concatenation than I like, but OK if > you aren't > building a huge list > $.each(themes,function(i,t){ > //this handles the li content > var li = > $('<li>').addClass('Themes').html(t[0].text+'<br />' > +friendlyLevels(t[1])+'<br />' > +(t[2]==''?'':t[2]+'<br />') > +'<a href="#Remove" class="Remove">Remove</a>' > ).appendTo(ol); > //now the inputs, this could also be done in > another loop with an > array of names, if it gets longer; and the brackets in the name are > still a bad idea > > $('<input>').attr({'type':'hidden','name':'Themes['+i > +'].Subject'}).val(t[0].value).appendTo(li); > > $('<input>').attr({'type':'hidden','name':'Themes['+i > +'].LevelCsv'}).val($.map(t[1],function(l,i){return l.value;}).join > ()).appendTo(li); > > $('<input>').attr({'type':'hidden','name':'Themes['+i > +'].Note'}).val(t[2]).appendTo(li); > }); > //just to keep things exactly as the original > example's UI > $('#Index').val(themes.length); > } > > function friendlyLevels(levels) { > if (levels.length == 1){ > return levels[0].text; > } > var friendly = ""; > $.each(levels,function(i,l){ > friendly += l.text + ((i==levels.length-2)?' > e ': > (i==levels.length-1)?'':', '); > }); > return friendly; > } > > Couple of things to note: friendlyLevels now has {} enclosing the > first if statement. You'll see lots of coders not do that, but it's > really a good idea, and not just a style choice: javascript suffers > from automatic semicolon insertion which although not a common problem > to run into, could make things difficult to debug. Even though there > are only three checkboxes, the each function with the ternary means > you don't have to refactor if you decide to add more checkboxes. > > To get the values into the hidden input, $.map() is used. Check it out > in the documentation. Hope this helps. > > On Feb 24, 11:20 am, shapper <mdmo...@gmail.com> wrote: > > > @Michael, > > > I just installed Firebug and I almost made this working. > > The only problem I have is when I am adding the levels to the list as > > html and as hidden input: > > > +friendlyLevels(t[1].text.join(', '))+'<br />' > > > $('<input>').attr({'type':'hidden','name':'Themes['+i > > +'].LevelCsv'}).val(t[1].value.join()).appendTo(li); > > > I get an error in Firebug: > > t[1].text is undefined > > [Break on this error] +friendlyLevels(t[1].text.join(', '))+'<br />' > > > But as far as I know to get the text and value I use .text and .value. > > > My friendlyLevels function is > > > function friendlyLevels(levels) { > > if (levels.length < 2) return levels.join(''); > > var first = levels.slice(0, -1), last = levels.slice(-1); > > var friendly = first.join(', '); > > if (last) { friendly += ' e ' + last; } > > return friendly; > > } > > > I am trying to display a join of the values in the hidden input and a > > join of the texts in the html but using friendlyLevels or anything > > similar to add the "e" at the end. > > I removed your code just because it was adding the "e" only for 3 > > items and using a function makes the code less confusing. > > > I updated my code in:http://www.27lamps.com/Beta/List/List5.html > > > I plan to optimize my code but first I would like to make it work so I > > can optimize it step by step. > > > @seasoup > > > I didn't forgot the problems you mentioned about using [] ... But what > > would you suggest to replace []? > > > I can post the suggestion on ASP.NET MVC forums where I participate on > > a daily basis. > > > I am using Microsoft ASP.NET MVC which gives me complete control of > > the HTML but still allows me to use C# and SQL. > > > Microsoft ASP.NET MVC ships now with JQuery since there was a > > partnership created between JQuery creators and Microsoft. > > > This is the reason why I am starting with JQuery but I am still > > learning ... but until now it seams great. > > > Thanks, > > Miguel > > >http://www.27lamps.com/Beta/List/List5.html > > > On Feb 24, 4:57 pm, mkmanning <michaell...@gmail.com> wrote: > > > > Creating a complete html string won't solve the current problem; it is > > > faster, and usually the way I prefer doing it also (see my note > > > further below though), but as I indicated in a code comment, since > > > this appears to be based on user input, the list (hopefully) won't be > > > very big, so the speed gain probably isn't appreciable. > > > > @Shapper - get Firebug and use Firefox for debugging, it will tell you > > > immediately that you have an error in your code: you define levelCsv = > > > [] but then use levelsCsv for the array.push() > > > > Once you get it working you can try seasoups suggestion for a speed > > > improvement if you like (or simply for your own edification); it will > > > definitely benefit you in future if you work with larger lists or > > > blocks of html. An even more important performance gain can be had by > > > not doing string concatenation (I put a caveat about this in the code > > > comment's also), but build an array of your html and then join the > > > array; it's siginficantly faster. Check the forum and you'll see > > > examples of this. > > > > On Feb 24, 8:23 am, seasoup <seas...@gmail.com> wrote: > > > > > Hi Miguel, not sure if it will solve your problem, but I find it is > > > > much faster to create a complete html string and then append it > > > > instead of doing lots of appends, which are slow. > > > > > //this handles the li content > > > > var li = > > > > $('<li>').addClass('Themes').html(t[0].text+'<br />' > > > > +friendlyLevels(t[1])+'<br />' > > > > +(t[2]==''?'':t[2]+'<br />') > > > > +'<a href="#Remove" > > > > class="Remove">Remove</a>' > > > > ).appendTo(ol); > > > > //now the inputs, this could also be > > > > done in another loop with an > > > > array of names, if it gets longer; and the brackets in the name are > > > > still a bad idea > > > > > > > > $('<input>').attr({'type':'hidden','name':'Themes['+i > > > > +'].Subject'}).val(t[0].value).appendTo(li); > > > > > > > > $('<input>').attr({'type':'hidden','name':'Themes['+i > > > > +'].LevelCsv'}).val(t[1].join()).appendTo(li); > > > > > > > > $('<input>').attr({'type':'hidden','name':'Themes['+i > > > > +'].Note'}).val(t[2]).appendTo(li); > > > > > is faster as > > > > > var html = '<li class="Themes"> + t[0].text + "<br /> + friendlyLevels > > > > (t[1]) + '<br />' + (t[2]==''?'':t[2]+'<br />') + '<a href="#Remove" > > > > class="Remove">Remove</a> + > > > > '<input type="hidden" name="Themes[' + i + '].Subject" value="' + t > > > > [0].value + '"> + > > > > '<input type="hidden" name="Themes[' + i + '].LevelCsv" value="' + > > > > t[1].join() + '"> + > > > > '<input type="hidden" name="Themes[' + i + '].Note" value="' + t > > > > [2].value + '">; > > > > > $(ol).append(html); // or $(html).appendTo(ol); > > > > > On Feb 24, 7:33 am, shapper <mdmo...@gmail.com> wrote: > > > > > > Hi, > > > > > > I think I did that ... > > > > > > I have this example working with Subjects and FriendlyLevels function > > > > > to add the "e" correctly:http://www.27lamps.com/Beta/List/List4.html > > > > > > Then I tried to do the same but for > > > > > levels:http://www.27lamps.com/Beta/List/List5.html > > > > > > But I keep having errors. > > > > > > What am I missing? > > > > > > Sorry, but I am just starting with JQuery. > > > > > > Thank You, > > > > > Miguel > > > > > > On Feb 23, 9:23 pm, mkmanning <michaell...@gmail.com> wrote: > > > > > > > That's because you changed levels to an object, which you don't need > > > > > > to. Just use the original var levels = $('input:checkbox:checked'), > > > > > > and then > > > > > > levels.each(function(){ > > > > > > levelsCsv.push({'text':this.value,'value':$ > > > > > > (this).next().text()}) > > > > > > }) > > > > > > > On Feb 23, 9:37 am, shapper <mdmo...@gmail.com> wrote: > > > > > > > > Hello, > > > > > > > > I tried to make the change: > > > > > > > levels.each(function(){ > > > > > > > > > > > > > > levelsCsv.push({'text':this.value,'value':$(this).next().text()}) > > > > > > > }) > > > > > > > > But I get an error on Firebug: > > > > > > > levels.each is not a function > > > > > > > > Am I doing something wrong? > > > > > > > > I also made a change on buildThemesList to use text and also to > > > > > > > fix > > > > > > > the problem on your code that adds "e" only when there are 3 > > > > > > > items. It > > > > > > > should be also applied when there are 2: > > > > > > > > $.each(themes,function(i,t){ > > > > > > > var li = > > > > > > > $('<li>').addClass('Themes').html(t[0].text+'<br />' > > > > > > > +friendlyLevels(t[1].text)+'<br />' > > > > > > > +(t[2]==''?'':t[2]+'<br />') > > > > > > > +'<a href="#Remove" class="Remove">Remover</a>' > > > > > > > ).appendTo(ol); > > > > > > > > function friendlyLevels(levels) { > > > > > > > if (levels.length < 2) return levels.join(''); > > > > > > > var first = levels.slice(0, -1), last = levels.slice(-1); > > > > > > > var friendly = first.join(', '); > > > > > > > if (last) { friendly += ' e ' + last; } > > > > > > > return friendly; > > > > > > > } > > ... > > read more »