jQuery(document).ready(function($) { 'use strict'; /** * set up the buttons on the entire form */ function acfRepeaterCollapserInit() { // HTML to put above each repeater instance var i = 1, $collapseAllButton = '', $collapseSingleButtonTable = '
', $collapseSingleButton = ''; // find each repeater & flexible instance, add the button if the field uses the row layout $('.field_type-repeater, .field_type-flexible_content').each( function() { var $repeater = $(this); // only use this on row layout if( $( '.acf-input-table', $repeater ).hasClass('row_layout') ) { $repeater.data('acf-rowset-collapsed', false).attr('aria-expanded', false); // first: nested, second: parent if( $repeater.is( 'tr' ) ) { $repeater.children( 'td:last-child' ) .children( '.inner' ) .prepend( $collapseAllButton ) .data('acf-rowset-collapsed', false) .data('acf-repeater-nested', true); $('.row,.row-clone', $repeater ).data('acf-repeater-nested', true); } else { $repeater.prepend( $collapseAllButton ).data('acf-rowset-collapsed', false); } } }); // append single repeater collapse to each row of repeater field $('.field_type-repeater .row_layout .row,.field_type-repeater .row_layout .row-clone').each( function() { var id = 'acf-repeater-' + i, $that = $(this); $that.prepend( $collapseSingleButtonTable ) .data('acf-row-collapsed', false).attr('aria-expanded', true) .attr('id','acf-repeater-' + i) .attr('aria-live','off'); $('.field-repeater-toggle-single', $that.first().attr('aria-controls',id ) ); i++; }); // append single repeater collapse to flex fields $('.field_type-flexible_content .layout').each( function() { var $that = $(this), id = 'acf-repeater-' + i; if( $('.acf-input-table', $that).hasClass('row_layout') ) { i++; $that.prepend( $collapseSingleButton ) .data('acf-row-collapsed', false) .attr('aria-expanded', true) .attr('id','acf-repeater-' + i) .attr('aria-live','off'); $('.field-repeater-toggle-single', $that).first().attr('aria-controls',id); } }); // Bind click events to the toggle functions // delegated to higher DOM element to handle dynamically added repeaters $( '.field_type-repeater, .field_type-flexible_content' ).on( 'click', '.field-repeater-toggle-all', acfRepeaterToggleAll ); $( '.field_type-repeater .row_layout,.field_type-flexible_content' ).on( 'click', '.field-repeater-toggle-single', acfRepeaterToggleSingle ); // prevent default flexible field collapsing for clarity $('.field_type-flexible_content').on( 'click', '.acf-fc-layout-handle', false ); } /** * Collapse a row or rows */ function acfRepeaterCollapseRow( $rows ) { var $rowButtonText = $('.screen-reader-text', $rows); $rows.addClass('collapsed-row') .data('acf-row-collapsed', true) .attr('aria-expanded', false); $rowButtonText.text(acfrcL10n.expandRow); } /** * Expand a row or rows */ function acfRepeaterExpandRow( $rows ) { var $rowButtonText = $('.screen-reader-text', $rows); $rows.removeClass('collapsed-row') .data('acf-row-collapsed', false) .attr('aria-expanded', true); $rowButtonText.text(acfrcL10n.collapseRow); } /** * Indicate a collapsed rowset */ function acfRepeaterExpandRowset( $wrapper ) { var $button = $('.field-repeater-toggle-all', $wrapper).first(); $wrapper.removeClass('collapsed-repeater').data('acf-rowset-collapsed', false); $button.text(acfrcL10n.collapseRows); } /** * Indicate an expanded rowset */ function acfRepeaterCollapseRowset( $wrapper ) { var $button = $('.field-repeater-toggle-all', $wrapper).first(); $wrapper.addClass('collapsed-repeater') .data('acf-rowset-collapsed', true); $button.text(acfrcL10n.expandRows); } /** * toggles set of repeater rows or flexible fields */ function acfRepeaterToggleAll( event ) { var $rows, $that = $(this), $rowsetButton = $that, $rowsetWrapper = $that.parent(); // select either nested or unnested repeater rows, not both if( true === $rowsetWrapper.data('acf-repeater-nested') ) { $rows = $('.row:data(acf-repeater-nested),.layout', $rowsetWrapper); } else { $rows = $('.row,.layout', $rowsetWrapper).not(':data(acf-repeater-nested)'); } // toggle repeater state and all rows if( true !== $rowsetWrapper.data('acf-rowset-collapsed') ) { acfRepeaterCollapseRowset( $rowsetWrapper ); acfRepeaterCollapseRow( $rows ); } else { acfRepeaterExpandRowset( $rowsetWrapper ); acfRepeaterExpandRow( $rows ); } // prevent bubbling up to parent repeater rowset event.stopPropagation(); } /** * toggles single repeater row or flexible field */ function acfRepeaterToggleSingle( event ) { var $rowButton = $(this), $rowButtonText = $('.screen-reader-text', $rowButton), $row = $rowButton.closest('.row,.layout'), $rowsetWrapper; // select either parent repeater field wrapper if( true === $row.data('acf-repeater-nested') ) { $rowsetWrapper = $row.closest( '.inner' ); } else { $rowsetWrapper = $row.closest('.field_type-repeater,.field_type-flexible_content'); } // toggle the row state and button text if( true !== $row.data('acf-row-collapsed') ) { acfRepeaterCollapseRow( $row ); } else { acfRepeaterExpandRow( $row ); } if( true === acfRepeaterAllCollapsed( $rowsetWrapper ) ) { acfRepeaterCollapseRowset( $rowsetWrapper ); } else { acfRepeaterExpandRowset( $rowsetWrapper ); } // prevent bubbling up to parent row button event.stopPropagation(); } /** * check to see if all rows in a rowset are collapsed * @param obj $rowsetWrapper jquery object * @return bool true if all rows in rowset are collapsed */ function acfRepeaterAllCollapsed( $rowsetWrapper ) { var $rows, rowStates = [], allCollapsed; // select either nested or unnested repeater rows, not both if( true === $rowsetWrapper.data('acf-repeater-nested') ) { $rows = $('.row:data(acf-repeater-nested),.layout:data(acf-repeater-nested)', $rowsetWrapper); } else { $rows = $('.row,.values .layout', $rowsetWrapper).not(':data(acf-repeater-nested)'); } // store every row collapsed state in an array $rows.each( function() { rowStates.push( $(this).data('acf-row-collapsed') ); }); // check if any rows are expanded allCollapsed = 0 > $.inArray( false, rowStates ); return allCollapsed; } // Initiatilize the plugin acfRepeaterCollapserInit(); });