Jump to content

Hook on Repeater Field save


Tom.
 Share

Recommended Posts

Really struggling with this one, I do wish there was more info on hooks. 

I'm trying to update the repeater title on save, my initial idea as when you save the page, it saves repeater which is also a page (under the hood):

$wire->addHookAfter("Pages::saveReady", function($event) {
    $page = $event->arguments(0);

    if($page->template == "repeater_variations") {
        $page->title = "Hello";
    }
});

This isn't working at all, so I've been looking at Captain hook on repeater hooks and found this:

$wire->addHookBefore("FieldtypeRepeater::savePageField", function($event) {
    $page = $event->arguments(0);

    if($page->template == "repeater_variations") {
        $page->title = "Hello";
    }
});

This still isn't working. So I tried accessing it from the page:

$wire->addHookAfter('Pages::saveReady', function($event) {
    $page = $event->arguments(0);

    foreach($page->variations as $variation) {
        $variation->title = "Hello";
    }
});

And still nothing. 

 

Anyone got any ideas on this? 

 

 

EDIT: 

I've done this for now, I know it's not efficient at all as save is probably called twice on each repeater. But it works:

$wire->addHookAfter("Pages::saveReady", function($event) {
    $page = $event->arguments(0);

    foreach($page->variations as $variations) {
        $title = array();
        foreach($variations->variation as $variation) array_push($title, $variation->title);
        $variations->title = implode(", ", $title);
        $variations->save();
    }
});

 

Link to comment
Share on other sites

The first hook in your post works as expected for me - it sets the title field inside the repeater item (assuming there is a title field included in your repeater).

But the last hook in your post looks like maybe you are instead trying to do something different - like you have a one "variations" repeater nested inside another "variations" repeater and you are concatenating the titles of the nested repeater to the parent repeater title. Incidentally, you should add a template check in that hook or you will get a PHP error for invalid foreach argument on any page that doesn't include the variations field.

Can you explain some more about what the objective is?

Link to comment
Share on other sites

2 hours ago, Robin S said:

The first hook in your post works as expected for me - it sets the title field inside the repeater item (assuming there is a title field included in your repeater).

But the last hook in your post looks like maybe you are instead trying to do something different - like you have a one "variations" repeater nested inside another "variations" repeater and you are concatenating the titles of the nested repeater to the parent repeater title. Incidentally, you should add a template check in that hook or you will get a PHP error for invalid foreach argument on any page that doesn't include the variations field.

Can you explain some more about what the objective is?

Strange, I can't get the first one working. I would assume it did work since when saving a page, repeaters also save to a page. 

To explain what's happening, I'm building an eCommerce system and front-end that I'm going to release open source for ProcessWire. It's in it's early stage and I'm mostly mapping the UX. The variations are variations of a product, this is a repeater on the product page. The variation you can see that I set as an array are titles from a PageReference field, that lets you select things like colour and sizes for that variation. 

The hook is to change the title field in the repeater to those titles, the repeater uses this title field for the name of the repeater item. For example "#1: Color - Red, Size - M" the title is a hidden field, used purely to show what product variation that repeater is. It does other things like check if there is two colors selected, and deleted one informing the user that it shouldn't have two from the same group. 

Sadly I still haven't figured out to do it without defining $repeater->save() inside the repeater foreach on page save. Which seems really inefficient. 

Link to comment
Share on other sites

I think I have things set up the same as you and it's working...

Repeater fields (title visibility is set to "hidden"):
2017-10-04_141013.png.14530d4bb409a32a53b586a0b330f47e.png

Hook:

$wire->addHookAfter('Pages::saveReady', function(HookEvent $event) {
    $page = $event->arguments(0);

    if($page->template == 'repeater_test_repeater') {
        $title = 'No pages selected';
        if($page->test_page->count) $title = $page->test_page->implode(', ', 'title');
        $page->title = $title;
    }
});

Result:
repeater.gif.13c5a8de0b8fd02f5343a5b4b23d5337.gif

 

Tracy Debugger will be helpful in debugging what is going inside your hook.

  • Like 2
Link to comment
Share on other sites

8 hours ago, Robin S said:

I think I have things set up the same as you and it's working...

Repeater fields (title visibility is set to "hidden"):
2017-10-04_141013.png.14530d4bb409a32a53b586a0b330f47e.png

Hook:


$wire->addHookAfter('Pages::saveReady', function(HookEvent $event) {
    $page = $event->arguments(0);

    if($page->template == 'repeater_test_repeater') {
        $title = 'No pages selected';
        if($page->test_page->count) $title = $page->test_page->implode(', ', 'title');
        $page->title = $title;
    }
});

Result:
repeater.gif.13c5a8de0b8fd02f5343a5b4b23d5337.gif

 

Tracy Debugger will be helpful in debugging what is going inside your hook.

 

No idea why my original code it wasn't working, I've given it another go and it's working now.

$wire->addHookAfter("Pages::saveReady", function($event) {
    $page = $event->arguments(0);
    
    if($page->template == "repeater_variations") {
        $title = array();
        $check = array();
        $i++;

        foreach($page->variation as $variation) {
            $parent = $variation->parent->title;

            if(in_array($parent, $check)) {
                $this->error("Variation #$i had a duplicate ". strtolower($parent) .", the duplicate has been removed.");
                $page->variation->remove($variation);
            } else {
                array_push($check, $parent);
                array_push($title, "$parent — $variation->title");
            }
        }
        $page->title = implode(", ", $title) . $parent_title;
    }
});

 

Thanks for you help. 

 

EDIT: 

Silly me, it was because I wasn't making changes to the repeater when testing, there for it wasn't firing saveReady. 

  • Like 2
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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...