Skip to content

Commit

Permalink
Merge pull request #18 from mrwweb/v5
Browse files Browse the repository at this point in the history
V5 support! Hooray!
  • Loading branch information
mrwweb committed Aug 15, 2014
2 parents 385fa4e + fe08aa4 commit fc29bfa
Show file tree
Hide file tree
Showing 6 changed files with 376 additions and 29 deletions.
43 changes: 33 additions & 10 deletions acf_repeater_collapser.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,45 @@
* Plugin Name: Advanced Custom Fields Repeater Collapser
* Plugin URI: https://github.com/mrwweb/ACF-Repeater-Collapser
* Description: Provides a way to collapse and expand repeater field instances in order to enable better sorting.
* Version: 1.3.0
* Version: 1.4.0
* Author: Mark Root-Wiley
* Author URI: http://mrwweb.com
*/

define( 'ACF_REPEATER_COLLAPSER_VERSION', '1.4.0' );

/* Load the javascript and CSS files on the ACF admin pages */
// 11 helps take precedence over core styles
add_action( 'acf/input/admin_enqueue_scripts', 'acf_repeater_collapser_assets', 11 );
function acf_repeater_collapser_assets() {
wp_enqueue_script(
'acf_repeater_collapser_admin_js',
esc_url( plugins_url( 'js/acf_repeater_collapser_admin.js', __FILE__ ) ),
array( 'jquery' )
);
wp_enqueue_style(
'acf_repeater_collapser_admin_css',
esc_url( plugins_url( 'css/acf_repeater_collapser_admin.css', __FILE__ ) )
);
$acf_version = acf()->settings['version'];
if( version_compare( $acf_version, '4.0', '>=' ) && version_compare( $acf_version, '5.0', '<' ) ) {
// version 4.X
wp_enqueue_script(
'acf_repeater_collapser_admin_js',
esc_url( plugins_url( 'js/acf4_repeater_collapser_admin.js', __FILE__ ) ),
array( 'jquery' ),
ACF_REPEATER_COLLAPSER_VERSION
);
wp_enqueue_style(
'acf_repeater_collapser_admin_css',
esc_url( plugins_url( 'css/acf4_repeater_collapser_admin.css', __FILE__ ) ),
false,
ACF_REPEATER_COLLAPSER_VERSION
);
} elseif( version_compare( $acf_version, '5.0', '>=' ) ) {
// version 5.X
wp_enqueue_script(
'acf_repeater_collapser_admin_js',
esc_url( plugins_url( 'js/acf5_repeater_collapser_admin.js', __FILE__ ) ),
array( 'jquery' ),
ACF_REPEATER_COLLAPSER_VERSION
);
wp_enqueue_style(
'acf_repeater_collapser_admin_css',
esc_url( plugins_url( 'css/acf5_repeater_collapser_admin.css', __FILE__ ) ),
false,
ACF_REPEATER_COLLAPSER_VERSION
);
}
}
File renamed without changes.
92 changes: 92 additions & 0 deletions css/acf5_repeater_collapser_admin.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/* Expand / Collapse Buttons */
.field-repeater-toggle-all {
float:right;
margin: -5px 0 15px !important;
}

.button.field-repeater-toggle-single {
padding: 1px 1px 0 1px;
}
.layout .field-repeater-toggle-single {
margin: 0 5px 0 -5px;
}
.repeater-button-cell {
background: #f9f9f9 !important;
padding: 0 !important;
vertical-align: middle !important;
text-align: center !important;
border-right-color: #e1e1e1 !important;
width: 30px !important;
/* Sorry 'bout the !importants. They are gross. Sadly, so are the ACF selectors I have to battle. */
}
/* Grossness: http://css-tricks.com/absolutely-position-element-within-a-table-cell/ */
.repeater-button-cell-div {
position: relative;
}

.field_type-flexible_content .layout {
padding-left: 30px;
background: transparent;
}

.field_type-flexible_content .field-repeater-toggle-single {
position: absolute;
top: 50%;
margin-top: -15px;
left: 5px;
}
/* Weird positioning exception */
.field_type-flexible_content .field_type-repeater .field-repeater-toggle-single {
left: 8px;
}

.field_type-flexible_content .acf-fc-layout-handle {
background: #fff;
}

.field-repeater-toggle::before {
content: "\f506";
display: inline;
-webkit-font-smoothing: antialiased;
font: normal 20px/1 'dashicons';
vertical-align: text-bottom;
color: #777;
}
.field-repeater-toggle-all::before {
margin: 3px 5px 0 0;
}

.collapsed-repeater .field-repeater-toggle-all::before,
.collapsed-row .field-repeater-toggle-single::before {
content: "\f211";
}

.acf_flexible_content,
.repeater {
clear: both;
}

.acf-table {
position: relative;
}

.collapsed-row .acf-table tr {
display: none;
}

.collapsed-row .acf-table tr:first-child {
display: table-row;
}

