Expand my Community achievements bar.

SOLVED

Multifield re-ordering in (Touch) UI

Avatar

Level 2

We are using the multifield control in our dialogs, and it is generally working well for us. (An example of what I am talking about is here.) But in some cases we've put enough fields in each element that they don't fit on the screen without scrolling. This is fine until you want to re-order the elements; Touch UI appears to only allow dragging (whereas classic had move-up-and-down buttons) which is not effective when the elements to be ordered don't fit in the viewport - you can't both drag and scroll.

So I'm looking for some advice:

  1. Is there an out-of-the-box solution in AEM 6.3 I've overlooked? Any sample solutions out there in the WWW?
  2. Would it be easy to add up/down controls? Presumably there is already javascript to handle the dragging re-order. Could it be repurposed to respond to buttons?
  3. Is there an easy way to make the multifield elements smaller? (Collapsing them like an accordion element, for example.)

Any suggestions would be appreciated. Thanks.

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

jwepurchase​: Here is my take on this:

  • Is there an out-of-the-box solution in AEM 6.3 I've overlooked? Any sample solutions out there in the WWW?

              There doesnt seem to be OOB solution for this. But you can always extend existing one to achieve what you want

  • Would it be easy to add up/down controls? Presumably there is already javascript to handle the dragging re-order. Could it be repurposed to respond to buttons?

               I tried adding 2 buttons and used jQuery for the same. You can place the code in appropriate files but here is what I did:

    •      Added 2 links in the DOM, one with class multi-move-up and other with class multi-move-down : Move up and Down in /libs/granite/ui/components/foundation/form/multifield/render.jsp --> Ideally should override  /libs/clientlibs/granite/coralui2/js/coral.js and add in the fieldTemplate variable:

var fieldTemplate =

    "<li class=\"js-coral-Multifield-input coral-Multifield-input\">" +

    "<div class=\"js-coral-Multifield-placeholder\"></div>" +

    removeButton +

    moveButton +

    "</li>";

    • Add event handlers to these new links:

<script>

    $("li a.multi-move-up").off().on("click", function(e){

        var $currentListElement = $(this).parent("li");

        var $prevListElement = $currentListElement.prev();

        if($prevListElement.length)

  $prevListElement.before($currentListElement);

    });

    $("li a.multi-move-down").off().on("click", function(e){

        var $currentListElement = $(this).parent("li");

        var $nextListElement = $currentListElement.next();

        if($nextListElement.length)

  $nextListElement.after($currentListElement);

    })

</script>

Ideally this should go in your author clientlib. You can also add CSS to make it look the way you want- Add icon instead of text link or whatever you think looks good for you,

  • Is there an easy way to make the multifield elements smaller? (Collapsing them like an accordion element, for example.)

As long as its just look and feel, you can always write your own CSS and make it the way you want it to be.

View solution in original post

7 Replies

Avatar

Level 10

You could look at writing an advanced SLing Resource type that uses JQuery re-ordering/sorting.

https://jqueryui.com/sortable/

A custom Sling Resource type can be based on a JQuery plug-in - as shown here - how we did the color picker:

Adobe Experience Manager Help | Creating a custom Experience Manager sling:resourceType for Touch UI

There is no example of this exact use case.

If other community members have an idea - please write them down .

Avatar

Correct answer by
Community Advisor

jwepurchase​: Here is my take on this:

  • Is there an out-of-the-box solution in AEM 6.3 I've overlooked? Any sample solutions out there in the WWW?

              There doesnt seem to be OOB solution for this. But you can always extend existing one to achieve what you want

  • Would it be easy to add up/down controls? Presumably there is already javascript to handle the dragging re-order. Could it be repurposed to respond to buttons?

               I tried adding 2 buttons and used jQuery for the same. You can place the code in appropriate files but here is what I did:

    •      Added 2 links in the DOM, one with class multi-move-up and other with class multi-move-down : Move up and Down in /libs/granite/ui/components/foundation/form/multifield/render.jsp --> Ideally should override  /libs/clientlibs/granite/coralui2/js/coral.js and add in the fieldTemplate variable:

var fieldTemplate =

    "<li class=\"js-coral-Multifield-input coral-Multifield-input\">" +

    "<div class=\"js-coral-Multifield-placeholder\"></div>" +

    removeButton +

    moveButton +

    "</li>";

    • Add event handlers to these new links:

<script>

    $("li a.multi-move-up").off().on("click", function(e){

        var $currentListElement = $(this).parent("li");

        var $prevListElement = $currentListElement.prev();

        if($prevListElement.length)

  $prevListElement.before($currentListElement);

    });

    $("li a.multi-move-down").off().on("click", function(e){

        var $currentListElement = $(this).parent("li");

        var $nextListElement = $currentListElement.next();

        if($nextListElement.length)

  $nextListElement.after($currentListElement);

    })

</script>

Ideally this should go in your author clientlib. You can also add CSS to make it look the way you want- Add icon instead of text link or whatever you think looks good for you,

  • Is there an easy way to make the multifield elements smaller? (Collapsing them like an accordion element, for example.)

As long as its just look and feel, you can always write your own CSS and make it the way you want it to be.

Avatar

Level 2

Thanks for your help.

This looks like what I need, but I haven't got it to work yet. I haven't been able to modify the template. I created the overriding coral.js file in /apps/clientlibs/granite/coralui2/js/coral.js and modified it by adding some logging and commenting out the move button, like so:

console.log("============================================= if you don't see this, it won't work");

var fieldTemplate =

   "<li class=\"js-coral-Multifield-input coral-Multifield-input\">" +

   "<div class=\"js-coral-Multifield-placeholder\"></div>" +

  removeButton +

   //moveButton +
   "</li>";

I see my comment coming up in the log, and that the code is in the /etc.clientlibs/clientlibs/granite/coralui2.js client lib file, but I also still see the move button. My assumption was that I could add (and remove) buttons by modifiying this template, but my test doesn't seem to agree. Have I missed something?

Avatar

Community Advisor

My bad. "clientlibs/granite/coralui2/js/coral.js" is used when you click on add button in multifield. You will see that in new item added, move button wont be there...

But it solves half of the problem.. The issue still left is when you open dialog, " /libs/granite/ui/components/foundation/form/multifield/render.jsp" is rendered which adds move and remove button in the multifield. This is done by JS that is different from coral.js.

So to change it, need to find the JS which has CUI.Multifield.init definition.. FYI, so far I could not find it...

Avatar

Level 2

My searches haven't turned up anything either. I figured that I should be able to at least change the icon on the existing control, but no luck. I've searched for the icon name, "moveUpDown", and I can't find it anywhere else in coralui2. There is a mention of it in coralui3, but that code isn't being loaded/executed. So I'm at a loss as to what it is that is creating the existing elements. Puzzling...

Avatar

Community Advisor

Though not being able to change the existing ones, There is still a way to add up/down buttons. In " /libs/granite/ui/components/foundation/form/multifield/render.jsp" change line 167 to:

<li class="coral-Multifield-input js-coral-Multifield-input" role="option" aria-selected="true" style="border-bottom:1px solid black"><% include(field, name, values[i], cmp, request); %><a href="javascript:void(0)" class="multi-move-up">Move Up</a><a href="javascript:void(0)" class="multi-move-down">Move Down</a></li>

and add same JS event handler there. Though not the best way to do it, but serves the purpose, if it is urgent..