views:

71

answers:

1

I am trying to have a form of text inputs. All inputs will in an ordered list OL/LI structure. There will be a + symbol next to the input that when you click on it, it should create a sub-OL and make a secondary list with another input. If you click it again, it adds another input. The new inputs have + symbols as well and you can do the same thing. I only technically want it to go three deep, but I think I can figure that part out later on, but what I'm really after is how to make this happen.

I have a beginning phase of it, but it's duplicating too much of the LI and I'm not sure what's going on. This is what I have.

    $('.add_sub_page').live('click',function(e){
    $("<ol>").append($(this).parent().clone()).insertAfter(this);
    e.preventDefault();
});

I brought this up an IRC chat room and I was provided with this solution, but it has the same issue as my first solution, so I'm not sure if it's easier to work with or not, so I will provide it as well.

    $('.add_sub_page').live('click',function(e){
    var ol = $("ol",this), new_ol = ol.length ? false : true;

    ol = new_ol ? $("<ol>") : ol;

    ol.append($(this).parent().clone());

    if (new_ol) {
        ol.insertAfter(this);
    }

    e.preventDefault();
});

And just so you can see what HTML I am working with...

<form id="sitemap" action="" method="post">
<ol>
    <li class="page-title"><label>Page Name: </label><input type="text" name="pages[]" value=""><a class="add_sub_page">+</a></li>
    <li class="page-title"><label>Page Name: </label><input type="text" name="pages[]" value=""><a class="add_sub_page">+</a></li>
    <li class="page-title"><label>Page Name: </label><input type="text" name="pages[]" value=""><a class="add_sub_page">+</a></li>
    <li class="page-title"><label>Page Name: </label><input type="text" name="pages[]" value=""><a class="add_sub_page">+</a></li>
    <li class="page-title"><label>Page Name: </label><input type="text" name="pages[]" value=""><a class="add_sub_page">+</a></li>
</ol>
<p><input type="submit" name="submit_step1" value="Next Step"></p>
</form>

You can preview the issue at http://jsbin.com/everu3 -- click the same Plus (+) sign twice to see the issue.

Thanks for any help you can provide!

+2  A: 

You just need to remove those child <ol> elements you added earlier when appending, like this:

$('.add_sub_page').live('click',function(e){
  $("<ol>").append($(this).parent().clone().children('ol').remove().end())
           .insertAfter(this);
  e.preventDefault();
});​

You can give it a try here, all we're doing different is when you're cloning it looks for .children() that are <ol> elements, perform a .remove() on them from the cloned set and use .end() to hop back up the chain to the original cloned element, since that's the one you want to append.


Edit: The original version created an <ol> per, to get the current numbering, we need one <ol> beside the <a> we're clicking. To do that change it up a bit like this:

$('.add_sub_page').live('click',function(e){
  $(this).parent(':not(:has(ol))').append('<ol></ol>');
  $(this).next().append($(this).parent().clone().children('ol').remove().end());
  e.preventDefault();
});​

Give it a try here. What this does is it goes to the parent, only if it doesn't have a <ol> and appends an <ol> (if it already has one the .append() wouldn't run in anything). Then we're just looking for that <ol> which should be the .next() element and appending to it.

Also here's a slightly modified version that stops at 3 levels:

$('.add_sub_page').live('click',function(e){
  $(this).parent(':not(:has(ol))').append('<ol></ol>').end()
         .next().append($(this).parent().clone().children('ol').remove().end());
  if($(this).parents('.page-title').length == 2)
     $(this).next().find('.add_sub_page').remove();
  e.preventDefault();
});​
Nick Craver
Hi Nick!That's really really close to what I'm going for, the only issue is that it's adding an OL around every single child instead of all the children. So instead of the LI list-style counting 1,2,3,4,etc it just repeats the number 1.I appreciate the initial push though! It's definitely a step in the right direction.
LostInQuery
@LostInQuery - Chrome disables numbering by default with my styling, let me take a look :)
Nick Craver
@LostInQuery - Is this what you're after? http://jsfiddle.net/nick_craver/GhDp7/1/
Nick Craver
That second example works great!!Thank you very much!
LostInQuery