Jump to content

JS events for repeaters


nikosch
 Share

Recommended Posts

From the repeater fieldytype javascript:

            // Re-enable CKEditor instances
            ui.item.find('textarea.InputfieldCKEditorNormal:not(.InputfieldCKEditorLoaded)').each(function() {
                $(this).closest('.InputfieldCKEditor').trigger('reloaded', [ 'InputfieldRepeaterSort' ]);
            });

            // Re-enable the TinyMCE instances
            ui.item.find('.InputfieldTinyMCE textarea').each(function() {
                tinyMCE.execCommand('mceAddControl', false, $(this).attr('id'));
            });

This is not nice. Please trigger global events on the window object, so every dynamic javascript component can subscribe and init/update it service on repeater ADD/MOVE/DELETE operations.

  • Like 1
Link to comment
Share on other sites

  • 5 months later...
12 minutes ago, tpr said:

They do fire a js event but the problem is not all field types support Ajax loading.

Saying an inputfield does not support AJAX loading often just means the inputfield doesn't initialise properly when it is added via AJAX. Probably because it only initialises on dom ready:

$(document).ready(function() {
    initialiseMyInputfield();
});

But if there is an event fired when a new repeater item is added the author of the inputfield module can update it so it will support AJAX loading:

$(document).ready(function() {
    initialiseMyInputfield();
});

$(document).on('repeaterItemAdded', function() {
    initialiseMyInputfield();
});

But in InputfieldRepeater.js I don't see events being triggered for repeater item add, sort, delete, etc that we can monitor for.

  • Like 1
Link to comment
Share on other sites

I see, thanks. I thought of the event firing when the repeater is expanded, not on add/delete etc events.

There's a "reloaded" event for Inputfields but of course that's not entirely the same. This could be used for the "add" event:

    $(document).on('reloaded', '.InputfieldRepeaterItem', function () {
        console.log($(this));
    });

 

Link to comment
Share on other sites

  • 7 years later...

Has this problem ever been resolved?

Is there an alternative strategy?

I have run into this situation with my grapick module.

I have a mutation observer watching ProcessPage Edit and initializing fields once nodes are added to the DOM, but it only works in the repeater items that are already open.

It would be nice to have some sort of trigger.

Alternatively, perhaps I could build a list of fields using my fieldtype, fieldgroups that contain that field, compare it with a list of fields used on a page template, and then I guess watch the repeater/repeater container for new nodes? Oh but that doesn't help because a repeater is a list in a list in a list right?

Link to comment
Share on other sites

Right, so if it is on the field will not instantiate.

Turned off it works fine. The weird thing is that I have something that watches for new elements so that if you have items open that haven't loaded yet and add a new item, the other items will initialize.

Link to comment
Share on other sites

I think this is a big issue with quite an impact in many areas:

https://github.com/processwire/processwire-requests/issues/176

https://github.com/processwire/processwire-issues/issues/1856#issuecomment-1878431067

We also have no events for modals, panels etc.

We have a JS API for Inputfields already, so it would make sense to expand on that concept: https://processwire.com/blog/posts/pw-3.0.145/#inputfields-javascript-api

I think this is one of a few cases where there are conceptual problems that Ryan should take more care about. I think these problems are not present enough in his head. Maybe someone can came up with a good writeup and maybe also propose a good solution? Sometimes that helps wonders, eg in 2020 I asked on stackoverflow about missing events in tabulator.info and the author of the library didn't seem to understand. Then in 2021 I posted the same thing in other words and he liked the idea a lot and it was instantly built into v5 and is now an integral feature of tabulator.

I think it would be great to have a unified events system for the PW backend similar to https://tabulator.info/docs/5.5/events

I could think of something like this:

ProcessWire.on("repeaterItemAdded", function() { ... });

ProcessWire.on("panelClosed", function() { ... });

ProcessWire.openPanel(...);

ProcessWire.addRepeaterItem(...);

And I could imagine that Ryan likes the idea as I think code would get cleaner and easier to maintain - just like it happened with the Inputfields api some time ago...

  • Like 1
Link to comment
Share on other sites

I've seen it come up in the past for sure.

Worth having a discussion.

I mean, even just an on-page array of booleans that state if a field is loaded on the page would be something, but I agree with this:

14 hours ago, bernhard said:

I could think of something like this:

ProcessWire.on("repeaterItemAdded", function() { ... });

ProcessWire.on("panelClosed", function() { ... });

ProcessWire.openPanel(...);

ProcessWire.addRepeaterItem(...);

And I could imagine that Ryan likes the idea as I think code would get cleaner and easier to maintain - just like it happened with the Inputfields api some time ago...

There are classes on page that indicate this for repeaters.

InputfieldRepeaterItem InputfieldStateCollapsed <- class gets applied to LI element for closed repeater item

InputfieldRepeaterItem InputfieldStateWasCollapsed <- class gets applied to LI once a repeater item is opened. Further, this gets applied once the AJAX content is loaded.

The same applies to repeatermatrix - InputfieldRepeaterMatrixItem gets added to the above.

For the immediate need I think what I am going to do is:

  • populate a jsConfig array key with field instance names e.g. field_name, repeater_field_name2300 and a 'loaded' flag
  • run an interval that
    • looks for the target field I need to instantiate,
    • looks for the wasCollapsed state and check for the target field.
  • once it is found in the DOM, create the instance and set the field flag to true, and
  • when all the flags are true break out of the interval.

It's sloppy, I hate using intervals to poll the page but my hope is that if someone is working with repeaters they are going to want to dig into new items pretty quickly anyway.

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...