Virtual Happy Hour this month, Jun 28, we'll be getting a sneak preview at our soon to launch SaaS CMS!

Try our conversational search powered by Generative AI!

Edit Mode - Trigger JS on Property Change?

Vote:
 

In one of our client projects (EPiServer 7.19) we have a grid-row ContentArea property into which blocks can be added and dragged/dropped to re-arrange. These blocks may all have different heights, which would result in a jagged bottom edge. To remedy this, some JS is run on page load to standardize the height of all blocks to the tallest item in each row, resulting in a nice even appearance.

However, this is causing a problem in edit mode. When the page is first loaded in edit mode, the JS is run and the blocks all look good. But after adding or re-arranging the blocks, the height standardization JS is not re-run and the bottom edge can get quite badly jagged, unless you refresh the page.

I'm familiar with using EditHints.AddFullRefreshFor to force the entire page to refresh automatically, but this seems like overkill and would interrupt the editors work re-arranging blocks.

Is there any way, in ASP.NET or JS, to trigger the height normalization JS when the contents/order of the ContentArea change?

#147699
Apr 21, 2016 15:28
Vote:
 

You might be able to jack onto the _onDropData function, it's what used to trigger the drop event. (dojo), here's an example.

_onDropData: function (dndData, source, nodes, copy) {
            //Drop item is an array with dragged items. This example just handles the first item.
            var dropItem = dndData ? (dndData.length ? dndData[0] : dndData) : null;

            if (dropItem) {

                //The data property might be a deffered so we need to call dojo.when just in case.
                dojo.when(dropItem.data, dojo.hitch(this, function (value) {
                    //Do something with the data, here we just log it to the console.
                    console.log(value);
                }));
            }


Good luck and take a look at this:
http://world.episerver.com/documentation/Items/Developers-Guide/Episerver-Framework/7/User-Interface/Drag-and-Drop/

#147713
Edited, Apr 21, 2016 22:47
Vote:
 

Robin, not sure I entirely understand your solution. Do we need to override the standard EPiServer _onDropData event handler somehow? Or do we need to create an all new component as in your link?

The goal we have is the following: most of our blocks have responsive images. There is a piece of JS which runs on page load and chooses which image should be used based on the browser width. What we need to achieve is being able to run the same JS after drag and drop event is complete.

#148204
May 05, 2016 16:48
Vote:
 

Hello Dasha

The following code will allow you to listen out for the drop event 

Merge into module.config:

<?xml version="1.0" encoding="utf-8"?>
<module>
  <dojo>
    <paths>
      <add name="blockmoved" path="Scripts/BlockMoved" />
    </paths>
  </dojo>
  <clientModule initializer="blockmoved.BlockMovedListener">
    <moduleDependencies>
      <add dependency="CMS" type="RunAfter" />
    </moduleDependencies>
  </clientModule>
</module>

Create a file called BlockMovedListener.js in /ClientResources/Scripts/BlockMoved as follows:

define([
        "dojo/_base/declare",
        "dojo/_base/lang",
        "dojo/topic"
    ],
    function
    (
        declare,
        lang,
        topic
    ) {

        return declare([], {

            initialize: function () {

                this.inherited(arguments);

                topic.subscribe("/dnd/drop", lang.hitch(this, "_onDrop"));

            },

            _onDrop: function (ctx) {
                // A lot of these evevts will fire!
                console.log('Content has been droppped, bear in mind this fires every time content is dropped ');
                console.log('anywhere in the UI, ctx object may contain something you can use to check if a ');
                console.log('block has been moved');

                // You will need to manually execute the JS function you have described in the frame thats displaying the content
            }
        });
    });
#148206
May 05, 2016 18:14
Vote:
 

David comes to the rescue as always :)

We found another old thread, where you suggested a similar solution: http://world.episerver.com/forum/developer-forum/-EPiServer-75-CMS/Thread-Container/2015/5/angular-blocks-break-when-reordering-in-content-area/. So this is the JS code we ended up with and it seems to work in all the scenarios we need to cover:

define(
    ["dojo/_base/declare",
     "dojo/aspect",
     "dojo/_base/lang",
     "dojo/topic",
     "epi/dependency",
     "/ClientResources/Scripts/menuPin/MenuPinInit.js"
    ],
    function(
        declare,
        aspect,
        lang,
        topic,
        dependency,
        menuPin
    ) {
        var onItemChanged = function (id, item) {
            // calling the code to reload the responsive images
            $(document).trigger("customreload");
        };

        return declare([menuPin], {
            initialize: function() {
                this.inherited(arguments);

                var registry = dependency.resolve("epi.storeregistry");
                var contentDataStore = registry.get("epi.cms.contentdata");
                aspect.after(contentDataStore, "onItemChanged", lang.hitch(this, onItemChanged));
            }

        });
    });

You will noticed we even managed to keep the MenuPin plugin in place. So thank you a lot for the help!

#148236
May 06, 2016 16:52
Vote:
 

Great stuff Dasha - glad you managed to sort it and glad you kept MenuPin in place too ;)!

#148238
May 06, 2016 16:57
Vote:
 

Thanks for all the responses - crunch meant that I didn't get a chance to address this, but it's on the pile for a future sprint, so I'll give this a go.

#149483
Jun 01, 2016 14:51
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.