Support » Plugin: CMB2 » cmb2_before_form related question

  • Resolved moxymore

    (@moxymore)


    Hi there,

    I’m finally giving a try to your plugin. I have a question regarding the ability to add custom html just before a form of an option page (admin backend area).

    I have found your cmb2_before_form hook, but how can I add it only for specific form id?

    Regards.

Viewing 12 replies - 1 through 12 (of 12 total)
  • Allright, I got it. I have used instead the ‘display_cb’ parameter of ‘new_cmb2_box’ in order to generate the output.

    Plugin Author Michael Beckwith

    (@tw2113)

    The BenchPresser

    Here’s the code in question, if I’m not mistaken.

    /**
     * Hook before form table begins
     *
     * @param array  $cmb_id      The current box ID.
     * @param int    $object_id   The ID of the current object.
     * @param string $object_type The type of object you are working with.
     *                            Usually <code>post</code> (this applies to all post-types).
     *                            Could also be <code>comment</code>, <code>user</code> or <code>options-page</code>.
     * @param array  $cmb         This CMB2 object.
     */
    do_action( 'cmb2_before_form', $this->cmb_id, $object_id, $object_type, $this );
    
    /**
     * Hook before form table begins
     *
     * The first dynamic portion of the hook name, $object_type, is the type of object
     * you are working with. Usually <code>post</code> (this applies to all post-types).
     * Could also be <code>comment</code>, <code>user</code> or <code>options-page</code>.
     *
     * The second dynamic portion of the hook name, $this->cmb_id, is the meta_box id.
     *
     * @param array  $cmb_id      The current box ID
     * @param int    $object_id   The ID of the current object
     * @param array  $cmb         This CMB2 object
     */
    do_action( "cmb2_before_{$object_type}_form_{$this->cmb_id}", $object_id, $this );
    

    First one is kind of a generic one, but does pass the CMB box ID, object ID which would be post ID in this case, the object type, and then the current CMB2 object. You could use the object ID for instances of needing the post ID, and the object type would be useful for only certain post types or similar.

    Second one is a bit more specific and would be useful for more conditional situations and less work. For example, if you wanted the output only be on a “portfolio” post type and a CMB2 box ID of “sample”, you would have a hook like cmb2_before_portfolio_form_sample and then the current portfolio post type and CMB2 object would be passed in as extra parameters for you.

    Plugin Author Justin Sternberg

    (@jtsternberg)

    @tw2113 is right in that the 2nd hook is probably what you want. However the “object_type” variable represents the type of object, not the post type, as denoted in the code comment.
    The first dynamic portion of the hook name, $object_type, is the type of object you are working with. Usually post (this applies to all post-types). Could also be comment, user or options-page.

    So the hook name you would use would be cmb2_before_options-page_form_box_id, where box_id represents the id you have given to the box.

    Allright, thank you for these answers, this helped me to better understand the whole process. But as said previously, the “display_cb” parameter fits perfectly for what I expected to do.

    I have another question, and I have searched on the web for a long time. If I must open a new topic, just reply to this post in order for me to post another one.

    I wonder if cmb2 is now able to dynamically set group titles? I have found a lot of post, from 2 years ago, speaking of it : https://github.com/CMB2/CMB2/issues/706. Have you added something other than these 2 tricks (a javascript based one, and a customization of group title hash replacement)?

    I never code in JS, i’ll be lost. If you can provide me some kind of information, it would be nice. Basically, my problem is this one :

    – I have a menu divided in several submenu working perfectly
    – In one of my submenu, I have added a group field (repeater) in which I expected to add dynamically the name of the group added by the user.
    – I can grab the data properly, I see the array without any problem :

    $values=cmb2_get_option( 'gia_cpt_options', 'gia_add_cpt' );
    var_dump($values);
    
    foreach ($values as $value) {
    	var_dump ($value['singular_name']);
    }

    – But because I can’t use a foreach loop in parameters, I’m kinda stuck.

    Regards.

    • This reply was modified 9 months, 1 week ago by moxymore.
    • This reply was modified 9 months, 1 week ago by moxymore.

    [EDIT] It’s allright, I have properly added this snippet and it works as expected.

    But feel free to post another pure PHP/MYSQL option if it exists 😉

    Thanks again for the help.

    Plugin Author Justin Sternberg

    (@jtsternberg)

    PHP option isn’t sufficient because it doesn’t account or the add/remove group methods that happens in Javascript. The javascript approach is the right one.

    Allright.

    A last question regarding this javascript snippet : is this a normal behaviour that when you delete an item of the fields group, it will revert back to the original value (‘group_title’ argument)?

    It’s not a big problem, because you have just to refresh the page, save it, or going in this specific field to change a single character in order for this snippet to do again its job. But it’s not very user friendly.

    Any workaround?

    Plugin Author Justin Sternberg

    (@jtsternberg)

    I’m not sure, as I haven’t used that snippet in a while. You could try adding the cmb2_remove_row event here: https://github.com/CMB2/CMB2-Snippet-Library/blob/master/javascript/dynamically-change-group-field-title-from-subfield.php#L90

    like this:

    
    .on( 'cmb2_add_row cmb2_remove_row cmb2_shift_rows_complete', replaceTitles )
    

    You’re the king. This solves the issue as you expected.

    Plugin Author Justin Sternberg

    (@jtsternberg)

    Ok great! I’ve updated the snippet.

    Trying to do this as well. I must be missing something, since when I added the suggested code snippet, nothing happens.

    $group_field_id = $cmb->add_field( array(
    	'id'          => 'MMDListsRecord',
    	'type'        => 'group',
    	'description' => __( 'Individual Directory Listings', 'mmd' ),
    	'options'     => array(
    		'group_title'       => __( 'Record {#}', 'mmd' ), // since version 1.1.4, {#} gets replaced by row number
    		'add_button'        => __( 'Add Another Record', 'mmd' ),
    		'remove_button'     => __( 'Remove Record', 'mmd' ),
    		'sortable'          => true,
    		'closed'            => true,
    	),
      'after_group' => 'add_js_for_repeatable_titles',
    ) );
    
    function add_js_for_repeatable_titles() {
    	add_action( is_admin() ? 'admin_footer' : 'wp_footer', 'add_js_for_repeatable_titles_to_footer' );
    }
    
    function add_js_for_repeatable_titles_to_footer() {
    	?>
    	<script type="text/javascript">
    	jQuery( function( $ ) {
    		var $box = $( document.getElementById( 'MMDListsRecord' ) );
    		var replaceTitles = function() {
    			$box.find( '.cmb-group-title' ).each( function() {
    				var $this = $( this );
    				var txt = $this.next().find( '[id$="title"]' ).val();
    				var rowindex;
    				if ( ! txt ) {
    					txt = $box.find( '[data-grouptitle]' ).data( 'grouptitle' );
    					if ( txt ) {
    						rowindex = $this.parents( '[data-iterator]' ).data( 'iterator' );
    						txt = txt.replace( '{#}', ( rowindex + 1 ) );
    					}
    				}
    				if ( txt ) {
    					$this.text( txt );
    				}
    			});
    		};
    		var replaceOnKeyUp = function( evt ) {
    			var $this = $( evt.target );
    			var id = 'title';
    			if ( evt.target.id.indexOf(id, evt.target.id.length - id.length) !== -1 ) {
    				$this.parents( '.cmb-row.cmb-repeatable-grouping' ).find( '.cmb-group-title' ).text( $this.val() );
    			}
    		};
    		$box
    			.on( 'cmb2_add_row cmb2_remove_row cmb2_shift_rows_complete', replaceTitles )
    			.on( 'keyup', replaceOnKeyUp );
    		replaceTitles();
    	});
    	</script>
    	<?php
    }
    

    Do you see something that is incorrect?

    Plugin Author Michael Beckwith

    (@tw2113)

    The BenchPresser

    My first questions are simply if that JS code is making it to the output of the page, and if there are any errors in your devtools console at the moment.

Viewing 12 replies - 1 through 12 (of 12 total)
  • The topic ‘cmb2_before_form related question’ is closed to new replies.