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

Format Parameters In XenForo Options

Discussion in 'XenForo Development Discussions' started by TheBigK, Aug 19, 2015.

  1. TheBigK

    TheBigK Well-Known Member

    My addon requires the option to be displayed in the following format :-

    [...department name...] : [ ...email address.....] (+)

    Clicking on + button at the end will duplicate these fields in the above mentioned format just below. I have therefore created a new Contact Group inside Options, and now creating a new option in it. I'm stuck with 'Edit Format' and 'Format Parameters'.

    I'm guessing that in order to display the option fields like above, I will have to write HTML in a template and then fetch it. I think the way to do this is to select:

    Edit Format: 'Named Template'
    Default Value = 'The Template Name?' Or What?

    I couldn't find relevant information about using 'Named Template' and 'PHP Callback'. Can someone tell me how do they work?
     
  2. katsulynx

    katsulynx Well-Known Member

    My Tutorial on how to create an ACP option with unlimited entries deals with using a named template if you're interested in an example. To answer your question: When you say "Edit Format = Named Template", the "Format Parameter" has to be the name of the (admin) template, while the default value is - as the name implies - still the default value of the field (in my guide it is an empty array for example).
     
    Sean Kendle and TheBigK like this.
  3. TheBigK

    TheBigK Well-Known Member

    Hey thanks, @katsulynx . Your tutorial is exactly what I need :) Thanks a lot!
     
    katsulynx likes this.
  4. TheBigK

    TheBigK Well-Known Member

    @katsulynx - I explored several templates and tried to figure a way to make my add-on work. My addon does this:

    1. In AdminCP Options, adds a new option: Department Names and Email:
    [Department Name ] [Department Email]
    (Add New Department) ---> This repeats above fields, just like mentioned in your tutorial. But my add-on has two input fields instead of one as described in the tutorial.

    Now, I'm really not sure how to make this work with controller. What variables should I define in my template? Basically, what really should my ControllerAdmin's $viewParams define?
     
  5. katsulynx

    katsulynx Well-Known Member

    Using two instead of one field is a bit tricky. You could work around by handling two options inside one template, but I'd rather store them into the same option, which requires a different workaround. I'm using the following template to handle an option-array with two fields:

    HTML:
    <xen:controlunit label="{$preparedOption.title}:">
        <ul id="{$preparedOption.title}Container" class="FieldChoices">
            <xen:foreach loop="$preparedOption.option_value" key="$key" value="$option">
            <xen:if is="{$option.name}">
                <li>
                    <input type="text" name="{$fieldPrefix}[{$preparedOption.option_id}][{$key}][value]" value="{$option.name}" class="textCtrl" placeholder="{xen:phrase acp_tesbooksugestions_bookname}" size="25" />
                    <input type="text" name="{$fieldPrefix}[{$preparedOption.option_id}][{$key}][text]" maxlength="25" value="{$option.alt}" class="textCtrl" placeholder="{xen:phrase acp_tesbooksugestions_bookalt}" size="25" />
                </li>
                <xen:set var="$cur_key">{$key}</xen:set>
            </xen:if>
            </xen:foreach>
            <li>
                <input type="text" name="{$fieldPrefix}[{$preparedOption.option_id}][{xen:calc '{$cur_key} + 1'}][value]" class="textCtrl" placeholder="{xen:phrase value}..." size="25" />
                <input type="text" name="{$fieldPrefix}[{$preparedOption.option_id}][{xen:calc '{$cur_key} + 1'}][text]" maxlength="25" class="textCtrl" placeholder="{xen:phrase text}..." size="25" />
            </li>
        </ul>
      
        <input type="button" value="{xen:phrase add_additional_choice}" id="{$preparedOption.title}Adder" class="button smallButton FieldAdder" data-source="ul.FieldChoices li" />
      
        <p class="explain" style="margin-top: 10px;">{xen:raw $preparedOption.explain}</p>
        {xen:raw $editLink}
    </xen:controlunit>
    
    <script>
    $(document).ready(function() {
        $('#{$preparedOption.title}Adder').click(function() {
            $('#{$preparedOption.title}Container').children().last().children().each(function() {
                $(this).attr('name',$(this).attr('name').replace( /(\d+)/, function(){return arguments[1]*1+1}));
            });
        });
    });
    </script>
    After that, {$xenOptions.yourOption} contains a multidimensional array of the form:
    1. -> Value, Text
    2. -> Value, Text
    So every entry contains your desired values. The script at the end is the workaround to ensure everything is saved correctly, as HTML->PHP cannot handle the array-wildcard [] when fields follow. It essentialy just ensures the numeration of all fields is correct, so that all values are stored. There's no need to change the script even if you add more fields, just change the value in the last brackets (where there's now 'value' and 'text').

    You can simply call it in your template by looping through {$xenOptions.yourOption}.
     
  6. TheBigK

    TheBigK Well-Known Member

    Thanks @katsulynx . I think a better approach would be to use PHP callback instead of named template?
     
  7. katsulynx

    katsulynx Well-Known Member

    A callback would essentially just allow you to process your data before showing them in a named template. The problems from above would persist though.
     
  8. TheBigK

    TheBigK Well-Known Member

    Thanks! I'm yet to dive into JS and now exploring the way XenForo does this. I checked the way they handle user fields and it looks straightforward. Let's see how it works out. Didn't expect to be complicated!
     
  9. Sean Kendle

    Sean Kendle Member

    @katsulynx I tried this example and the options don't seem to save. Can you tell me what I'm doing wrong? I copied the code directly.
     
  10. Sean Kendle

    Sean Kendle Member

    Also, for debugging purposes, where do these values get saved in the database?

    EDIT:

    Values of options are saved (helpfully) in the database under the xf_options table. Their values are BLOBs, so MySQL Workbench (v5.2.x) won't show you their values, and you'll have to select against the table like so (replace YOUR_OPTION_ID with the named option ID you set in the Edit Option section:

    Code:
    SELECT *, SUBSTRING(option_value,1,2000)  FROM lsdemo.xf_option
    WHERE option_id = 'YOUR_OPTION_ID'
    ;
     
    Last edited: Nov 25, 2015
  11. Sean Kendle

    Sean Kendle Member

    @TheBigK did you ever get multiple textbox options working? I need some help here! Thanks!
     
  12. Sean Kendle

    Sean Kendle Member

    Ok, after hours of frustration, I figured this out. @katsulynx, please correct me if I'm wrong, but I think your example has a few errors.

    It was trying to set the value fields of the input elements to $option.name and $option.alt, when it should have set them to $option.text and $option.value!

    Also, the <xen:if is="{option.name}"> line should have been <xen:if is="{option.text}"> (or .value)!

    (Make sure you have an asterisk in the "Array Sub-Options" field, and you don't need anything in the Default field.)

    Code:
    <xen:controlunit label="{$preparedOption.title}:">
        <ul id="{$preparedOption.title}Container" class="FieldChoices">
            <xen:foreach loop="$preparedOption.option_value" key="$key" value="$option">
            <xen:if is="{$option.text}">
                <li>
                    <input type="text" name="{$fieldPrefix}[{$preparedOption.option_id}][{$key}][value]" value="{$option.value}" class="textCtrl" placeholder="{xen:phrase value}" size="25" />
                    <input type="text" name="{$fieldPrefix}[{$preparedOption.option_id}][{$key}][text]" maxlength="25" value="{$option.text}" class="textCtrl" placeholder="{xen:phrase text}" size="25" />
                </li>
                <xen:set var="$cur_key">{$key}</xen:set>
            </xen:if>
            </xen:foreach>
            <li>
                <input type="text" name="{$fieldPrefix}[{$preparedOption.option_id}][{xen:calc '{$cur_key} + 1'}][value]" class="textCtrl" placeholder="{xen:phrase value}..." size="25" />
                <input type="text" name="{$fieldPrefix}[{$preparedOption.option_id}][{xen:calc '{$cur_key} + 1'}][text]" maxlength="25" class="textCtrl" placeholder="{xen:phrase text}..." size="25" />
            </li>
        </ul>
    
        <input type="button" value="{xen:phrase add_additional_choice}" id="{$preparedOption.title}Adder" class="button smallButton FieldAdder" data-source="ul.FieldChoices li" />
    
        <p class="explain" style="margin-top: 10px;">{xen:raw $preparedOption.explain}</p>
        {xen:raw $editLink}
    </xen:controlunit>
    
    <script>
    $(document).ready(function() {
        $('#{$preparedOption.title}Adder').click(function() {
            $('#{$preparedOption.title}Container').children().last().children().each(function() {
                $(this).attr('name',$(this).attr('name').replace( /(\d+)/, function(){return arguments[1]*1+1}));
            });
        });
    });
    </script>
    I thought my code wasn't saving at first, but that was because it wasn't setting the value fields of the input elements to the proper $option value!

    Also, it wasn't entering the for statement at all, due to it checking a variable that was never set!
     
    Last edited: Nov 25, 2015

Share This Page