How to re-use "component" in angularjs? - angularjs

I have a view for editing address, that has a controller attached to it. It fetches all states and territories, with some internal nomenclature, allows user to select country/state, allows use to enter zip code and it fetches correct city etc. There is also validation, and model that gets populated. It depends on some server side services also. Now, I need to use this exact same functionality in like 5-6 forms. I don't want to copy or repeat logic, I would like to declare it in view as directive, and bind complete model (Address) to model of the enclosing view. How do I do this? How do I make connection between view controller and directive controller, and also how do I make connection between view's model (vm.address) and enclosing model (for example vm.client.address)?
Let's say I have this html snippet that has a controller (addressEditCtrl) associated with it.
<div class="row" data-ng-controller="addressEditCtrl">
<div class="col-xs-3">
<div class="form-group">
<label>Address:</label>
<span style="margin-left: 10px; font-weight: normal; font-size: 9px;">
Clear
</span>
<textarea class="form-control" style="height: 80px; width: 300px;"
data-ng-model="vm.address.street" maxlength="255"></textarea>
</div>
</div>
<div class="col-xs-6">
<div class="row">
<div class="col-xs-3">
<label for="zipCode">Zip Code:</label><br>
<input id="zipCode" type="text" class="form-control" placeholder="" style="float: left; width: 45%; margin-right: 10px;"
data-ng-model='vm.address.zipCode'
data-ng-blur="vm.bindZipCodeInfo()" maxlength="5">
<input id="zipCode2" name="zipCode2" type="text" class="form-control" placeholder="" style="float: left; width: 45%;"
data-ng-model='vm.mailingZipPlus' maxlength="4">
</div>
<div class="col-xs-4">
<label for="city">City:</label>
<input id="city" type="text" class="form-control" placeholder=""
data-ng-model='vm.address.city' maxlength="30">
</div>
<div class="form-group col-xs-5 p-0">
<label for="county">County:</label>
<input id="county" class="col-xs-12" type="text" disabled
data-ng-model='vm.address.countyName'>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<label for="states">State:</label>
<select id="states" class="form-control"
data-ng-model="vm.address.stateCode"
data-ng-options="state.Code as state.Description for state in vm.states">
<option value=''> Please Select</option>
</select>
</div>
<div class="col-xs-6">
<label for="countries">Country:</label>
<select id="countries" class="form-control"
data-ng-model="vm.selectedCountry"
data-ng-options="country as country.Description for country in vm.countries"></select>
</div>
</div>
</div>
</div>
I want to turn this into directive. This piece does not work, because in link function scopes are different (directive vs addressEditorCtrl). I am also not sure if I need link or controller defined on the directive as I am not manipulating anything.
(function (angular) {
'use strict';
angular
.module('app')
.directive('srAddressEditor', srAddressEditor);
srAddressEditor.$inject = [];
function srAddressEditor() {
var directive = {
templateUrl: '/app/shared/addressEditor/addressEdit.html',
scope: {
address:'=address'
}
};
return directive;
}
})(angular);
This is what I am after, two way binding. vm.client.mailingAddress and vm.address in above address editor are of the same shape. Any change in either one of them should be synched. I also want to be able to put multiple of these on the form, so isolated scope is what I am after.
<div data-ng-controller="clientEditCtrl">
<div class="col-xs-12">
<sr-address-editor address="vm.client.mailingAddress"></sr-address-editor>
</div>
</div>

Related

Angularjs form scope bug

