We are currently implementing a module for a customer which manipulates filters and should update the sidebar with new content. I think I found a very nifty way to pass informations to the JS to update the sidebar without another request.
Product list ist HTML and not JSON
The first important finding was, that although the filters are updated with JSON, the product list is not. I tried to just add a <script> tag as in the good old Magento times, because Magento 1 parsed the script out and executed it, but this didn’t work.
Maybe because the <script> tag was not added to the HTML, but maybe even if it would have been I guess it would not have worked. By the way, I think the script was not added, because it was too deep in the DOM and only part of the responded HTML is (re)placed in the DOM.
Add infos but run own JS
The cool thing is, once the product list is replaced an event is published, so I played around with this event and understood, that I can pass infos with it, extract it and run my JS based on this.
Our implementation looks like this:
init() { const plugin = window.PluginManager.getPluginInstanceFromElement(document.querySelector('[data-listing]'), 'Listing'); if (!plugin) { return; } plugin.$emitter.subscribe('Listing/afterRenderResponse', this.onListUpdate.bind(this)); } onListUpdate(event) { const response = event.detail.response; const categoryList = this.parseResponse(response); // do your stuff } parseResponse(response) { const parser = new DOMParser(); const dom = parser.parseFromString(response, "text/html"); return dom.querySelector('template[data-ww-hide]').dataset.wwHide; }
What you can see here is, that we register the event subscriber in init()
. The important part is the beginning of onListUpdate()
! We are getting the complete response from the event, create our own document from it and can then query the DOM and use the infos to do whatever you want!
I hope this helps you wo solve other problems!
One thought on “Pass infos to product listing page via virtual(?) DOM”