Skip to content

Commit

Permalink
function as model fix and test case
Browse files Browse the repository at this point in the history
  • Loading branch information
beradrian committed Aug 3, 2015
1 parent 3854489 commit 52e4be0
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 31 deletions.
10 changes: 6 additions & 4 deletions checklist-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,12 @@ angular.module('checklist-model', [])
return;
}
var current = getter(scope.$parent);
if (newValue === true) {
setter(scope.$parent, add(current, value, comparator));
} else {
setter(scope.$parent, remove(current, value, comparator));
if (angular.isFunction(setter)) {
if (newValue === true) {
setter(scope.$parent, add(current, value, comparator));
} else {
setter(scope.$parent, remove(current, value, comparator));
}
}

if (checklistChange) {
Expand Down
33 changes: 33 additions & 0 deletions docs/blocks/function-as-model/ctrl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
app.controller('Ctrl8', function($scope) {
$scope.roles = [
'guest',
'user',
'customer',
'admin'
];
$scope.user = {
roles: ['user']
};
$scope.checkAll = function() {
$scope.user.roles = angular.copy($scope.roles);
};
$scope.uncheckAll = function() {
$scope.user.roles = [];
};
$scope.checkFirst = function() {
$scope.user.roles.splice(0, $scope.user.roles.length);
$scope.user.roles.push('guest');
};
$scope.getRoles = function() {
return $scope.user.roles;
};
$scope.check = function(value, checked) {
var idx = $scope.user.roles.indexOf(value);
if (idx >= 0 && !checked) {
$scope.user.roles.splice(idx, 1);
}
if (idx < 0 && checked) {
$scope.user.roles.push(value);
}
};
});
40 changes: 40 additions & 0 deletions docs/blocks/function-as-model/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
describe('function-as-model', function() {

beforeEach(function() {
browser().navigateTo(mainUrl);
});

var s = '[ng-controller="Ctrl1"] ';
var a = s+' input[type="checkbox"]';

it('should initialize with correct values', function() {
check(a, [0,1,0,0]);
expect(element(s+'pre').text()).toBe('[\n \"user\"\n]');
});

it('should check/uncheck items', function() {
using(s+'label:eq(0)').input('checked').check(true);
using(s+'label:eq(1)').input('checked').check(false);
check(a, [1,0,0,0]);
expect(element(s+'pre').text()).toBe('[\n \"guest\"\n]');
});

it('should check all', function() {
element(s+'button[ng-click="checkAll()"]').click();
check(a, [1,1,1,1]);
expect(element(s+'pre').text()).toBe('[\n \"guest\",\n \"user\",\n \"customer\",\n \"admin\"\n]');
});

it('should uncheck all', function() {
element(s+'button[ng-click="uncheckAll()"]').click();
check(a, [0,0,0,0]);
expect(element(s+'pre').text()).toBe('[]');
});

it('should check first', function() {
element(s+'button[ng-click="checkFirst()"]').click();
check(a, [1,0,0,0]);
expect(element(s+'pre').text()).toBe('[\n \"guest\"\n]');
});

});
3 changes: 3 additions & 0 deletions docs/blocks/function-as-model/view.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<label ng-repeat="role in roles">
<input type="checkbox" checklist-model="getRoles()" checklist-value="role" ng-change="check(role, checked)"> {{role}}
</label>
1 change: 1 addition & 0 deletions docs/index.jade
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ html(ng-app='app')
- items.push({id: 'array-object', text: 'Array of objects (pick object)', ctrlName: 'Ctrl3', testValue: 'user.roles'})
- items.push({id: 'single-object', text: 'Array of only one object', ctrlName: 'Ctrl7', testValue: 'user.roles'})
- items.push({id: 'object', text: 'Object properties', ctrlName: 'Ctrl4', testValue: 'user.roles'})
- items.push({id: 'function-as-model', text: 'Use a function as checklist-model', ctrlName: 'Ctrl8', testValue: 'getRoles()'})
- items.push({id: 'array-object-with-ngmodel', text: 'Array of object, specifying also the ngModel attribute', ctrlName: 'Ctrl3a', testValue: 'user.roles'})
- items.push({id: 'filter', text: 'Comparator', ctrlName: 'Ctrl6', testValue: 'selectedUsers'})
- items.push({id: 'comparator-expression', text: 'Comparator expression', ctrlName: 'Ctrl6a', testValue: 'selectedUsers'})
Expand Down
128 changes: 102 additions & 26 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,103 @@ <h3>js</h3>
$scope.user.roles.splice(0, $scope.user.roles.length);
$scope.user.roles.push('guest');
};
});</pre>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<h2 style="margin-bottom: 0">Use a function as checklist-model</h2>
</div>
</div>
<div ng-controller="Ctrl8" class="row">
<div class="col-xs-12 col-sm-6">
<h3>demo</h3>
<div class="well"><label ng-repeat="role in roles">
<input type="checkbox" checklist-model="getRoles()" checklist-value="role" ng-change="check(role, checked)"> {{role}}
</label></div>
<script>app.controller('Ctrl8', function($scope) {
$scope.roles = [
'guest',
'user',
'customer',
'admin'
];
$scope.user = {
roles: ['user']
};
$scope.checkAll = function() {
$scope.user.roles = angular.copy($scope.roles);
};
$scope.uncheckAll = function() {
$scope.user.roles = [];
};
$scope.checkFirst = function() {
$scope.user.roles.splice(0, $scope.user.roles.length);
$scope.user.roles.push('guest');
};
$scope.getRoles = function() {
return $scope.user.roles;
};
$scope.check = function(value, checked) {
var idx = $scope.user.roles.indexOf(value);
if (idx >= 0 && !checked) {
$scope.user.roles.splice(idx, 1);
}
if (idx < 0 && checked) {
$scope.user.roles.push(value);
}
};
});</script>
<button ng-click="checkAll()" style="margin-right: 10px">Check all</button>
<button ng-click="uncheckAll()" style="margin-right: 10px">Uncheck all</button>
<button ng-click="checkFirst()">Check first</button>
<button ng-click="setToNull()" ng-if="setToNull">Set to null</button>
</div>
<div class="col-xs-12 col-sm-6">
<h3>getRoles()</h3>
<pre>{{getRoles()|json}}</pre>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<h3>html</h3>
<pre class="prettyprint ng-non-bindable">&lt;label ng-repeat=&quot;role in roles&quot;&gt;
&lt;input type=&quot;checkbox&quot; checklist-model=&quot;getRoles()&quot; checklist-value=&quot;role&quot; ng-change=&quot;check(role, checked)&quot;&gt; {{role}}
&lt;/label&gt;</pre>
<h3>js</h3>
<pre class="prettyprint">var app = angular.module(&quot;app&quot;, [&quot;checklist-model&quot;]);
app.controller('Ctrl8', function($scope) {
$scope.roles = [
'guest',
'user',
'customer',
'admin'
];
$scope.user = {
roles: ['user']
};
$scope.checkAll = function() {
$scope.user.roles = angular.copy($scope.roles);
};
$scope.uncheckAll = function() {
$scope.user.roles = [];
};
$scope.checkFirst = function() {
$scope.user.roles.splice(0, $scope.user.roles.length);
$scope.user.roles.push('guest');
};
$scope.getRoles = function() {
return $scope.user.roles;
};
$scope.check = function(value, checked) {
var idx = $scope.user.roles.indexOf(value);
if (idx &gt;= 0 &amp;&amp; !checked) {
$scope.user.roles.splice(idx, 1);
}
if (idx &lt; 0 &amp;&amp; checked) {
$scope.user.roles.push(value);
}
};
});</pre>
</div>
</div>
Expand Down Expand Up @@ -485,7 +582,7 @@ <h3>js</h3>
</div>
<div class="row">
<div class="col-xs-12">
<h2 style="margin-bottom: 0">Filter</h2>
<h2 style="margin-bottom: 0">Comparator</h2>
</div>
</div>
<div ng-controller="Ctrl6" class="row">
Expand Down Expand Up @@ -753,29 +850,8 @@ <h3>js</h3>
&copy; <a href="https://github.com/vitalets">Vitaliy Potapov</a> 2013. Released under the MIT license.</p>

