ngDisabled and ngClick can't work together - angularjs

I've this form:
<div class="form-group">
<label for="GrpName"> Mail:</label>
<input ng-model="customerToUpdate.mail" type="text" class="form-control" id="name">
<button type="button" class="btn btn-default" ng-click="loadCustomer()">
Load
</button>
</div>
<div class="form-group">
<label for="GrpName"> Username:</label>
<input ng-disabled="{{isDisabled}}" ng-model="customerToUpdate.username" type="text" class="form-control" id="name">
</div>
Controller :
$scope.isDisabled = true;
$scope.loadCustomer = function() {
Customer.getByEmail($scope.customerToUpdate.mail)
.success(function(customer, status, headers, config) {
if(!isEmptyObject(customer)){
$scope.isDisabled = false;
}else
$scope.isDisabled = true;
});
};
Using chrome, i can inspect and see that ng-disabled changed to true and false but no UI updates. I also tried readonly instead but same result..
I'm missing something?

ng-disabled is bound with '=' not with '#', so you should not use the braces:
Turn your
<input ng-disabled="{{isDisabled}}" ng-model="customerToUpdate.username" type="text" class="form-control" id="name">
into
<input ng-disabled="isDisabled" ng-model="customerToUpdate.username" type="text" class="form-control" id="name">
and it should work!

after you make http request and in the callback after change $scope you must use
$scope.$apply();
to force reflection in view

Related

Get form input value from angularjs

I'm using Angularjs to submit the form then pass the value to my laravel function.
This is my HTML code
<form class="form-horizontal" method="post" name='form' novalidate ng-submit="submit()" ng-controller="syncApiCtrl">
<div class="col-lg-10">
<div class="input-group">
<input type="text" class="form-control" id="name" name="name" placeholder="Your_name">
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<input type="submit" name="sale" value="Sync Sale" class="btn btn-primary"></input>
<input type="submit" novalidate ng-click="sync_product(record)" name="product" value="Sync Product" class="btn btn-primary"></input>
</div>
</div>
</form>
This is my JS
$scope.submit = function () {
//$scope.form.$submitted = true;
// proceed if form valid
if ($scope.form.$valid) {
// is loading
$scope.loading = true;
// prepare data packet
var data = {};
angular.forEach($scope.form, function (v, k) {
if (k.indexOf('$') < 0 && typeof v.$dirty !== 'undefined' && v.$dirty) {
data[k] = v.$modelValue;
}
});
}
};
This is my laravel function
public function sync_sale() {
$name= preg_replace('/[^A-Za-z0-9\_]/', '', Input::get('name'));
Debugbar::info($name);
}
My laravel function always can't get the value after user submit a form.
You should have bound your input to a ng-model. This one is working. You should use data binding methods in angularJs.
<input type="text" class="form-control" id="name" name="name" placeholder="Your_name" ng-model="name">

How pass dynamic values to ProgressBar and below message based number forms completed?

