Skip to content
This repository has been archived by the owner on Oct 2, 2019. It is now read-only.

Preselect items by remote call in multiple select with object items doesn't work #404

Open
Thomas-Adams opened this issue Nov 15, 2014 · 25 comments

Comments

@Thomas-Adams
Copy link

When trying to preselect a ui-select with multiple selected items, retrieved by a remote call, here $http service, the preselection is not set.

Example: The following does not work

$http.get(baseUrl + "/todotags/" + $scope.todoForm.id,{}).
    success(function(data, status, headers, config){
    $scope.todoForm.selectedTags  = data.records;           
 }).error(....);

Whereas setting it o an array of values that were fetched in a previous step does work:

$http.get(baseUrl + "/todotags/" + $scope.todoForm.id,{}).
    success(function(data, status, headers, config){
    $scope.todoForm.selectedTags  = [array of values previuosly fetched];           
 }).error(....);

In both case the remotely fetched data array and the fixed array are identical.

The corresponding HTML:

<ui-select multiple ng-model="todoForm.selectedTags" theme="bootstrap"  class="selectize-control">
    <ui-select-match placeholder="Select tags...">{{$item.text}}</ui-select-match>
    <ui-select-choices refresh-delay="110" repeat="tag in tags">
        {{tag.text}}
    </ui-select-choices>
</ui-select>

The array looks like this :

[
    {
        "id" : 9,
        "guid" : "09efa3cd-a5cd-4ea0-8a1c-83fc66860895",
        "text" : "Node.js",
        "createdAt" : "2014-11-14T10:06:52.000Z",
        "updatedAt" : null
    }, {
        "id" : 10,
        "guid" : "d765b48c-cb5a-49d8-af55-f70ebc5ff11f",
        "text" : "Sequelizer.js",
        "createdAt" : "2014-11-14T10:06:59.000Z",
        "updatedAt" : null
    }, {
        "id" : 11,
        "guid" : "c4b5f0dc-f11f-4bba-af47-584aa4e50c9b",
        "text" : "SQLite",
        "createdAt" : "2014-11-14T10:07:05.000Z",
        "updatedAt" : null
    }
]

Is there any possibility to make that work?

Cheerio Thomas

@richardallen
Copy link

I had a similar problem using $resource. The objects retrieved using $resource are of type Resource and the model object they are compared to is type Object. Otherwise, the two objects are identical. However, the test if (result == value) within checkFnMultiple at line 651 of select.js evaluates to false. I had to swap the model object with its equivalent Resource object to get the option selected.

Ideally, ui-select would allow the user to specify the object property to compare by or provide a comparison function.

@richardallen
Copy link

PR #256 provides a fix.

@alvarezmario
Copy link

I have this same issue and I tested this even without a remote server call, so the server response is not the one causing this issue. In the example Demo Multiple, in Plunker, in the Array of Objects section, by default are two items selected, by doing this in the code:

$scope.multipleDemo.selectedPeople = [$scope.people[5], $scope.people[4]];

This works fine, but when I change that for this:

$scope.multipleDemo.selectedPeople = [{ name: 'Michael',   email: '[email protected]',   age: 15, country: 'Colombia' }];

The items are no preselected anymore. This is weird, because it's basically the same, so it should work, but it doesn't.

Anyone know why?

@yaneq
Copy link

yaneq commented Nov 19, 2014

I have similar problems. The reason seems to be that the control will only add values that are listed in the options. In my use-case i have the profile of a person which might speak several languages. The languages he might have added to his profile previously are not shown in ui-select.

Here is a demo of the behavior:
http://plnkr.co/edit/swKr14zURxlrvdTdUt7O

@alvarezmario
Copy link

That's exactly what happens with me

2014-11-19 12:03 GMT-05:00 Jan Koeppen [email protected]:

I have similar problems. The reason seems to be that the control will only
add values that are listed in the options. In my use-case i have the
profile of person which might speak several languages. The languages he
might have added to his profile previously are not shown in ui-select.

Here is a demo of the behavior:
http://plnkr.co/edit/swKr14zURxlrvdTdUt7O


Reply to this email directly or view it on GitHub
#404 (comment)
.

@yaneq
Copy link

yaneq commented Nov 19, 2014

I opened a PR that fixed the problem for me #419

@yaneq
Copy link

yaneq commented Nov 21, 2014

seems to be a duplicate of #192

I solved it now by setting the choices to the model value on page load and it seems to work well.

@Adriien-M
Copy link

yaneq's fix worked for me... Thanks!

@sagar-ranglani
Copy link

Facing same problem!
Can someone please explain the solution with an example.

Thank you in advance!

@Flightfreak
Copy link

