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

Allow creation of new item before search action returns #28

Open
sarus opened this issue Jun 16, 2016 · 2 comments
Open

Allow creation of new item before search action returns #28

sarus opened this issue Jun 16, 2016 · 2 comments

Comments

@sarus
Copy link

sarus commented Jun 16, 2016

Currently if you are using the search action (instead of options) to populate the drop down list a user can't create a new option until the search action resolves.

For creating tags this means that the user has to wait for the "autocomplete" search to finish before they can create a tag. If the user quickly types the tag and presses enter the typed text just disappears.

Is there anyway to configure it so that a new list option can be created even if the search action is still pending? It feels very clunky to have to know to wait for the "Create new item" message to appear before hitting enter.

To make it more concrete this is my setup

{{#power-select-with-create
    multiple=true
    search=(action "searchTags")
    selected=selectedTags
    oncreate=(action "createTag")
    searchField="name"
    onchange=(action (mut selectedTags))
    as |tag term|
    }}
      {{tag.name}}
{{/power-select-with-create}}

Right now the createTag action can't be triggered until after the searchTags action has resolved. I'd like to allow a user to create a new tag right away without having to wait for the searchTags method to return (it issues a query to the server to function as an autocomplete).

Thanks!

@livkiss
Copy link
Collaborator

livkiss commented Jun 26, 2016

This is tricky. When we use search, the results should reflect the response of the asynchronous action (usually the response of an HTTP request), and any user-created item created before the response would be replaced when the response from the server finishes.

We would have to somehow merge all locally created items into the results returned by the promise. This sounds flaky and can lead to hard-to-debug situations where the actual select items doesn't match the return of the promise.

What would you suggest as a possible solution? I might have a look at it whenever I find the time. Contributions are welcome as well. ;-)

@cibernox What do you think?

@sarus
Copy link
Author

sarus commented Jun 26, 2016

I took a stab at this and what I have appears to be working at least for my use case. It did require upgrading to the beta version so that I had access to the search results from the public API and could manipulate that list outside of the search action (I could be doing things incorrectly or not following guidelines for this component as I still don't know the details that well)

I'm basically using ember-power-select-with-create (with multiple=true) as a way to input tags. Tags are also suggested based on a server side search. The server side provided results are only suggestions however and a user can create any tag they want.

As a user types, the first item in the result list reflects what they have typed and that item should be highlighted so if the user presses enter the tag is immediately added to the selected array. If the user stops typing then the searchAndSuggest method runs and fetches suggestions from the server. When the results are retrieved the the server side suggestions are displayed as well as the option for the user to create a tag for whatever they currently have entered as the term.

Here's what that method looks like. It gets called on the onkeydown action.

onkeydown=(action "typeAndSuggest")
    typeAndSuggest(select, e){

      if(!this.get('createAsTyping')){
        return;
      }

      // We don't want to do anything if the user is pressing the arrow keys to navigate
      // the dropdown menu
      if(this._isArrowKey(e)){
        return;
      }

      // The value of searchText always seems to be one key behind unless I wait for next
      Ember.run.next(this, function(){
        let selected = this.get('selected');

        if (!selected.includes(select.searchText) && !Ember.isBlank(select.searchText)) {
          let results = select.results;
          let suggestion = this.buildSuggestionForTerm(select.searchText);

          if(results.length !== 0){
            //remove the existing suggestion
            results.shiftObject();
          }
          //add our "suggestion" which is based off what the user has typed and highlight it
          results.unshiftObject(suggestion);
          select.actions.highlight(suggestion);
        }

        if(Ember.isBlank(select.searchText)){
          select.results.clear();
          // If we don't set highlighted to undefined it appears to have a residual value
          // which means if the user presses enter even when the input is empty a value
          // shows up
          Ember.set(select, 'highlighted', undefined);
        }
      });
    },

Note that this is placed into a fork of ember-power-select-with-create where I upgraded to the latest beta version of ember-power-select.

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