I am displaying progress bar, progress bar status message bellow by passing static values, how can pass dynamic values to progress bar and bellow progress bar i need show progress bar status message dynamically. bellow I written code for static. please help me for passing dynamic values to progress bar, and progress bar status message.
html
----
<div ng-app="app" ng-controller="main">
<div>
<form ng-hide="form_1" name="form1" novalidate>
<span>
<input name="group1" type="radio" value="Yes" ng-model ="user.ans1" ng-required="true" />Yes
<input name="group1" type="radio" value="NO" ng-model ="user.ans1" ng-required="true" />No
</span><br/>
<span>
<input name="group2" type="radio" value="Yes" ng-model ="user.ans2" ng-required="true" />Yes
<input name="group2" type="radio" value="NO" ng-model ="user.ans2" ng-required="true" />No
</span><br/>
<span>
<button type="button" ng-disabled="form1.$invalid" ng-click="start();">start</button>
</span>
</form>
<form ng-show="form_2" name="form2" novalidate>
<div>
<p progressbar prog="form2.$valid ? '33':'0'" ></p>
<p>{{form2.$valid ? 'Set 1 of 3 completed':''}}</p>
</div>
<span>
<input name="group3" type="radio" value="Male" ng-model ="gender" ng-required="true" /> Male
<input name="group3" type="radio" value="Female" ng-model ="gender" ng-required="true" /> Female
</span><br/>
<button type="button" ng-disabled="form2.$invalid" ng-click="form2Next();" >Next</button>
</form>
<form ng-show="form_3" name="form3" novalidate>
<div>
<p progressbar prog="form3.$valid ? '66':'33'" ></p>
<p>{{form3.$valid ? 'Set 1 of 3 completed':''}}</p>
</div>
<span>
<input name="group4" type="radio" value="btech" ng-model ="course" ng-required="true" /> Btech
<input name="group4" type="radio" value="mtech" ng-model ="course" ng-required="true" /> Mtech
</span><br/>
<button type="button" ng-disabled="form3.$invalid" ng-click="form3Next();" >Next</button>
</form>
<form ng-show="form_4" name="form4" novalidate>
<div>
<p progressbar prog="form4.$valid ? '100':'66'" ></p>
<p>{{form4.$valid ? 'Set 1 of 3 completed':''}}</p>
</div>
<span>
<input name="group5" type="radio" value="software" ng-model ="emp" ng-required="true" /> software
<input name="group5" type="radio" value="hardware" ng-model ="emp" ng-required="true" /> hordeware
</span><br/>
<button type="button" ng-disabled="form4.$invalid" ng-click="form4Next();" >Next</button>
</form>
</div>
</div>
script
------
angular.module("app", [])
.controller("main", ['$scope', function($scope) {
$scope.start = function(){
if((($scope.user.ans1 == "Yes")&&($scope.user.ans2 == "Yes"))||(($scope.user.ans1 == "No")&&($scope.user.ans2 == "Yes"))){
$scope.form1Next();
}
else{
$scope.form2Next();
}
}// startasignment function End
$scope.form1Next = function(){debugger;
$scope.form_1 = true;
$scope.form_2 = true;
}
$scope.form2Next = function(){debugger;
$scope.form_1 = true;
$scope.form_2 = false;
$scope.form_3 = true;
}
$scope.form3Next = function(){debugger;
$scope.form_2 = false;
$scope.form_3 = false;
$scope.form_4 = true;
}
$scope.form4Next = function(){debugger;
alert("successfully submited")
$scope.form_4 = false;
}
}])
.directive('progressbar', [function() {
return {
restrict: 'A',
scope: {
'progress': '=prog'
},
template: '<div class="stripe" style="background-color: #C7D2D2; height:30px; width:100%;"> <div ng-style="style" style="background-color:#FFFF00; height:100%"></div> </div>',
controller: function($scope, $element, $attrs) {
$scope.$watch(function() {
$scope.style = {"width": $scope.progress + "%"}
})
}
}
}]);
if you'r using an angularjs progress bar directive
then you can assign a variable to the prog attribute and manipulate it as you want like
<p progressbar prog="Progress" ></p>
call it like :
<input type="button" value="add 10" ng-click="AddProgress(10)">
and in controller
$scope.Progress ='0';
$scope.AddProgress = function (percentige) {
$scope.Progress = parseInt($scope.Progress)+percentige;
}
now you can put the progressbar in a shared div (without hiding and showing) and maybe animate it ..
first thing i found when searched angularJs progress bar was this cool looking thing
here is a jsFiddle

hide submit button again after clicking (ng-show - form validation)

