Jump to content

Lock repeater item for editing


gebeer
 Share

Recommended Posts

Hello,

I would like to prevent future editing of a repeater item once a checkbox in the repeater item has been checked. Either the form inputs of the repeater item should be read only or only the field values should be rendered.

Looking at the module code I can't seem to figure out where to hook for that functionality.

Any ideas would be much appreciated.

Link to comment
Share on other sites

A quick&dirty piece for site/ready.php. The collapsed status still needs some working on, but it appears to also be working in ajax mode:

wire()->addHookAfter("Field::getInputfield", null, "hookGetInputfield_lockCheckedRepeaters");

function hookGetInputfield_lockCheckedRepeaters(HookEvent $event) {
	$thisPage = wire('page');
	// Only run our locking logic if we are editing the page in the backend
	if($thisPage->process != "ProcessPageEdit") return;
	
	// We don't want to lock the repeater itself (or do we?)
	if($event->object->type instanceOf FieldtypeRepeater) return;
	
	$repPage = $event->arguments(0);
	$context = $event->arguments(1);
	
	// The backend retrieves the field within the repeater context, otherwise something else
	// is happening we do not want any part of ;-)
	if($context != "_repeater" . $repPage->id) return;
	
	// Set collapsed status in the input field (the event's return), could be made a little
	// more elaborate
	$event->return->collapsed = ($event->return->collapsed === Inputfield::collapsedNo || $event->return->collapsed === Inputfield::collapsedNoLocked) ?
								Inputfield::collapsedNoLocked :
								Inputfield::collapsedYesLocked;
}

 

  • Like 3
Link to comment
Share on other sites

Probably obvious, but if you want to lock only repeater items that have the checkbox checked then you would add a conditional for that in the hook that BitPoet suggested.

if($repPage->your_checkbox) {
    $event->return->collapsed = ($event->return->collapsed === Inputfield::collapsedNo || $event->return->collapsed === Inputfield::collapsedNoLocked) ?
        Inputfield::collapsedNoLocked :
        Inputfield::collapsedYesLocked;
}

 

  • Like 2
Link to comment
Share on other sites

@BitPoet Thank you very much for the heads-up. Also to @Robin S.

I finally ended up with this hook function in a module context which does exactly what I need, also in ajax mode:

    $this->addHookAfter('Field::getInputfield', $this, "lockConfirmedItems");
    public function lockConfirmedItems(HookEvent $event) {

		if($this->user->isSuperuser() || $this->user->hasRole('certificationadmin')) return;
		$thisPage = wire('page');
		// // Only run our locking logic if we are editing a user in the backend
		if($thisPage->process != "ProcessUser") return;
		
		$repeaterPage = $event->arguments(0);
		$context = $event->arguments(1);
		if($context != "_repeater" . $repeaterPage->id) return;
		if(!$repeaterPage->confirmed) return;
		$event->return->collapsed = 7;

	}

Setting collapsed with the Inputfield constants like in BitPoet's code didn't work for me.

  • Like 3
Link to comment
Share on other sites

  • 1 year later...
7 hours ago, PWaddict said:

I would like to lock a specific repeater item with the id 1553 to prevent editing from non-superusers

Try:

$wire->addHookAfter('Field::getInputfield', function(HookEvent $event) {
	$page = $event->arguments(0);
	$inputfield = $event->return;
	// Only for non-superusers
	if($event->wire('user')->isSuperuser()) return;
	// Only for a particular Repeater page ID
	if($page->id !== 1553) return;
	// Set collapsed to Inputfield::collapsedNoLocked or Inputfield::collapsedHidden as suits
	$inputfield->collapsed = Inputfield::collapsedNoLocked;
});

 

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

  • 1 year later...

@Robin S

Brilliant! Not quite what I needed but a great starting point. My scenario was:

  • Didn't know the repeater item id
  • Did know the id of a particular (page) field inside the repeater page

And wanted any repeater item with that field id to be locked for editing by all, including super users. Here's what worked for me:

<?php
$wire->addHookAfter('Field::getInputfield', function(HookEvent $event) {
    $page = $event->arguments(0);
    if (!$page instanceof RepeaterPage) return;
    $inputfield = $event->return;
    // Only for a particular Repeater page field (fieldtype page) ID
    if($page->my-page-field->id !== 4486) return;
    // Set collapsed to Inputfield::collapsedNoLocked or Inputfield::collapsedHidden as suits
    $inputfield->collapsed = Inputfield::collapsedNoLocked;
});

 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...