I have a Angularjs form with a list with names.
When I click on a name the form will change with here profile.
When I change one input and don't save it and I click on a other profile every thing change except the one input that has changed.
<form class="form-horizontal bordered-row" >
<div class="form-group">
<label class="col-sm-4 control-label">Naam</label>
<div class="col-sm-6">
<input type="text" class="form-control" id="" value="{{gegevens.naam | capitalize}}">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">Categorie</label>
<div class="col-sm-6">
<select class="form-control">
<option ng-repeat="x in producten_categorie" value="{{x.value}}" ng-selected="gegevens.categorie == x.value">{{x.name}}</option>
</select>
</div>
</div>
<div class="form-group pad25L">
<button class="btn btn-info" ng-click="productAlgemeen_update(gegevens.naam);">Save</button>
</div>
</form>
And the change scope:
$scope.productGegevens = function(product){
$http.post("php/producten-locatie.php", {'id':product.id}).then(function(response){
$scope.producten_locatie = response.data.records[0];
$scope.gegevens = {
id:product.id,
naam:product.naam,
categorie:product.categorie,
straatnaam:$scope.producten_locatie.straatnaam,
huisnummer:$scope.producten_locatie.huisnummer,
postcode:$scope.producten_locatie.postcode,
stadsnaam:$scope.producten_locatie.stadsnaam
};
});
}
Please note that input data needs to bind with ng-model whereas you are entering your input with value tag. it means the value is rendered in html not in model, so when you click on other profile UI can not detect the change. Please use ng-model for input value not value tag of input box.

How to dynamically validation under ng-repeat in angularjs

Hello I am beginner of Angularjs and I want to build dynamic validations.Here is my code shortened as well as possible.
JS
$scope.inputValidates = [
{ 'name':'name',
'validate':'required',
},
{ 'name':'email',
'validate':'type = email',
}]
HTML
<div ng-repeat="vitem in vm.inputValidates">
<input name={{vitem.name}} ng-model="vm.useraccount[vitem.name]" {{item.validate}}>
</div>
I want this input result as
<input name=name ng-model="vm.useraccount[vitem.name] required>
<input name=name ng-model="vm.useraccount[vitem.name] type = email>
Thanks for taking time for this.
Use ng-required:
<div ng-repeat="vitem in vm.inputValidates">
<input name={{vitem.name}} ng-model="vm.useraccount[vitem.name]" ng-required="item.validate">
</div>
By the way, I see you assigned inputValidates to your $scope. So you should be accessing it in your view by inputValidates, not vm.inputValidates.
Sample is HERE
Sample contains both required and pattern validation applied on textbox rendered using ng-repeat and use ng-switch based on your validation type
<div ng-repeat="field in fields">
<div style="width:600px">
<div ng-form name="validMe" style="width:58%;float:left" ng-switch="field.validationType">
{{field.name}} :
<div ng-switch-when="required">
<input id="input{{$index}}" name="input{{$index}}" type="text" ng-model="field.value" required>
<span style="color: #a94442" ng-show="validMe['input\{\{$index\}\}'].$error.required ">Field Required!</span>
</div>
<div ng-switch-when="email">
<input type="email" id="input{{$index}}" name="input{{$index}}" ng-model="field.value" ng-pattern="/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/">
<span style="color: #a94442" ng-show="validMe['input\{\{$index\}\}'].$error.pattern">Not a valid email!</span>
</div>
</div>
</div>
</div>

AngularJS Multiple Transclusion

I have an AngularJS directive with multiple transclusions and one transclusion slot is wrapped by a form.
Everything is working fine except for the form validation messages.
The directive template:
<ng-form name="nbcardform" ng-submit="submit()" novalidate>
<ng-transclude ng-transclude-slot="back"></ng-transclude>
<div class="row">
<div class="col-xs-12">
<button type="submit">Save</button>
</div>
</div>
</ng-form>
Here is an example of the directive usage:
<nb-card>
<nb-card-back>
<input type="text" name="username" ng-model="vm.username" required>
<div ng-messages="nbcardform.username.$error" role="alert">
<div ng-message="required">Required field</div>
</div>
</nb-card-back>
<nb-card>
For some reason the expression nbcardform.username.$error is undefined.
Can someone help me with this?
You should be creating a subform in your directive as it's scope is (likely?) different and it has no idea what nbcardform is.
<nb-card ng-form="myDirectiveForm">
<nb-card-back>
<input type="text" name="username" ng-model="vm.username" required>
<div ng-messages="myDirectiveForm.username.$error" role="alert">
<div ng-message="required">Required field</div>
</div>
</nb-card-back>
<nb-card>
This will still wire in nicely and in the parent directive you could use something like this:
<ng-form name="nbcardform" ng-submit="submit()" novalidate>
<ng-transclude ng-transclude-slot="back"></ng-transclude>
<div class="row">
<div class="col-xs-12">
<button type="submit">Save</button>
</div>
</div>
{{ nbcardform.$valid }}
{{ nbcardform.myDirectiveForm.$valid }}
{{ nbcardform.myDirectiveForm.username.$valid }}
</ng-form>
Have you tried:
<div ng-messages="vm.username.$error" role="alert">
The transcluded content uses the outer scope unless you specify a different scope to the transclude function in your linking function. See "Providing your own Transclusion Scope" here. Note that once you do that, you may no longer be able to reference vm.

