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.
Related
When I reload the page, the first option is always empty. I want the option containing text Any Make to be the default select option. Here is the code for my view:
<select class="form-control" id="make" name="make" ng-init="Any Make" ng-model="makeSelected" ng-change="makeChanged()">
<option value="0" selected="selected"> Any Make</option>
<option ng-repeat="obj in makeData" value="{{obj.make_id}}"> {{ obj.make_name | uppercase }} </option>
</select>
here is my controller code:
.controller("homeController", function ($scope, makeData, $http) {
$scope.makeData = makeData;
$scope.makeChanged = function () {
$http({
method: "GET",
url: "homeService.asmx/GetModelById"})
.then(function (response) {
$scope.modelData = response.data;
})
}
})
just remove ng-init and in your model give default value
$scope.makeSelected = 0;
Here is a running fiddle for your code Click here
Fiddle for code with dynamic data Click here
If you aren't going to use ngOptions, at least get rid of that ng-init since it isn't a function, and in the controller function set $scope.makeSelected = 0;
Then you can remove the selected="selected" on that initial option, since the angularJS code will be handling what is selected.
See a demonstration below:
angular.module('app', [])
.value('makeData', [{
"make_id": 1,
"make_name": "cat"
},{
"make_id": 2,
"make_name": "dog"
},{
"make_id": 6,
"make_name": "monkey"
}])
.controller("homeController", function($scope, makeData, $http) {
//initialize the value associated with ng-model on the select list
$scope.makeSelected = 0;
$scope.makeData = makeData;
$scope.makeChanged = function() {
console.log('makeChanged');
//$http() request removed because we don't have access outside this domain for AJAX requests.
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="homeController">
<select class="form-control" id="make" name="make" ng-model="makeSelected" ng-change="makeChanged()">
<option value="0"> Any Make</option>
<option ng-repeat="obj in makeData" value="{{obj.make_id}}"> {{ obj.make_name | uppercase }} </option>
</select>
<div>makeSelected: {{makeSelected}}</div>
</div>
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">
Ive run into a little problem and I can't seem figure out where ive went wrong.
I am trying to change an href value outside of the select field when it changes. Console is logging properly but href is not changing.
**I would like the href value to change and contain text + an angularjs data like so "http://test.com/{{ch.names}}"
here is my select:
<select class="form-control3" name="ch" id="ch">
<optgroup label="Ch">
<option value="x6">x6</option>
<option value="P4">P4</option>
</optgroup>
</select>
this is the href attempting to change:
{{ch.names}}
and here is my jquery:
<script type="text/javascript">
$(document).ready(function() {
$("#ch").change(function() {
if($(this).val() == 'P4') {
$(".a-class").attr("href", "http://test.com/{{ch.names}}");
console.log(".a-class");
}
else {
$(".a-class").attr("href", "http://test2.com/{{ch.names}}");
console.log(".a-class1");
}
});
});
</script>
when the values are changed it will log the class or class1 fitting the if statement but my href does not change where have I went wrong?
It would be a lot cleaner to simply do this with Angular:
<div ng-app="TestApp">
<div ng-controller="TestController">
<select ng-model="selected" ng-options="option for option in options"></select>
<a ng-href="http://test.com/{{selected}}">Selected: {{selected}}</a>
</div>
</div>
Controller
var myApp = angular.module('TestApp',[]);
myApp.controller('TestController', ['$scope', function($scope) {
$scope.options = ['x6', 'P4'];
$scope.selected = 'P4';
}]);
Fiddle: here
EDIT
From your comment, it sounds like you want to switch the whole URL to something else depending on the selection. You could save that data as a property in an array of objects, like this:
myApp.controller('TestController', ['$scope', function($scope) {
$scope.options = [
{
title: 'x6',
urlPrefix: 'http://test1.com/'
}, {
title: 'P4',
urlPrefix: 'http://test2.com/'
}];
$scope.selected = $scope.options[1];
}]);
You'll need to change the HTML a little:
<select ng-model="selected" ng-options="option.title for option in options"></select>
<a ng-href="{{selected.urlPrefix}}{{selected.title}}">Selected: {{selected.title}}</a>
Updated fiddle: here
The angular way to do this is not to use jQuery at all. You create an app and a controller, bind the values and let angular take care of it. Plunkr
Html:
<body ng-app="TestApp">
<div ng-controller="TestCtrl">
<select class="form-control3" name="ch" id="ch" ng-model="href_value" ng-options="value.data group by value.group for value in opt_values"></select>
{{href_value.data}}
</div>
</body>
Javascript:
angular.module('TestApp', [])
.controller('TestCtrl', ['$scope', function($scope) {
$scope.opt_values = [
{data: 'x6', url: "http://test.com/", group: "Ch"},
{data: 'P4', url: "http://test2.com/", group: "Ch"}];
}]);
I am trying to connect some functionality between controllers. Basically I want a div to hide/show based on what radio is selected in a different controller.
With a little help I managed to get this working part of the way. Here's what I have so far.
I set up a factory to bridge communication between the 2 controllers where I have an update function that is fired upon ng-change to update the string with the new desired one.
.factory("sessionCheck", function() {
var sessionCheck = {};
var update = function (index) {
console.log(index);
sessionCheck = index;
return sessionCheck;
};
return { update: update }
So in the first controller will call the function when ng-change occurs on the radios, like so:
//bring in session check, (injected above)
$scope.updateChecker = sessionCheck;
$scope.sessionChange = function(){
$scope.updateChecker.update($scope.opMeasure);
};
So this works fine if I console.log the index in the change function in the factory. So where I'm struggling is pulling this information into another controller and using it to ng-hide (or show) a div.
It would also be cool if there was a default value of "1" returning before the ng-change fired. It would be even better if there is an easier way that directly reads off of the radios' model (opMeasure) instead of firing off the ng-change of the radios.
Been struggling with this for a few hours, any help would be much appreciated. Thanks!!
I have answered a similar question yesterday. You can do this by sharing a common data object reference across your controllers using a common service.
DEMO
JAVASCRIPT
angular.module('demo', [])
.factory('SessionCheck', function() {
var sessionCheck = {
data: {}
};
// default value
sessionCheck.data.selection = 1;
return sessionCheck;
})
.controller('Ctrl1', function($scope, SessionCheck) {
$scope.data = SessionCheck.data;
})
.controller('Ctrl2', function($scope, SessionCheck) {
$scope.data = SessionCheck.data;
});
HTML
<div ng-controller="Ctrl1">
<h1>Controller 1</h1>
Measurement:
<select ng-model="data.selection">
<option value="">-- Select</option>
<option value="1">1 Meter</option>
<option value="2">2 Meters</option>
<option value="3">3 Meters</option>
</select>
</div>
<div ng-controller="Ctrl2">
<h1>Controller 2</h1>
<div ng-show="data.selection == 1">
1 Meter items
</div>
<div ng-show="data.selection == 2">
2 Meter items
</div>
<div ng-show="data.selection == 3">
3 Meter items
</div>
</div>
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>