leocaseiro / angular-chosen

AngularJS Chosen directive is an AngularJS Directive that brings the Chosen jQuery in a AngularJS way
http://leocaseiro.github.io/angular-chosen/
MIT License
682 stars 248 forks source link

Setting angular-chosen directive ng-model attribute from a controller function, angular-chosen does not update it. #221

Closed egidiocs closed 7 years ago

egidiocs commented 8 years ago

Hello Leo, angular-chosen directive is a time saving piece of code, obrigado thanks.

I've run into an issue when moving from v1.3.0 to v1.5.0;

Setting chosen directive ng-model attribute from a ctlr function, angular-chosen does not update it.

because initOrUpdatefunction returns before it reaches element.trigger('chosen:updated'). After some inspection, commenting the return statement, made it work.

if (dropListDom && dropListDom.length > 0 && dropListDom.css("left").indexOf("0") >= 0)
       { //return; /*commented to test*/}
 return element.trigger('chosen:updated');

However, console.log shows me both approaches (via chosen or via function) enters the condition, so the root cause it's not the return statement. The fact is that via function, the dropListDom.css do not receive de .ng-valid-parse class. Maybe this is the reason, but my skills cannot ensure that. And also I don't know why, when using the fn, the directive updates twice.

Thank you, valeu! -egidio

image

image

chosen 1.6.2 / angular-chosen v1.5.0

egidiocs commented 8 years ago

the broken img contains the pieces of code.

    main.randomizeStatesObj = function(){

        var i = shuffle(statesObj.map(x=>x.id))[0];
        this.selectedStatesObj = statesObj.find(x=> x.id == i)

    } 
    <pre>selectedStatesObj: {{main.selectedStatesObj}}</pre>
     <select chosen id="states2" class="chosen-select"
         ng-model="main.selectedStatesObj" 
         ng-options="option.name for option in main.statesObj track by option.id">
     </select>
     <label class="btn btn-xs btn-info" ng-click="main.randomizeStatesObj()">Random Change State</label>
thelastinuit commented 8 years ago

@egidiocs did you find the solution?

leocaseiro commented 8 years ago

Hi @egidiocs. thank you for reporting that issue.

I'm sorry my delay respond. I'm working in a few projects atm and I'll have to look this issue in a few weeks.

If you could provide me a plunker will make my life easier. Also, I'm not sure what exactly is your issue.

If you remove chosen, works fine?

leocaseiro commented 8 years ago

It seems being related to #209

thelastinuit commented 8 years ago

What works for me was: NOTE: I tried a custom selected variable, nop, it does not work but the convention is all right.

$scope.object = {
   selected: [0]
}
$scope.objects = [
{
  id: 1
  name: "Han Solo"
},
{ ... }
]

and in the view

<select 
  chosen 
  multiple
  data-placeholder="Select one or few star wars heroes"
  ng-model="object.selected"                                                                                                                                                       
  ng-options="o.id as o.name for o in objects">
  <option value=""></option>
</select>

and it works quite great! @leocaseiro thanks, carnal!!!

lucienimmink commented 8 years ago

Can you explain the thought behind this check please dropListDom.css("left").indexOf("0") >= 0

lucienimmink commented 8 years ago

this still breaks my implementation; Happy to submit a PR to remove the check since it is (imo) a faulty check anyways. left: 0px, 10px or even 65709px hit by this check.

leocaseiro commented 8 years ago

Hi @lucienimmink, thanks for your update.

Unfortunately, I'm not able to reproduce the error. Could someone please provide me with a plunker that doesn't work as my tests were fine?

My tests here https://plnkr.co/edit/4dpqKG?p=preview

lucienimmink commented 8 years ago

That line of code is in your code and telling that if the dropdown container has an offset of x pixels where x has a '0' somewhere in it that then the update on the choosen element is not triggered.

My question is why is that check in place anyway; what does it do what should it fix?

because initOrUpdatefunction returns before it reaches element.trigger('chosen:updated'). After some inspection, commenting the return statement, made it work. if (dropListDom && dropListDom.length > 0 && dropListDom.css("left").indexOf("0") >= 0) { //return; /commented to test/} return element.trigger('chosen:updated');

lucienimmink commented 8 years ago

I'll try to make a demo and post the link here btw

leocaseiro commented 8 years ago

Hi @lucienimmink, thanks for the quick reply.

This condition, as commented on my source is to fix the issue #59

If you have a better fix for that issue, please submit a PR and I'll be happy to accept.

I had more than 2 users asking for that fix.

You can see more about in this commit https://github.com/leocaseiro/angular-chosen/commit/8b7e137f458f26fd643317cfa1102b7ccde5b238

Thanks

jakob-lundberg commented 8 years ago

I am also having this issue and would like to come up with a better fix. But there is one thing I do not understand with the fix as it is now.

There is a check on the CSS left value to see if it contains a 0. What does this represent?

dropListDom.css("left").indexOf("0") >= 0

When I try this in Plunker the CSS left value is -9999px. And does therefore not contain a 0. This allows updates to work correctly.

In my own application the CSS left value is -9000px. Thus a 0 on index 2. This disables the update function.

leocaseiro commented 8 years ago

Hi @jakob-lundberg, thanks for reporting that.

Unfortunately, I can't really help with any issue that I'm not aware of. I've asked kindly several times for someone to help me out how to reproduce this issue(which I don't know what it is still), but nobody could help me out. Would you mind sending me a plunker.

Or this is an issue to find out what is in the source code is about? Is there any bugs? What are them?

This hack(ish) fix avoid the dropdown to close/reload while making multiple selections holding the Command key (Ctrl on PC).

Here's a record of the bug behaviour, before this fix (notice that on each click, the dropdown list scrolls to the top by itself, which is annoying): chosen-bug-scroll

Here is the current dropdown behaviour with this fix (Notice that the dropdown stays on each click): chosen-fixed

PS: Again, I'm very happy to refactor the code wherever better solution, but I need this fix and so do few users of angular-chosen.

You can play in this plunker if you would like to check the bug behaviour: Like so: https://plnkr.co/edit/rSAVHn?p=preview

billxinli commented 8 years ago

Hmm I'm getting this issue as well.

When I unset the attribute, the dropdown does now update to the placeholder text.

$scope.dropdown.value = null
<select chosen ng-model='dropdown.value'> ... </select>
leocaseiro commented 8 years ago

Hi @billxinli, thanks for reporting this issue.

Here is a test with the current version. I set a single select with a button that set's to null: https://plnkr.co/edit/DKcARp?p=preview

Can you please check if works for you?

 <select chosen ng-model="state.selected" ng-options="s.id as s.title for s in states"
    placeholder-text-single="'My palceholder'">
    <option value=""></option>
  </select>
<button ng-click="settonull()">set to null</button>
$scope.state = {selected: 3};

$scope.settonull = function() {
    $scope.state.selected = null;  
}

$scope.states = [
    {id:1, title: 'New York'},
    {id:2, title: 'Los Angeles'},
    {id:3, title: 'Chicago'},
    {id:4, title: 'Houston'}
];

Update: Make sure you are using placeholder-text-single or placeholder-text-multiple. Do not use data-placeholder

billxinli commented 8 years ago

Odd, the above is not working for me.

Using Angular 1.5.8 and In my bower file:

    "angular-chosen-localytics": "^1.5.0",
    "chosen": "^1.6.2",
leocaseiro commented 8 years ago

Well, check what is different from my plunker. It's working with jquery: 3.3.1 //cdn angular: 1.5.8 //cdn angular-chosen-localytics: 1.5.0 //from bower chosen: 1.6.2 //cdn

Please see https://plnkr.co/edit/BvvzZm?p=preview

What's your behaviour? What is not working? Can you please make me a screenshot or something like that? Share your code?

On my plunker works for you?

billxinli commented 8 years ago

Edit @leocaseiro Thanks again for your help. It looks like it was a CSS issue.

I had:

.chosen-container .chosen-drop {
  left: -9000px; //instead of -9999px
}
jakob-lundberg commented 8 years ago

Here is a Plunker https://plnkr.co/edit/MxeMGV4BL5E5LWwRQ4ZU?p=preview

The issue is as we have seen that there are CSS changes where the left attribute of chosen-drop is -9000px (or something else containing a 0) instead of -9999px.

I got this issue because I was using the styling sheet from angular-timezone-selector. https://github.com/mishguruorg/angular-timezone-selector/blob/master/styling/angular-timezone-selector.css#L22

leocaseiro commented 8 years ago

Wow. I see. That explains why I wasn't able to reproduce the error.

Thanks for that @jakob-lundberg and @billxinli

Does it fix your issue as well @egidiocs ? How about you, @lucienimmink?

lucienimmink commented 8 years ago

Hi @leocaseiro ; My issue is when the chosen dropdown is shown (left: 0px) and the model is updated elsewhere the chosen view is not updated due to the indexOf('0') line. So no it will not be fixed by setting a different offset in CSS.

lucienimmink commented 8 years ago

I have made a small work-around in my own code that triggers the 'chosen:updated' event manually after updating the model (which is not the fix imo).

leocaseiro commented 8 years ago

Just an update that any better fix to avoid the scroll go to the top will be accepted as a PR.

PS: I'm also planning to implement a kind of emit call for chosen:update. Probably will work on that this weekend. (If I have time to do so).

jakob-lundberg commented 8 years ago

I created a pull request #225. This fixes the problem when the css value is for example -9000px instead of -9999px.

But it does not address the issue that @lucienimmink has, of updating the list while the drop down is open.

leocaseiro commented 7 years ago

Hi @jakob-lundberg, thanks for your PR.

I've released 1.5.1 with your fix.

Sorry for my delay.

leocaseiro commented 7 years ago

I'll close this issue because it's a mix of different scenarios and the author, @egidiocs, has never replied back.

If you have a similar issue, please open a new issue with your own details. Just referring this issue, won't help me to fix.

Thanks