I'm running into a really weird situation using ng-options inside a directive. Ideally, I'm trying to render a list of the 50 US States, but I'm running into the issue no matter what I fill the array with. Basically It's rendering each select option twice, as if it went through the loop twice, I'm using Angular 1.6.3 and webpack:
Directive:
var ctrl = function($scope){
// $scope.states_list = statesList
$scope.states_list = [
{ abbr : 'A', name : 'Test A' },
{ abbr : 'B', name : 'Test B' },
{ abbr : 'C', name : 'Test C' },
]
$scope.init = function(){
// $scope.states_list = statesList
}
}
var directive = function(){
return {
restrict : 'E',
templateUrl : '/templates/forms/address',
controller : ctrl,
// transclude: true,
// require: 'ngModel',
replace : true,
scope : {
form : '=',
address : '='
}
}
}
module.exports = function(app){
app.directive('addressForm', directive)
}
Template: (In Jade/Pug)
div(ng-init="init()")
.row: .form-group.col-md-12(validate-field="form.name", error-message="Please enter a name")
label.control-label Name
input.form-control(name='name', placeholder='Name', type='text', required, ng-model="address.name")
.row: .form-group.col-md-12(validate-field="form.address1", error-message="Please enter an address")
label.control-label Address
input.form-control(name='address1', placeholder='Address', type='text', required, ng-model="address.address1")
.row: .form-group.col-md-12
label.control-label Address2
input.form-control(name='address2', placeholder='Address2', type='text', ng-model="address.address2")
.row
.form-group.col-md-6(validate-field="form.city", error-message="Please enter a city")
label.control-label City
input.form-control(name='city', placeholder='City', type='text', required, ng-model="address.city")
.form-group.col-md-3(validate-field="form.state", error-message="Please select a state")
label.control-label State / Province
select.form-control(name="state", ng-model="address.state", ng-options="st.abbr as st.name for st in states_list")
option(value="") -- Select a State --
.form-group.col-md-3(validate-field="form.postal_code", error-message="Please enter a valid ZIP Code")
label.control-label Postal/ZIP Code
input.form-control(name='postal_code', placeholder='Postal/ZIP Code', type='text', required, ng-model="address.postal_code")
input(type="hidden", name="country", value="US", ng-model="address.country")
Results:
<div ng-init="init()" address="delivery" form="ctrl.shipping_form" class="ng-isolate-scope">
<div class="row">
<div error-message="Please enter a name" class="form-group col-md-12 ng-scope" ng-class="{ 'has-error': form.name.$dirty && form.name.$invalid }" tooltip-trigger="'none'" uib-tooltip="Please enter a name" tooltip-is-open="form.name.$dirty && form.name.$invalid">
<label class="control-label">Name</label>
<input name="name" placeholder="Name" type="text" required="required" ng-model="address.name" class="form-control ng-pristine ng-untouched ng-empty ng-invalid ng-invalid-required">
</div>
</div>
<div class="row">
<div error-message="Please enter an address" class="form-group col-md-12 ng-scope" ng-class="{ 'has-error': form.address1.$dirty && form.address1.$invalid }" tooltip-trigger="'none'" uib-tooltip="Please enter an address" tooltip-is-open="form.address1.$dirty && form.address1.$invalid">
<label class="control-label">Address</label>
<input name="address1" placeholder="Address" type="text" required="required" ng-model="address.address1" class="form-control ng-pristine ng-untouched ng-empty ng-invalid ng-invalid-required">
</div>
</div>
<div class="row">
<div class="form-group col-md-12">
<label class="control-label">Address2</label>
<input name="address2" placeholder="Address2" type="text" ng-model="address.address2" class="form-control ng-pristine ng-untouched ng-valid ng-empty">
</div>
</div>
<div class="row">
<div error-message="Please enter a city" class="form-group col-md-6 ng-scope" ng-class="{ 'has-error': form.city.$dirty && form.city.$invalid }" tooltip-trigger="'none'" uib-tooltip="Please enter a city" tooltip-is-open="form.city.$dirty && form.city.$invalid">
<label class="control-label">City</label>
<input name="city" placeholder="City" type="text" required="required" ng-model="address.city" class="form-control ng-pristine ng-untouched ng-empty ng-invalid ng-invalid-required">
</div>
<div error-message="Please select a state" class="form-group col-md-3 ng-scope" ng-class="{ 'has-error': form.state.$dirty && form.state.$invalid }" tooltip-trigger="'none'" uib-tooltip="Please select a state" tooltip-is-open="form.state.$dirty && form.state.$invalid">
<label class="control-label">State / Province</label>
<select name="state" ng-model="address.state" ng-options="st.abbr as st.name for st in states_list" class="form-control ng-pristine ng-valid ng-empty ng-touched">
<option value="" class="" selected="selected">-- Select a State --</option>
<option label="Test A" value="string:A">Test A</option>
<option label="Test B" value="string:B">Test B</option>
<option label="Test C" value="string:C">Test C</option>
<option label="Test A" value="string:A">Test A</option>
<option label="Test B" value="string:B">Test B</option>
<option label="Test C" value="string:C">Test C</option>
</select>
</div>
<div error-message="Please enter a valid ZIP Code" class="form-group col-md-3 ng-scope" ng-class="{ 'has-error': form.postal_code.$dirty && form.postal_code.$invalid }" tooltip-trigger="'none'" uib-tooltip="Please enter a valid ZIP Code" tooltip-is-open="form.postal_code.$dirty && form.postal_code.$invalid">
<label class="control-label">Postal/ZIP Code</label>
<input name="postal_code" placeholder="Postal/ZIP Code" type="text" required="required" ng-model="address.postal_code" class="form-control ng-pristine ng-untouched ng-empty ng-invalid ng-invalid-required">
</div>
<input type="hidden" name="country" value="US" ng-model="address.country" autocomplete="off" class="ng-pristine ng-untouched ng-valid ng-empty">
</div>
</div>
Any thoughts? Thanks in advance for the help.
Related
The ui-view elements are not appear when I use as below:
casper.start('https://carepilot-web-staging.herokuapp.com/login');
casper.then( function () {
require('utils').dump(this.getElementInfo('.main-page'));
phantomcss.screenshot( '.loginWrapper', 'Get login page' );
this.echo('get login page...');
} );
the require print out the div null
<div ui-view=\"\" class=\"main-page ng-scope\"></div>
it should be:
<div ui-view="" class="main-page ng-scope" style="">
<div class="loginWrapper ng-scope" ng-controller="loginController as vm">
<div class="login-panel">
<div login-form="" ng-hide="vm.showForgotPassword || vm.showTOU"><form name="vm.loginForm" ng-submit="vm.login()" class="ng-pristine ng-valid-email ng-invalid ng-invalid-required" style="">
<div class="panel-fields">
<div class="logo icon-logo"></div>
<div>
<input type="email" name="username" id="username" class="form-control ng-pristine ng-untouched ng-empty ng-valid-email ng-invalid ng-invalid-required" ng-model="vm.username" placeholder="Email" required="" ng-class="{'error': vm.loginError && username.$pristine}" style="">
<!-- ngIf: vm.loginError -->
</div>
<div>
<input type="password" name="password" id="password" class="form-control ng-pristine ng-untouched ng-empty ng-invalid ng-invalid-required" ng-model="vm.password" placeholder="Password" required="" ng-class="{'error': vm.loginError && password.$pristine}" style="">
<!-- ngIf: vm.loginError -->
</div>
<div ng-show="vm.resetEmail" class="ng-binding ng-hide" style="">Reset Password email has been sent to </div>
</div>
<div class="panel-buttons">
<button id="loginButton" type="submit" class="btn-login ng-binding ng-hide-remove" ng-show="!vm.loginError || vm.loginForm.$dirty" ng-class="{ 'btn-login-green' : vm.loginForm.$valid }">Login</button>
<button id="errorButton" class="btn-login btn-login-red ng-hide" ng-show="vm.loginError && !vm.loginForm.$dirty" disabled="disabled" style="">
<div class="ng-binding">SORRY</div>
<div class="ng-binding">We didn't recognize that email and password</div>
</button>
<button id="forgotPwdButton" type="button" class="btn-login btn-clear ng-binding" ng-click="vm.showForgotPassword=true">I forgot my password</button>
</div>
</form>
</div>
</div>
</div>
I tried a hole day with no success, can anyone give me some suggestion? Thanks!
Edit:
the detail is that:
**Error: undefined is not a constructor (evaluating 'config.url.startsWith('api/CarePilot/')')
request#https://carepilot-web-staging.herokuapp.com/config.js:71:42
More info: [
{
"file": "https://carepilot-web-staging.herokuapp.com/bower_components/angular.js",
"line": 14199,
"function": ""
}
]
Broken interceptor detected: Config object not supplied in rejection:
https://github.com/chieffancypants/angular-loading-bar/pull/50
the config line 71 is if (config.url.startsWith('api/CarePilot/')) {
I change it to if (_.startsWith(config.url,'api/CarePilot/')) {, it is ok.
I am quite new to Angular. I would like to change form dynamically as per the selection from select box.
<form name="register" method="post" id="register" role="form" ng-submit="registerForm()">
<div class="form-group" ng-class="{ 'has-error' : erroractype }">
<select id="actype" name="actype" class=" selector form-control" ng-model="formData.actype" required="required">
<option value="" selected="selected" >I am</option>
<option value="1"> Student</option>
<option value="2"> Teacher</option>
<option value="3"> School</option>
</select>
<span class="help-block" ng-show="errorName" class="ng-cloak">{{ erroractype }}</span>
</div>
<div class="form-group" ng-class="{ 'has-error' : errorFname }">
<input type="text" id="fname" name="fname" placeholder="First Name" title="Please Enter Your First Name" class="form-control input-sm textbox1" required="required" ng-model="formData.Fname">
<div class = "alert alert-danger" ng-show="errorFname" class="ng-cloak">{{errorFname}}</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : errorLname }">
<input type="text" id="lname" name="lname" placeholder="Last Name" title="Please Enter Your Last Name" class="form-control input-sm textbox1" required="required" ng-model="formData.Lname">
<div class = "alert alert-danger" ng-show="errorLname" class="ng-cloak">{{ errorLname }}</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : errorEmail1 }">
<input type="email" id="email1" name="email1" placeholder="Email" class="form-control input-sm textbox1" title="Please Enter Your Valid Email" required="required" ng-model="formData.Email1">
<div class = "alert alert-danger" ng-show="errorEmail1" class="ng-cloak">{{ errorEmail1 }}</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : errorPassword1 }">
<input type="password" name="password1" id="password1" placeholder="Password" title="Please enter AlphaNumeric value" class="form-control input-sm textbox1" required="required" ng-model="formData.Password1">
<div class = "alert alert-danger" ng-show="errorPassword1" class="ng-cloak">{{ errorPassword1 }}</div>
{{ errorPassword1 }}
</div>
<div class="form-group" ng-class="{ 'has-error' : errormobile }">
<input type="text" id="mobile" name="mobile" placeholder="Mobile Number (+1)" title="Please Enter Your Contact Number without Coutry Code." class="form-control input-sm textbox1" required="required" ng-model="formData.mobile">
<div class = "alert alert-danger" ng-show="errormobile" class="ng-cloak">{{ errormobile }}</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-home" name="btn-register" id="btn-register" required="required">Register</button>
</div>
</form>
As you can see three types of registration can be done as per the selection in select box. Student, Teacher and School.
For Student and Teacher form is looking fine. They would have first name & last name. But when people select school that time first name last name looks ugly. It should be only school with single textbox.
So, basically I want whenever school get selected lastname text box get hidden and First Name textbox become Name of School. How can I achieve that?
Okay I came up with something like this. When You'll select the option One you'll see the changes you require. Here is a link to the working example: http://codepen.io/ayushgp/pen/BWMjgG
HTML code:
<body ng-app="example">
<div ng-controller="test">
<select name="number" ng-model="type">
<option value="0" selected>--Select an option--</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<div>
{{type == 1 ? 'Name of school' : 'First Name'}}: <input type="text" />
</div>
<div ng-style="{'display':type==1?'none':'block'}">
Last name: <input type="text" />
</div>
</div>
</body>
In controller CommentController I have scope: $scope.comment = {file : {}};
In template there is code:
<form ng-controller="CommentController" class="form-horizontal" name="formComment" enctype="multipart/form-data" novalidate>
<textarea ng-model="comment.body" ng-minlength="5" ng-maxlength="500" class="form-control todo-taskbody-taskdesc" rows="4" placeholder="Type comment..." required autofocus></textarea>
<input type="text" ng-model="comment.file" ng-value="f | ngfDataUrl" ng-repeat="f in files">
</form>
If to make {{comment}} in tempate I can see binding comment.body when I typing text in textarea.
But I dont see values in:
<input type="text" ng-model="comment.file" ng-value="f | ngfDataUrl" ng-repeat="f in files">
But object files is not empty.
Input file is:
<input type="text" ng-model="comment.file[$index]" ng-value="f | ngfDataUrl" ng-repeat="f in files" class="ng-pristine ng-valid ng-scope ng-empty ng-touched" value="blob:http://bg.com/ec70ef5e-0971-4cb5-b7c0-6032413c4bee">
I am trying to show error message after validation. Backend is php and it is returning the data i can see that in network tab.
Here are the codes.
function formRegister($scope, $http) {
// create a blank object to hold our form information
// $scope will allow this to pass between controller and view
$scope.formData = {};
$scope.registerForm = function() {
$http({
method : 'POST',
url : 'registerexec.php',
data : $.param($scope.formData), // pass in data as strings
headers : { 'Content-Type': 'application/x-www-form-urlencoded' } // set the headers so angular passing info as form data (not request payload)
})
.success(function(data) {
console.log(data);
if (!data.success) {
// if not successful, bind errors to error variables
//{{$scope.errorFname}}
$scope.erroracType = data.errors.actype;
$scope.errorFname = data.errors.Fname;
$scope.errorLname = data.errors.Lname;
$scope.errorEmail1 = data.errors.email1;
$scope.errorPassword1 = data.errors.password1;
$scope.errormobile = data.errors.mobile;
$scope.message1 = data.message1;
}
});
};
}
Here is the form.
<div class="feature-box wow animated flipInX animated">
<div id="validation-errorss" ng-show="message1" ><div class="alert alert-danger"><strong >{{ message1 }}</strong><div></div></div>
</div>
<div class="panel-body" id="success"></div>
<font size="4" color="#fff">Register</font>
<form name="register" method="post" id="register" role="form" ng-submit="registerForm()">
<div class="form-group" ng-class="{ 'has-error' : erroractype }">
<select id="actype" name="actype" class=" selector form-control" ng-model="formData.actype" required="required">
<option value="" selected="selected" >I am</option>
<option value="1">a user</option>
<option value="2">an admin</option>
</select>
<span class="help-block" ng-show="errorName">{{ erroractype }}</span>
</div>
<div class="form-group" ng-class="{ 'has-error' : errorFname }">
<input type="text" id="fname" name="fname" placeholder="First Name" title="Please Enter Your First Name" class="form-control input-sm textbox1" required="required" ng-model="formData.Fname">
<span class="help-block" ng-show="errorFName">{{ errorFname }}</span>
</div>
<div class="form-group" ng-class="{ 'has-error' : errorLname }">
<input type="text" id="lname" name="lname" placeholder="Last Name" title="Please Enter Your Last Name" class="form-control input-sm textbox1" required="required" ng-model="formData.Lname">
<span class="help-block" ng-show="errorLName">{{ errorLname }}</span>
</div>
<div class="form-group" ng-class="{ 'has-error' : errorEmail1 }">
<input type="email" id="email1" name="email1" placeholder="Email" class="form-control input-sm textbox1" title="Please Enter Your Valid Email" required="required" ng-model="formData.Email1">
<span class="help-block" ng-show="errorEmail1">{{ errorEmail1 }}</span>
</div>
<div class="form-group" ng-class="{ 'has-error' : errorPassword1 }">
<input type="password" name="password1" id="password1" placeholder="Password" title="Please enter AlphaNumeric value" class="form-control input-sm textbox1" required="required" ng-model="formData.Password1">
<span class="help-block" ng-show="errorPassword1">{{ errorPassword1 }}</span>
</div>
<div class="form-group" ng-class="{ 'has-error' : errormobile }">
<input type="text" id="mobile" name="mobile" placeholder="Mobile Number (Without +91)" title="Please Enter Your Contact Number without Coutry Code." class="form-control input-sm textbox1" required="required" ng-model="formData.mobile">
<span class="help-block" ng-show="errormobile">{{ errormobile }}</span>
</div>
<div class="form-group">
<button type="submit" class="btn btn-home" name="btn-register" id="btn-register" required="required">Register</button>
</div>
</form>
Problem is when form get validated in backend. The array messages are not showing in .
Here are the validation errors which found in firebug.
errors:Object Fname:"Your First name must be between 3 to 30
characters!" Lname:"Your Last name must be between 3 to 30
characters!" Password1:"Your password must be between 6 to 30
characters!" success:false
Add novalidate attribute to form tag
<form novalidate>
You might use this if you plan to do your own client-side validation, if you want to create your own validation bubbles, or if you plan to go all server-side validation (which you need to do anyway).
I have this form (shown after page loads with Angular filled in data):
<div ng-controller="ItemsController">
<form name="Items" class="form-horizontal ng-dirty ng-valid-parse ng-valid ng-valid-required ng-submitted" ng-submit="submit()" _lpchecked="1">
<input ng-model="item._token" name="_token" type="hidden" value="gej20f0RMOJypfL5n93Mon3QL6PjrrgWgZ20RnGe" class="ng-pristine ng-untouched ng-valid">
<input ng-model="item.no_label" name="no_label" type="hidden" value="1" class="ng-pristine ng-untouched ng-valid">
<fieldset>
<legend>Add New Item</legend>
<div class="form-group">
<label class="col-md-2 control-label" for="sku">SKU</label>
<div class="col-md-3">
<input id="sku" name="sku" ng-model="item.sku" type="text" placeholder="Enter SKU" class="form-control input-md ng-dirty ng-valid-parse ng-valid ng-valid-required ng-touched" required="">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label" for="Name">Name</label>
<div class="col-md-5">
<input id="name" name="name" ng-model="item.name" type="text" placeholder="Optional name" class="form-control input-md ng-valid ng-dirty ng-valid-parse ng-touched">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label" for="add"></label>
<div class="col-md-4">
<button id="add" name="add" class="btn btn-success">
<i class="fa fa-plus"></i> Add
</button>
<button id="cancel" name="cancel" class="btn btn-danger">Cancel</button>
</div>
</div>
</fieldset>
</form>
</div>
And this controller:
myApp.controller('ItemsController', ['$scope', '$http', function ($scope, $http) {
$scope.item = {};
$scope.submit = function () {
if ($scope.validate()) {
$http.post('/items/store', $scope.item)
.success(function (data) {
toastr['success']('Added ' + $scope.item.sku + ' to list.', 'Success!');
$scope.Items.$setPristine();
oTable.ajax.reload();
}).error(function (data) {
if ('error' in data)
toastr['error']('ERROR: ' + data['error'], 'Error!');
else
toastr['error'](JSON.stringify(data), 'Error!');
});
}
};
$scope.validate = function () {
return $.trim($scope.item.sku) != '';
};
}]);
Everytime I submit this form, the data in $scope.item is missing item._token and item.no_label.
Why and how do I correct this?
ng-model is used for two-way data binding. Since you are using hidden input elements, which can not be modified by or shown to users, there is no reason using ng-model. The less two-way binding, the better Perf would be.
So the best way to fix this issue is that add _token and no_label value to $scope.item in controller.
$scope.item = {
_token: 'gej20f0RMOJypfL5n93Mon3QL6PjrrgWgZ20RnGe',
no_label: 1
};
If you must add these elements in View, use one-way binding in View
<input name="_token" type="hidden" value="{{:: item._token}}" class="ng-pristine ng-untouched ng-valid">
<input name="no_label" type="hidden" value="{{:: item.no_label}}" class="ng-pristine ng-untouched ng-valid">
Check this pr to know more about how Angular guys think about data binding on hidden elements.
Instead of using the value attribute try using ng-value:
<input ng-model="item._token" name="_token" type="hidden" ng-value="gej20f0RMOJypfL5n93Mon3QL6PjrrgWgZ20RnGe" class="ng-pristine ng-untouched ng-valid">
<input ng-model="item.no_label" name="no_label" type="hidden" ng-value="1" class="ng-pristine ng-untouched ng-valid">
Another option is updating item like this:
$scope.item = {
_token: 'gej20f0RMOJypfL5n93Mon3QL6PjrrgWgZ20RnGe',
no_label: 1
};