Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ng-sortable without ng-repeat

I have this working example using ng-sortable;

HTML

<ul as-sortable="vm.sortableOptions" ng-model="vm.items">
    <li ng-repeat="item in vm.items" as-sortable-item class="as-sortable-item">
        <div as-sortable-item-handle class="as-sortable-item-handle" style="height: 50px">
            <span data-ng-bind="item.name"></span>
        </div>
    </li>
</ul>

JS

vm.items = [
    { name: 'item 1' },
    { name: 'item 2' }
];

vm.sortableOptions = {
    containment: '#sortable-container'
};

This gives me the result:

Sortable items using ng-repeat

In my case I cannot use ng-repeat since all elements I need sortable have unique and complex HTML content and are not repeatable. For this reason I tried this:

HTML

<ul as-sortable="vm.sortableOptions" ng-model="vm.items">
    <li as-sortable-item class="as-sortable-item">
        <div as-sortable-item-handle class="as-sortable-item-handle">
            <span>Test1</span>
        </div>
    </li>

    <li as-sortable-item class="as-sortable-item">
        <div as-sortable-item-handle class="as-sortable-item-handle">
            <span>Test2</span>
        </div>
    </li>
</ul>

Unfortunately, this gives me the following result: Trying to use ng-sortable without using ng-repeat

The "sortable-items" seems to be "unsortable" if ng-repeat is omitted. Is there any workaround to this? Is it even possible to simply sort x number of divs within one container without using ng-repeat?

like image 609
Marcus Avatar asked Mar 21 '26 08:03

Marcus


2 Answers

Ok, so this is how I finally decided to solve my problem, it is not optimal but works.

JS

vm.templates = [
    { url: '/test1.html' },
    { url: '/test2.html' }
];

HTML

<ul as-sortable="vm.sortableOptions" ng-model="vm.templates">
    <li ng-repeat="item in vm.templates" ng-if="item.show" as-sortable-item class="as-sortable-item">
        <div as-sortable-item-handle class="as-sortable-item-handle">
            <div ng-include="'content/scripts/app/templates'+ item.url"></div>
        </div>
    </li>
</ul>

test1.html:

<span>Test1</span>

test2.html:

<span>Test2</span>
like image 107
Marcus Avatar answered Mar 24 '26 03:03

Marcus


You could take another way, using ng-repeat but looping over your own list of previous ordered components by you of course, where every object in the list could have attributes like type and properties for an individual element. Inside the ng-repeat you could call a directive created by you for inject hmtl code for every element. The example is only for give you a little idea. Hope this help and give you another view point.

html

<div ng-repeat="item in items">
   <div createhtml mid=item.mid data=item.data background=item.background mtitle=item.mtitle>
   </div>
</div>

angularjs

.directive('createhtml', ['$compile',
    function ($compile) {
       return {
             scope:{
                mid:"=",
                data:"=",
                background:"=",
                mtitle:"="
             },
             link: function(scope, element, attr) {
          function createHtmlAtFly(){
             //the html can be as complex as you want
             var htmlStr = "<div type='" + properties.type + "' mid='" + properties.mid+ "' data='" + properties.data + " ' background='" + properties.background "'+ title='" + properties.title +"'>\n" +
    "</div>\n";
           var container = element.find(".divcontainer");
           var toInsert = angular.element(htmlStr);
           container.append(toInsert);
           $compile(toInsert)(scope);
         }
         scope.$watch("data", function (newValue, oldValue) {
            //make element dynamic depending in changes on values in a controller
         }
      }
   }])
like image 35
Luis Carlos Avatar answered Mar 24 '26 03:03

Luis Carlos