<ui-select id="facility" multiple ng-model="IdRequest.formData.facilityRequestedArray" validation="required" ng-disabled="IdRequest.formData.applicantReadOnly" class="drop-down">
<ui-select-match allow-clear="true" placeholder="{{'select'|translate}}">
{{$item.displayText}}
</ui-select-match>
<ui-select-choices repeat="facility.id as facility in IdRequest.facilityList">
{{facility.displayText}}
</ui-select-choices>
</ui-select>
Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: $item in $select.selected, Duplicate key: number:1, Duplicate value: 1
I'm having the same issue with ui-select (version 2.1.3). The selected items are loaded via ajax, the correct selection will show up but when clicked to select another option, the already selected options are within the possible options and when selected again a dupe error is firing.
I decided not to dig in the sources, instead to force refresh the directive from the script.
This is the fix:
HTML
<ui-select multiple="true" ng-model="x.itemsSelected" theme="bootstrap">
<ui-select-match placeholder="Select Eligibility Item...">{{$item.name + ' #' + $item.id}}</ui-select-match>
<ui-select-choices repeat="item.id as item in x.itemsAvailable | filter: $select.search track by $index" refresh="uiSelectRefreshFix($select)" refresh-delay="1000">
<div ng-bind-html="item.name + ' #' + item.id | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
Controller
// ui-select bugfix.
$scope.uiSelectRefreshFix = function () {
if ($scope.uiSelectFix) return;
$scope.uiSelectFix = true;
var fix = $scope.x.itemsSelected;
$scope.x.itemsSelected = [];
setTimeout(function() {
$scope.$apply(function(){
$scope.x.itemsSelected = fix;
});
}, 100)
console.log([model, query]);
}
Set your multiple equal to true like so:
<ui-select id="facility" multiple='true' ng-model="IdRequest.formData.facilityRequestedArray" validation="required" ng-disabled="IdRequest.formData.applicantReadOnly" class="drop-down">
See this github link: https://github.com/angular-ui/ui-select/issues/366
If you have duplicate facilities also add track by $index to your repeater like this:
<ui-select-choices repeat="facility.id as facility in IdRequest.facilityList track by $index">
Related
I have this ui select:
<ui-select multiple
ng-model="meas.daysSelected"
theme="bootstrap"
close-on-select="false">
<ui-select-match placeholder="days">{{$item}}</ui-select-match>
<ui-select-choices repeat="day in days | filter:$select.search">
<div ng-bind-html="day | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
$scop.days = ['Sun', 'Mon', 'Tue' ... ]
it is in a simple table with angular ng-repeat
<tr ng-repeat="meas in foo= (res.foos | filter: subSearch : strict)">
and I filter it with:
<input type="text" class="form-control" ng-model="subSearch.daysSelected">
The problem is like this: the "daySelected" model is becoming an array when I select an object and then de-select it. the filter of angular just dismisses it and filters it.
So I need help in one of the 2:
make daySelected as a string (when selected it will be: "sun, mon"
or
adjust the filter to work in array
Assuming the search text is going to be like "Mon,Tue" which will filter all the ui-selects which have ["Mon","Tue"] you can write your own filter function and pass that. For example:
<tr ng-repeat="meas in foo= (res.foos | filter: $ctrl.filterDaysSelected">
And in your controller you'd need to create that function:
$ctrl.filterDaysSelected = function(value, index, array) {}
Where you would need to:
Split the value of your search criteria by ","
Validate that each item in your split array exists in the function value parameter
Well, I have a hidden field in my form and trying to validate the ui-select element. I'm using the Angular-Validation plugin, which depends on the jQuery Validate plugin. On submit it shows the error label, but when the hidden fields gets it value from the ng-model, the error is still shown and also i am not able to submit the form.
Here's the html
<ui-select ng-model="noPostData.locaopt.id" theme="selectize">
<ui-select-match placeholder="Select Location">
{{$select.selected.name}}
</ui-select-match>
<ui-select-choices repeat="obj.id as obj in locaoptions | filter: {name: $select.search}">
<div ng-bind-html="obj.name | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
<input type="hidden" name="subloc_loca" ng-model="noPostData.locaopt.id">
Here's the options
$scope.validationOptions={
ignore: [],
rules: {
subloc_loca: {
required: true
},
message: {
subloc_loca: {
required: "Select location"
},
}
}
If the hiddden field is getting its value, why the error label is not going away. Why is this happening and how can i achieve this. Please help me
Typically, in these situations where a graphical element replaces the default, you have to get creative. In this case there is a input type="hidden" that is presumably replacing the select. Since jQuery Validate does not get automatically triggered when the value of the hidden element changes, you have to programmatically trigger this yourself.
Write a handler that forces validation of the hidden element that contains your value.
$('#Your-Graphical-Select-Element').on('focusout', function() {
$('[name="subloc_loca"]').valid(); // force validation test
});
Can I filter my search in ui-select on specific fields of my object? Or should I create a custom filter? I have seen this answer and it says it works, but my following code is not working:
<ui-select ng-model="model.selected">
<ui-select-match>
<span class="ng-cloak">{{$select.selected.id ? $select.selected.id+ ' (' + $select.selected.sn + ') ' : "Select One" }}</span>
</ui-select-match>
<ui-select-choices repeat="item in items | filter: {id: $select.search.id, sn: $select.search.sn}">
<span ng-bind="(item.id) + ' (' + (item.sn) + ') ' "></span>
</ui-select-choices>
</ui-select>
Assuming the each item in items has the following attributes:
id
sn
fn
Given the following dataset:
[
{"id":"Ja111", "sn":"Jacobs","fn":"Jim"},
{"id":"Ja222", "sn":"Jagger","fn":"Robert"},
{"id":"Jo111", "sn":"Jones","fn":"Stan"},
{"id":"J111", "sn":"Johnson","fn":"Alfred"},
{"id":"Sm111", "sn":"Smith","fn":"Joe"}
]
using:
<ui-select-choices repeat="item in items | filter: {id: $select.search, sn: $select.search}">
will perform an "and" operation on the specified fields (in this case id and sn) (e.g. the search criteria "Jo" will find only "Stan Jones")
using:
<ui-select-choices repeat="item in items | filter: $select.search">
will perform an "or" operation across all fields (e.g. the search criteria "Jo" will find "Stan Jones", "Alfred Johnson" and "Joe Smith")
using:
<ui-select-choices repeat="item in items | propsFilter: {id: $select.search, sn: $select.search}">
will perform an "or" operation on the specified fields (in this case id and sn) (e.g. the search criteria "Jo" will find "Stan Jones" and "Alfred Johnson" - note it won't find "Joe Smith" as the filter is not looking at the fn field)
The following Plunkr shows the above examples in action.
For your requirements (I assume you want an "or" filter but only on specific fields) I'd go down the propsFilter route. This seems to be what the ui-select Basic Demo uses too.
I want to determine the ascending/descending property of the ng-repeat by passing a value coming from a dropdown box.
I defined a variable called "asdc" whose value is determined by a dropdown box. This variable should determine if the table will be sorted ascending or descending. The variable already created in the AngularJS controller so I don`t post it here. I am pasting the codes below. It does not work this way. I am wondering what I am missing.
This is the table that I want to sort.
<tr ng-repeat="technology in technologies | limitTo: rowlimit | orderBy: sortby : adsc" >
<td>{{technology.name | uppercase}}</td>
</tr>
This is the drowdown box. It defines the value of adsc as true or false and passes the value to "adsc".
<select ng-model="adsc">
<option value="true">Asc</option>
<option value="false">Dsc</option>
</select>
Use ng-options to bind to something other than a string:
In controller:
$scope.directions = [
{
value: false,
label: 'Asc'
},
{
value: true,
label: 'Desc'
}
];
In view:
<select name="direction" ng-model="adsc"
ng-options="direction.value as direction.label for direction in directions">
</select>
Here's a plunkr demonstrating its use.
Also, note that passing true will sort in descending order, not ascending.
I am doing a directive using select2. In my screen I will have many select2 objects, so this is why I want to use a directive that I can reuse it many times.
This is the directive:
<div class='form-group'>
<p>{{title}}</p>
<ui-select ng-model="selectedItem" on-select="onChange($item);" theme="bootstrap">
<ui-select-match placeholder="{{placeholder}}">
{{selectedItem.state}}
</ui-select-match>
<ui-select-choices repeat="item in items | filter: $select.search">
<span ng-bind="item.state"></span>
</ui-select-choices>
</ui-select>
Then I can do this to pass the parameters in my index.html file:
<strainer-select
items="strainer.states"
selectedItem="strainer.selectedState"
handler="onStateChange"
title="Estados"
placeholder="Escolha um Estado"
></strainer-select>
My problem is: in select2 I need inform a property of my object to "bind" and be displayed in the view, like so:
{{selectedItem.state}}
But, of course, the property 'state' will not be available in all objects. If I have a "city" object it can be "cityName" or if I want display users it could be just "name" or "userName".
I want avoid to make a interceptor and modify all my data to replicate properties just to fit a generic "name" in the data. If my object is:
{
state: "Sao Paulo",
uf: "SP"
}
I do not want change it to:
{
state: "São Paulo",
uf: "SP",
name: "São Paulo" // replicated from "state" property
}
jus to use inside my directive.
So, I've tried pass the bind property name dynamically to the directive like this:
<strainer-select
items="strainer.states"
selectedItem="strainer.selectedState"
handler="onStateChange"
title="Estados"
placeholder="Escolha um Estado"
bindName="state"
></strainer-select>
And use it in the directive like this:
<span ng-bind="item.{{bindName}}"></span> // didnt work
<span ng-bind="item[{{bindName}}]"></span> // didnt work
<span ng-bind="item['{{bindName}}']"></span> // didnt work
And the ui-select-match looks worst....
<ui-select-match placeholder="{{placeholder}}">
{{selectedItem["{{bindName}}"]}} // didnt work
</ui-select-match>
but with no success.
Does anyone has a clue how I can dynamically change the property name used by ng-bind?
Thank you.
Try
<span ng-bind="item[bindName]"></span>
<ui-select-match placeholder="{{placeholder}}">
{{selectedItem[bindName]}}
</ui-select-match>
Whilst in ng-bind you do not need to escape the use of variables you are writing raw code - hence why you need to quote and direct usages of strings.