Skip to content

Commit

Permalink
checklistBeforeChange
Browse files Browse the repository at this point in the history
  • Loading branch information
beradrian committed Nov 21, 2015
1 parent d91ed0e commit b29aeff
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 33 deletions.
30 changes: 23 additions & 7 deletions checklist-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ angular.module('checklist-model', [])
var getter = $parse(checklistModel);
var setter = getter.assign;
var checklistChange = $parse(attrs.checklistChange);
var checklistBeforeChange = $parse(attrs.checklistBeforeChange);

// value added to list
var value = attrs.checklistValue ? $parse(attrs.checklistValue)(scope.$parent) : attrs.value;
Expand All @@ -78,23 +79,38 @@ angular.module('checklist-model', [])
if (newValue === oldValue) {
return;
}

if (checklistBeforeChange && (checklistBeforeChange(scope) === false)) {
scope[attrs.ngModel] = contains(getter(scope.$parent), value, comparator);
return;
}

setValueInChecklistModel(value, newValue);

if (checklistChange) {
checklistChange(scope);
}
});

function setValueInChecklistModel(value, checked) {
var current = getter(scope.$parent);
if (angular.isFunction(setter)) {
if (newValue === true) {
if (checked === true) {
setter(scope.$parent, add(current, value, comparator));
} else {
setter(scope.$parent, remove(current, value, comparator));
}
}

}

if (checklistChange) {
checklistChange(scope);
}
});

// declare one function to be used for both $watch functions
function setChecked(newArr, oldArr) {
scope[attrs.ngModel] = contains(newArr, value, comparator);
if (checklistBeforeChange && (checklistBeforeChange(scope) === false)) {
setValueInChecklistModel(value, scope[attrs.ngModel]);
return;
}
scope[attrs.ngModel] = contains(newArr, value, comparator);
}