I have the following code, which shows the a.btn anchor if both inputs have values and inputURL is a valid URL. Works fine but I want to hide the button again on click, how do I do this, do I reset the form or actually hide the button on click?
<form name="myForm" class="row inputs">
<div class="col-xs-5">
<label for="exampleInputPassword1">Enter a Title/Description</label>
<input name="inputName" type="text" id="urlName" class="form-control" placeholder="" ng-model="mvName" required>
</div>
<div class="col-xs-5">
<label for="exampleInputPassword1">Enter a URL</label>
<input type="url" name="inputURL" id="urlLink" class="form-control" placeholder="" ng-model="mvUrl" required>
</div>
<div class="col-xs-2">
Post
</div>
</form>
What I've done before is create a scope variable in your controller:
$scope.formSubmitted = false;
Then in your saveToList function set $scope.formSubmitted to true. From here you have a few options. If you're "Post" button is an actual button then you could set the disabled attribute. You could also check if formSubmitted is true inside your saveToList function and if it is true you don't continue. Or you can change your ng-show to be:
ng-show="myForm.$valid && !formSubmitted"
you can do something like this:
define another $scope.someToggle variable, and assign it true, then at the ng-show of the button add it like ng-show="myForm.$valid && someToggle". then at the end (or in callback) of saveToList($event) function, set $scope.someToggle to false.
also you can put this on both inputs: ng-change = "someToggle = true" so whenever they change(after the save button has been clicked) you'd be able to bring it back...
HTML
<body ng-app="myApp">
<div ng-controller="formCtrl">
<form name="myForm" class row inputs">
<div class="col-xs-5">
<label for="exampleInputPassword1">Enter a Title/Description</label>
<input name="inputName" type="text" id="urlName" class="form-control" placeholder="" ng-model="mvName" required>
</div>
<div class="col-xs-5">
<label for="exampleInputPassword1">Enter a URL</label>
<input type="url" name="inputURL" id="urlLink" class="form-control" placeholder="" ng-model="mvUrl" required>
</div>
<div class="col-xs-2">
Post
</div>
</form>
</div>
</body>
controller
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope) {
$scope.saveToList = function() {
$scope.mvName = '';
$scope.mvUrl = '';
}
});
Alternative
with scope variable without invalidating form
Post
app.controller('formCtrl', function($scope) {
$scope.logicalExp = "||";
$scope.formSubmitted = true;
$scope.saveToList = function() {
$scope.logicalExp = "&&";
$scope.formSubmitted = true;
}
});
the problem with this is, user needs to invalidate the form by himself by removing entered value then hyperlink will be hidden-ed.

Form input is undefined

Why the name and password are undefined?
I've used ng-model on them...
<form class="login" name="form">
<div class="form-group" ng-class="{'has-error': isInvalidLogin}">
<label for="name">Name: </label>
<input type="text" ng-model="name" id="name" class="form-control" placeholder="Nitzan">
</div>
<div class="form-group" ng-class="{'has-error': isInvalidLogin}">
<label for="password">Password: </label>
<input type="password" ng-model="password" id="password" class="form-control" placeholder="1234">
<p class="help-block" ng-if="isInvalidLogin">Name or password are wrong!</p>
</div>
<button type="submit" class="btn btn-block btn-lg btn-success login-btn" ng-click="login()">Login</button>
</form>
In the controller:
$scope.login = function () {
usersService.get($scope.name, $scope.password).then(function success(result){
$scope.currentUser = result;
}, function error() {
$scope.isInvalidLogin = true;
});
};
See the plunker:
http://plnkr.co/edit/QD3vtil3w9pd4d1TGl9v?p=preview
Your problem is because of ng-if directive which is creating child scope from current scope. Hence $scope.name & $scope.password is undefined inside $scope.login function.
I'd suggest you do create one object for user which is initially blank like user={} or you can do this on html using ng-init, then put it inside of mainController so that it can directly access by the parent without doing $parent. notation.
And place name and password inside user object.
HTML
<div ng-init="user={}">
<div class="container login-div" ng-if="!currentUser">
<form class="login" name="form" ng-submit="login()">
<div class="form-group" ng-class="{'has-error': isInvalidLogin}">
<label for="name">Name:</label>
<input type="text" ng-model="user.name" id="name" class="form-control" placeholder="Nitzan">
</div>
<div class="form-group" ng-class="{'has-error': isInvalidLogin}">
<label for="password">Password:</label>
<input type="password" name="test" ng-model="user.password" id="password" class="form-control" placeholder="1234">
<p class="help-block" ng-if="isInvalidLogin">Name or password are wrong!</p>
</div>
<button type="submit" class="btn btn-block btn-lg btn-success login-btn">Login</button>
</form>
</div>
</div>
CODE
$scope.login = function () {
alert("Name "+ $scope.user.name +"& password is " +$scope.user.password)
//usersService.get($scope.name, $scope.password).then(function success(result){
// $scope.currentUser = result;
//}, function error() {
// $scope.isInvalidLogin = true;
//});
};
Working Plunkr here.
Update
Otherwise you need to add change your ng-model to refer this scope to parent scope like
HTML
For name ng-model="$parent.name"
For password ng-model="$parent.password"
CODE
$scope.login = function () {
alert("Name "+ $scope.name +"& password is " +$scope.password)
//usersService.get($scope.name, $scope.password).then(function success(result){
// $scope.currentUser = result;
//}, function error() {
// $scope.isInvalidLogin = true;
//});
};
Plunkr Here
Hope this could help you. Thanks.

Elements in $scope missing from form

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
};

Resources