Trigger data-request programatically

Hello,

I have a select like that :

<select name="test" data-request="onAjax">
    ....
</select>

If I select some different values in that select, the method is triggered, works well.

But somewhere else, I modify the selected element of my select programatically.

The problem is, after the automatic change, the select is not considered as “changed” and the onAjax method is not triggered.

How can I “force” the change of the select to trigger the data-request method, exactly like if I chose in the select directly ?

Thank you

Would this help? I’m not sure to understand how the select is “programatically” changed.

$("#selector").trigger('change');

You can use the Javascript API in your change handler.
Abbreviated example:

function yourSelectionHasChanged(event) {
    oc.ajax('onAjax', {
        data: { selected: event.target.value },
        success: function(data) {
            this.success(data); // in case your onAjax handler returns something
            console.log('Finished! Got data back from server: ', data);
        }
    });
}

More information here: JavaScript API - October CMS - 3.x

and don’t forget to read the introduction: Introduction - October CMS - 3.x

you’ll need to integrate the framework into your frontend theme.

I tested that solution as first attempt, but it seems that triggering the change event don’t trigger the data-request function again. I don’t find the right event to trigger the event.

I know the javascript API but I can’t use it in my case.

I use a partial to display my forms elements (text, checkbox etc…) my partial is like that :

{% partial 'form/text' name="test" label="Test" request={'data-request':'onAjax', 'data-request-confirm': 'alert("toto")' %}

It would be very difficult to pass the whole “yourSelectionHasChanged” JS code like that.

You can always use JS to trigger and listen to DOM events. Nothing prevents you from adding something like the following to your page or your partial:

<script defer>
document.addEventListener("DOMContentLoaded", function(event) { 
  const selectInput = document.querySelector('select[name="your-select"']);
  if(el) {
      selectInput.addEventListener('change', function(event) {
          oc.ajax('onAjax', {
            data: { selected: event.target.value },
              success: function(data) {
                this.success(data); // in case your onAjax handler returns something
                console.log('Finished! Got data back from server: ', data);
              }
         });
     }
  }
});
</script>

(quick and dirty-is example, please don’t quote me on that ;-))

You could create a place holder at the bottom of your layout to add extra scripts if you want to do it clean. Or event better, create a separate JS file and include that.

But I think you will have to describe what you’re doing a bit more and show more of your code.

But somewhere else, I modify the selected element of my select programatically.

What do you by “programatically” and how?

I have a partial that I call when I want to display a select dropdown in my website. For design purpose, that partial have a standard select (<select> tag that is hidden) and a <div> that replace my select.

Than, I have some alpine.js stuff that add options dropdown to my replacement <div> and copy the value of choosen option to the regular select.

To help you understand, I created a loom to show you. The select above is the real <select>, the one below is the <div>.

You can see that, when I change a value in my <div>, my select change too. This part works. But it does not trigger the ajax method that is associated to the <select> with data-request attribute. You can see, at the end of the video, that the ajax request correctly trigger when I change the value of the <select> directly.

I’m not far from something completely working, just need to find how to trigger the data-request method when my <select> change programatically. I know I could probably fix the issue by using javascript API instead of data-request API but I prefer the data-request method as it’s easier to read and easier to maintain in my case (because all data-request options can be passed to my partial as parameters).

I’m sure there is an single line of JS code to trigger again the data-request method associated to a field, or, if not, it should exist.

Ok, I see. Thank you for the explanation and the loom! And sorry for the late reply.

I don’t think this is something you can do with a data-attribute API method. Since the cause for your intended effect is a change in the DOM by alpine.js, the imho best place to trigger the request would be there. You basically have to mimic what OCMS framework does: get the data-request attribute and trigger the ajax request with oc.ajax(yourSelectElement). I think that can be safely placed in your other frontend script, without intervening with the dynamic nature of your field partials.

Hope that helps somehow! :smiley:

1 Like

Thank you for your answer. I would have liked to be able to trigger an event so that everything else is triggered rather than redoing all this behavior with the javascript api (because I can trigger an event with alpine if needed), but if such an event doesn’t exist, I guess I have no choice ^^.

You can call oc.request on an established object to trigger it again

oc.request('#myid')

@daft this is exactly what I was looking for, thank you