md-chips with md-select in multi select mode - html

When I am trying to generate md-chips on selecting multiple values from md-select, It is not working. Does md-chips works only with autocomplete analyser and input field?
<md-chips ng-model="launchAPIQueryParams.type">
<md-select name="launchCalType" ng-model="launchAPIQueryParams.type"
multiple="true" placeholder="Launch Type"
md-on-close='applylaunchFilter("type")'>
<md-option ng-repeat="typeOption in launchTypeOptions" ng-value="typeOption[1]">
{{typeOption[0]}}
</md-option>
</md-select>
</md-chips>

The short answer: No.
<md-chips> component will only takes <input> or <md-autocomplete> into its transcluded context.
However, the same thing can be achieved with md-autocompelet.
The key is set md-min-length on <md-autocomplete> to 0 so it will auto show the menu just like what a <md-select> menu would be.
Here's an example:
// controller.js
angular
.moduel('mdChipsDemo', [])
.controller('MdChipsDemoCtrl', function() {
var vm = this;
vm.selectedOption = '';
vm.searchText = '';
vm.launchAPIQueryParams = {
types: [],
};
vm.launchTypeOptions = [
{name: 'Op1', value: 1},
{name: 'Op2', value: 2},
{name: 'Op3', value: 3},
{name: 'Op4', value: 4},
];
});
// template.html
<div ng-app="mdChipsDemo" ng-controller="MdChipsDemoCtrl as vm">
<md-chips ng-model="vm.launchAPIQueryParams.types">
<md-autocomplete
md-selected-item="vm.selectedOption"
md-search-text="vm.searchText"
md-items="typeOption in vm.launchTypeOptions"
md-item-text="typeOption.name"
md-min-length="0"
placeholder="Search for a launchTypeOptions">
<span md-highlight-text="vm.searchText">{{typeOption.name}}</span>
</md-autocomplete>
<md-chip-template>
<span>{{$chip.name}}</span>
</md-chip-template>
</md-chips>
</div>
If your ultimate goal is to have multiple select ability, <md-autocomplete> also expose <md-item-template> where you can put your <md-select> in. Check the doc for md-autocomplete and you will see.
Or if you really insist on using <select>, there's an 3rd-party component on npm calls md-chips-select which does what you want.
https://www.npmjs.com/package/md-chips-select

Related

Apply the styles to selected values in the multi-select dropdown in Angular

I am new to angular. As part of my baby steps , I have a ng-select(multiple)component.
this is my component.html
<label>Multiselect with custom bindings</label>
<ng-select [multiple]=true>
<ng-option *ngFor= "let city of cities" [value]="city.id"> {{city.name}}</ng-option>
</ng-select>
component.ts
cities = [
{ id: 1, name: 'Vilnius' },
{ id: 2, name: 'Kaunas' },
{ id: 3, name: 'Pavilnys' },
{ id: 4, name: 'PabradÄ—' },
{ id: 5, name: 'KlaipÄ—da' },
];
I have custom component called tags which styles the selected values.
<tags [(ng-model)]="values" </tags>
My query is I need to pass these selected values to this component and display the styled selected values in the same place . Please help!. Thanks in advance.
Passing the selected values to the component:
component.ts:
selectedValues = [];
component.html:
add the following to your ng-select:
[(ngModel)]="selectedValues"
It will automatically update this array.
Then you can display the array data again where you need them.
Not sure if this answers your question. What do you mean by 'display the styled selected values in the same place'?

Knockout Select2 set initial value by object

I have a Knockout.js web application where I have a select2 dropdown. I want to bind both the id and text values to a variable instead of just the id. Here's my data:
var cars = [{id: 1, name: 'Honda'}, {id: 2, name: 'Toyota'}, {id: 3, name: 'Dodge'}];
var selectedCar = ko.observable();
Here's my html:
<select data-bind="value: selectedCar, optionsCaption: 'Select', optionsText: 'name', options: cars"></select>
So now, whenever I select something in the dropdown my variable contains the entire object like so:
selectedCar = {id: 1, name: 'Honda'};
The only problem occurs when you load the page and want the dropdown to be set to a specific value. Even though before rendering the html the selectedCar variable is set to {id: 1, name: 'Honda'} when the page renders the dropdown is not set to anything, it just is set to the placeholder 'Select'.
What am I doing wrong?
If you want to bind both the id and text value to a variable, you need to use the optionsValue binding and bind the entire context to it ($data);
<select data-bind="value: selectedCar,
optionsCaption: 'Select',
optionsText: 'name',
options: cars,
optionsValue: $data"></select>
Normally we would specify the id or whatever to get an initial value selected. So it would make sense like in your question to supply the entire object {id: 1, name: 'Honda'} as the initial value to selectedCar if wet set optionsValue: $data and not $optionsValue: 'id'.
(IMPORTANT) But turns out this doesn't work, because we're creating a new object and so Knockout's equality test will fail when it compares the objects of cars with the object inside selectedCar. The correct way to set the initial value is cars[0].
I'm sure this is a typo, but I'll specify anyway: when you create any variable that needs to be accessed by the HTML you need to bind it to this, which would be a reference to the viewModel.
this.cars = [{id: 1, name: 'Honda'}, {id: 2, name: 'Toyota'}, {id: 3, name: 'Dodge'}];
this.selectedCar = ko.observable();
Let's test all this with a fiddle:
var viewModel = function(){
var self = this;
self.cars = [{id: 1, name: 'Honda'}, {id: 2, name: 'Toyota'}, {id: 3, name: 'Dodge'}];
self.selectedCar = ko.observable(self.cars[0]);
};
ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select data-bind="value: selectedCar, optionsCaption: 'Select', optionsText: 'name', optionsValue:$data, options: cars"></select>
<!-- to verify that we are getting the entire object -->
<p data-bind="text: ko.toJSON(selectedCar)"></p>
The value of a select box will become the object that corresponds to the selected item or the property set in the optionsValue parameter. So in the case of objects, the selected value you set must be the same instance that exists in the array. Having a different instance of an object happens to be structurally equivalent is not enough.
For situations like this, I find it easier to bind the value of the select box to a unique id for the object instead. Then you could map out that id to the actual instance that you want through a computed value.
function ViewModel(data) {
this.cars = data.cars;
this.selectedCarId = ko.observable(data.selectedCarId);
this.selectedCar = ko.computed(() => {
let selectedCarId = this.selectedCarId();
return this.cars.find(c => c.id === selectedCarId);
});
}
let model = {
cars: [
{ id: 1, name: 'Honda' },
{ id: 2, name: 'Toyota' },
{ id: 3, name: 'Dodge' }
],
selectedCarId: 2
};
ko.applyBindings(new ViewModel(model), document.getElementById('content'));
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/js/select2.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/css/select2.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div id="content">
<select data-bind="value: selectedCarId,
optionsCaption: 'Select',
optionsText: 'name',
optionsValue: 'id',
options: cars">
</select>
<p>selectedCarId: <span data-bind="text: selectedCarId"></span></p>
<p>selectedCar: <span data-bind="text: ko.toJSON(selectedCar)"></span></p>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
</div>
If you'd rather not use a separate computed property, you would still need to pass in an index, but the value you set, must be obtained from the array.
function ViewModel(data) {
this.cars = data.cars;
this.selectedCar = ko.observable(
data.cars.find(c => c.id === data.selectedCarId)
);
}

How to get alert when Ichange dropdown options using angularjs

This is my dropddown menu, when I change the option will get alert its working, but when i select again on the same option i didnt get alert.How it posiible
index.html
<body ng-app="demoApp">
<div ng-controller="DemoController">
<div>
<select ng-model="currentlySelected" ng-options="opt as opt.label for opt in options" ng-change="logResult()">
</select>
The value selected is {{ currentlySelected.value }}.
</div>
</div>
</body>
app.js
angular.module('demoApp', []).controller('DemoController', function($scope) {
$scope.options = [
{ label: 'one', value: 1 },
{ label: 'two', value: 2 }
{ label: 'three', value: 3 }
{ label: 'four', value: 4 }
{ label: 'five', value: 5 }
];
$scope.currentlySelected = $scope.options[1];
$scope.logResult = function() {
alert($scope.currentlySelected);
}
});
What I expect is if I select "two" twice i need to alert twice. Is this possible or should I be using a different directive for this?
No, it's not possible. onchange event is fired when selection changes, not when you make a selection. So unless you choose different option, it's not going to fire.
If you need this behaviour I would suggest using one of the custom select solutions, even custom CSS based select would work. Then you could bind to onclick event instead of onchange.

