JavaScript powered forms
images provided for your amusement by characterslist.com
by Kent C. Dodds
@kentcdodds
@kentcdodds
Kent! Don't forget to Selfie!
@kentcdodds
Air Squats
@kentcdodds
@kentcdodds
@kentcdodds
<form name="vm.userForm" ng-submit="vm.onSubmit(vm.user)">
<div class="form-group" has-error="vm.userForm.firstName">
<label for="firstName">First Name</label>
<input type="text" ng-model="vm.user.firstName" name="firstName" class="form-control" id="firstName" placeholder="First Name" required>
<div my-messages="vm.userForm.firstName"></div>
</div>
<div class="form-group" has-error="vm.userForm.lastName">
<label for="lastName">Last Name</label>
<input type="text" ng-model="vm.user.lastName" name="lastName" class="form-control" id="lastName" placeholder="Last Name" required>
<div my-messages="vm.userForm.lastName"></div>
</div>
<div class="form-group" has-error="vm.userForm.email">
<label for="emailAddress">Email Address</label>
<input type="email" ng-model="vm.user.email" name="email" class="form-control" id="emailAddress" placeholder="Email address" required>
<div my-messages="vm.userForm.email"></div>
</div>
<div class="form-group" has-error="vm.userForm.confirmEmail">
<label for="emailAddressConfirm">Confirm Email Address</label>
<input type="email" ng-model="vm.user.confirmEmail" name="confirmEmail" must-match="vm.user.email" class="form-control" id="emailAddressConfirm" placeholder="Confirm Email address" required>
<div my-messages="vm.userForm.confirmEmail"></div>
</div>
<div class="form-group" has-error="vm.userForm.password">
<label for="password">Password</label>
<input type="password" ng-model="vm.user.password" name="password" class="form-control" id="password" placeholder="Password" required>
<div my-messages="vm.userForm.password"></div>
</div>
<div class="form-group" has-error="vm.userForm.confirmPassword">
<label for="passwordConfirm">Confirm Password</label>
<input type="password" ng-model="vm.user.confirmPassword" must-match="vm.user.password" class="form-control" id="passwordConfirm" placeholder="Password" required>
<div my-messages="vm.userForm.confirmPassword"></div>
</div>
<div class="radio-group" has-error="vm.userForm.genderRadios">
<label>Your Gender?</label>
<div class="radio">
<label>
<input type="radio" ng-model="vm.user.model" name="genderRadios" id="genderRadios1" value="male" required>
Male
</label>
</div>
<div class="radio">
<label>
<input type="radio" ng-model="vm.user.model" name="genderRadios" id="genderRadios2" value="female" required>
Female
</label>
</div>
<div class="radio">
<label>
<input type="radio" ng-model="vm.user.model" name="genderRadios" id="genderRadios3" value="unspecified" required>
Prefer not to say
</label>
</div>
<div my-messages="vm.userForm.genderRadios"></div>
</div>
<div class="checkbox" has-error="vm.userForm.agree">
<label>
<input type="checkbox" name="agree" ng-model="vm.user.agree" required> Do you sign your soul away to our TOS?
</label>
<div my-messages="vm.userForm.agree"></div>
</div>
<button type="submit" class="btn btn-default" ng-disabled="vm.userForm.$invalid">Submit</button>
</form>
<form name="vm.userForm" ng-submit="vm.onSubmit(vm.user)">
<formly-form model="vm.user" fields="vm.fields" form="vm.userForm">
<button type="submit" class="btn btn-default" ng-disabled="vm.userForm.$invalid">
Submit
</button>
</formly-form>
</form>
... and a little JS :-)
@kentcdodds
To forms in AngularJS Apps
@kentcdodds
@kentcdodds
@kentcdodds
<input ng-model="vm.user.firstName" />
@kentcdodds
<div>
<label>First Name</label>
<input ng-model="vm.user.firstName" />
</div>
@kentcdodds
<div>
<label for="name">First Name</label>
<input ng-model="vm.user.firstName" id="name" />
</div>
@kentcdodds
<div class="form-group">
<label for="name">First Name</label>
<input ng-model="vm.user.firstName"
id="name"
class="form-control"
/>
</div>
@kentcdodds
<div class="form-group">
<label for="{{::vm.id}}">{{vm.label}}</label>
<input ng-model="vm.model"
id="{{::vm.id}}"
class="form-control"
/>
</div>
angular.module('app').directive('nlInput', function() {
var unique = 0;
return {
restrict: 'E',
template: require('./nl-input.html'), // webpack ftw
replace: true,
scope: {
label: '@',
model: '='
},
bindToController: true,
controllerAs: 'vm',
controller: function() {
var vm = this;
vm.id = `field${Math.floor(Math.random() * 999)}${unique++}`; // es6 ftw
}
};
});
@kentcdodds
<div class="form-group">
<label for="{{::vm.id}}">{{vm.label}}</label>
<input ng-model="vm.model"
id="{{::vm.id}}"
class="form-control"
ng-required="vm.required"
/>
</div>
angular.module('app').directive('nlInput', function() {
var unique = 0;
return {
restrict: 'E',
template: require('./nl-input.html'), // webpack ftw
replace: true,
scope: {
label: '@',
model: '='
},
bindToController: true,
controllerAs: 'vm',
controller: function() {
var vm = this;
vm.id = `field${Math.floor(Math.random() * 999)}${unique++}`; // es6 ftw
},
link: function(scope, el, attrs) {
scope.vm.required = attrs.hasOwnProperty('required');
}
};
});
<div class="form-group">
<label for="{{::vm.id}}">{{vm.label}}</label>
<!-- but let's be honest... this is getting ridiculous (-‸ლ) -->
<input ng-model="vm.model"
id="{{::vm.id}}"
class="form-control"
ng-required="vm.required"
ng-disabled="vm.disabled"
ng-maxlength="vm.maxlength"
ng-minlength="vm.minlength"
/>
</div>
angular.module('app').directive('nlInput', function() {
var unique = 0;
return {
restrict: 'E',
template: require('./nl-input.html'), // webpack ftw
replace: true,
scope: {
label: '@',
model: '='
},
bindToController: true,
controllerAs: 'vm',
controller: function() {
var vm = this;
vm.id = `field${Math.floor(Math.random() * 999)}${unique++}`; // es6 ftw
},
link: function(scope, el, attrs) {
// I'm not a fool, let's JavaScript here
var extraAttrs = ['required', 'disabled', 'maxlength', 'minlength'];
angular.forEach(extraAttrs, attr => {
scope.vm[attr] = attrs.hasOwnProperty(attr);
});
}
};
});
Sure, yeah... cool... uh...
Give me a sec to write a directive and update everything...
done!
@kentcdodds
@kentcdodds
@kentcdodds
@kentcdodds
JavaScript powered forms for AngularJS
[coding forms without angular-formly] leads to anger
anger leads to hate
hate... leads to suffering
- Yoda (presenter liberties taken)
@kentcdodds
(ó ì_í)=óò=(ì_í ò)
@kentcdodds
Total Control
@kentcdodds
@kentcdodds
consistent & simple
@kentcdodds
DRY HTML
@kentcdodds
Dead simpler than dead simple
@kentcdodds
but there's not enough time...
bit.ly/ngFormly
@kentcdodds
Give it a go!
@kentcdodds
Slides: bit.ly/ng-formly-slides
Feedback please: bit.ly/ng-formly-feedback