Текстовое поле автозаполнения калитки не обновляет модель при выборе щелчком мыши

У меня есть калитка AutoCompleteTextField. Для обновления модели я использую событие onblur. И мне нужно обновить текстовое поле после события «onblur», потому что требуется проверка.

Вот пример кода для иллюстрации проблемы

Подкласс веб-страницы:

public class TestPage extends WebPage {

    private Integer testField;

    public TestPage() {

        final List<Integer> allowedValues = new ArrayList<Integer>();
        for (int i = 0; i < 5; i++) {
            allowedValues.add(50 + i * 5);
        }

        final PropertyModel<Integer> testModel = new PropertyModel<Integer>(this, "testField");

        final AutoCompleteSettings autoCompleteSettings = new AutoCompleteSettings();
        autoCompleteSettings.setShowListOnEmptyInput(true);
        autoCompleteSettings.setShowListOnFocusGain(true);

        final AutoCompleteTextField<Integer> testInput =
                new AutoCompleteTextField<Integer>("testInput", testModel, autoCompleteSettings) {
                    @Override
                    protected Iterator<Integer> getChoices(final String input) {
                        return allowedValues.iterator();
                    }
                };

        testInput.setOutputMarkupId(true);
        testInput.setMarkupId("testInput");
        add(testInput);

        testInput.add(new AjaxFormComponentUpdatingBehavior("onblur") {
            @Override
            protected void onUpdate(final AjaxRequestTarget target) {
                target.add(testInput);
            }
        });
    }
} 

Соответствующий HTML:

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" xml:lang="en"
      lang="en">
<body>

<input type="text" wicket:id="testInput"/>

</body>
</html>

Проблема в том, что невозможно выбрать значение щелчком мыши.

Я пытался использовать OnChangeAjaxBehavior - и выбор щелчком мыши работает, но я не хочу выполнять проверку после каждого отдельного изменения (например, пользователь хочет ввести 54, он набирает 5 => проверка начинается, потому что OnChangeAjaxBehavior запущен)

Я пытался использовать комбинацию AjaxFormComponentUpdatingBehavior("onblur") и OnChangeAjaxBehavior, и у меня была та же проблема: невозможно выбрать значение щелчком мыши, потому что «onblur» запускается перед «onchange»

Обратите внимание, что если вы прокомментируете строку target.add(testInput);, она будет работать как положено.

Это похоже на эту проблему Wicket.

В нем говорится, что проблема исправлена ​​для версии 6.18.0, но я использую именно Wicket 6.18.0 и эта проблема все еще есть.

Мы выполняли обновление с Wicket 1.4 до Wicket 6. И в Wicket 1.4 все работало нормально.

Пожалуйста, дайте мне совет, как решить эту проблему. Ваша помощь будет действительно оценена. Заранее спасибо.


person ComeOn    schedule 24.03.2015    source источник
comment
Вероятно, есть лучший способ сделать это, но вы можете установить флаг в onblur и проверить его в onchange.   -  person RobAu    schedule 24.03.2015
comment
Спасибо РобАу! Я уже думал об этом, но это не решает: если пользователь вводит 5 -> при изменении срабатывает, и я устанавливаю флаг, а затем он решает выбрать 50 или 55 с помощью мыши -> так что у меня такая же проблема   -  person ComeOn    schedule 24.03.2015
comment
Я использую только OnChangeAjaxBehavior, и это сработало для меня. Упомянутая вами проблема коснулась и меня, и для меня она была исправлена.   -  person Robert Niestroj    schedule 24.03.2015
comment
Спасибо, Роберт. Я знаю, что OnChangeAjaxBehavior будет работать, но пользователю это будет неприятно. Представьте себе следующее: у меня есть допустимый диапазон 40-90. Пользователь вводит 5, поэтому в OnChangeAjaxBehavior я проверяю его, показываю сообщение об ошибке (5 не находится в диапазоне) и, поскольку я обновляю поле - курсор перемещается в первую первую позицию в текстовом поле. Согласитесь, это будет довольно неприятно.   -  person ComeOn    schedule 24.03.2015
comment
Вы можете использовать скрипт jquery, чтобы поместить курсор в конец текста на входе после его обновления.   -  person papkass    schedule 25.03.2015
comment
Спасибо, пиканд. В итоге я сделал почти так, как вы предлагаете. Вместо этого на OnchageAjaxBehavior я использую AjaxFormComponentUpdatingBehavior('onchange'), который не срабатывает каждый раз, когда я что-то ввожу. И во время обновления компонента я устанавливаю курсор в последнюю позицию в поле ввода.   -  person ComeOn    schedule 26.03.2015


Ответы (1)


Я предлагаю вам использовать поле автозаполнения пользовательского интерфейса wicket Jquery:

HTML:

