Rhyzz Repeatable-fields javascript in php and wordpress

I'm having a hard time figuring out why my repeatable fields javascript doesn't work. I'm using the following plugin: Rhyzz (repeatable-fields): http://www.rhyzz.com/repeatable-fields.html. I scraped the website and I see he ran the script inside html and also ran his javascript all on the same page. My website is a lot larger. I'm using Wordpress and I did the following to call the script in functions.php.

 wp_enqueue_script( 'jquery', 'https://code.jquery.com/jquery-1.11.2.min.js', array(), '20120206', true );
 wp_enqueue_script( 'jquery-ui', 'https://code.jquery.com/ui/1.11.4/jquery-ui.min.js', array(), '20120206', true );
 wp_enqueue_script( 'jquery-repeatable',  get_template_directory_uri() . '/js/repeatable.js', array( 'jquery', 'jquery-ui' ), '20120206', true );

I also have about another 10 scripts. The files are all in the proper directories. I then have a particular page on my site (PHP) implementing the repeatable fields, but none of the buttons work. I don't have the following anywhere, and I don't know if it's necessary, but on Rhyzz's site he puts it in his HTML:

jQuery(function() {
    jQuery('.repeat').each(function() {
        jQuery(this).repeatable_fields();
    });
});

I'm very frustrated and don't know what to do. I also don't know if I'm enqueueing the script properly, as in if I should pass in jquery and jquery-ui into the array field. If anyone can help me with this please do so!

Note: This is Rhyzz's GitHub with a tutorial on how to implement in HTML, https://github.com/Rhyzz/repeatable-fields.

Topic jquery-ui jquery Wordpress javascript

Category Web


Adding tested code example to the already good answer from @Dave Romsey

It is possible to use Rhyzz repeatable fields for meta-boxes. In fact a short time ago I was building a small testplugin for this! I wanted to get a simple repeatable WYSIWYG field. As this field type has some limitations, it was replaced with a normal textarea element.

So the following code was not live tested and should not be used as is, but should work.

First we must enqueue JQuery sortable, Rhyzz repeatable fields, and our own JS file to init.

/**
 * Enqueue our styles and scripts
 */
function prfx_enqueue_scripts() {

    // enqueue JQuery sortable
    wp_enqueue_script( 'jquery-ui-sortable', array( 'jquery' ) );
    // enqueue Rhyzz Repeatable-fields
    wp_enqueue_script( 'prfx-repeatable-fields-js', plugins_url('/inc/repeatable-fields/repeatable-fields.js', __FILE__), array( 'jquery' ) );
    // enqueue init JS
    wp_enqueue_script( 'prfx-init-js', plugins_url('/js/scripts.js', __FILE__) );
}
add_action( 'admin_enqueue_scripts', 'prfx_enqueue_scripts', 99 );

Now we create a new meta-box, for an example only on page post-types.

/**
 * Create custom metabox
 */
function prfx_add_meta_boxes() {
    add_meta_box( 
        'prfx_repeatable-fields', 
        'prfx_Repeatable Fields', 
        'prfx_callback', // see callback function below
        'page', // post-type
        'normal', 
        'default'
    );
}
add_action('admin_init', 'prfx_add_meta_boxes', 1);

Now we can create our callback function. In this function you will see the table HTML of Rhyzz repeatable fields templates.

I could not use the placeholder {{row-count-placeholder}}, so I ended up just using PHP to increase the row number.

/**
 * Callback function of our fields
 */
function prfx_callback() {
    global $post;

    // check our fields
    $repeatable_fields = get_post_meta($post->ID, 'an-input-field', true);

    // create a nonce for the field
    wp_nonce_field( 'prfx_repeatable_meta_box_nonce', 'prfx_repeatable_meta_box_nonce' ); ?>

<div class="repeat">
    <table class="wrapper" width="100%">
        <thead>
            <tr>
                <td width="100%" colspan="4"><span class="add button">Add Editor</span><hr></td>
            </tr>
        </thead>
        <tbody class="container">

    <?php if ($repeatable_fields) { 

        $i = 0;

         foreach ($repeatable_fields as $field) { 

            ++$i; ?>

            <tr class="row">

                <td width="100%" class="td">

                     <textarea rows="3" id="custom_editor_<?php echo $i; ?>" name="an-input-field[]" class="custom-editor-box"><?php echo $field; ?></textarea>

                     <p>
                        <hr>
                        <span class="move button">Move</span>
                        <span class="remove button">Remove</span>
                     </p>

                </td>

            </tr>

        <?php } 
    } ?>

        <!-- template row, if "Add" button is clicked, this template will show -->
        <tr class="template row">

                <td width="100%">

                    <textarea rows="3" id="custom_editor_0" name="an-input-field[]" class="custom-editor-box"></textarea>

                    <p>
                        <hr>
                        <span class="move button">Move</span>
                        <span class="remove button">Remove</span>
                    </p>

                </td>

        </tr>

        </tbody>
    </table>
</div>  
<?php }

