ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

safecracker update form

July 05, 2012 7:31am

Subscribe [2]
  • #1 / Jul 05, 2012 7:31am

    Alli

    158 posts

    I have a safecracker form for updating a channel.
    Most of it is working ok but I am not sure how to display this following category fields so that if the category is already selected, it will show on the update form:

    <label for="country_of_residence" class="required">Country:</label>
             <select name="country_of_residence" id="country"> 
                                            <option value="">Select Country</option>  
                       {exp:channel:categories channel="zoo_visitor" category_group="1" parent_only="yes" style="linear" parse="inward"}
                               <option value="{category_name}"}>{category_name}</option>
                           {/exp:channel:categories}</select> 
    
    
    
              <label for="region" class="required">Region:</label>       
              <select name="category[]" id="region"> 
                   <option value="">Select Region</option>
                 {exp:channel:categories channel="zoo_visitor" disable="category_fields" style="linear"}
                 {if parent_id == '0'}{if count != '1'}</optgroup>{/if}<optgroup label="{category_name}">{/if}
                 {if parent_id != '0'}<option value="{category_id}">{category_name}</option>{/if}
                 {/exp:channel:categories}
                </select> 
    
  • #2 / Jul 05, 2012 8:31am

    ipixel (Australia)

    158 posts

    You can try {selected}:

    <option value="{category_id}" {selected}>{category_name}</option>

    I’ve found it sometimes problematic though with regards to using {exp:channel:categories} within a Safecracker form. I know that you’re using a <select>, but here’s one of done with checkboxes, should be easy enough to adapt:

    <div id="specialty-categories-list">
      {categories group_id="1"}
        {if '{category_depth}' == '1'}<h4 class="toggle-next">{category_name}</h4>{/if}
        {if '{category_depth}' != '1'}<label class="checkbox"><input class="checkbox required" type="checkbox" value="{category_id}" name="category[]" id="specialty-{category_id}" {checked}> {category_name}</label><br>{/if}
      {/categories}
    </div>

    Note the difference of having to use {category_depth} rather than {parent_id} which isn’t available within the {categories} loop of Safecracker.

    Cheers
    Brendan

  • #3 / Jul 05, 2012 5:38pm

    Dan Decker

    7338 posts

    Hi Alli,

    Brendan’s example is really good, and you should avoid nesting the channel categories tag inside of SafeCracker if possible.

    The categories variable pair is available in SafeCracker and works just as Brendan has described.

    Cheers,

  • #4 / Jul 05, 2012 8:36pm

    ipixel (Australia)

    158 posts

    Yeah, just to be clear, for <select name=‘category[]’>‘s use {selected} to determine what’s previously been set in the categories. For <input type=“checkbox” name=‘category[]’> or <input type=“radio” name=‘category[]’> use {checked}.

    Dan, maybe some of these type of examples would be great added to the documentation. As it is I’m always going to the docs then remembering what I need to do is not in there, especially given the fact that many EE sites that are using Safecracker are generally sophisticated enough to warrant either multiple category groups or at least a category group with parent and child categories.

    Cheers
    Brendan

  • #5 / Jul 06, 2012 6:53am

    Alli

    158 posts

    Thanks guys
    That drop down works well for the safecracker registration page but… here’s an interesting thing…
    When I take the same code into a safecracker update form the country dropdown is empty and while the region dropdown shows the selected region, it also shows all the other countries and regions in the dropdown.

    I know it is probably do do with the fact that the parent category is automatically set to fill when the child is selected. Im just not sure how to remedy this while still linking the selects. Here’s the code I am using and the related jquery:

    <label for="country_of_residence">Country:</label>
             <select name="country_of_residence" id="country"> 
                                            <option value="">Select Country</option> 
           {categories group_id="1"}
           {if '{category_depth}' =="1"}  <option value="{category_name}" {selected}>{category_name}</option>{/if} 
                       {/categories}</select> 
    
    
    
             <label for="region">Region:</label>       
             <select name="category[]" id="region"> 
                  <option value="">Select Region</option>
               {categories group_id="1"}
                       {if '{category_depth}' == '1'}{if count != '1'}</optgroup>{/if}<optgroup label="{category_name}">{/if}
                          {if '{category_depth}' != '1'}<option value="{category_id}" {selected} >{category_name}</option>{/if}
                      {/categories}
                  </select>
    

    Jquery:

    [removed]
    
    (function($) {
    $.fn.dependent = function(opts) {
    
    opts.data = {};
    
    this.each(function() {
        $.each(opts.chain, function(index, selectID) {
            // identifier is #region then #city
            var ident = selectID.substr(1);
            var selectHTML = $(selectID).html();
    
            opts.data[ident] = {};
    
            // Data parsing for all selects
            $('<select>'+selectHTML+'</select>').find('optgroup').each(function() {
                var optGroup = $('<div>').append( $(this).eq(0).clone() ).html();
                var group = $(this).attr('label');
    
                opts.data[ident][group] = optGroup;
            });
    
            if(opts.chain[index+1]) {
                $(opts.chain[index]).bind('change', { 'nextID' : opts.chain[index+1] }, binding);
            }   
        });
        // Don't forget to bind the original select
        $(this).bind('change', { 'nextID' : opts.chain[0] }, binding);
    
    
        function binding(event) {
            var next = event.data.nextID.substr(1);
            $('#'+next).html(opts.data[next][$(this).val()]);
            $('#'+next).trigger('change');
        }  
    });
    }
    })(jQuery);
    
    
    
    
    
    
    $(document).ready(function() {
    $('#country').dependent({
    chain : ['#region']
    });
    });
    
    
    
    
    [removed]

     

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases