0

In the project I am working on, I am applying a ui-sort via Angular on a to-do list and am trying to get a toggle to work for when a user is editing tasks. My current method of testing this toggle is employing the use of a button to toggle sorting on and off.

My strategy is this: Employ an angular directive to generate an initial template with sorting on. Add a button which, when clicked, modifies a scope variable in the controller ($scope.sortingEnabled) to toggle between true and false. Inside my directive, I have a watch set on 'sortingEnabled' in a link function to add/remove the sorting attribute from a .

Here is the in todo.html before I tried employing a directive: sortableOptions is a function written to re-order the todos on internal records.

<ul class="unstyled" ng-model="todos" ui-sortable="sortableOptions">
<!-- list items here via ng-repeat -->
</ul>

The following is the code in todo.html after my directive:

<sortable></sortable>

And my current draft for the directive inside todo-directives.js:

app.directive('sortable', function() {

    var innerHtml = '<li ng-repeat="todo in todos" class="item">' +
        '<span ng-model="todo.name" >{{todo.name}}</span> ' +
        '</li>';

    var link = function (scope, element, attrs) {

        scope.$watch('sortingEnabled', function() {
            if(scope.sortingEnabled === true) {
                element.contents().attr("ui-sortable", "sortableOptions");
                //needed else ui-sortable added as a class for <ul> initially for
                //some reason
                element.contents().removeClass("ui-sortable");
            }
            else {
                element.contents().removeAttr("ui-sortable");
                //needed else ui-sortable added as a class for <ul> initially for
                //some reason
                element.contents().removeClass("ui-sortable");
            }
        });


    };
    return {
        restrict: 'E',
        transclude: true,
        template: '<ul class="unstyled" ng-model="todos" ui-sortable="sortableOptions"  ng-transclude>' + innerHtml + '</ul>',
        link: link
    };

});

This code works in the source code view of Chrome's debugger, but the view does not properly refresh. I have tried scope.$apply() within the watch function but get a $digest already running error. I have also tried $compile, but my understanding of how that works is severely lacking, so I get errors of which I do not remember. Am I missing something crucial, or doing things incorrectly? I am unsure, as my understanding is low, being that I have been leaning Angular for a few weeks. Any help would be greatly appreciated!

1 Answer 1

1

The angular directive supports watching when the sortable options change:

scope.$watch(attrs.uiSortable, function(newVal, oldVal){

So all you had to do was look at the jqueryui sortable documentation, and update the correct property on the plugin.

Plunker: http://plnkr.co/edit/D6VavCW1BmWSSXhK5qk7?p=preview

Html

<ul ui-sortable="sortableOptions" ng-model="items">
   <li ng-repeat="item in items">{{ item }}</li>
 </ul>
<button ng-click="sortableOptions.disabled = !sortableOptions.disabled">Is Disabled: {{sortableOptions.disabled}}</button>

JS

app.controller('MainCtrl', function($scope) {
  $scope.items = ["One", "Two", "Three"];

  $scope.sortableOptions = {
    disabled: true
  };
});
Sign up to request clarification or add additional context in comments.

3 Comments

Essentially what I am trying to do is toggle the sorting feature on the list. I tried to generate a template, and then modify its attributes, either removing the attribute when the sort is toggled off ($scope.sortEnabled false) or is toggled on ($scope.sortEnabled true). This would then trigger the watch I have set, either removing or adding the ui-sortable="sortingOptions" respectively, which would then result in the view/DOM refreshing to apply this effect to the list. This person I believe was trying the same thing as me: groups.google.com/forum/#!topic/angular/13Mc7hry0bE
this person's answer seems correct: stackoverflow.com/questions/16150887/…
hmm, yes I remember seeing that question yesterday and attempting to modify my watch with element.sortable("disable"); yields the following error: Error: cannot call methods on sortable prior to initialization; attempted to call method 'enable'. I am a newbie with this, so I am not sure if that function is even compatible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.