// watch original model change
Expand Down
12 changes: 8 additions & 4 deletions docs/blocks/event/ctrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ app.controller('Ctrl5', function($scope) {
u: 'User'
};

$scope.testValue = 'Im not changed yet!';
$scope.imChanged = function(){
$scope.testValue = $scope.user.roles.join(',');
}
$scope.testValue = 'Im not changed yet!';
$scope.imChanged = function(){
$scope.testValue = $scope.user.roles.join(',');
}
$scope.shouldChange = function(key){
console.log("should change " + key);
return key !== "g";
}

$scope.user = {
roles: ['c']
Expand Down
8 changes: 7 additions & 1 deletion docs/blocks/event/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ describe('event', function() {
it('should check of roles are changed to new value before checklist-change is fired', function() {
element(s+'button[ng-click="checkFirst()"]').click();
check(a, [1,0,0,0]);
expect(element(s+'pre').text()).toBe('"a"');
expect(element(s+'pre').text()).toEqual("\"a\"");
});

it('should check that checklist-before-change can deny change of values', function() {
element(s+'button[ng-click="checkAll()"]').click();
check(a, [1,1,0,1]);
expect(element(s+'pre').text()).toEqual("\"a,c,u\"");
});

});
2 changes: 1 addition & 1 deletion docs/blocks/event/view.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<label ng-repeat="(key, text) in roles">
<input type="checkbox" checklist-change="imChanged()" checklist-model="user.roles" checklist-value="key"> {{text}}
<input type="checkbox" checklist-before-change="shouldChange(key)" checklist-change="imChanged()" checklist-model="user.roles" checklist-value="key"> {{text}}
</label>
1 change: 0 additions & 1 deletion docs/index.jade
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ html(ng-app='app')
title Checklist-model - AngularJS directive for list of checkboxes

// Bootstrap 3
script(src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js")
link(href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css", rel="stylesheet", media="screen")
link(href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css", rel="stylesheet", media="screen")

Expand Down
29 changes: 18 additions & 11 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Checklist-model - AngularJS directive for list of checkboxes</title>
<!-- Bootstrap 3-->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css" rel="stylesheet" media="screen">
<!--docs css-->
Expand Down Expand Up @@ -831,7 +830,7 @@ <h2 style="margin-bottom: 0">Event</h2>
<div class="col-xs-12 col-sm-6">
<h3>demo</h3>
<div class="well"><label ng-repeat="(key, text) in roles">
<input type="checkbox" checklist-change="imChanged()" checklist-model="user.roles" checklist-value="key"> {{text}}
<input type="checkbox" checklist-before-change="shouldChange(key)" checklist-change="imChanged()" checklist-model="user.roles" checklist-value="key"> {{text}}
</label></div>
<script>app.controller('Ctrl5', function($scope) {
$scope.roles = {
Expand All @@ -841,10 +840,14 @@ <h3>demo</h3>
u: 'User'
};

$scope.testValue = 'Im not changed yet!';
$scope.imChanged = function(){
$scope.testValue = $scope.user.roles.join(',');
}
$scope.testValue = 'Im not changed yet!';
$scope.imChanged = function(){
$scope.testValue = $scope.user.roles.join(',');
}
$scope.shouldChange = function(key){
console.log("should change " + key);
return key !== "g";
}

$scope.user = {
roles: ['c']
Expand Down Expand Up @@ -881,7 +884,7 @@ <h3>testValue</h3>
<div class="col-xs-12">
<h3>html</h3>
<pre class="prettyprint ng-non-bindable">&lt;label ng-repeat=&quot;(key, text) in roles&quot;&gt;
&lt;input type=&quot;checkbox&quot; checklist-change=&quot;imChanged()&quot; checklist-model=&quot;user.roles&quot; checklist-value=&quot;key&quot;&gt; {{text}}
&lt;input type=&quot;checkbox&quot; checklist-before-change=&quot;shouldChange(key)&quot; checklist-change=&quot;imChanged()&quot; checklist-model=&quot;user.roles&quot; checklist-value=&quot;key&quot;&gt; {{text}}
&lt;/label&gt;</pre>
<h3>js</h3>
<pre class="prettyprint">var app = angular.module(&quot;app&quot;, [&quot;checklist-model&quot;]);
Expand All @@ -893,10 +896,14 @@ <h3>js</h3>
u: 'User'
};

$scope.testValue = 'Im not changed yet!';
$scope.imChanged = function(){
$scope.testValue = $scope.user.roles.join(',');
}
$scope.testValue = 'Im not changed yet!';
$scope.imChanged = function(){
$scope.testValue = $scope.user.roles.join(',');
}
$scope.shouldChange = function(key){
console.log(&quot;should change &quot; + key);
return key !== &quot;g&quot;;
}

$scope.user = {
roles: ['c']
Expand Down
17 changes: 9 additions & 8 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ from several checkboxes.
## Usage
You should play with attributes of `<input>` tag:

| Attribute | Mandatory | Description |
| :----------------: | :-------: | --------------------------------------------- |
| `checklist-model` | Yes | Use instead of `ng-model` |
| `checklist-value` | No | What should be picked as array item |
| `value` | No | What should be picked as item, but unlike `checklist-value`, this does not evaluate as an angular expression, but rather a static value |
| `ng-model` | No | Every checkbok will span a new scope and define a variable named `checked` to hold its state. You can modify this name by using this attribute. |
| `checklist-comparator` | No | A custom comparator. If it starts with dot(`.`) then it will be an expression applied to the array item. Otherwise it should evaluate to a function as an angular expression. The function return true if the first two arguments are equal and false otherwise. |
| `checklist-change` | No | An angular expression evaluated each time the `checklist-model` has changed. |
| Attribute | Mandatory | Description |
| :-----------------------: | :-------: | --------------------------------------------- |
| `checklist-model` | Yes | Use instead of `ng-model` |
| `checklist-value` | No | What should be picked as array item |
| `value` | No | What should be picked as item, but unlike `checklist-value`, this does not evaluate as an angular expression, but rather a static value |
| `ng-model` | No | Every checkbok will span a new scope and define a variable named `checked` to hold its state. You can modify this name by using this attribute. |
| `checklist-comparator` | No | A custom comparator. If it starts with dot(`.`) then it will be an expression applied to the array item. Otherwise it should evaluate to a function as an angular expression. The function return true if the first two arguments are equal and false otherwise. |
| `checklist-before-change` | No | An angular expression evaluated each time before the `checklist-model` has changed. If it evaluates to 'false' then the model will not change anymore. |
| `checklist-change` | No | An angular expression evaluated each time the `checklist-model` has changed. |

* If you modify directly the value of the `checklist-model`, it is possible that the UI won't be updated. This is because this directive looks for the model in the parent, not in the current scope. Instead of doing `checklistModelList = []` it is better to do `checklistModelList.splice(0, checklistModelList.length)` or wrap it in another object.
* If you're using `track by` you must specify the same thing for `checklist-value` too. See [#46](https://github.com/vitalets/checklist-model/issues/46).
Expand Down

0 comments on commit b29aeff

Please sign in to comment.