Support

Account

Home Forums Add-ons Repeater Field Disable reordering of the repeater field items Reply To: Disable reordering of the repeater field items

  • These is more in responsive to the thread about disabling dragging only on certain items, but that thread doesn’t allow new replies. I needed to disable dragging/ordering only certain items in a flexible content field. We create these items dynamically when a post is created and want them to remain always at the top. The only solution that worked well was destroying the jQuery UI sortable instance and creating a new one. I’ll post the code for that below, but first here’s what would answer the OP’s question:

    acf.addAction( 'ready_field/key=field_5f6de18aefdd9', ( field ) => {
    
    	let list = $( '.acf-flexible-content:first > .values', field.$el[0] );
    
    	list.on( 'sortcreate', ( event, ui ) => {
    
    		list.sortable( 'destroy' );
    
    	} );
    
    } );

    Here’s what I did to exclude certain items from being dragging and also from being drop targets:

    acf.addAction( 'ready_field/key=field_5f6de18aefdd9', ( field ) => {
    
    	let list = $( '.acf-flexible-content:first > .values', field.$el[0] );
    
    	list.on( 'sortcreate', ( event, ui ) => {
    
    		if ( list.data( 'reinitializing-sortable' ) === true ) {
    			list.data( 'reinitializing-sortable', false );
    			return;
    		}
    
    		list.data( 'reinitializing-sortable', true );
    		list.sortable( 'destroy' );
    		list.sortable( {
    			items: '> .layout:not([data-layout="first_name"]):not([data-layout="last_name"]):not([data-layout="email"])',
    			handle: '> .acf-fc-layout-handle',
    			forceHelperSize: true,
    			forcePlaceholderSize: true,
    			scroll: true,
    			stop: ( event, ui ) => {
    				field.render();
    			},
    			update: ( event, ui ) => {
    				field.$input().trigger( 'change' );
    			}
    		} );
    
    		$( '> .layout[data-layout="first_name"], > .layout[data-layout="last_name"], > .layout[data-layout="email"]', list ).each( function() {
    
    			$( '.acf-fc-layout-handle', this ).css( 'cursor', 'default' );
    
    		} );
    
    	} );
    
    } );

    Technically, based on the docs, I shouldn’t have to destroy and recreate the sortable instance. I should just be able to do this:

    list.sortable( 'option', 'items', '> .layout:not([data-layout="first_name"]):not([data-layout="last_name"]):not([data-layout="email"])' );

    But that wouldn’t work, so instead I had to use the hacky solution above.