I am exploring advanced features in AngularJS such as custom directives. I want to have a textbox which by using custom directive should allow either numbers only or text only depending upon the value chosen by the user from a dropdown box. I have managed to create a custom directive which allows numbers only based upon AngularJs Custom Directive fails the text box validation . I am not sure how to apply a custom directive dynamically to the same textbox. I have create another custom directive which allows text only, but not sure how to replace the number only directive with the text only directive dynamically.
<body>
<div ng-app="TextboxExample" ng-controller="ExampleController">
<form name="shippingForm" novalidate>
<select id="textBoxOptions" >
<option value="number" selected="selected">Numbers Only</option>
<option value="text">Text Only</option>
<option value="special">Special Characters</option>
<option value="any">Any Value</option>
</select>
<input id="customTextBox" unbindable number-only-input type="text" name="name" ng-model="testvalue.number" required />
<span class="error" ng-show="shippingForm.name.$error.required">
Please enter a value
</span>
</form>
</div>
<script src="scripts/angular.js"></script>
<script src="scripts/jquery.min.js"></script>
<script>
$("select").change(function () {
var selected = $("#textBoxOptions").val();
$('#customTextBox').attr("ng-model", selected);
});
</script>
<script>
angular.module('TextboxExample', [])
.controller('ExampleController', ['$scope', function ($scope) {
$scope.testvalue = { number: 1, validity: true };
}])
.directive('numberOnlyInput', ['$compile', function ($compile) {
return {
link: function (scope, element, attrs) {
var watchMe = attrs["ngModel"];
scope.$watch(watchMe, function (newValue, oldValue) {
if (newValue == undefined || newValue == null || newValue == "") {
return;
} else if (isNaN(newValue)) {
var myVal = watchMe.split(".");
switch (myVal.length) {
case 1:
scope[myVal[0]] = oldValue;
break;
case 2:
scope[myVal[0]][myVal[1]] = oldValue;
}
}
$compile(element)(scope);
});
}
};
}]);
</script>
When I change the value in the dropdown box, it correctly changes the ng-model on customTextBox as checked by inspect element. However, I am not sure how to create and apply multiple directives. Thanks
There are several possibilities. You can switch directive atttibute or whole elements:
<input {{ yourmode ? number-directive : text-directive }} ng-model="data">
or
<input ng-show="yourmode" number-directive ng-model="data">
<input ng-show="!yourmode" text-directive ng-model="data">
or you change the mode with dynamic directive attributes
<input directive-data="yourmode" my-input-directive ng-model="data">
Related
I am using selectboxit plugin for the selection list on my angularJS page an have bind the "ng-change" event on it. But unfortunately, it is not giving me the data on change.
index.html
<select data-ng-model="object.word" ng-change="test(object.word)" id="blog-cat">
<option value="" selected="selected">Select...</option>
<option ng-hide="item.name == ''" ng-repeat="item in businessParentItems track by $index" value="{{item.term_id}}" item-business-directive>{{item.name}}</option>
</select>
{{object.word}}
testCtrl.js
$scope.test = function(test) {
console.log('got it!');
}
directive.js
resource_app.directive('itemBusinessDirective', function () {
return function (scope, element, attrs) {
if (scope.$last === true) {
$('.resources-search-bar .container .select-part select').selectBoxIt();
}
};
});
Please help with this to render the ng-model value on change of selection list.
I am trying to implement a multiselect dropdown in AngularJS and trying to store the values in an list in my JS file. However I am unable to handle the event for selecting multiple values.
I have used ng-change but this handles only one click. Selecting multiple values using CTRL + arrow key is not handled. My list is dynamically generated.
Please suggest ways to handle it using Javascript/AngularJS
<div>
<select multiple class="form-control drop-down" name="abclist" id="users" ng-model="databaseUser" ng-options="databaseUser.username for databaseUser in databaseUsers" ng-change="ctrl.onchange()" required>
<option value="" >SELECT USER VALUE</option>
</select>
</div>
(function () {
'use strict';
angular.module(userdetails.module).controller('UserController', UserController);
UserController.$inject = ['$scope', '$rootScope','$http', 'dData', '$location', '$uibModal'];
function AdminController($scope, $rootScope, $http, dData, $location, $uibModal) {
function onchange(){
}
You don't need to catch the onChange event to do that, the ng-model attribute will do the work for you.
HTML
<div ng-app="myModule">
<div ng-controller="myController as ctrl">
<div>
<p>Selected users: {{ctrl.selectedUsers}}</p>
<select multiple
id="users"
ng-model="ctrl.selectedUsers"
ng-options="user as user.label for user in ctrl.users track by user.id">
</select>
</div>
</div>
</div>
Javascript
var module = angular.module("myModule", []);
module.controller("myController", function() {
var $ctrl = this;
$ctrl.users = [{id:1, label:'eyp'}, {id:2, label:'jrt'}];
$ctrl.selectedUsers = null;
});
Here you have a JSFiddle test to show you how it works.
I select element bound with a list using ng-options. I have a custom directive which adds validation directive to the select element. This custom directive compiles the select element. After compiling the select element, the options are duplicated. Is there a way to stop the duplication or clear them before compiling atleast ?
In the below code, metadata is a custom directive. In that directive, I have the compile($el)($scope) line. After executing this line, select becomes like below
Please select gender
Male
Female
Male
Female
function ($scope, $el, $attr, $ngModel) {
if (!$ngModel) {
return;
}
var elementMetadata = JSON.parse($attr.metadata);
angular.forEach(elementMetadata.validators,
function (item) {
$el.attr(item.name, item.value);
});
$el.removeAttr('metadata');
$compile($el)($scope);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<select name="gender" id="lstGender" ng-options="gender for gender in genderList track by gender" ng-model="fields.gender" metadata="{{template.gender}}">
<option value="">Please select gender</option>
</select>
Move the compiling select element to last function of compiling to execute by using post
pre: function(scope, element) {
scope.values = [ 'male', 'female' ];
},
post: function() {
$compile(tElement)(scope);
}
codepen- https://codepen.io/nagasai/pen/MQQLbB
I am trying to perform a case-insensitive bind of an ng-model to a dynamic select drop-down using AngularJS.
by going through various other relavent answers from stack over flow, i have come up with something like below on the view , here caseinsensitive-options is an directive which i have come up with referencing the following solution
AngularJS case-insensitive binding to a static select drop-down
HTML:
<select id="dcName" caseinsensitive-options="" ng-model="DC.name" class="form-control">
<option value="">--- Please Select ---</option>
<option ng-repeat="dataCenter in inventoryDataCenters" value="{{dataCenter}}">{{dataCenter}}</option>
</select>
js directive code :
app.directive('caseinsensitiveOptions', function() {
return {
restrict: 'A',
require: ['ngModel', 'select'],
link: function(scope, el, attrs, ctrls) {
var ngModel = ctrls[0];
ngModel.$formatters.push(function(value) {
var option = [].filter.call(el.children(), function(option) {
return option.value.toUpperCase() === value.toUpperCase()
})[0];
return option ? option.value : value
});
}
}
});
The expected result is
when i pass something like this for
$scope.inventoryDataCenters = ["TEST1","test2",teST3]; and ng-model for DC.name has value TesT1.
The drop down should show TEST1 by doing case insensitive binding. That doesnt happen now. The above solution works perfect when we have static drop down.
things to be considered is that the select is inside a div which ng-repeat as shown below
ng-repeat="DC in workflowData.project_data.service_info.variables.service_data['data-center']"
and ng-model for select DC.name is derived from the above array DC.
check this URL for binding based on case insensitive value
https://jsfiddle.net/dwd2du17/6/
<div ng-app="module" ng-controller="controller as ctrl">
<select id="animal" ng-model="ctrl.animal">
<option value="">--- Select ---</option>
<option value="CaT">Cat</option>
<option value="DOg">Dog</option>
</select>
{{ctrl.animal}}
</div>
var appForm = angular.module('module', [])
.controller('controller', function($scope) {
});
What is the simplest way to add some commands to the end of the Angular select box?
E.g. I want to get a list like this:
Cat
Dog
Octopus
Browse…
All items except Browse are some data / ng-options, but Browse is a command and always present. It should not be actually selectable as an item, and should call a handler instead.
I suppose I could put this command into the list bound to ng-options and manage it as a special case, but that feels like a hack. Is there a proper approach to this?
Take a look at this, here when you select the browse it will open a dialog box
Working Demo
html
<form ng-app="app" ng-controller="Ctrl" ng-init="item = this">
<select ng-model="animal" ng-change="clickToOpen()" ng-init="animal='select'">
<option value="select">Please select an animal</option>
<option ng-repeat="animal in animalsGroup">{{animal.name}}
</option>
<option value="Browse..">Browse..</option>
</select>
<script type="text/ng-template" id="templateId">
<h1>Template heading</h1>
<p>Content goes here</p>
<center><input type="button" value="OK" ng-click="closeThisDialog(this)"/></center>
</script>
</form>
script
var app = angular.module("app", ['ngDialog']);
app.controller('Ctrl', function ($scope, ngDialog) {
$scope.animalsGroup = [
{name:'Cat'},
{name:'Dog'},
{name:'Octopus'}
];
// select initial value
$scope.animal = $scope.animalsGroup[0];
//
$scope.clickToOpen = function () {
if ($scope.animal === 'Browse..')
{
$scope.animal = "select";
ngDialog.open({
template: 'templateId',
className: 'ngdialog-theme-plain',
showClose: false,
});
}
else
{
// other than 'Browse'
}
};
$scope.closeThisDialog = function (dialog) {
dialog.close();
}
});
If i understood corectly you want to handle the browse option differently .
Script :
$scope.colors = [
{name:'Cat'},
{name:'Dog'},
{name:'Octopus'},
{name:'Browse'}
];
$scope.handleChange = function(){
if ($scope.myColor.name === 'Browse'){
// your implementation
}
}
Html :
<select ng-model="myColor" ng-options="color.name for color in colors" ng-change="handleChange"></select>