Show/hide element AngularJS based on Controller boolean variable - angularjs

I am trying to hide/show a portion of a form based on a Controller boolean variable. this is my html code:
<div id="sheetform-container" ng-controller="SheetController as SheetCtrl">
<form action="#">
<div class="sheetform-row" ng-show="canShow('Price')">
<div class="sheetform-left-col fl-left"><label for="sheetform-price">Price</label></div>
<div class="sheetform-midlle-col fl-left"><input type="text" class="sheetform-input" id="sheetform-price" name="price" value="$ 0.00" /></div>
<div class="sheetform-right-col fl-right"></div>
</div>
</form>
</div>
I have created a function that changes the Price attribute to true/false according to the value sent, its called setConfig. This is how the Controller code looks like:
ngApp.controller('SheetController', ['$scope', function($scope) {
$scope.Price = true;
$scope.canShow = function(field) {
return $scope.Price;
}
$scope.setConfig = function(config) {
$scope.Price = config.Price;
}
}]);
Any idea what am I missing?
Thanks!

If you are intending for price to be the actual price of something then you shouldn't be using that for the boolean in this case. Assign the price using ng-model. Also, don't use a capital letter to name a variable. Only classes should be capitalized.
<div id="sheetform-container" ng-controller="SheetController as SheetCtrl">
<form action="#">
<div class="sheetform-row" ng-show="showPrice">
<div class="sheetform-left-col fl-left"><label for="sheetform-price">Price</label></div>
<div class="sheetform-midlle-col fl-left"><input type="text" class="sheetform-input" id="sheetform-price" name="price" ng-model="price" /></div>
<div class="sheetform-right-col fl-right"></div>
</div>
</form>
</div>
Then in your controller you can remove the function you have and also initialize the variables
ngApp.controller('SheetController', ['$scope', function($scope) {
$scope.showPrice = true;
$scope.price = null;
}]);
I'm not sure how you are determining whether the price should be shown or not but you can either have $scope.showPrice assigned to a property in whatever object the form is for or if it's a toggle then you can just say:
<a href ng-click="showPrice = !showPrice"></a>

In the <div class="sheetform-row" ng-show="canShow('Price')">
canShow() function needs a boolean value so that ng-show can change the output accordingly.
'Price' is treated as a string 'Price' not a boolean in your controller.
So change it to ng-show="canShow(Price)",here Price's value will be true/false ,this will help ng-show to hide/show properly.
Also setConfig is not influencing the value of price right now.
Let me know if it helps you or u need further help.

you're missing $digest().
angular only updates DOM in digest loop.
official documentation
$watch how $apply runs $digest

Related

Angularjs: How to get value of input without ng-model