And last, but not least, we also need a save function to save our repeatable fields.

/**
 * Save our metafields
 */
function prfx_repeatable_meta_box_save($post_id) {

    if ( ! isset( $_POST['prfx_repeatable_meta_box_nonce'] ) ||
    ! wp_verify_nonce( $_POST['prfx_repeatable_meta_box_nonce'], 'prfx_repeatable_meta_box_nonce' ) )
        return;

    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
        return;

    if (!current_user_can('edit_post', $post_id))
        return;

    if ( isset( $_POST['an-input-field'] ) ) {
        $contents = $_POST['an-input-field'];
        update_post_meta( $post_id, 'an-input-field', $contents );
    }

}
add_action('save_post', 'prfx_repeatable_meta_box_save');

This is the PHP code which is needed, now we just need to fill our scripts.js file like this:

jQuery(document).ready(function($){

    $('.repeat').each(function() {

        $(this).repeatable_fields({
            wrapper: '.wrapper',
            container: '.container',
            row: '.row',
            add: '.add',
            remove: '.remove',
            move: '.move',
            template: '.template',
            is_sortable: true, 
        });

    });

});

This example uses a normal textarea element.

Just a heads up if you want to use this technique with a WYSIWYG / editor field: This is more complicated as TinyMCE uses an iframe. For example you need to listen to JQuery sortable to remove the editor on sortable start, and re-add the editor on sortable stop. And also more problems are following (Ive been there).


Yes this is doable. Here's a tested solution to help you get up and running.

Enqueuing the scripts

WordPress already includes jQuery and jQuery UI so it's not necessary (or suggested, usually) to include them from an external source. Sometimes, JavaScript libraries will work using a declarative syntax, which means that they can be initialized by using certain ids, classes, or data attributes in the HTML. Other times (and this is most often the case), you will need to include some additional JavaScript to initialize the JavaScript library that you're trying to use. That seems to be the case with this repeatable fields script.

Here is the code that will enqueue the repeatable fields library and our initialization script. Make sure the paths are correct for your particular setup.

add_action( 'wp_enqueue_scripts', 'wpse_repeatable_scripts' );
function wpse_repeatable_scripts() {
    wp_enqueue_script(
        'jquery-repeatable',
        get_template_directory_uri() . '/js/repeatable-fields/repeatable-fields.js',
        array( 'jquery', 'jquery-ui-core' ),
        '20120206',
        true
    );

    wp_enqueue_script(
        'jquery-repeatable-init',
        get_template_directory_uri() . '/js/repeatable-init.js',
        array( 'jquery-repeatable' ),
        '20120206',
        true
    );  
}

repeatable-init.js

Here is the contents of repeatable-init.js, which initializes the repeatable fields library so that it attaches to markup using the .repeat class.

jQuery( document ).ready( function( $ ) {
    $( ".repeat" ).each( function() {
        $( this ).repeatable_fields();
    });
});

Finally, here is the HTML (via the developer's docs):

<div class="repeat">
    <table class="wrapper" width="100%">
        <thead>
            <tr>
                <td width="10%" colspan="4"><span class="add">Add</span></td>
            </tr>
        </thead>
        <tbody class="container">
        <tr class="template row">
            <td width="10%"><span class="move">Move</span></td>

            <td width="10%">An Input Field</td>

            <td width="70%">
                <input type="text" name="an-input-field[{{row-count-placeholder}}]" />
            </td>

            <td width="10%"><span class="remove">Remove</span></td>
        </tr>
        </tbody>
    </table>
</div>

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.