/* "Masks" the first field in order to prevent clicking on it */
.collapsed-row .acf-table tr::after {
position: absolute;
top: 0; bottom: 0; left: 0px; right: 0;
display: block;
content: ' ';
background: -webkit-gradient(linear, left top, left bottom, from(rgba( 244, 244, 244, .2 )), to(rgba( 244, 244, 244, 1 )));
background: -o-linear-gradient( rgba( 244, 244, 244, .2 ), rgba( 244, 244, 244, 1 ) );
background: -moz-linear-gradient( rgba( 244, 244, 244, .2 ), rgba( 244, 244, 244, 1 ) );
background: -webkit-linear-gradient( rgba( 244, 244, 244, .2 ), rgba( 244, 244, 244, 1 ) );
background: linear-gradient( rgba( 244, 244, 244, .2 ), rgba( 244, 244, 244, 1 ) );
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,15 @@ jQuery(document).ready(function($) {
// 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() {
id = 'acf-repeater-' + i;
i++;

$(this).prepend( $collapseSingleButtonTable )
.data('acf-row-collapsed', false).attr('aria-expanded', true)
.attr('id','acf-repeater-' + i)
.attr('aria-live','off');
$('.field-repeater-toggle-single', $(this)).first()
.attr('aria-controls',id);

i++;
});

// append single repeater collapse to flex fields
Expand Down
214 changes: 214 additions & 0 deletions js/acf5_repeater_collapser_admin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
jQuery(document).ready(function($) {

/**
* set up the buttons on the entire form
*/
function acfRepeaterCollapserInit() {
// HTML to put above each repeater instance
$collapseAllButton = '<button type="button" role="button" class="button field-repeater-toggle field-repeater-toggle-all">Collapse All Rows</button>';
$collapseSingleButtonTable = '<td class="repeater-button-cell"><div class="repeater-button-cell-div"><button type="button" role="button" class="button field-repeater-toggle field-repeater-toggle-single"><span class="screen-reader-text">Collapse Row</span></button></div></td>';
$collapseSingleButton = '<button type="button" role="button" class="button field-repeater-toggle field-repeater-toggle-single"><span class="screen-reader-text">Collapse Row</span></button>';

// find each repeater & flexible instance, add the button if the field uses the row layout
$('.field_type-repeater, .field_type-flexible_content').each( function() {
$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' ) ) {
$( '.acf-repeater', $repeater ).first().prepend( $collapseAllButton );
$repeater
.data('acf-rowset-collapsed', false)
.data('acf-repeater-nested', true);
$('.acf-row,.acf-row.clone', $repeater ).data('acf-repeater-nested', true);
} else {
$repeater.prepend( $collapseAllButton )
.data('acf-rowset-collapsed', false);
}
}
});

// iterator for adding IDs/aria-controls attributes to repeater buttons
i = 1;
// append single repeater collapse to each row of repeater field
$('.field_type-repeater .row-layout > tbody > .acf-row,.field_type-repeater > tbody > .row-layout .acf-row.clone').each( function() {
id = 'acf-repeater-' + i;

$(this).prepend( $collapseSingleButtonTable )
.data('acf-row-collapsed', false)
.attr('aria-expanded', true)
.attr('id','acf-repeater-' + i)
.attr('aria-live','off');
$('.field-repeater-toggle-single', $(this)).first()
.attr('aria-controls',id);

i++;
});

// append single repeater collapse to flex fields
$('.field_type-flexible_content .layout').each( function() {
if( $('.acf-input-table', $(this)).hasClass('row-layout') ) {
id = 'acf-repeater-' + i;
i++;

$(this).prepend( $collapseSingleButton )
.data('acf-row-collapsed', false)
.attr('aria-expanded', true)
.attr('id','acf-repeater-' + i)
.attr('aria-live','off');

$('.field-repeater-toggle-single', $(this)).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 ) {
$rowButtonText = $('.screen-reader-text', $rows);
$rows.addClass('collapsed-row')
.data('acf-row-collapsed', true)
.attr('aria-expanded', false);
$rowButtonText.text('Expand Row')
}

/**
* Expand a row or rows
*/
function acfRepeaterExpandRow( $rows ) {
$rowButtonText = $('.screen-reader-text', $rows);
$rows.removeClass('collapsed-row')
.data('acf-row-collapsed', false)
.attr('aria-expanded', true);
$rowButtonText.text('Collapse Row');
}

/**
* Indicate a collapsed rowset
*/
function acfRepeaterExpandRowset( $wrapper ) {
$button = $('.field-repeater-toggle-all', $wrapper).first();

$wrapper.removeClass('collapsed-repeater')
.data('acf-rowset-collapsed', false);
$button.text('Collapse All Rows');
}

/**
* Indicate an expanded rowset
*/
function acfRepeaterCollapseRowset( $wrapper ) {
$button = $('.field-repeater-toggle-all', $wrapper).first();

$wrapper.addClass('collapsed-repeater')
.data('acf-rowset-collapsed', true);
$button.text('Expand All Rows');
}

/**
* toggles set of repeater rows or flexible fields
*/
function acfRepeaterToggleAll() {
$rowsetButton = $(this);
$rowsetWrapper = $(this).closest('.acf-field');

// select either nested or unnested repeater rows, not both
if( true === $rowsetWrapper.data('acf-repeater-nested') ) {
$rows = $('.acf-row:data(acf-repeater-nested),.layout', $rowsetWrapper);
} else {
$rows = $('.acf-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() {
$rowButton = $(this);
$rowButtonText = $('.screen-reader-text', $rowButton);
$row = $rowButton.closest('.acf-row,.layout');
$rowsetWrapper = $(this).closest('.acf-field');

// 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 ) {
// select either nested or unnested repeater rows, not both
if( true === $rowsetWrapper.data('acf-repeater-nested') ) {
$rows = $('.acf-row:data(acf-repeater-nested),.layout:data(acf-repeater-nested)', $rowsetWrapper).not('.clone');
} else {
$rows = $('.acf-row,.values .layout', $rowsetWrapper).not(':data(acf-repeater-nested)').not('.clone');
}

// store every row collapsed state in an array
var rowStates = new 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();

});
Loading

0 comments on commit fc29bfa

Please sign in to comment.