JSFiddle - React, Tailwind, and code Playground
by kryo
HTML
<body ng-app="testApplication">
<form name="testForm" ng-controller="formCtrl" form-grade>
<ul class="grading" ng-if="formMsgs.length > 0">
<li ng-repeat="item in formMsgs" class="{{item.cls}}">{{item.msg}}</li>
</ul>
<dl>
<dt>Enter something below:</dt>
<dd>
<input type="text" ng-model="formEntry.name" required />
<ul class="grading" ng-if="fieldMsgs.name.length > 0">
<li ng-repeat="item in fieldMsgs.name" class="{{item.cls}}">{{item.msg}}</li>
</ul>
</dd>
</dl>
<dl>
<button ng-click="submit()" ng-disabled="testForm.$invalid">Submit</button>
<button ng-click="submit()">Submit (overridden)</button>
<button ng-click="reset()" ng-disabled="isClean()">Reset</button>
</dl>
<div class="state">
<pre>Current entry state: {{formEntry | json}}
-------------------------------------------------
Grade state:
scope.formMsgs: {{formMsgs | json}}
scope.fieldMsgs: {{fieldMsgs | json}}</pre>
</div>
</form>
</body>
SCSS
@import 'compass/reset';
.state {
padding: 5px 10px;
margin-top: 10px;
background-color: silver;
}
dl {
dt, dd {
padding: 0;
margin: 0;
}
dt {
font-weight: bold;
}
dd {
}
}
.grading {
display: block;
list-style: none;
padding: 0;
margin: 0;
.info {
color: green;
}
.error {
color: red;
}
}
JavaScript
'use strict';
angular.module("testApplication", [])
.config(function(){
})
.factory('pseudoData', function(){
return {
post: function(entry){ // this simulates the angular $http post (pretend it's backend).
var
valid = ['hans','kryo','jr'],
param = 'name',
responseCode = 200,
response = [];
if(valid.indexOf(entry[param]) === -1) {
responseCode = 400; // invalid response code
response.push({ // simulates the node-validator format
param: param,
msg: 'Value must be one of: ' + valid.join(', '),
value: entry[param]
});
response.push({ // add form failure msg
msg: 'Form submission failed, please check messages.'
});
}
else {
response.push({ // add field success msg
param: param,
msg: 'Good job!',
value: entry[param]
});
response.push({ // add form success msg
msg: 'Form completed successfully!'
});
}
return {
then: function(success, error){
var angularPseudoResponse = {
config: {},
data: response,
headers: function(){},
status: responseCode
};
if(responseCode === 200) {
success(angularPseudoResponse);
}
else {
error(angularPseudoResponse);
}
return this;
}
};
}
};
})
.directive('formGrade', function($compile){
return {
restrict: 'A',
controller: function($scope, $element) {
var
gradeTpl = ['<ul class="grade">',
'<li ng-repeat="item in messages" class="{{item.cls}}">{{item.msg}}</li>',
'</ul>'].join('');
function clearGrading() {
$scope.formMsgs = [];
$scope.fieldMsgs = {};
}
function addFormMsg(msg, cls) {
$scope.formMsgs.push({
cls: cls,
msg: msg
});
}
...