Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support any type of markup when customizing repeating group row #1187

Merged
merged 2 commits into from Dec 3, 2018

Conversation

lipemat
Copy link
Contributor

@lipemat lipemat commented Nov 13, 2018

Changes proposed in this pull request

Changing a groups markup can be accomplished quite easily using the render_row_cb argument when registering the group. If said customized group supported repeating and uses a div as the wrap of each group's fields, all repeat, delete, etc. group functionality works as expected.

However, If you use another element type such as li or tr in your customized group, the JS in it's current form will repeat the group as a div and not what it started as.

This one-liner fixes this edge case to support any element type with a customized group.

js/cmb2.js Outdated Show resolved Hide resolved
@lipemat lipemat force-pushed the feature/group-row-dynamic-markup branch 2 times, most recently from 0fbf49d to 82b0472 Compare November 14, 2018 12:03
@lipemat lipemat force-pushed the feature/group-row-dynamic-markup branch from 82b0472 to 6ee5efd Compare November 14, 2018 12:12
@lipemat lipemat force-pushed the feature/group-row-dynamic-markup branch from 6ee5efd to cf30a0f Compare November 14, 2018 12:15
@jtsternberg
Copy link
Member

That's a cool idea/use-case. Would you mind providing your render_row_cb and box/field registration code so we can test? I'm curious to see how you're handling it.

@lipemat
Copy link
Contributor Author

lipemat commented Nov 15, 2018

I found some time to flatten this even further to make it easier to test against :)
This is a drop-in which will register a group and add an image and caption as a repeatable table row.