Show/Hide divs depend on dropdown select in AngularJS

I am trying to show a div depending on what is selected from the drop down list. For example, if a user selects 'Cash' from the list show Cash div or if the user select 'Check' from the list show Check div
I have put together sample but its incomplete and needs to wire-up
http://jsfiddle.net/abuhamzah/nq1eyj1v/
Also when the user change the selection I would also like to clear the previous selection so when the user goes back to the previous selection they should not see.
<div ng-controller="MyCtrl">
<div class="col-xs-12">
<label class="col-xs-6 control-label">Type:</label>
<div class="col-xs-6">
<select name="type" ng-model="payment.type" ng-dropdown required ng-change="changeme()" >
<option ng-option value="Cash">Cash</option>
<option ng-option value="Check">Check</option>
<option ng-option value="Money Order">Money Order</option>
</select>
</div>
</div>
<div class="col-xs-12" id="cash">
<div >
<label class="col-xs-6 control-label">Cash :</label>
<div class="col-xs-6">
<input type="number" class="form-control" ng-model="payment.cash" />
</div>
</div>
</div>
<div class="col-xs-12" id="check">
<div >
<label class="col-xs-6 control-label">check :</label>
<div class="col-xs-6">
<input type="number" class="form-control" ng-model="payment.check" />
</div>
</div>
</div>
<div class="col-xs-12" id="money_order">
<div >
<label class="col-xs-6 control-label">money_order :</label>
<div class="col-xs-6">
<input type="number" class="form-control" ng-model="payment.money_order" />
</div>
</div>
</div>
</div>
//controller:
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.changeme = function() {
alert('here');
}
}
you didnt initialize as the angular app coz u missed the ng-app directive first
and this is the solution using ng-if
DEMO
<div ng-app="myApp" ng-controller="MyCtrl"> // initialize as a angular app
<div class="col-xs-12" id="cash" ng-if="payment.type == 'Cash'"> // this div will show if the value of `payment.type` model equals to `cash`. and so on.

Unable to determine why form won't submit

I've created a basic angular form and can't determine why it's not submitting.
http://contact-info.checkoutbiblebowl.com/
The form validation is valid and it still won't submit. I feel like I've overlooked something silly, but have looked at this over the last few days and can't figure out what it is. Any suggestions?
<form method='post' action='' name='form' novalidate ng-controller="myController">
<div class="row form">
<div class="form-inline">
<div class="form-row">
<label class="form-label" style='margin-top: 20px'>Name</label>
<div class="form-item">
<div style="float: left">
First<br/>
<input type="text" ng-model="firstName" name="firstName" class="small" style="width: 200px" maxlength="32" required>
<div ng-cloak ng-show="form.firstName.$error.required" class="required">First name is required</div>
</div>
<div style="float: left; margin-left: 1em">
Last<br/>
<input type="text" ng-model="lastName" name="lastName" class="small" style="width: 200px" maxlength="32" required>
<div ng-cloak ng-show="form.lastName.$error.required" class="required">Last name is required</div>
</div>
<div style="clear:both"></div>
</div>
</div>
<div class="button-row">
<button ng-disabled="!form.$valid" type="submit" class="btn" ng-click="debug()">Submit</button>
</div>
</div>
</div>
</form>
My Controller:
<script type="text/javascript">
angular.module('contact', []).
controller('myController', function ($scope) {
$scope.debug = function () {
console.log($scope.form);
}
});
</script>
I think you just need to specify the action explicitly, not with an empty string otherwise angular will prevent the submission.
http://docs.angularjs.org/api/ng.directive:form
like so:
http://plnkr.co/edit/WtP03BFVyEsnOqf3n8a4?p=preview

Resources