</footer>
</div><!-- Yandex.Metrika counter -->
<script type="text/javascript">
(function (d, w, c) {
(w[c] = w[c] || []).push(function() {
try {
w.yaCounter22971388 = new Ya.Metrika({id:22971388,
accurateTrackBounce:true});
} catch(e) { }
});

var n = d.getElementsByTagName("script")[0],
s = d.createElement("script"),
f = function () { n.parentNode.insertBefore(s, n); };
s.type = "text/javascript";
s.async = true;
s.src = (d.location.protocol == "https:" ? "https:" : "http:") + "//mc.yandex.ru/metrika/watch.js";

if (w.opera == "[object Opera]") {
d.addEventListener("DOMContentLoaded", f, false);
} else { f(); }
})(document, window, "yandex_metrika_callbacks");
</script>
<noscript><div><img src="//mc.yandex.ru/watch/22971388" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->
</div>
</body>
</html>
</html>
<!-- if env == 'prod'-->
<!-- include metrika.html-->
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "checklist-model",
"description": "AngularJS directive for list of checkboxes",
"version": "0.4.0",
"version": "0.5.0",
"homepage": "http://vitalets.github.io/checklist-model",
"author": {
"name": "Vitaliy Potapov",
Expand Down
1 change: 1 addition & 0 deletions test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<script src="../docs/blocks/array-id/test.js"></script>
<script src="../docs/blocks/array-object/test.js"></script>
<script src="../docs/blocks/single-object/test.js"></script>
<script src="../docs/blocks/function-as-model/test.js"></script>
<script src="../docs/blocks/array-object-with-ngmodel/test.js"></script>
<script src="../docs/blocks/object/test.js"></script>
<script src="../docs/blocks/filter/test.js"></script>
Expand Down

8 comments on commit 52e4be0

@DevQueen
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying so hard to use this code, but I cannot get it to work. I need to display the selected values, which I can, but if a box is unchecked, I cannot get it to remove it. You have a value called "checked" that you pass to a function, but for the life of me, I can figure out where or how it gets set in the html.

@beradrian
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use a function as a model, then this is different. The model is only like a getter, there is no setter. This you have to do it manually, using something like ng-change, like in the example.

@DevQueen
Copy link

@DevQueen DevQueen commented on 52e4be0 Aug 19, 2015 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@beradrian
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you create a plunkr or jsfiddle example?

@DevQueen
Copy link

@DevQueen DevQueen commented on 52e4be0 Aug 19, 2015 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DevQueen
Copy link

@DevQueen DevQueen commented on 52e4be0 Aug 19, 2015 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@beradrian
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But you're not using the checklist-model as a function in that example. Btw, are you fine with moving our conversation to the issue list? Just submit a new issue with the plunkr example.

@DevQueen
Copy link

@DevQueen DevQueen commented on 52e4be0 Aug 20, 2015 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.