function render_table_row_callback( $field_args, \CMB2_Field $field_group ) {
	$cmb = CMB2_Boxes::get( $field_group->cmb_id );
	$group_val = (array) $field_group->value();
	echo '<div class="cmb-row cmb-repeat-group-wrap cmb-group-table cmb-group-display-' . esc_attr( $field_group->args( 'display' ) ) . ' ' . esc_attr( $field_group->row_classes() ), '" data-fieldtype="group"><div class="cmb-td"><div data-groupid="' . esc_attr( $field_group->id() ) . '" id="' . esc_attr( $field_group->id() ) . '_repeat" ' . $cmb->group_wrap_attributes( $field_group ) . '>';
	echo '<table class="cmb-table" cellpadding="0" cellspacing="0">';

	?>
	<tr class="cmb-row">
		<th>&nbsp;</th>
		<?php
		foreach ( $field_group->args( 'fields' ) as $_field ) {
			echo '<th>' . esc_html( $_field['name'] ) . '</th>';
		}
		?>
		<th>&nbsp;</th>
	</tr>
	<?php

	if ( ! empty( $group_val ) ) {
		foreach ( $group_val as $group_key => $field_id ) {
			render_group_table_row( $field_group );
			$field_group->index ++;
		}
	} else {
		render_group_table_row( $field_group );
	}

	echo '</table>';

	if ( $field_group->args( 'repeatable' ) ) {
		echo '<div class="cmb-row"><div class="cmb-td"><p class="cmb-add-row"><button type="button" data-selector="' . esc_attr( $field_group->id() ) . '_repeat" data-grouptitle="{#}" class="cmb-add-group-row button-secondary">' . esc_html( $field_group->options( 'add_button' ) ) . '</button></p></div></div>';
	}

	echo '</div></div></div>';
	?>
	<style>
		.cmb-group-table th,.cmb-group-table.cmb-group-display-row .cmb-table{border-top:#DFDFDF solid 1px}.cmb-group-table table{width:100%}.cmb-group-table td:last-child,.cmb-group-table th:last-child{border-right:#DFDFDF solid 1px}.cmb-group-table td,.cmb-group-table th{border-left:#DFDFDF solid 1px;border-bottom:#DFDFDF solid 1px;padding:8px!important;vertical-align:top;text-align:left}.cmb-group-table.cmb-group-display-row td{padding-bottom:0!important}.cmb-group-table-control{width:16px;padding:0!important;vertical-align:middle!important;text-align:center!important;background:#f4f4f4;text-shadow:#fff 0 1px 0}.cmb-group-table .cmb-group-table-control a{float:none!important;display:block!important;margin:5px 0!important;text-align:center!important}.cmb-group-table-control a,.cmb-group-table-control h3{color:#aaa!important}.cmb-group-table-control a:hover,.cmb-group-table-control:hover h3{color:#23282d!important}.cmb-group-table .cmb-group-table-control .cmb-remove-group-row{color:#F55E4F!important;margin-top:12px!important}.cmb-repeatable-group.sortable .cmb-group-table-control:first-child{cursor:move}.cmb-group-table .cmb-group-title{position:relative;background:0 0;margin:0!important;padding:0!important}.cmb-group-table th{width:auto}.cmb-group-table .cmb-repeat-group-field{padding:0!important}
	</style>
	<?php

	return $field_group;
}

function render_group_table_row( \CMB2_Field $field_group ) {
	$cmb = CMB2_Boxes::get( $field_group->cmb_id );
	?>
	<tr class="cmb-row cmb-repeatable-grouping" data-iterator="<?= esc_attr( $field_group->index ); ?>">
		<?php
		if ( $field_group->args( 'repeatable' ) ) {
			?>
			<td class="cmb-group-table-control">
				<h3 class="cmb-group-title cmbhandle-title">
					<span><?= esc_html( $field_group->replace_hash( '{#}' ) ); ?></span>
				</h3>
			</td>
			<?php
		}

		foreach ( array_values( $field_group->args( 'fields' ) ) as $field_args ) {
			?>
			<td class="inside cmb-nested cmb-field-list">
				<?php
				if ( 'hidden' === $field_args['type'] ) {
					// Save rendering for after the metabox.
					$cmb->add_hidden_field( $field_args, $field_group );
				} else {
					$field_args['show_names'] = false;
					$cmb->get_field( $field_args, $field_group )->render_field();
				}
				?>
			</td>
			<?php
		}

		if ( $field_group->args( 'repeatable' ) ) {
			?>
			<td class="cmb-remove-field-row cmb-group-table-control">
				<div class="cmb-remove-row">
					<a href="javascript:void(0)" type="button"
					   data-selector="<?= esc_attr( $field_group->id() ); ?>_repeat"
					   class="cmb-remove-group-row cmb-remove-group-row-button button-secondary cmb-shift-rows"
					   title="<?= esc_attr( $field_group->options( 'remove_button' ) ); ?>">
						<span class="dashicons dashicons-no-alt"/>
					</a>
				</div>
			</td>
			<?php
		}
		?>
	</tr>
	<?php
}

add_action( 'cmb2_init', function () {
	$cmb = new_cmb2_box( [
		'id'           => 'example',
		'context'      => 'normal',
		'object_types' => [ 'page' ],
		'title'        => 'Example Box',
		'priority'     => 'high',
	] );

	$cmb->add_field( [
		'name'          => 'Table Group',
		'id'            => 'wiki_test_repeat_group',
		'type'          => 'group',
		'desc'          => '',
		'options'       =>
			[
				'sortable'      => true,
				'closed'        => false,
				'group_title'   => 'ITEM {#}',
				'add_button'    => 'Add One',
				'remove_button' => 'Remove One',
			],
		'position'      => 5,
		'render_row_cb' => 'render_table_row_callback',
	] );

	$cmb->add_group_field( 'wiki_test_repeat_group', [
		'name'         => 'IMG',
		'id'           => 'featured_image',
		'type'         => 'file',
		'desc'         => '',
		'options'      => [
			'url' => false,
		],
		'position'     => 0,
		'preview_size' => 'thumbnail',
		'text'         => [
			'add_upload_file_text' => 'Add image',
		],
		'query_args'   => [
			'type' => 'image',
		],
	] );

	$cmb->add_group_field( 'wiki_test_repeat_group', [
		'name'     => 'Caption',
		'id'       => 'caption',
		'type'     => 'text',
		'desc'     => '',
		'position' => 1,
	] );
} );

@jtsternberg jtsternberg merged commit 0e5be57 into CMB2:trunk Dec 3, 2018
jtsternberg added a commit that referenced this pull request Dec 3, 2018
@jtsternberg
Copy link
Member

Works great, thanks!

lipemat added a commit to lipemat/CMB2 that referenced this pull request Jul 19, 2019
…ng-for-groups

* upstream/trunk:
  Add props for CMB2#1147
  Some additional cleanup on CMB2#1147
  Add props for CMB2#1187
  Pull in the nodename, and default to div
  Make field description color accessible (fix color contrast ratio). h/t @rianrietveld. Fixes CMB2#1193
  Add optional mb_callback_args box property which allows defining args for add_meta_box. Closes CMB2#1191
  Update changelong to give @staurand props for CMB2#1190 (Fixes CMB2#1156)
  Revert file changes from CMB2#1190 and move gutenberg compatibility callback to main cmb JS file
  Update assets
  Fix tests: add cmb2-wysiwyg-gutenberg-fix as js dependency
  Fix CMB2#1156 / Update Gruntfile
  Fix CMB2#1156
  Updates 1187 - explicitly specifiy closing bracket when adding a new row to group
  support any type of markup when repeating group row
  Fix PR urls in changelog
  Add props for CMB2#1179
  Qa/phpcs cleanup (CMB2#1179)
  add our minimum required php version to the readme
  Update changelong to give props for CMB2#1177
  Another instance where we should use call_user_func() instead of direct call
  use call_user_func() instead of direct call.
  Add 3 custom field types from @scottsawyer to readme resources. Closes CMB2#1171
  update some more 3rd party resource items
  cleanup phpdocs for `php_to_js_dateformat`
  update 3rd party resources to include Leaflet Map field type. Props @villeristi
  Minor correction in URL
  Added new custom field type
  Tweak inline comments, and update changelog to give props for CMB2#1166
  Add CMB2_Field::get_rest_value method for sending value through several filters before sending to REST request
  WP_Http class constants were added in WP 4.5
  Doing it CMB2 way
  Fix the issue in WP prior to 4.7
  Add Switch Button field type to resources. Closes CMB2#1151
  make remove_default_tax_metaboxes method public so it may be called by hooks
  Call remove_default_tax_metaboxes from any type of post_hooks
  Add Props for CMB2#1142
  Update the draggable state's border style
  Fix docblock for CMB2_Type_Base::__call
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants