Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<select> is losing selected option during animation #586

Open
Turbo87 opened this issue Sep 13, 2017 · 4 comments
Open

<select> is losing selected option during animation #586

Turbo87 opened this issue Sep 13, 2017 · 4 comments

Comments

@Turbo87
Copy link
Contributor

Turbo87 commented Sep 13, 2017

We are using {{one-way-select}} inside of an ember-modal-dialog and are animating that dialog using liquid-fire (via liquid-wormhole). Unfortunately during the animation the select box will always select the first element in the list instead of the selected one. Once the animation has settled the correct option is selected.

I've traced this down to the selected property in <option selected={{isSelected}}> not being set properly on the DOM node (see also https://stackoverflow.com/questions/41839681/how-can-i-dynamically-set-the-selected-attribute-on-an-option-tag). Since liquid-fire appears to clone the modal DOM for animation the cloned <option> will not have the selected property set on it, which causes the select box to default to the first entry.

This seems to be caused by a design decision in the clone() method of jQuery:

Note: For performance reasons, the dynamic state of certain form elements (e.g., user data typed into textarea and user selections made to a select) is not copied to the cloned elements. When cloning input elements, the dynamic state of the element (e.g., user data typed into text inputs and user selections made to a checkbox) is retained in the cloned elements.

(see https://api.jquery.com/clone/)

Since liquid-fire seems to use of $.clone() internally to create the animated DOM nodes it has the same problem, but since we can't adjust the clone() call from outside of liquid-fire we can't workaround the problem as easily as we could if jQuery was used directly.

One possible workaround for this issue is to monkey-patch the $.clone() method to correctly set the select values after the nodes have been cloned.
(https://stackoverflow.com/a/11804162/1478093)

I've also found https://developer.mozilla.org/de/docs/Web/API/Node/cloneNode, which seems to do something similar to $.clone() using native APIs, but it seems to have the same problem (see https://jsbin.com/basoxehupa/1/edit?html,output).

Original issue: DavyJonesLocker/ember-one-way-controls#168

@ef4
Copy link
Collaborator

ef4 commented Sep 17, 2017

It's the explode transition that relies on cloning. It's being used here in order to apply different animations to the background vs the dialog.

As a workaround, it would probably be fine to use two separate liquid-bind's instead. One for the background and one for the dialog. Then there would be no need for explode and nothing would get cloned.

@Turbo87
Copy link
Contributor Author

Turbo87 commented Sep 27, 2017

As a workaround, it would probably be fine to use two separate liquid-bind's instead.

can you elaborate on that?

what I have right now looks like this:

{{#liquid-wormhole class="modal-dialog-container"}}
  <div class="modal-dialog-overlay" onclick={{action onClose}}></div>

  {{! This crazy stuff makes the dialog both centered *and* vertically scrollable }}
  <div class="modal-dialog-table-wrapper">
    <div class="modal-dialog-table-cell-wrapper">
      <div class="modal-dialog {{containerClass}}">
        {{yield}}
      </div>
    </div>
  </div>
{{/liquid-wormhole}}
  this.transition(
    this.hasClass('modal-dialog-container'),
    this.use('explode', {
      pick: '.modal-dialog-overlay',
      use: ['fade', { duration: 200 }],
    }, {
      pick: '.modal-dialog',
      use: ['modal', { duration: 200 }],
    })
  );

@ef4
Copy link
Collaborator

ef4 commented Sep 28, 2017

This commit demonstrates how to change the animated modal in the ember-elsewhere demo app to be explode-free via two liquid-binds:

ef4/ember-elsewhere@a8cd6ea

@ef4
Copy link
Collaborator

ef4 commented Sep 28, 2017

As a benefit of this approach, all the layout stuff can live in the modal-target component, and your actual modal dialogs can be clean.

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

No branches or pull requests

2 participants