Mockup sortable pattern: how to refresh list after appending new item?

Hi All,

I was using JQuery UI for the sortable function for keyword management. I am considering to switch to Plone's native mockup patterns. I feel my need is simple enough without going for JQuery UI.

I need to add a new item into sortable list. But obviously the sortable pattern will not know that there is a new

  • element. How do I refresh the list or re-initialize to add the new item? JQuery UI sortable simply use "refresh" option. What can I do with mockup's sortable? Thanks!
  • Correct me if I'm wrong, but you just need to call and reinitialize the pattern on the list using its base class..?

    Thanks for the suggestion. I tried it like below, but the new item is not draggable. Just to confirm the sortable is working, I added a couple li elements in the template and it is sortable. Did I do the reinitialization right?

    require(['jquery', 'mockup-patterns-sortable'], function($, sortable) {
        $('#mykeywords').append($("<li>new key</li>"));
        sortable.init();
    }

    Here is the code that I actually tested inside the mockup project. I can add a new li using the submit form, but the new element is not draggable.

    <!DOCTYPE html>
    <head>
      <title>Mockup</title>
    
      <script src="node_modules/requirejs/require.js"></script>
      <script src="js/config.js"></script>
      <script>
        require(['jquery', 'pat-registry','mockup-patterns-sortable'],
         function($, registry, sortable) {
           $(document).ready(function (){
             registry.scan($('body'));
    
            $(".btn").click(function (e) {
              e.preventDefault();
              var text = $("input[name='add1']").val();
              var $li = $("<li />").text(text);
              $("#main").append($li);
              sortable.init();
             });
           });
        });
      </script>
      <style type=text/css>
        li {margin:;5px; padding:5px; display: inline-block; position:relative;}
        li {padding: 15px; background: cyan;}
        div {padding:10px;}
      </style>
    </head>
    
    <body>
    <div class="pat-sortable" data-pat-sortable="selector:li;"> 
      <ul id="main"><div>Category 1</div>
        <li><span>Item 1</span></li>
        <li ><span>Item 2</span></li>
      </ul>
    <input thype="text" name="add1" /> <input class="btn" type="submit" value="submit" />
    </body>
    </html>

    Looks like "sortable.init()" is not the right way. This one worked:

    new sortable($("div.pat-sortable"));

    Makes sense, since the pattern initializes on any li element in the pattern namespace. Like you did, it's necessary to pass in the new element after creating it, the init() function doesn't seem to do much by itself.

    Also, just a little heads up...

    $(".btn").on('click', function (e) {
    ...
    

    ...is generally better to use as it creates a single handler for all matched elements resulting in lower memory usage. It also has the benefit of working on dynamically added elements...

    You're matching $('.btn') which is very broad, so I would use .on() instead.

    Thanks for the heads up. But creating a new instance still isn't a good approach: it creates clones of dragging items but they stay after dropping. Need to look into that.