Skip to content

Commit

Permalink
added repeater block toggle header
Browse files Browse the repository at this point in the history
  • Loading branch information
MatthewKosloski committed Jun 26, 2017
1 parent cf3a7e4 commit d0ebe49
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 56 deletions.
151 changes: 102 additions & 49 deletions metabox_constructor_class.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class Metabox_Constructor {

const BLOCK_NAMESPACE = 'mcc-box'; // (A.K.A "Metabox Constructor Class")
const REPEATER_INDEX_PLACEHOLDER = 'CurrentCounter';
const REPEATER_ITEM_NUMBER_PLACEHOLDER = 'ItemNumber';

/**
* Stores the metabox config that
Expand Down Expand Up @@ -122,15 +123,39 @@ public function save() {
}
}

public function column($width, $contents) {
if(isset($width, $contents)) {
return sprintf(
'<div class="%s %s">%s</div>',
esc_attr( $this->get_element_class_with_namespace('col') ),
esc_attr( $this->get_element_class_with_namespace(sprintf('col-%d', $width)) ),
esc_html( $contents )
);
}
}

/**
* Returns a formatted string for a class name of a field element
* or non-field element.
* Returns a formatted string for a block-element (block__element) class name.
*
* @param string $block
* @param string $element
* @return string
*/
public function get_block_element_class($block, $element) {
if(isset($block, $element)) {
return trim(sprintf('%s__%s', $block, $element));
}
}

/**
* Returns a formatted string for a block-element (block__element) class name
* of a field element or non-field element prefixed with the namespace.
*
* @param string $element
* @param boolean $isField
* @return string
*/
public function get_block_element_class($element, $isField = true) {
public function get_block_element_class_with_namespace($element, $isField = true) {
if(isset($element)) {
return trim(sprintf(
'%s %s%s',
Expand All @@ -144,6 +169,23 @@ public function get_block_element_class($element, $isField = true) {
}
}

/**
* Returns a formatted string for a class name prefixed with
* the namespace.
*
* @param string $suffix
* @return string
*/
public function get_element_class_with_namespace($suffix) {
if(isset($suffix)) {
return trim(sprintf(
'%s-%s',
self::BLOCK_NAMESPACE,
$suffix
));
}
}

/**
* Echos some HTML that preceeds a field (container, label, description, etc.)
*
Expand All @@ -153,14 +195,14 @@ public function get_block_element_class($element, $isField = true) {
public function before_field($field, $meta = null) {
echo sprintf(
'<div class="%s %s">',
esc_attr( $this->get_block_element_class('field-container', false) ),
esc_attr( $this->get_block_element_class($field['type'].'-container', false) )
esc_attr( $this->get_block_element_class_with_namespace('field-container', false) ),
esc_attr( $this->get_block_element_class_with_namespace($field['type'].'-container', false) )
);

if(isset($field['label'])) {
echo sprintf(
'<label class="%s" for="%s">%s</label>',
esc_attr( $this->get_block_element_class('label', false) ),
esc_attr( $this->get_block_element_class_with_namespace('label', false) ),
esc_attr( $field['id'] ),
esc_html( $field['label'] )
);
Expand Down Expand Up @@ -189,7 +231,7 @@ public function after_field($field = null) {
public function get_field_description($desc) {
echo sprintf(
'<p class="%s">%s</p>',
esc_attr( $this->get_block_element_class('description', false) ),
esc_attr( $this->get_block_element_class_with_namespace('description', false) ),
esc_html( $desc )
);
}
Expand All @@ -206,7 +248,7 @@ public function get_image_preview($field, $meta) {
echo sprintf(
'<img id="%s" class="%s" src="%s" alt="%s">',
esc_attr( sprintf('js-%s-image-preview', $field['id']) ),
esc_attr( sprintf('%s %s', $this->get_block_element_class('image-preview', false), empty($meta) ? 'is-hidden' : '') ),
esc_attr( sprintf('%s %s', $this->get_block_element_class_with_namespace('image-preview', false), empty($meta) ? 'is-hidden' : '') ),
esc_attr( $meta ),
esc_attr( '' )
);
Expand Down Expand Up @@ -270,7 +312,7 @@ public function show_field_text($field, $meta) {
$this->before_field($field);
echo sprintf(
'<input type="text" class="%1$s" id="%2$s" name="%2$s" value="%3$s">',
esc_attr( $this->get_block_element_class($field['type']) ),
esc_attr( $this->get_block_element_class_with_namespace($field['type']) ),
esc_attr( $field['id'] ),
esc_attr( $meta )
);
Expand All @@ -281,7 +323,7 @@ public function show_field_textarea($field, $meta) {
$this->before_field($field);
echo sprintf(
'<textarea class="%1$s" id="%2$s" name="%2$s">%3$s</textarea>',
esc_attr( $this->get_block_element_class($field['type']) ),
esc_attr( $this->get_block_element_class_with_namespace($field['type']) ),
esc_attr( $field['id'] ),
esc_html( $meta )
);
Expand All @@ -292,7 +334,7 @@ public function show_field_checkbox($field, $meta) {
$this->before_field($field);
echo sprintf(
'<input type="checkbox" class="%1$s" id="%2$s" name="%2$s" %3$s>',
esc_attr( $this->get_block_element_class($field['type']) ),
esc_attr( $this->get_block_element_class_with_namespace($field['type']) ),
esc_attr( $field['id'] ),
checked(!empty($meta), true, false)
);
Expand Down Expand Up @@ -328,7 +370,7 @@ public function show_field_repeater($field, $meta) {
echo sprintf(
'<div id="%s" class="%s">',
esc_attr( sprintf('js-%s-repeated-blocks', $field['id']) ),
esc_attr( $this->get_block_element_class('repeated-blocks', false) )
esc_attr( $this->get_block_element_class_with_namespace('repeated-blocks', false) )
);

$count = 0;
Expand All @@ -350,7 +392,7 @@ public function show_field_repeater($field, $meta) {
%s
</a>',
esc_attr( sprintf('js-%s-add', $field['id']) ),
esc_attr( $this->get_block_element_class('add', false) ),
esc_attr( $this->get_block_element_class_with_namespace('add', false) ),
esc_html( sprintf('Add %s', $field['single_label']) )
);

Expand All @@ -374,7 +416,9 @@ public function show_field_repeater($field, $meta) {
var count = '.$count.';
$("#js-'. $field['id'] .'-add").on("click", function() {
var repeater = \''.$js_code.'\'.replace(/'. self::REPEATER_INDEX_PLACEHOLDER .'/g, count);
var repeater = \''.$js_code.'\'
.replace(/'. self::REPEATER_INDEX_PLACEHOLDER .'/g, count)
.replace(/'. self::REPEATER_ITEM_NUMBER_PLACEHOLDER .'/g, count + 1);
$("#js-'. $field['id'] .'-repeated-blocks").append(repeater);
count++;
return false;
Expand All @@ -384,49 +428,58 @@ public function show_field_repeater($field, $meta) {
}

public function get_repeated_block($field, $meta, $index, $isTemplate = false) {

echo sprintf(
'<div class="%s">',
esc_attr( $this->get_block_element_class('repeated', false) )
esc_attr( $this->get_block_element_class_with_namespace('repeated', false) )
);

echo sprintf('%s %d', $field['single_label'], $index + 1);

foreach($field['fields'] as $child_field) {
$old_id = $child_field['id'];

$child_field['id'] = sprintf(
'%s[%s][%s]',
$field['id'],
($isTemplate ? self::REPEATER_INDEX_PLACEHOLDER : $index),
$child_field['id']
);
// block header
echo sprintf(
'<div class="%s %s">
<p class="%s">%s</p>
<ul class="%s">
<li>
<a class="%s %s" title="%s">
<span class="dashicons dashicons-no"></span>
</a>
</li>
<li>
<a class="%s %s" title="Click and drag to sort">
<span class="dashicons dashicons-menu"></span>
</a>
</li>
</ul>
</div>',
esc_attr( $this->get_element_class_with_namespace('repeated-header', false) ),
esc_attr( $this->get_element_class_with_namespace('clearfix') ),
esc_attr( sprintf('%s %s %s', $this->get_block_element_class('repeated-header', 'title'), $this->get_element_class_with_namespace('col'), $this->get_element_class_with_namespace('col-6')) ),
esc_html( sprintf('%s '.($isTemplate ? '%s' : '%d'), $field['single_label'], ($isTemplate ? self::REPEATER_ITEM_NUMBER_PLACEHOLDER : $index + 1)) ),
esc_attr( sprintf('%s %s %s', $this->get_block_element_class('repeated-header', 'nav'), $this->get_element_class_with_namespace('col'), $this->get_element_class_with_namespace('col-6')) ),
esc_attr( $this->get_block_element_class_with_namespace('repeater-button', false) ),
esc_attr( $this->get_block_element_class_with_namespace('remove', false) ),
esc_attr( sprintf('Remove %s', $field['single_label']) ),
esc_attr( $this->get_block_element_class_with_namespace('repeater-button', false) ),
esc_attr( sprintf('js-%s-sort', self::BLOCK_NAMESPACE) )
);

$child_meta = isset($meta[$old_id]) && !$isTemplate ? $meta[$old_id] : '';
echo sprintf('<div class="%s is-hidden">', esc_attr( $this->get_block_element_class_with_namespace('repeated-content', false) ));
// populate block with fields
foreach($field['fields'] as $child_field) {
$old_id = $child_field['id'];

call_user_func( array($this, 'show_field_' . $child_field['type']), $child_field, $child_meta );
}
$child_field['id'] = sprintf(
'%s[%s][%s]',
$field['id'],
($isTemplate ? self::REPEATER_INDEX_PLACEHOLDER : $index),
$child_field['id']
);

// "remove" button
echo sprintf(
'<a class="%s %s button" title="Remove Item">
<span class="dashicons dashicons-no"></span>
</a>',
esc_attr( $this->get_block_element_class('repeater-button', false) ),
esc_attr( $this->get_block_element_class('remove', false) )
);
$child_meta = isset($meta[$old_id]) && !$isTemplate ? $meta[$old_id] : '';

// "sort" button
if($field['is_sortable']) {
echo sprintf(
'<a class="button %s %s" title="Click and drag to sort">
<span class="dashicons dashicons-menu"></span></span>
</a>',
esc_attr( $this->get_block_element_class('repeater-button', false) ),
esc_attr( sprintf('js-%s-sort', self::BLOCK_NAMESPACE) )
);
}

echo '</div>';
call_user_func( array($this, 'show_field_' . $child_field['type']), $child_field, $child_meta );
}
echo '</div></div>';
}

}
Expand Down
10 changes: 7 additions & 3 deletions script.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,25 @@

image_frame.on('select', function() {
var attachment = image_frame.state().get('selection').first().toJSON();
$('#image-' + id).val(attachment.url);
$('#image-'+id).val(attachment.url);

$('#js-'+id+'-image-preview').removeClass('is-hidden').attr('src', attachment.url);

$('.js-mcc-box-image-upload-button').text('Change Image');

$('#' + id).css({background: 'red'});
$('#'+id).css({background: 'red'});
});

image_frame.open();

});

$('.mcc-box__field-container').on('click', '.mcc-box-repeated-header', function(){
$(this).siblings('.mcc-box__repeated-content').toggleClass('is-hidden');
});

$('.mcc-box__repeated-blocks').on('click', '.mcc-box__remove', function() {
$(this).parent().remove();
$(this).siblings('.mcc-box__repeated').remove();
return false;
});

Expand Down
53 changes: 49 additions & 4 deletions style.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
margin-bottom: 16px;
}

.mcc-box-clearfix:after {
content: "";
display: table;
clear: both;
}

.mcc-box__label {
display: block;
margin-bottom: 4px;
Expand Down Expand Up @@ -41,21 +47,60 @@
display: none;
}

.mcc-box-repeated-header {
background-color: #008ec2;
color: #fff;
padding: 8px 12px;
cursor: pointer;
}

.repeated-header__title,
.repeated-header__nav {
margin: 5px 0 0 0;
}

.mcc-box-repeated-header a {
color: #fff;
cursor: pointer;
padding: 5px;
}

.mcc-box-repeated-header a:hover {
color: #ddd;
}

.repeated-header__nav {
text-align: right;
}

.repeated-header__nav li {
display: inline-block;
}

.mcc-box__repeated {
margin-bottom: 12px;
}

.mcc-box__repeated-content {
border: 1px solid #ddd;
background-color: #f5f5f5;
padding: 12px;
margin: 0 0 12px 0;
}

.mcc-box__repeated-content.is-hidden {
display: none;
}

.mcc-box__add span {
margin-top: 4px;
}

.mcc-box__repeater-button span {
margin-top: 3px;
.mcc-box-col {
display: block;
float: left;
}

.mcc-box__repeated .mcc-box__remove {
margin-right: 12px;
.mcc-box-col-6 {
width: 50%;
}

0 comments on commit d0ebe49

Please sign in to comment.