EllisLab text mark
Advanced Search
     
safecracker update form
Posted: 05 July 2012 07:31 AM   [ Ignore ]
Joined: 2008-08-28
245 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> <br />


          <
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> <br
 
Posted: 05 July 2012 08:31 AM   [ Ignore ]   [ # 1 ]   [ Rating: 0 ]
Joined: 2005-01-17
206 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

 Signature 

Brendan Underwood
ipixel web design & development

 
Posted: 05 July 2012 05:38 PM   [ Ignore ]   [ # 2 ]   [ Rating: 0 ]
Avatar
Joined: 2005-10-18
7340 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,

 Signature 

How may I help you?

 
Posted: 05 July 2012 08:36 PM   [ Ignore ]   [ # 3 ]   [ Rating: 0 ]
Joined: 2005-01-17
206 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

 Signature 

Brendan Underwood
ipixel web design & development

 
Posted: 06 July 2012 06:53 AM   [ Ignore ]   [ # 4 ]   [ Rating: 0 ]
Joined: 2008-08-28
245 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> <br />


         <
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><br

Jquery:

[removed]

(function($) {
$.fn.dependent = function(opts{

opts
.data {};

this.each(function() {
    
$.each(opts.chain, function(indexselectID{
        
// 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]