This behaviour is resulting from the fact that the pre-selected items are checked for equal reference with the provided source items by the checkFnMultiple function (https://github.com/angular-ui/ui-select/blob/master/dist/select.js#L954). That behaviour is nicely demonstrated by @nomack84 test (Identical objects, but different references). To my current knowledge (first time user) the test is required to keep tidy ship and avoid duplicate values in the list and result-set but the current function fails to handle hard copies of the source items. This #256 should fix this.

@ahmer-yasin
Copy link

i have one issue when i save data in db it save objectc in array for using ui select
but i retrive the data it will never selected how can i fix it

@MikeABentley
Copy link

I have a somewhat similar problem. I have a link on my form that will populate a remotely populated multi-select control. The item I want to add on the fly will likely not be part of the control's options list (since the list is typically empty as most remotely populated selects will be). Simply setting the value the model that's bound to the select doesn't work (example of the code provided below).

It's pretty disappointing that something like this doesn't work. I have other issues with the remote functionality of the control as well that add to the frustration I guess. Any idea if this will be fixed soon?

$scope.data.solicitors.push({ id: $scope.data.current_user_contact_id, name: $scope.data.current_user_contact_name });

You would think that after updating the value of the model bound to the select control would then update the selected array in the control as well.

@MikeABentley
Copy link

Just wanted to play around a bit to see if I could figure out any sort of workaround. I did find one. It's not pretty and I'm not going to use it in the production world, but here it is nonetheless.

Basically, you have to push your own programatically sourced item into the model that's bound to the choice portion of your select control. Once you've done that you can then update the model that's ultimately bound to the control's selected array.

As you can see here the choices are bound to a local solicitorSearchResults array. The control itself is bound to a property on my "data" object called solicitors. I'm passing the control into the locals.solicitorSearch() function for other reasons (cough filtering out currently seleced results from the results array because the control doesn't do it for you cough).

<ui-select multiple ng-model="data.solicitors" reset-search-input="true" data-bbauto-field="SolicitorList">
     <ui-select-match placeholder="{{resources.solicitor_search_watermark}}">{{$item.name}}</ui-select-match>
     <ui-select-choices repeat="solicitor in locals.solicitorSearchResults | filter: $select.search" refresh="locals.solicitorSearch($select.search, $select)" refresh-delay="100">
          <span data-bbauto-field="{{solicitor.name}}">{{solicitor.name}}</span>
     </ui-select-choices>
</ui-select>

I have this function which is bound to an anchor via ng-click. This function lives on my locals object as well. See the truncated definition of locals below. Once I place the item i want to add into the solicitorSearchResults I was then able to set my solicitors array which would then in turn update the select control. It appears that the act of adding it to the solicitorSearchResults array makes it become "valid" and will then be picked up the select control.

.....
.....
assignToMe: function () {
          var currentUser = { id: $scope.data.current_user_contact_id, name: $scope.data.current_user_contact_name };

          $scope.locals.solicitorSearchResults = [currentUser];
          $scope.data.solicitors.push(currentUser);
.....
.....

However, I'm sure you what this introduces. Now my multi-select select control; which is populated remotely; has an item in the list of results. When I remove the item I added programatically via the UI and then place focus into the control I'll see that item in the list of available choices......when no remote search has been initiated by the user.

Since this control is remotely sourced on the fly I'm going to have the same issue when I load this from with an existing record. On load I'll have to add all current solicitors to the locals.solicitorSearchResults array and then set the data.solicitors value.

@sporkd
Copy link

sporkd commented Jan 30, 2015

The problem I'm seeing is an inconsistency between the options you need to provide ui-select-choices on initialization vs. when fetch/search is called subsequent times.

To sum it up:

  1. If you want to initialize a multi select with existing selections, then you need to pass those options into ui-select-choices, or else they won't be pre-selected.
  2. However, on subsequent calls to fetch (e.g. when typing), you need to make sure you EXCLUDE any selected options, otherwise it will re-suggest, and let you select duplicates.

I believe the initialization issue (1.) only appeared in a recent release, as I don't remember having to do that in the past. The requirement to exclude options was already existing behavior.

@jukkasi
Copy link

jukkasi commented Jan 31, 2015

@MBentley1976 I think I'm facing similar problem, described here #256

@brazorf
Copy link

brazorf commented Apr 20, 2015

I've just upgraded to 0.11.2, and still this doesn't seem to be fixed

@olso
Copy link

olso commented Apr 21, 2015

0.11.2 here...

Still facing problems with duplicates when having ngModel (multiple) set before choices are loaded as @sporkd explained.

For now, I "fixed" it by $watching when choices are populated and then I set ngModel.

However, Angular digest cycle is a whole another problem with this**...**

@olso
Copy link

olso commented Apr 22, 2015

@brazorf Have you fixed it or what did you do?

@Zach-Barnes-Volusion
Copy link

+1 Still broken in 0.11.2

@toddb
Copy link

toddb commented Jun 28, 2015

+1 broken - I am pretty sure this is the same issue I found. I am using Array of Objects too.

See http://plnkr.co/edit/PJdDL58wCx5XiKsUCOw3 for demonstration of problem and solution/workaround.

Problem: I would expect to push items onto a watched Choice list but the Match list isn't correctly synchronised in the case where the Match list is populated with objects asynchronously.

Workaround: you must assign the Match list from the Choice list.

@bademux
Copy link

bademux commented Aug 11, 2015

+1

@JonnyBGod
Copy link

+1

@codegeek1001
Copy link

Not sure this helps but I solved this issue for my project. It seems like ui.select expects "Resource" type and if you supply "Object", then it fails to display them correctly even though the scope variable has the correct details.

The trick is to ensure that whenever you set in ng-model, it is a Resource type. Lets say that your ng-model is "items" or $scope.items (in controller). Then check the following:

console.log(typeof $scope.items)

If this displays "Object", you have a problem. If it displays "Resource", then you are good.

@gentisaliu
Copy link

+1!

@malkitbhasin
Copy link

+1

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests