Last active
May 24, 2016 09:04
-
-
Save mattheu/7563045 to your computer and use it in GitHub Desktop.
A custom CMB field type for some flexible content
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var CMB_Linklist = { | |
init : function ( field ) { | |
var _this = this; | |
_this.uniqueID = jQuery(field).find( '.linklist-wrap' ).attr( 'id' ); | |
field.find('button.cmb-linklist-toggle').click( function(e) { | |
e.preventDefault(); | |
_this.selectFieldType.call( _this, this ); | |
} ); | |
jQuery( '.linklist-type-field.linklist-postlink:visible' ).each( function() { | |
_this.postSelectInit( jQuery(this) ); | |
} ) | |
jQuery( '.linklist-type-field.linklist-pdflink:visible' ).each( function() { | |
_this.pdfSelectInit( jQuery(this) ); | |
} ) | |
}, | |
selectFieldType : function( btn ) { | |
btn = jQuery( btn ); | |
var _this = this, | |
fieldItem = btn.closest('.field-item'), | |
type = btn.attr('data-type'); | |
var typeInput = fieldItem.find( '.linklist-type-field.linklist-' + type ); | |
fieldItem.find( '.linklist-type-field' ).not( typeInput ).remove(); | |
typeInput.find( '.linklist-type' ).val( type ); | |
typeInput.show(); | |
_this.postSelectInit( typeInput ); | |
_this.pdfSelectInit( typeInput ); | |
}, | |
getPostSelectOptions : function () { | |
var postType = ( typeof( linklistPostType ) !== 'undefined' ) ? linklistPostType[this.uniqueID] : 'post'; | |
var options = { placeholder: "Type to search" }; | |
var query = JSON.parse( '{"showposts":-1,"post_type" : "' + postType + '", "orderby" : "title", "order" : "ASC" }' ); | |
options.data = []; | |
options.ajax = { | |
url: ajaxurl + "?action=cmb_ajax_linklist", | |
dataType: 'json', | |
data: function( term, page ) { | |
query.s = term; | |
query.paged = page; | |
return query; | |
}, | |
results : function( data, page ) { | |
return { results: data }; | |
} | |
}; | |
options.initSelection = function(element, callback) { | |
var id = jQuery( element ).val(); | |
if ( id === "" ) | |
return; | |
query.post__in = [ id ]; | |
jQuery.ajax( | |
ajaxurl + "?action=cmb_ajax_linklist", { | |
data: query, | |
dataType: "json" | |
} ).done(function(data) { | |
callback( data[0] ); | |
}); | |
}; | |
return options; | |
}, | |
postSelectInit : function( item ) { | |
var options = this.getPostSelectOptions(); | |
item.find('input.linklist-postlink-select').each( function( index, el ) { | |
if ( jQuery( el ).is( ':visible' ) && ! jQuery( el ).hasClass( 'select2-added' ) ) { | |
jQuery(el).addClass( 'select2-added' ).select2( options ); | |
} | |
} ); | |
}, | |
getPdfSelectOptions : function () { | |
var options = { placeholder: "Type to search" }; | |
var query = JSON.parse( '{ "showposts":-1, "post_type" : "attachment", "post_status" : "inherit", "post_mime_type" : "application/pdf", "orderby" : "title", "order" : "ASC" }' ); | |
options.data = []; | |
options.ajax = { | |
url: ajaxurl + "?action=cmb_ajax_linklist", | |
dataType: 'json', | |
data: function( term, page ) { | |
query.s = term; | |
query.paged = page; | |
return query; | |
}, | |
results : function( data, page ) { | |
return { results: data }; | |
} | |
}; | |
options.initSelection = function(element, callback) { | |
var id = jQuery( element ).val(); | |
if ( id === "" ) | |
return; | |
query.post__in = [ id ]; | |
jQuery.ajax( | |
ajaxurl + "?action=cmb_ajax_linklist", { | |
data: query, | |
dataType: "json" | |
} ).done(function(data) { | |
callback( data[0] ); | |
query.post__in = null; | |
}); | |
}; | |
return options; | |
}, | |
pdfSelectInit : function( item ) { | |
var options = this.getPdfSelectOptions(); | |
item.find('input.linklist-pdflink-select').each( function( index, el ) { | |
if ( jQuery( el ).is( ':visible' ) && ! jQuery( el ).hasClass( 'select2-added' ) ) { | |
jQuery(el).addClass( 'select2-added' ).select2( options ); | |
} | |
} ); | |
} | |
} | |
jQuery(document).ready( function() { | |
jQuery('.field.CMB_Linklist .field-item' ).each( function() { | |
CMB_Linklist.init( jQuery(this) ); | |
} ); | |
CMB.addCallbackForClonedField( 'CMB_Linklist', function( newT ) { | |
CMB_Linklist.init( newT ); | |
} ) | |
} ); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Custom CMB Field for displaying links of Legal/FAQ lists. | |
* | |
* Each field allows you to select either a heading, | |
* link (input both text and url), or select from a legal page or uploaded pdf. | |
*/ | |
class CMB_Linklist extends CMB_Field { | |
private $uniqid; | |
public function __construct( $name, $title, array $values, $args = array() ) { | |
add_action( 'admin_head', array( $this, 'wp_head' ) ); | |
parent::__construct( $name, $title, $values, $args ); | |
if ( ! isset( $this->args['linklist_post_type'] ) ) | |
$this->args['linklist_post_type'] = 'post' ; | |
$this->uniqid = uniqid(); | |
} | |
/** | |
* Output custom field style in head | |
* | |
* @return null | |
*/ | |
public function wp_head() { | |
?> | |
<script> | |
if ( typeof( linklistPostType ) === 'undefined' ) | |
linklistPostType = {}; | |
linklistPostType['<?php echo esc_js( $this->uniqid ); ?>'] = '<?php echo esc_js( $this->args['linklist_post_type'] ); ?>'; | |
</script> | |
<style> | |
.field.CMB_Linklist .field-item { background: rgba(0,0,0,0.05); background: #E9E9E9; border: 1px solid rgba(0,0,0,0.1); border-width: 1px; padding-top: 10px; padding-bottom: 0; margin-bottom: -1px !important; padding-left: 10px; } | |
.field.CMB_Linklist.sortable .field-item { padding-left: 20px; } | |
.field.CMB_Linklist input, | |
.field.CMB_Linklist button { margin-bottom: 10px; } | |
.linklist-type-field { padding-left: 140px; } | |
.field.CMB_Linklist .button.repeat-field { margin-top: 10px; } | |
.linklist-type-field-label { width: 120px; float: left; margin-left: -140px; padding-top: 4px; } | |
.linklist-type-field.linklist-link input { width: 45%; margin-right: 5px; } | |
.field.CMB_Linklist .cmb_element .ui-state-default .ui-icon { top: 50%; margin-top: -8px; right: 4px; } | |
.field.CMB_Linklist .select2-container { margin-bottom: 8px; } | |
.field.CMB_Linklist .cmb-delete-field { top: 16px; right: 4px; } | |
</style> | |
<?php | |
} | |
public function enqueue_scripts() { | |
parent::enqueue_scripts(); | |
wp_enqueue_script( 'cmb-linklist-script', get_stylesheet_directory_uri() . '/functions/js/cmb.field.linklist.js' ); | |
wp_enqueue_script( 'select2', trailingslashit( CMB_URL ) . 'js/select2/select2.js', array( 'jquery' ) ); | |
} | |
public function enqueue_styles() { | |
parent::enqueue_styles(); | |
wp_enqueue_style( 'select2', trailingslashit( CMB_URL ) . 'js/select2/select2.css' ); | |
} | |
public function parse_save_values() { | |
foreach ( $this->values as &$value ) | |
if ( $value['type'] === 'postlink' || $value['type'] === 'pdflink' ) | |
$value['title'] = basename( get_permalink( $value['text'] ) ); | |
} | |
/** | |
* The output. | |
* | |
* @return null | |
*/ | |
public function html() { | |
$data = $this->value; | |
$type = ! empty( $data['type'] ) ? $data['type'] : false; | |
$post_type = get_post_type_object( $this->args['linklist_post_type'] ); | |
?> | |
<div class="linklist-wrap" id="<?php echo esc_attr( $this->uniqid ); ?>"> | |
<?php if ( empty( $this->value['type'] ) ) : ?> | |
<div class="linklist-type-field linklist-type-select" style="<?php if ( false !== $type ) echo 'display: none;'?>"> | |
<label class="linklist-type-field-label">Select list item type.</label> | |
<button class="button cmb-linklist-toggle" data-type="heading">New Heading</button> | |
<button class="button cmb-linklist-toggle" data-type="link">New Link</button> | |
<button class="button cmb-linklist-toggle" data-type="postlink">New <?php echo esc_html( $post_type->labels->singular_name ); ?> Link</button> | |
<button class="button cmb-linklist-toggle" data-type="pdflink">New PDF Link</button> | |
</div> | |
<?php endif; ?> | |
<?php if ( empty( $this->value['type'] ) || ! empty( $this->value['type'] ) && 'link' === $this->value['type'] ) : ?> | |
<div class="linklist-type-field linklist-link" style="<?php if ( 'link' !== $type ) echo 'display: none;'?>"> | |
<label <?php $this->for_attr( 'text' ); ?> class="linklist-type-field-label">Link</label> | |
<input type="text" <?php $this->id_attr( 'text' ); ?> <?php $this->boolean_attr(); ?> <?php $this->class_attr(); ?> <?php $this->name_attr( '[text]' ); ?> value="<?php echo esc_attr( ! empty( $data['text'] ) ? $data['text'] : null ); ?>" placeholder="Link Text"/> | |
<input type="text" <?php $this->id_attr( 'url' ); ?> <?php $this->boolean_attr(); ?> <?php $this->class_attr( 'code' ); ?> <?php $this->name_attr( '[url]' ); ?> value="<?php echo esc_url( esc_attr( ! empty( $data['url'] ) ? $data['url'] : null ) ); ?>" placeholder="Link URL"/> | |
<input type="hidden" class="linklist-type" <?php $this->id_attr( 'type' ); ?> <?php $this->name_attr( '[type]' ); ?> value="link" /> | |
</div> | |
<?php endif; ?> | |
<?php if ( empty( $this->value['type'] ) || ! empty( $this->value['type'] ) && 'heading' === $this->value['type'] ) : ?> | |
<div class="linklist-type-field linklist-heading" style="<?php if ( 'heading' !== $type ) echo 'display: none;'?>"> | |
<label class="linklist-type-field-label" <?php $this->for_attr( 'text' ); ?>><b>Heading</b></label> | |
<input type="text" <?php $this->id_attr( 'text' ); ?> <?php $this->boolean_attr(); ?> <?php $this->class_attr(); ?> <?php $this->name_attr( '[text]' ); ?> value="<?php echo esc_attr( ! empty( $data['text'] ) ? $data['text'] : null ); ?>"/> | |
<input type="hidden" class="linklist-type" <?php $this->id_attr( 'type' ); ?> <?php $this->name_attr( '[type]' ); ?> value="heading" /> | |
</div> | |
<?php endif; ?> | |
<?php if ( empty( $this->value['type'] ) || ! empty( $this->value['type'] ) && 'postlink' === $this->value['type'] ) : ?> | |
<div class="linklist-type-field linklist-postlink" style="<?php if ( 'postlink' !== $type ) echo 'display: none;'?>"> | |
<?php $val = isset( $this->value['text'] ) ? array( $this->value['text'] => get_the_title( $this->value['text'] ) ) : array(); ?> | |
<label <?php $this->for_attr(); ?> class="linklist-type-field-label">Select <?php echo $post_type->labels->singular_name; ?></label> | |
<input <?php $this->id_attr(); ?> <?php $this->name_attr( '[text]' ); ?> class="linklist-postlink-select" style="width: 100%" value="<?php echo isset( $this->value['text'] ) ? esc_attr( $this->value['text'] ) : null; ?>"/> | |
<input type="hidden" class="linklist-type" <?php $this->id_attr( 'type' ); ?> <?php $this->name_attr( '[type]' ); ?> value="postlink" /> | |
</div> | |
<?php endif; ?> | |
<?php if ( empty( $this->value['type'] ) || ! empty( $this->value['type'] ) && 'pdflink' === $this->value['type'] ) : ?> | |
<div class="linklist-type-field linklist-pdflink" style="<?php if ( 'pdflink' !== $type ) echo 'display: none;'?>"> | |
<?php $val = isset( $this->value['text'] ) ? array( $this->value['text'] => get_the_title( $this->value['text'] ) ) : array(); ?> | |
<label <?php $this->for_attr(); ?> class="linklist-type-field-label">Select PDF</label> | |
<input <?php $this->id_attr(); ?> <?php $this->name_attr( '[text]' ); ?> class="linklist-pdflink-select" style="width: 100%" value="<?php echo isset( $this->value['text'] ) ? esc_attr( $this->value['text'] ) : null; ?>"/> | |
<input type="hidden" class="linklist-type" <?php $this->id_attr( 'type' ); ?> <?php $this->name_attr( '[type]' ); ?> value="pdflink" /> | |
</div> | |
<?php endif; ?> | |
</div> | |
<?php } | |
} | |
/** | |
* Ajax callback for legal post select. | |
* | |
* @return null | |
*/ | |
function cmb_ajax_linklist() { | |
$query = new WP_Query( $_GET ); | |
$posts = $query->posts; | |
$json = array(); | |
foreach ( $posts as $post ) | |
$json[] = array( 'id' => $post->ID, 'text' => get_the_title( $post->ID ) ); | |
echo json_encode( $json ); | |
exit; | |
} | |
add_action( 'wp_ajax_cmb_ajax_linklist', 'cmb_ajax_linklist' ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment