Quantcast
Channel: Tutorial Archives - Kathy is Awesome
Viewing all articles
Browse latest Browse all 14

Add a Repeating Text Field to Options Framework Plugin

$
0
0

Options framework repeating field
This is what we’ll be building.
I don’t hardly even know why I was working on this today.  Well a friend wanted to be able to control the radio buttons in a metabox, from the backend (since the otherwise brilliant WP-Alchemy is all dev-level coding) and for some reason  my brain went to theme option.  He ultimately went a different route and used Advanced Custom Fields.  But some days I just feel like not working and doing something fun, and the question of repeating fields in the theme options piqued my interest.  I asked Devin Price if his awesome Options Framework plugin has such a thing and he replied that no it didn’t exist…. yet. He wasn’t sure it was possible, which is like the worst thing to say to me. Of course it is possible! And now instead of working on something responsible, I will now solve this riddle. So I started digging into Options Framework. At first I thought that I would fork OF, but it turns out that all the functions/filters needed are already in place!   Wherever you have your $options array in your theme’s options.php to get a repeating field you’d define your custom option like so:

// add this to your $options array
$options[] = array(
'name' => __('Repeating Text', 'options_framework_theme'),
'desc' => __('A repeating text input field.', 'options_framework_theme'),
'id' => 'example_repeat',
'std' => 'Default',
'type' => 'repeat_text');

Then to handle all the parts of displaying this, scripting the repeat, and validating the data you’ll need the following group of functions, added to your theme’s functions.php.

Creating the Output

First, we need to output something when Options Framework gets running and encounters the custom option of type ‘repeat_text’. Devin has a catch-all filter already built-in, so we just have to attach a function to the {$option_type}_option_type filter, in this case repeat_text_option_type. This callback will create the input box (as many as needed by the array of values) plus one hidden one. It also creates the “Add New” button and for good fun we’ll throw in delete buttons next to each input. The markup (and later the script to handle the repeat) draws a lot of inspiration for WP Alchemy’s repeating groups.

// add this to your theme's functions.php

/* * Define a custom option type * this type will repeat some text inputs */

function repeat_text_option_type( $option_name, $option, $values ){

    $counter = 0;

    $output = '<div class="of-repeat-loop">';

    if( is_array( $values ) ) foreach ( (array)$values as $value ){

        $output .= '<div class="of-repeat-group">';
        $output .= '<input class="of-input" name="' . esc_attr( $option_name . '[' . $option['id'] . ']['.$counter.']' ) . '" type="text" value="' . esc_attr( $value ) . '" />';
        $output .= '<button class="dodelete button icon delete">'. __('Remove') .'</button>';

        $output .= '</div><!–.of-repeat-group–>';

        $counter++;
    }

    $output .= '<div class="of-repeat-group to-copy">';
    $output .= '<input class="of-input" data-rel="' . esc_attr( $option_name . '[' . $option['id'] . ']' ) . '" type="text" value="' . esc_attr( $option['std'] ) . '" />';
    $output .= '<button class="dodelete button icon delete">'. __('Remove') .'</button>';
    $output .= '</div><!–.of-repeat-group–>';

    $output .= '<button class="docopy button icon add">Add</button>';

    $output .= '</div><!–.of-repeat-loop–>';

    return $output;


}
add_filter( 'optionsframework_repeat_text', 'repeat_text_option_type', 10, 3 );

Sanitation and Saving

Options Framework won’t save anything unless the data gets run through a sanitization filter. The neat thing, is that if you set up the input names as name="somefield[1]" and so on, WordPress will automatically save all the “somefield” fields in an array. So we just need to rifle through the array and sanitize each text field. We can do this quickly with array_map. Next

/*
* Sanitize Repeat Fields
*/
function sanitize_repeat_field( $input, $option ){
$clean = '';
if( is_array( $input ) )
$clean = array_map( 'sanitize_text_field', $input);
return $clean;
}
add_filter( 'of_sanitize_repeat_text', 'sanitize_repeat_field', 10, 2 );

Style and Scripting the Repeating Fields

Finally, all the bells and whistles. What good is a repeating field if it doesn’t, you know, repeat. Again, I have to credit Dimas Begunoff for his WP Alchemy class. I’ve simplified some of what he was doing in metaboxes, by merely adding a data-rel to the hidden input. Then a few quick on handlers for the button click events and that hidden input we created earlier gets cloned and given a proper name attribute. Clicking a delete button, removes it’s associated input from the DOM.

/*
* Custom repeating field scripts
* Add and Delete buttons
*/
function of_repeat_script(){ ?>

    <style>
        #optionsframework .to-copy {display: none;}

        #optionsframework .of-repeat-group {
        overflow: hidden;
        margin-bottom: 1.4em;
        }
        #optionsframework .of-repeat-group .of-input {
        width: 80%;
        }

        .of-repeat-group .dodelete {
        float: right;
        }
    </style>

    <script type="text/javascript">
        jQuery(function($){

            $(".docopy").on("click", function(e){

                // the loop object
                $loop = $(this).parent();

                // the group to copy
                $group = $loop.find('.to-copy').clone().insertBefore($(this)).removeClass('to-copy');

                // the new input
                $input = $group.find('input');

                input_name = $input.attr('data-rel');
                count = $loop.children('.of-repeat-group').not('.to-copy').length;

                $input.attr('name', input_name + '[' + ( count - 1 ) + ']');

            });

            $(".of-repeat-group").on("click", ".dodelete", function(e){
                $(this).parent().remove();
            });

        });
    </script>
<?php
}
add_action( 'optionsframework_custom_scripts', 'of_repeat_script' );

Output

Because we’ve saved an array of data the if you try to echo out the results of of_get_option('example_repeat'); you will get Array. You have to loop through the array to print out each on individually with a foreach loop.

This is definitely beta-ish. For instance, I know it doesn’t take into account a way to set an array of defaults… like if you wanted to have two fields set up as the default. Maybe it is Google Chrome, but I’m also having a little issue with tab indexing. And finally… there was something else, but my mind just went blank. Get the full code from my Gist. As beta code, I am totally open to suggestions and improvements, but I won’t be able to help you set this up on your own sites. I’m just putting it out there for information purposes only. What would you use a repeating field for in theme options?


Viewing all articles
Browse latest Browse all 14

Latest Images

Trending Articles



Latest Images