Skip to content

ngMessages support #132

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 30 commits into from
Dec 26, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
592a0b6
added ngMessages support and example
jamesbrobb Nov 26, 2014
c056803
Delete test.sqlite
jamesbrobb Nov 26, 2014
7278703
added overriden get_widget_attrs to NgMessagesMixin to add rejected-v…
jamesbrobb Nov 26, 2014
101ddb2
added overriden get_widget_attrs to NgMessagesMixin to add rejected-v…
jamesbrobb Nov 26, 2014
7e1bc4d
removed need for hardcoded rejected from msg_format_bind
jamesbrobb Nov 26, 2014
048ffe1
bindable field error messages are now assigned to a related property …
jamesbrobb Nov 27, 2014
5369961
changed exclusion of $pristine error to exclusion of $message error, …
jamesbrobb Nov 27, 2014
b0f013c
refactoring
jamesbrobb Nov 27, 2014
35a3a8d
fixed super c and p error
jamesbrobb Nov 29, 2014
d278bf1
added seperate form and field error classes for ngMessages mixin
jamesbrobb Dec 1, 2014
5f3af87
added valid message display and changed field error format to ul/li
jamesbrobb Dec 2, 2014
546ac9d
tweaking field states to display errors correctly
jamesbrobb Dec 3, 2014
7e8d0e5
styling and error/valid display trigger properties updated
jamesbrobb Dec 3, 2014
f5829c2
updated rejected validation directive to check $message.rejected value
jamesbrobb Dec 4, 2014
6fed82e
updated rejected validation directive to check $message.rejected value
jamesbrobb Dec 4, 2014
778be3e
added client tests
jamesbrobb Dec 8, 2014
130bbc0
fixed merge conflict
jamesbrobb Feb 22, 2015
f7ce5c8
added ngMessages client tests
jamesbrobb Mar 13, 2015
2eb3731
added bound form error handling and tests
jamesbrobb Mar 18, 2015
589dad4
added docs for ngMessages support
jamesbrobb Mar 19, 2015
72f8ef6
merge
jamesbrobb Mar 19, 2015
06b68ba
fixed minor issue in change log
jamesbrobb Mar 19, 2015
d30fb00
added python unit tests
jamesbrobb Mar 25, 2015
b1ecb51
merge
jamesbrobb Mar 25, 2015
9694628
tweaks
jamesbrobb Mar 25, 2015
5234442
tweaks
jamesbrobb Mar 26, 2015
877aac0
merge
jamesbrobb Apr 1, 2015
ae87482
POST now working for validation only. Fixed failing tests
jamesbrobb Apr 1, 2015
ef2fe0d
updated docs
jamesbrobb Apr 1, 2015
da11d88
removed error warning that 1.3 is required
jamesbrobb Apr 1, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions client/karma.conf.1.3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'use strict';

