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; > > > > > > } > > > > > > > I am not completely sure that I am doing this right because I get > > > > > > the > > > > > > error before. > > > > > > > Thank You, > > > > > > Miguel > > > > > > On Feb 20, 5:02 pm, mkmanning <michaell...@gmail.com> wrote: > > > > > > > > levels.text = $('input[name="Levels"]:checked + label'); > > > > > > > levels.value = $('input[name="Levels"]:checked'); > > > > > > > > Those don't get you the right values for the levels object, they > > > > > > > both > > > > > > > return a jQuery object. > > > > > > > Accessing the levels object as this.value won't work either. > > > > > > > > Try this: > > > > > > > > levels.each(function(){ > > > > > > > > > > > > > > levelsCsv.push({'text':this.value,'value':$(this).next().text()}) > > > > > > > > }) > > > > > > > > On Feb 20, 5:22 am, shapper <mdmo...@gmail.com> wrote: > > > > > > > > > Hi, > > > > > > > > > I followed your tips but I still have a few problems. > > > > > > > > The subject is working fine but when I do the same to the > > > > > > > > levels it > > > > > > > > does not work. > > > > > > > > > I think the problem, but I am not sure, is in: > > > > > > > > levels.each(function(){ > > > > > > > > levelCsv.push(this.value);//array to hold the levels > > > > > > > > }); > > > > > > > > > I changed everything else. I updated my > > > > > > > > example:http://www.27lamps.com/Beta/List/List3.html > > > > > > > > > Other problem I notice is that when two levels are added the > > > > > > > > word "e" > > > > > > > > is not added between the both. > > > > > > > > Only when 3 levels are added. On my first example I had a > > > > > > > > function > > > > > > > > that was doing it:http://www.27lamps.com/Beta/List/List.html > > > > > > > > > I just don't know how to integrate this on your code. > > > > > > > > I don't need to use my FriendlyLevels example. I just need to > > > > > > > > have the > > > > > > > > "e" every time there is more then 1 level. > > > > > > > > > How can I do it? > > > > > > > > > Thank You, > > > > > > > > Miguel > > > > > > > > > - The subject is working fine. > > > > > > > > - > > > > > > > > > On Feb 20, 1:50 am, mkmanning <michaell...@gmail.com> wrote: > > > > > > > > > > You could modify the subject variable being put into the > > > > > > > > > array to make > > > > > > > > > it an object: subject = {} > > > > > > > > > then add the option's value and text to it: > > > > > > > > > > subject.value = $('#Subject option:selected').val(); > > > > > > > > > subject.text = $('#Subject option:selected').text(); > > > > > > > > > > or in one line to replace what's there now: > > > > > > > > > subject = {'text':$('#Subject > > ... > > read more »