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 »

Reply via email to