I need to make some inputs by ng-repeat, and in my json file I have in object where is a property called name, like this:
"url":"find_company",
"values":[
{
"name":"company name",
"type":"input_search"
},{
"name":"company_phone",
"type":"input_search"
}
]
I want to make search in DB, in search you can find by any field or by two or more field. Field called the same as property of object. So by ng-keyup I need to send to my function
search(field, value)
two arguments. I want to do something like this
<div ng-repeat="value in param.values">
<input ng-if="value.type == 'input_search'"
ng-keyup="search(value.name, this.text)"
type="text">
How can a send to function text of this input without using ng-model? Where this.text is value of input.
since you are using ng-keyup, you can retrieve input value with $event.target.value.
comment: this is fit for normal event like onclick, but not fit for angular.
refer the below example.
angular.module("app", [])
.controller("myCtrl", function($scope) {
$scope.showValue = function(val) {
alert(val);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="app" ng-controller="myCtrl">
<input type="test" ng-keyup="showValue($event.target.value)">
</div>
This is how you do it with ngModel:
<div ng-repeat="value in param.values">
<input ng-if="value.type == 'input_search'" ng-model="value.val" ng-keyup="search(value)" type="text">
And in your controller:
$scope.search = function( item ) {
console.log( item.val ); // Here you have the value using ngModel
console.log( item.name ); // Here you have the "name" property of the element inside the loop
}
As you can see, you CAN use ngModel and by passing the object itself to the function you can access its properties from the function in the controller.
Note that there's that this.text in the view - I don't know what it is exactly so I dropped it from the example to make things clearer, but you can use it in your code of course.
I know the question said without using ng-model. But I suspect you may want this because you want to customize when data-binding occurs. If that's the case, you can use ng-model-options with ng-change:
<input type="text" ng-model="yourModel" ng-model-options="{ updateOn: 'keyup' }" ng-change="search()" />
ng-change fires when the model has been updated, which is after keyup in this case. So the value of yourModel will be up to date when search() executes.

angular-selectize form's validation

I'm searching to set validation for an input caused by angular-selectize directive (https://github.com/machineboy2045/angular-selectize).
The problem is that this directive:
<selectize config="pic.interGermConfig" options="pic.interGermOptions" data-ng-model="pic.interGermFilter"></selectize>
Produces this output:
<selectize config="pic.interGermConfig" options="pic.interGermOptions" data-ng-model="pic.interGermFilter"></selectize>
<div class=“selectize-control”>
<div class=“selectize-input items not-full”>
<div data-value=“value” class=“item”>Visual value</div>
<input type=“text” autocomplete=“off” placeholder=“” />
</div>
<div class=“selectize-dropdown multi”>
<div class=“selectize-dropdown-content”>
<div data-value=“value” data-selectable class=“option”>Visual value</div>
</div>
</div>
This tag:
<input type=“text” autocomplete=“off” placeholder=“” />
doesn't have ng-model directive property, so I can't use a custom directive with ngModel require, to set input validity.
Is it possible to do this in some way or is it possible sets input validity inside a controller rather that inside a directive?
Thanks
I find a solution for my needs, but I think this isn't the best way to do this.
In a first moment, I've tried to use $watch on model passed to selectize directive, but this it's not allowed because ng-model attribute is obscured and not propagated to the new DOM element when use selectize.
So, looking angular-selectize code, I've seen that directive allows to use ng-required attribute (https://github.com/ptesser/angular-selectize/blob/master/dist/angular-selectize.js).
So I've created a function to checks model and sets errors in the controller and then I've passed this function to ng-require.
<selectize config="pic.interGermConfig" options="pic.interGermOptions"
data-ng-model="pic.interGermFilter"
data-ng-required="pic.checkSelectizeRequire(pic.interGermFilter, 'germs')">
</selectize>
And this is the function
function checkSelectizeRequire(array, filter){
array = array === undefined ? [] : array;
if (array.length === 0){
vm.errorFilter[filter] = true;
}else{
vm.errorFilter[filter] = false;
vm.dirtyFilter[filter] = true;
}
}
To check errors in the form, I've created my own variables, because I don't know how check 'required' option for selectize input like classic way:
form.inputName.$error.required

AngularJS - using ng-model on a checkbox and toggling it on/off through the controller

Please see jsFiddle
In this simple example here I want to set the checkbox value to true or '1' using a controller. I also want to keep a variable called $scope.button within the controller that is tied to the checkbox using ng-model.
However I am unable to set the checkbox value to true or 1 using $scope.button = 1
<div ng-app="App">
<div ng-controller="MyCtrl">
<input ng-model="$scope.button" ng-true-value="1" ng-false-value="0" type="checkbox"/>
</div>
</div>
Angular code
var app = angular.module('App', [])
app.controller('MyCtrl', function($scope) {
$scope.button = 1;
});
Use this:
<div ng-app="App">
<div ng-controller="MyCtrl">
<input ng-model="button" type="checkbox"/>
<span ng-bind="button"></span>
</div>
</div>
I've removed $scope from the ng-model attribute as this doesn't belong there. It's already being bound to the scope.
Working fiddle: http://jsfiddle.net/4bdkkenp/3/

injecting error manually to form

Is there any way to inject error manually to form, I know the way via directive but not sure how can inject error from the controller.
<div ng-controller="myController">
<form name="createForm">
<div ng-repeat="item in someItems">
<input type="text" ng-change="customValidation()" />
</div>
<input type="button" ng-disabled="createForm.$invalid" value="Submit" />
</form>
</div>
controller
function myController($scope) {
$scope.customValidation = function() {
//do some validation and made createForm valid/invalid based on it
};
}
Yes, You can do it in two ways.
instead of Creaeform.$invalid. You can use some value inside your scope.
You should set the value true or false depending on the validation result of the input. If this doesn't make sense to you, give a comment. I'll give some code.
another way is passing the form object itself to the controller and set the createForm.$valid = false; in the controller.

How to pass custom directive name dynamically in class attribute of div tag?

I am very new to AngularJS. I have made a custom directive user and I want to call it dynamically in class attribute by using a variable.
e.g. $scope.dirName = "user";
When i use this variable in below code:
<div class = {{dirName}}></div>
Its result must show two input fields with specified values. But it is not doing so. When I replace {{dirName}} with user. It is working fine, means two input fields are shown with values as specified. Can anybody tell, what mistake I am doing?
This is index.html
<div ng-controller = "Ctrl">
<form name = "myForm">
<div class = {{dirName}}></div>
<hr>
<tt>userName : {{user}}</tt>
</form>
This is script.js
<pre>var app = angular.module('App',[]);
app.controller('Ctrl', function($scope){
$scope.user = {name:'adya',last:'Rajput'};
$scope.dirName = "user";
});
app.directive('user',function(){
return{
restrict:'C',
templateUrl:'template.html'
};
});</pre>
template.html contains:
UserName : <input type='text' name='userName' ng-model='user.name' required>
LastName : <input type='text' name='lastName' ng-model='user.last'>
Unfortunately, you cannot save names of directives in string variables and access them in the HTML. You can, however, save a string in a variable in $scope and use ng-switch to select the correct directive:
<div ng-switch="dirName">
<div ng-switch-when="ng-user">
<div ng-user></div>
</div>
<div ng-switch-when="...">
...
</div>
</div>
However, now it might be better to use something more descriptive than ng-user to switch over.
Sidenote: Do not use ng- prefix in your own directives. Angular uses that prefix so that it does not collide with other namespaces. You should use your own prefix for your directives.
Update: For the updated question as to why <div class="{{dirName}}"></div> does not work, it happens because angular $compiles the directive only once. If you first $interpolate the content of the template (which will replace {{dirName}} with ng-user) and then explicitly $compile it before entering it in the HTML, it should work.

Resources