1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

xfInsert'ing into a specific tab?

Discussion in 'XenForo Development Discussions' started by Myke623, Oct 16, 2014.

  1. Myke623

    Myke623 Active Member

    Dynamically inserting new content with ajax is all well and good when working in a flat list, like so:

    HTML:
    <ol id="myList">
            <li class="listItem"></li>
            <li class="listItem"></li>
            <li class="listItem"></li>
            <!-- insert here -->
    </ol>
    And the relevant js code would be:
    Code:
    $(e.ajaxData.templateHtml).xfInsert('insertAfter', '#myList li:last');
    But what if one has lists across multiple tabs, and you want to insert the new content in a specific tab? Consider:
    HTML:
    <ul id="myCategories">
        <li id="firstCategory">
            <ol class="listItems">
                <li class="listItem"></li>
                <li class="listItem"></li>
                <li class="listItem"></li>
                <!-- how do you insert here? -->
            </ol>
        </li>
        <li id="secondCategory">
            <ol class="listItems">
                <li class="listItem"></li>
                <li class="listItem"></li>
                <li class="listItem"></li>
                ...
            </ol>
        </li>
    </ul>
    In my particular case, new content is inserted via a form overlay. On this form you can select which category the item belongs to, via a drop-down menu. Once the form is submitted, I would like for the new item to be inserted in the correct tab.

    I know that I can pass variables into the javascript using data-foo tags, but how do I determine the value to set the variable as? For example, say the template looks as follows:
    Code:
    <form action="{xen:link 'myAddon/save'}" method="post" class="xenForm AutoValidator" id="AppendItem" data-list="????">
            <fieldset>
                <dl class="ctrlUnit">
                    <dt><label for="ctrl_category">Category:</label></dt>
                    <dd>
                        <select name="cat_id" class="textCtrl autoSize" id="ctrl_category">
                            <option value="firstCategory">First Category</option>
                            <option value="secondCategory">Second Category</option>
                        </select>
                    </dd>
                </dl>
             
                ...
    </form>
    What I'd really like to do is set the data-list attribute dynamically based on the option value that's selected in the Categories drop down.

    Is this possible? If not, then is there an alternative method?
     
  2. Myke623

    Myke623 Active Member

    Just to add, here's a screenshot of the tabs I'm referring to (and not to be confused with nav tabs):

    tab-lists.png
     
  3. Myke623

    Myke623 Active Member

    Almost got it working as I had originally surmised:

    This was just a case of adding some jQuery to the form which would:
    • Initialise the attribute 'data-list' to the currently selected option value, and
    • Whenever the selected option would change, to re-set the attribute
    Here's the jQuery, which is registered with the form, but works on the specific option select within it (named 'ctrl_category'):
    Code:
    OptionSelect: function($handle)
            {
                var $optTxt = $handle.find('#ctrl_category option:selected').text();
                $handle.attr('data-list', "#" + $optTxt);
              
                $handle.find('#ctrl_category').change(function() {
                  
                    $optTxt = $handle.find('#ctrl_category option:selected').text();
                    $handle.attr('data-list', "#" + $optTxt);
    
                });
            }
    Now, the above code works successfully by updating the form's data-list attribute accordingly.

    Also registered with the form is the following jQuery which appends the item to the bottom of the specific list:
    Code:
    AppendItem: function($form)
            {
                $form.on('AutoValidationComplete', function(e)
                {
                    new XenForo.ExtLoader(e.ajaxData, function()
                    {
                        // Escape any spaces in the ID, and select the last list item
                        var $anchor = $form.data('list').replace(' ', '\\ ') + ' li:last';
                       
                        // Append the new item to the anchor
                        $(e.ajaxData.templateHtml).xfInsert('insertAfter', $anchor);
                    });
                   
                });
            }
    
    When the form is submitted for the first time, it will successfully insert it as the last item in the correct tab that was chosen (via the option select). However, if I try to add a new item again, it will always append it to the previous tab, regardless of the the fact that data-list is being updated according to the option select value.

    If I reload the page, the items will re-appear in the correct tabs.

    It's as if the $anchor variable isn't being updated whenever data-list changes. What might be causing this?
     
  4. Myke623

    Myke623 Active Member

    Finally figured it out!

    While dynamically updating the data-list attribute in the form works fine, referencing $form.data('list') in the jQuery didn't seem to work. However, referencing the attribute as $form.attr('data-list') seems to do the trick. Final code below:

    Code:
    AppendItem: function($form)
    {
        $form.on('AutoValidationComplete', function(e)
        {
            new XenForo.ExtLoader(e.ajaxData, function()
            {
                // Escape any spaces in the ID, and select the last list item
                $anchor = $form.attr('data-list').replace(' ', '\\ ') + ' li:last';
              
                // Append the new item after the last list item found in our anchor
                $(e.ajaxData.templateHtml).xfInsert('insertAfter', $anchor);
            });
          
        });
    }
    
     

Share This Page