Chosen: Chosen search text dissapear when collection changes

Created on 17 May 2016  路  13Comments  路  Source: harvesthq/chosen

Issue

I use this plug-in on my site and I had some performance issues with large data sets.
So I created something that would only populate the drop down list when the user opens it.

Then a user reported that his text disappeared when he was trying to search in that data set.
He uses the keyboard to put the focus on the dropdown and then starts to type. The dropdown gets filled and his typed text disappears.

I have created a punkler to show you what I mean.

How to reproduce

https://plnkr.co/edit/QPhLpqM6R9Ohldm0ecUd

  1. Click in the textbox to put focus on it.
  2. Press tap to put the focus on the dropdown
  3. Type some text
  4. The text disappears

Expected behavior

The user input should not be cleared after adding new options. And it should still search after adding the options (With the user input)

Actual behavior

The user input gets cleared and then all options are shown. (search)

Environment

  • Chosen Version:1.5.1
  • jQuery or Prototype Version:jQuery
  • Browser and Version: Bug is not a specific browser issue
    Chrome 50.0.2661.102
    Firefox 46.0.1
    Internet explorer 11.306.10586.0
  • OS and Version:
    Not relevant

Most helpful comment

@mosreg I've had the same issue recently, and here is a simple way to prevent it :
Replace
$(".select").trigger("chosen:updated");

With:

var ChosenInputValue = $('#YourFormId .chosen-search input').val();
$(".select").trigger("chosen:updated");
$('#YourFormId .chosen-search input').val(ChosenInputValue);

Should work fine ;)

All 13 comments

This happens for me too. I have an event attached to the input box that performs a search when the user types in at least 3 characters. The results of that search are added as options to the select, but it seems when I trigger 'chosen:updated', it wipes out the existing text that has been typed in.

I identified the line that ends up causing this: https://github.com/harvesthq/chosen/blob/master/coffee/chosen.jquery.coffee#L204

I have modified chosen locally so that you can specify a parameter reset_search_field_on_update when creating the chosen select which allows you to disable the text reset (note that you also probably only want to omit that function when updating the box, not necessarily when creating). I've forked Chosen, and I'll try to get this change committed soon and will post a link here when that's done.

I can also submit a pull request to have this change merged, although the change would probably need to be made for the prototype version as well. I don't really work with prototype, so I'm not sure if there is anything to watch out for, but the changes are pretty minor.

That is awesome, I haven't done anything with Prototype too. So I properly can't help with that part of the code.

hey @mosreg check out this fork on my branch: https://github.com/jfoo1984/chosen/tree/disable_input_reset_on_update

I've added two new parameters that you can set when creating the Chosen box reset_search_field_on_update (default true) and reset_multiple_search_field_on_focus_change (default true). Setting the first to false allows you to dynamically update options and trigger chosen:updated without losing the searched text. Setting the second param to false prevents the text box from being cleared if you click out and into the Chosen box. Let me know what you think. I can't make a pull request for now, since I haven't made these updates to prototype, but if this seems helpful, I can certainly do that.

That is perfect!

Chosen's update option wasn't really intended to work as a user typed in search so it doesn't surprise me to see that you'd run into issues when using it this way. @jfoo1984's solution seems to have solved your problem so I'm going to close it. Thanks for sharing!

@pfiller, Is this an option/feature that would be considered for inclusion, once I can make the changes for the prototype version as well?

I think this is the kind of solution that makes sense to keep in a fork. Updating selects as people type is not a use case we want to appear to support ... and that's the only reason for an option like this.

Having a fork that solves this is a better solution, imo.

I got the text to remain when a multiple select is updated by commenting out this line 811 in the Chosen.prototype.results_build function. This may not be the correct place but so far its working. This function is called during$("#Selector").trigger("chosen:updated"); and the select list is filtered.

chosen

@mosreg I've had the same issue recently, and here is a simple way to prevent it :
Replace
$(".select").trigger("chosen:updated");

With:

var ChosenInputValue = $('#YourFormId .chosen-search input').val();
$(".select").trigger("chosen:updated");
$('#YourFormId .chosen-search input').val(ChosenInputValue);

Should work fine ;)

@Motchouk Your solution working pretty well i.e retaining typed input but with this approach choosing options with arrow key will not work, please check demonstration https://gph.is/g/46glP1q

Any solution for it?

I had issues with keystrokes being lost due to .chosen-search being made read-only so i implemented the code below and it seems to be working like a charm with no changes to the chosen script.

`

$(document).on("keyup", '.chosen-container-active', function(e){
    if($('.chosen-container-active').find('.chosen-search input[type="text"]').val().length < 1 && e.which === 8){
        $("#selector").empty().append('<option>Placeholder Text</option>').trigger("chosen:updated");
    }
});

$(document).on("keypress", '.chosen-container-active', function(e){

    let keyCode = e.which, selfield = $("#selector"),
    searchField = $('.chosen-container-active').find('.chosen-search input[type="text"]'),
    searchText = searchField.val() + String.fromCharCode(keyCode);

    if(searchText.length > 2  ){
        $.getJSON(selfield.attr("data-url"), {filter : searchText}, function(json){
            if(Object.keys(json).length > 0){
                selfield.empty();
                json.map(function(obj,idx) {
                    selfield.append('<option value="' + obj.gotoid + '">' + obj.nf + " " + obj.nl + " - "  + obj.t + ", \n" + obj.c + '</option>');
                });
                selfield.trigger("chosen:updated");
                searchField.val(searchText);
            }
        });
    }
});

`

@Motchouk Your solution working pretty well i.e retaining typed input but with this approach choosing options with arrow key will not work, please check demonstration https://gph.is/g/46glP1q

Any solution for it?

Here's what I did:

$(".chosen-search input").on("paste keyup", function (e) {
    var code = (e.keyCode || e.which);
    if (code == 37 || code == 38 || code == 39 || code == 40) {
        console.log("arrow keys used");
    } else {
        var ChosenInputValue = $('#YourFormId .chosen-search input').val();
        $(".select").trigger("chosen:updated");
        $('#YourFormId .chosen-search input').val(ChosenInputValue);
    }
});
Was this page helpful?
0 / 5 - 0 ratings