// Karma configuration
module.exports = function(config) {
function getFiles() {
var fs = require('fs');
var files = [];
['angular.js', 'angular-mocks.js', 'angular-messages.js'].forEach(function(item) {
var cachename = 'cdncache/' + item;
files.push(fs.existsSync(cachename) ? cachename : 'http://code.angularjs.org/1.3.0/' + item);
});
return files.concat(['src/js/*.js', 'tests/*.js', 'mocks/*.js']);
}

config.set({
// frameworks to use
frameworks: ['jasmine'],

// list of files / patterns to load in the browser
files: getFiles(),

// list of files to exclude
exclude: [],

// test results reporter to use
// possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
reporters: ['progress'],

// web server port
port: 9090,

// enable / disable colors in the output (reporters and logs)
colors: true,

// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,

// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,

// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera (has to be installed with `npm install karma-opera-launcher`)
// - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`)
// - PhantomJS
// - IE (only Windows; has to be installed with `npm install karma-ie-launcher`)
browsers: ['ChromeCanary'],

// If browser does not capture in given timeout [ms], kill it
captureTimeout: 60000,

// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: false
});
};
2 changes: 1 addition & 1 deletion client/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ module.exports = function(config) {
files: getFiles(),

// list of files to exclude
exclude: [],
exclude: ['tests/djangoNgMessagesSpec.js'],

// test results reporter to use
// possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
Expand Down
257 changes: 257 additions & 0 deletions client/src/js/ng-django-angular-messages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
(function(angular, undefined) {
'use strict';


if(angular.version.minor < 3 ) {
// throw new Error('The ng.django.angular.messages module requires AngularJS 1.3+');
}


angular
.module('ng.django.angular.messages',[
'ng.django.forms'
])
.directive('form', formDirectiveFactory())
.directive('ngForm', formDirectiveFactory(true))
.directive('djngError', djngError)
.directive('djngRejected', djngRejected)
.factory('djngAngularMessagesForm', djngAngularMessagesForm);




/**
* An extension to form
*
* Adds the following methods and functionality:
*
* - djngSetValidFieldsPristine()
*/

function formDirectiveFactory(isNgForm) {

return function() {

return {
restrict: isNgForm ? 'EAC' : 'E',
require: 'form',
link: {
pre: function(scope, element, attrs, formCtrl) {

var controls,
modelName;

var _superAdd = formCtrl.$addControl;

formCtrl.$addControl = function(control) {

_superAdd(control)

controls = controls || [];

if(controls.indexOf(control) === -1) {
controls.push(control);
}
}

var _superRemove = formCtrl.$removeControl;

formCtrl.$removeControl = function(control) {

_superRemove(control)

if(controls && controls.indexOf(control) !== -1) {
controls.splice(controls.indexOf(control), 1);
}
}

formCtrl.djngSetValidFieldsPristine = function() {

var i = 0,
len = controls.length,
control;

for(; i < len; i++) {
control = controls[i];
if(control.$valid) {
control.$setPristine();
}
}
}
}
}
}
}

}


function djngError($timeout) {

return {
restrict: 'A',
require: [
'?^form',
'?ngModel'
],
link: function(scope, element, attrs, ctrls) {

var formCtrl = ctrls[0],
ngModel = ctrls[1];

if (attrs.djngError !== 'bound-msgs-field' || !formCtrl || !ngModel)
return;

element.removeAttr('djng-error');
element.removeAttr('djng-error-msg');

$timeout(function(){

// TODO: use ngModel.djngAddRejected to set message

ngModel.$message = attrs.djngErrorMsg;
ngModel.$validate();
formCtrl.$setSubmitted();
});
}
}
}


function djngRejected() {

return {
restrict: 'A',
require: '?ngModel',
link: function(scope, element, attrs, ngModel) {

if(!ngModel || attrs.djngRejected !== 'validator')
return;

var _hasMessage = false,
_value = null;

ngModel.$validators.rejected = function(value) {

if(_hasMessage && (_value !== value)) {

_hasMessage = false;
_value = null;

ngModel.$message = undefined;

}else{

_hasMessage = !!ngModel.$message;

if(_hasMessage)
_value = value;
}

return !_hasMessage;
}

/*
ctrl.djngClearRejected = function() {
if(!!ctrl.$message) {
ctrl.$message = undefined;
ctrl.$validate();
}
};

ctrl.djngAddRejected = function(msg) {
ctrl.$message = msg;
ctrl.$validate();
};
*/
}
}
}


function djngAngularMessagesForm() {

var NON_FIELD_ERRORS = '__all__';

return {
setErrors: setErrors
}

/* ============================ */

function setErrors(form, errors) {
_clearFormMessage(form);
_displayErrors(form, errors);
return _isNotEmpty(errors);
};

function _clearFormMessage(form) {
form.$message = undefined;
};

function _displayErrors(form, errors) {

form.$setSubmitted();

angular.forEach(errors, function(error, key) {

var field,
message = error[0];

if(key == NON_FIELD_ERRORS) {

form.$message = message;
/*
* Only set current valid fields to pristine
*
* Any field that's been submitted with an error should
* still display its error
*
* Any field that was valid when the form was submitted,
* may have caused the NON_FIELD_ERRORS, so should be set
* to pristine to prevent it's valid state being displayed
*/
form.djngSetValidFieldsPristine();

}else if(form.hasOwnProperty(key)) {

field = form[key];
field.$message = message;

if (isField(field)) {

field.$validate();

} else {

// this field is a composite of input elements
field.$setSubmitted();

angular.forEach(field, function(subField, subKey) {

if(isField(subField)) {
subField.$validate();
}
});
}

}
});
}

function isField(field) {
return !!field && angular.isArray(field.$viewChangeListeners);
}

function _isNotEmpty(obj) {
for (var p in obj) {
if (obj.hasOwnProperty(p))
return true;
}
return false;
}
};



})(window.angular);
2 changes: 1 addition & 1 deletion client/src/js/ng-django-forms.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,4 +363,4 @@ djng_forms_module.directive('djngBindIf', function() {
};
});

})(window.angular);
})(window.angular);
Loading