Update md-select programmatically

I have the following HTML
<md-select id="testSelect"
ng-model="objElements" ng-change="onElementChange()"
name="objElements" placeholder="Select Stuff">
<md-option id="testOption"
ng-repeat="ele in Elements"
ng-if="ele.Completed==false"
ng-value=ele.ID
ng-selected="$first">
{{ele.Name}}
</md-option>
Elements is populated using a $http.get request and is displaying correctly - I am able to select an element and ng-change fires correctly.
If I add a new element using a $http.post, then pushing the new object onto Elements[] using Elements.push($scope.NewElement), is there a way I can set the new object as the 'selected' element?
I can see the new element has been added correctly to the Elements[] but cannot figure out how to set ng-selected=NewElement.
Yes, simply set objElements to your new element from the response. Should do the trick.
There's a good example here: https://material.angularjs.org/latest/api/directive/mdSelect (code below).
<div ng-controller="MyCtrl">
<md-select ng-model="selectedUser">
<md-option ng-value="user" ng-repeat="user in users">{{ user.name }}</md-option>
</md-select>
</div>
angular.controller('MyCtrl', function($scope) {
$scope.users = [
{ id: 1, name: 'Bob' },
{ id: 2, name: 'Alice' },
{ id: 3, name: 'Steve' }
];
$scope.selectedUser = { id: 1, name: 'Bob' };
});

Autofill html select AngularJS

I have a little issue with a HTML select with AngularJS. When I do a petition to my API I get one of the values as an integer, but when I try to autofill a select with it I can't set de "value" correctly.
In this picture you can se what the HTML is receiving and the values that I want to set
Are there any way to cast this value?
Thanks in advance :)
EDITED:
The controller to get customer data and fill the form
.controller('CustomerDetailCtrl', ['Customer', '$scope', '$sessionStorage', '$stateParams', '$ionicPopup', function (Customer, $scope, $sessionStorage, $stateParams, $ionicPopup) {
if ($sessionStorage.auth) {
Customer.get({data: $stateParams.customerId + '_' + $sessionStorage.user_id}).$promise.then(function (data) {
if (data.response && $sessionStorage.role === 1) {
$scope.customer = data.response[0];
if (data.history) {
$scope.histories = data.history;
}
} else {
console.log('Error de accesso...');
}
})
}
$scope.addTask = function (customer) {
alert('add task!');
}
$scope.deleteTask = function (customer, history) {
alert('delete task!');
}
}])
The form:
<label class="item item-input item-select">
<div class="input-label">
Cliente avisado?
</div>
<select name="informed" ng-model="customer.informed" required>
<option value="0">NO</option>
<option value="1">SI</option>
</select>
</label>
And here a picture of the data from de API:
I know that you've already received an answer on this, but I wanted to show you one other potential option that doesn't involve having to change your data from an int to string. If you define the options for your select in your controller (or in a service if this will be used in multiple different places throughout your app) then you can take advantage of ng-options and its ability to use a value other than a string.
Here's an example (obviously I've hardcoded some things and put this all in a single module - not something you'd do in a real app).
JS:
angular.module('app', [])
.controller('ctrl', function($scope){
// select options (if these are common maybe store them in a service
// so you can share them in many controllers without duplicating the code)
$scope.selectOptions = [
{
text: 'NO',
value: 0
},
{
text: 'SI',
value: 1
}];
// sample data
$scope.customer = {
address: 'San Rosendo 11',
date: '2016-03-16T16:19:13+0100',
email: 'Montes',
equipment: 'PC',
id: 262,
informed: 1,
lastName: 'Montes',
location: 'Tienda',
name: 'Juanma',
notes: '',
pass: 'no tiene',
phone: '900112233',
price: '0',
status: 'Pendiente',
tasks: 'dfsdf'
};
});
HTML:
<div ng-app='app' ng-controller='ctrl'>
<select ng-model='customer.informed' ng-options='option.value as option.text for option in selectOptions'></select>
</div>
jsFiddle
Define a default value somewhere in your controller: $scope.customer.informed = "NO";