Here's a wholly different approach for consideration. Rather than try
and keep track of LI elements and regex their names with the current
index, just use an array placeholder and rebuild the list. Chances are
if the user is required to add items, the list isn't going to get
unmanageably huge (at least I'd hope not from a usability standpoint).
Below is a refactored example, and you can see it live here:
http://actingthemaggot.com/test/add_theme.html

Refactored (uses markup from http://www.27lamps.com/Beta/List/List.html):
(function($) {
        var themes = [], //this will be an array of arrays to keep track, we
can use its indexing to rebuild the themes list, and it can be
serialized if we want to post the data
        ol = $('#Themes').bind('click',function(e){//event delegation for
removing themes, livequery's fine, but this works too
                e = $(e.target);
                if(e.is('a')){
                        var li_index = 
$(this).children('li').index(e.parents('li'));
                        themes =$.grep(themes, function(n,i){
                                return (i != li_index);
                        });
                        buildThemesList();
                }
                return false;
        });
        //Add theme
        $('#AddTheme').click(function(){
                var levels = $('input:checkbox:checked'), subject = 
$('#Subject').val
(), temptheme = [];
                //validate before we go any further to avoid unnecessary 
operations
                if(levels.length==0 || subject == ''){
                        return false;
                }
                //process subject
                temptheme.push(subject);
                //process levels
                var levelCsv = []; //array to hold the levels
                levels.each(function(){
                        levelCsv.push(this.value);
                });
                temptheme.push(levelCsv);
                //process note
                temptheme.push($('#Note').val());
                //finally, add to the themes array
                themes.push(temptheme);
                //generate markup by rebuilding,
                buildThemesList();
        });
        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]+'<br />'
                        +(t[1].length>2?t[1].join(', ').replace(/(,\s)(\w+)$/,' 
e $2'):t
[1].join(', '))+'<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]).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);
                });
                //just to keep things exactly as the original example's UI
                $('#Index').val(themes.length);
        }
})(jQuery);

Also, syntax like  "var valid = new Boolean(true);" can just be var
valid = true;

Hope this gives you some ideas; I'll leave it to you to optimize (or
ignore) it :)

On Feb 17, 10:03 pm, Ricardo Tomasi <ricardob...@gmail.com> wrote:
> That's because you have that empty <li style="display:none"></li>. Is
> it really necessary?
>
> just decrement the index to start at 0:
>
> $('#Themes li').each(function(index){
>    index--;
>    $('input:hidden', this).each(function(){
>       var fixName = $(this).attr('name').replace(/\[\d\]/, '['+index
> +']');
>       $(this).attr('name', fixName);
>    });
>
> });
>
> cheers,
> - ricardo
>
> On Feb 17, 10:56 pm, shapper <mdmo...@gmail.com> wrote:
>
> > I added an input which shows the number of items in the list ...
>
> > The problem is that I am not able to reorder the list so it is 0
> > based ...
>
> > Any idea?
>
> > Thanks,
> > Miguel
>
> > On Feb 18, 1:48 am, shapper <mdmo...@gmail.com> wrote:
>
> > > I have been trying to make this work but no success ...
> > > ... in fact the inputs get undefined.
>
> > > I am not sure if I am using your function on the right way.
> > > The function should be called, I think, after adding or removing an
> > > item to reorder the ids.
>
> > > Anyway, I created an example:http://www.27lamps.com/Beta/List/List.html
>
> > > Please, not that you have to select a subject and at least one level
> > > to add it to the list.
>
> > > Could someone, please, help me out with this?
>
> > > Basically, every time I add or remove an item I need to reorder the
> > > names of the input fields.
>
> > > Please check my original message on this post. It explains the
> > > situation.
>
> > > Thanks,
> > > Miguel
>
> > > On Feb 12, 4:36 am, Ricardo Tomasi <ricardob...@gmail.com> wrote:
>
> > > > Probably not the most efficient function, but should work:
>
> > > > $('#ThemesList li').each(function(index){
> > > >   $('input:hidden', this).each(function(){
> > > >        var fixName = $(this).attr('name').replace(/\[\d\]/, '['+index
> > > > +']');
> > > >        $(this).attr('name', fixName);
> > > >   });
>
> > > > });
>
> > > > - ricardo
>
> > > > On Feb 11, 7:19 pm, shapper <mdmo...@gmail.com> wrote:
>
> > > > > Hello,
>
> > > > > I am adding and removing a items from a list, using JQuery, which is
> > > > > rendered has follows:
>
> > > > > <ol id="ThemesList">
> > > > >   <li">
> > > > >     <input type="hidden" name="Themes[0].Subject" value="A" />
> > > > >     <input type="hidden" name="Themes[0].Levels" value="L1,L2" />
> > > > >     <input type="hidden" name="Themes[0].Description" value="Paper" />
> > > > >   </li>
> > > > >   <li">
> > > > >     <input type="hidden" name="Themes[2].Subject" value="B" />
> > > > >     <input type="hidden" name="Themes[2].Levels" value="L1,L5" />
> > > > >   </li>
> > > > >   <li">
> > > > >     <input type="hidden" name="Themes[5].Subject" value="D" />
> > > > >     <input type="hidden" name="Themes[5].Levels" value="L2,L4" />
> > > > >     <input type="hidden" name="Themes[5].Description" value="Book" />
> > > > >   </li>
> > > > > </ol>
>
> > > > > Every time I add or remove a Theme I need to be sure that the list is
> > > > > ordered (name) starting with Themes[0].
>
> > > > > So basically I need to loop through each list item in list ThemesList.
> > > > > - In first list item all HIDDEN inputs names should start with "Themes
> > > > > [0]"
> > > > > - In second list item all HIDDEN inputs names should start with 
> > > > > "Themes
> > > > > [1]"
> > > > > ...
>
> > > > > So in this example, "Themes[2]. ..." would become "Themes[1]. ..." and
> > > > > "Themes[5]. ..." would become "Themes[2]. ..."
>
> > > > > Could someone please help me out?
>
> > > > > I have no idea how to do this.
>
> > > > > Thanks,
> > > > > Miguel

Reply via email to