Skip to content

Commit

Permalink
Merge pull request #629 from marmelab/boolean-choice
Browse files Browse the repository at this point in the history
[RFR] Make the boolean type handle null values
  • Loading branch information
fzaninotto committed Aug 31, 2015
2 parents e2a48da + dc2aae5 commit 0ad9b5f
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 12 deletions.
24 changes: 23 additions & 1 deletion doc/Configuration-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ A field is the representation of a property of an entity.
* [`datetime` Field Type](#datetime-field-type)
* [`number` Field Type](#number-field-type)
* `float` Field Type
* `boolean` Field Type
* [`boolean` Field Type]
* [`choice` and `choices` Field Types](#choice-and-choices-field-types)
* `json` Field Type
* [`file` Field Type](#file-field-type)
Expand Down Expand Up @@ -483,6 +483,28 @@ Format for number to string conversion. Based on [Numeral.js](http://numeraljs.c
nga.field('cost', 'number').format('$0,0.00');
// now 1234.5 will render as '$1,234.50'

### `boolean` Field Type

A field of type `boolean` can have 3 values: true, false, or null. That's why the form widget for such a field is a dropdown and not a checkbox.

* `choices(array)`
Array of choices used for the boolean values. By default:

[
{ value: null, label: 'undefined' },
{ value: true, label: 'true' },
{ value: false, label: 'false' }
]

Override it with custom labels to fit your needs:

nga.fields('power_user', 'boolean')
.choices([
{ value: null, label: 'not yet decided' },
{ value: true, label: 'enabled' },
{ value: false, label: 'disabled' }
]);

### `choice` and `choices` Field Types

* `choices(array|function)`
Expand Down
12 changes: 11 additions & 1 deletion examples/blog/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,18 @@
.label('Upper name')
.template('{{ entry.values.name.toUpperCase() }}')
])
.filters([
nga.field('published', 'boolean')
])
.batchActions([]) // disable checkbox column and batch delete
.listActions(['show']);
.listActions(['show', 'edit']);

tag.editionView()
.fields([
nga.field('name'),
nga.field('published', 'boolean')
.choices([{ value: null, label: 'null' }, { value: true, label: 'yes'}, {value: false,label: 'no' }])
])

tag.showView()
.fields([
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"url": "git://github.com/marmelab/ng-admin.git"
},
"devDependencies": {
"admin-config": "^0.2.14",
"admin-config": "^0.2.15",
"angular": "~1.3.15",
"angular-bootstrap": "^0.12.0",
"angular-mocks": "1.3.14",
Expand Down
4 changes: 2 additions & 2 deletions src/javascripts/ng-admin/Crud/column/maBooleanColumn.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ define(function (require) {
value: '&',
},
link: function(scope) {
scope.isOk = !!scope.value();
scope.value = scope.value();
},
template: '<span class="glyphicon" ng-class="{\'glyphicon-ok\': isOk, \'glyphicon-remove\': !isOk}"></span>'
template: '<span class="glyphicon" ng-class="{\'glyphicon-ok\': value === true, \'glyphicon-remove\': value === false }"></span>'
};
}

Expand Down
5 changes: 3 additions & 2 deletions src/javascripts/ng-admin/Crud/field/maChoiceField.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ function maChoiceField($compile) {
'value': '=',
'entry': '=?',
'datastore': '&?',
'refresh': '&'
'refresh': '&',
'choices': '&?'
},
restrict: 'E',
compile: function() {
Expand All @@ -32,7 +33,7 @@ function maChoiceField($compile) {
refreshAttributes = 'refresh-delay="refreshDelay" refresh="refresh({ $search: $select.search })"';
}

var choices = field.choices ? field.choices() : [];
var choices = scope.choices() ? scope.choices : (field.choices ? field.choices() : []);
var attributes = field.attributes();
scope.placeholder = (attributes && attributes.placeholder) || 'Filter values';

Expand Down
4 changes: 2 additions & 2 deletions src/javascripts/ng-admin/Crud/fieldView/BooleanFieldView.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module.exports = {
getReadWidget: () => '<ma-boolean-column value="::entry.values[field.name()]"></ma-boolean-column>',
getLinkWidget: () => '<a ng-click="gotoDetail()">' + module.exports.getReadWidget() + '</a>',
getFilterWidget: () => '<ma-checkbox-field field="::field" value="values[field.name()]"></ma-checkbox-field>',
getWriteWidget: () => '<ma-checkbox-field field="::field" value="entry.values[field.name()]"></ma-checkbox-field>'
getFilterWidget: () => `<ma-choice-field field="::field" value="values[field.name()]" choices="[{value: 'true', label: 'true' }, { value: 'false', label: 'false' }]"></ma-choice-field>`,
getWriteWidget: () => `<div class="row"><ma-choice-field class="col-sm-4 col-md-3" field="::field" value="entry.values[field.name()]"></ma-choice-field></div>`
}
31 changes: 28 additions & 3 deletions src/javascripts/test/e2e/EditionViewSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,39 @@ describe('EditionView', function () {
});
});

describe('BooleanField', function() {
beforeEach(function() {
browser.get(browser.baseUrl + '#/tags/edit/5');
});

it('should render as a choice field', function () {
$$('.ng-admin-field-published .ui-select-container')
.then(function(uiSelect) {
expect(uiSelect.length).toBe(1)
})
.then(function() {
return $$('.ng-admin-field-published .btn').first().click();
})
.then(function() {
return $$('.ng-admin-field-published .ui-select-choices-row');
})
.then(function(choices) {
expect(choices.length).toBe(3)
});
});
})

describe('DetailLink', function() {
beforeEach(function() {
browser.baseUrl + '#/posts/edit/1';
browser.get(browser.baseUrl + '#/posts/edit/1');
});

it('should redirect to corresponding detail view even for referenced_list entity', function () {
$$('#row-comments td a').first().click();
browser.getLocationAbsUrl().then(function(url){
$$('#row-comments td a').first().click()
.then(function() {
return browser.getLocationAbsUrl();
})
.then(function(url){
expect(url).toContain('/comments/edit/');
});
});
Expand Down

0 comments on commit 0ad9b5f

Please sign in to comment.