<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
<head>
<wicket:head>
    <title>Wicket - jQuery UI: auto-complete</title>
    <style type="text/css">
        .ui-autocomplete {
            max-height: 200px;
            overflow-y: auto;
            overflow-x: hidden;
            padding-right: 20px;
        }   
    </style>
</wicket:head>
</head>
<body>
<wicket:extend>
    <div id="wrapper-panel-frame" class="ui-corner-all">
        <form wicket:id="form">
            <div>Choose your favorite rock genre: (that starts with your criteria)</div>
            <br/>
            <input wicket:id="autocomplete" type="text" size="30" title="enter your criteria here"></input><br/>
            <br/>
            <div wicket:id="feedback" style="width: 360px;"></div>
        </form>
    </div>
</wicket:extend>
</body>
</html>

Ява

package com.googlecode.wicket.jquery.ui.samples.pages.autocomplete;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.Model;

import com.googlecode.wicket.jquery.ui.form.autocomplete.AutoCompleteTextField;
import com.googlecode.wicket.jquery.ui.panel.JQueryFeedbackPanel;

public class DefaultAutoCompletePage extends AbstractAutoCompletePage
{
    private static final long serialVersionUID = 1L;
    private static final List<String> CHOICES = Arrays.asList("Acid rock", "Alternative metal", "Alternative rock", "Anarcho punk", "Art punk", "Art rock", "Beat music", "Black metal", "Blues-rock", "Britpop", "Canterbury scene",
            "Chinese rock", "Christian metal", "Crossover Thrash Metal", "Crust punk", "Crustgrind", "Dark cabaret", "Death metal", "Deathcore", "Deathrock", "Desert rock", "Djent", "Doom metal", "Dream pop", "Drone metal",
            "Dunedin Sound", "Electronic rock", "Emo", "Experimental rock", "Folk metal", "Folk rock", "Freakbeat", "Funk metal", "Garage punk", "Garage rock", "Glam metal", "Glam rock", "Goregrind", "Gothic metal", "Gothic rock",
            "Grindcore", "Groove metal", "Grunge", "Hard rock", "Hardcore punk", "Heavy metal", "Indie pop", "Indie rock", "Industrial metal", "Industrial rock", "J-Rock", "Jazz-Rock", "Krautrock", "Math rock", "Mathcore",
            "Melodic Death Metal", "Melodic metalcore", "Metalcore", "Neo-psychedelia", "New Prog", "New Wave", "No Wave", "Noise pop", "Noise rock", "Noisegrind", "Nu metal", "Paisley Underground", "Pop punk", "Pop rock", "Pornogrind",
            "Post-Britpop", "Post-grunge", "Post-hardcore", "Post-metal", "Post-punk", "Post-punk revival", "Post-rock", "Power metal", "Power pop", "Progressive metal", "Progressive rock", "Psychedelic rock", "Psychobilly", "Punk rock",
            "Raga rock", "Rap metal", "Rap rock", "Rapcore", "Riot grrrl", "Rock and roll", "Rock en Español", "Rock in Opposition", "Sadcore", "Screamo", "Shoegazer", "Slowcore", "Sludge metal", "Soft rock", "Southern rock", "Space Rock",
            "Speed metal", "Stoner rock", "Sufi rock", "Surf rock", "Symphonic metal", "Technical Death Metal", "Thrash metal", "Thrashcore", "Twee Pop", "Unblack metal", "World Fusion");

    public DefaultAutoCompletePage()
    {
        // Form //
        final Form<Void> form = new Form<Void>("form");
        this.add(form);

        // FeedbackPanel //
        final FeedbackPanel feedback = new JQueryFeedbackPanel("feedback");
        form.add(feedback.setOutputMarkupId(true));

        // Auto-complete //
        form.add(new AutoCompleteTextField<String>("autocomplete", new Model<String>()) {

            private static final long serialVersionUID = 1L;

            @Override
            protected List<String> getChoices(String input)
            {
                List<String> choices = new ArrayList<String>();
                String inputLowerCase = input.toLowerCase();

                int count = 0;
                for (String choice : CHOICES)
                {
                    if (choice.toLowerCase().startsWith(inputLowerCase))
                    {
                        choices.add(choice);

                        // limits the number of results
                        if (++count == 20)
                        {
                            break;
                        }
                    }
                }

                return choices;

                //
                // Equivalent to:
                // return ListUtils.startsWith(input, CHOICES);
                //
            }

            @Override
            protected void onSelected(AjaxRequestTarget target)
            {
                info("Your favorite rock genre is: " + this.getModelObject());
                target.add(feedback);
            }
        });
    }
}

Вы можете изменить этот компонент на любое событие, которое вы хотите

проверьте эту ссылку ниже, если это не подходит:

http://www.7thweb.net/wicket-jquery-ui/autocomplete/DefaultAutoCompletePage;jsessionid=7916524E210E1245C95DCCB697DE6182?0

person soorapadman    schedule 07.09.2015