angular-selectize form's validation - angularjs

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

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.

AngularJS - unchanged data passed by ng-model is interpreted as undefined instead of the value

I'm using Angular to generate some inputs and populate them with data using ng-repeat. I also want to bind the data inside the input to a save changes button which takes parameters provided by ng-model directives. save changes button prints the passed arguments using the built-in JS arguments object. For some reason, unless I change the text inside the input box, the output is [undefined, undefined]. Once I change the text inside the input boxes, the correct output is printed. Why is that?
JSfiddle code.
HTML:
<div ng-app="myApp" ng-controller="MainCtrl">
<p ng-repeat = "man in men">
<label>name</label><input type="text" ng-model="mname" ng-value="man.name"><br>
<label>status</label><input type="text" ng-model="mstatus" ng-value="man.status"><br>
<button ng-click="save(mname,mstatus)">
save changes
</button>
</p>
</div>
JS:
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope) {
$scope.men = [{
name: "jon snow",
status: "depands"
}, {
name: "rob stark",
status: "dead"
}];
$scope.save = function() {
console.log(arguments);
}
});
This is not recommended but for your specific requirement you can use ng-init to bind ng-value to your model
<p ng-repeat = "man in men">
<label>name</label><input type="text" ng-model="mname" ng-value="man.name" ng-init="mname = man.name"><br>
<label>status</label><input type="text" ng-model="mstatus" ng-value="man.status" ng-init="mstatus = man.status"><br>
<button ng-click="save(mname,mstatus)">
save changes
</button>
</p>
This wouldn't bind your changes to the original model.
Fiddle
ngModel doesn't update untill you use a key to change it, or set it from your controller. Because you are setting the field of the input using ngValue, it doesn't register to your ngModel untill you change it.
This problem is similar to how most datepickers don't work with ngModel, as they set the field with DOM-manipulation and NOT by inserting the value by "key".
You can easily fix this by using the following HTML instead:
<label>name</label><input type="text" ng-model="man.name"><br>
<label>status</label><input type="text" ng-model="man.status"><br>
I simply removed the ngValue and linked the ngModel to your "man".

How to get the input value of an input on which a function is being called in angularjs? (Directive, ng-repeat)

how do I get a value of an input that is in ng-repeat? I want to be able to ng-repeat the value (as a default) but I also want to be able to change the value.
It's hard to explain what I mean but I can give you can example:
In my Directive (the relevant part):
ctrl.numbers = [1,2,3,4,5]
ctrl.myFun = function () {
console.log(ctrl.val)
};
My HTML:
<div ng-repeat="num in numbers">
<input type="text" value="{{num}}" ng-click="ctrl.myFun()">
</div>
So on click I want to get the "this" value of the input on which the function is being called. I thought this will be supereasy but every way I try to do it I get undefined. I tried to do it with scope { value : "#" } inside my directive and failed, I tried ng-model and ng-bind and failed as well.
I want to be able to attach the function to multiple fields so I don't want to hardcode any variables.
Many thanks!
Firstly, use ng-model because it's Angular and just pass the value to the function like so.
<div ng-repeat="num in numbers">
<input type="text" ng-model="num" ng-click="ctrl.myFun(num)">
</div>
ctrl.numbers = [1,2,3,4,5]
ctrl.myFun = function (val) {
console.log(val)
};
JSFiddle

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.

Show/hide element AngularJS based on Controller boolean variable

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

Resources