Установить фокус на компонент с помощью Apache Wicket?

Как установить фокус на компонент с помощью Apache Wicket? Поиск дает очень мало информации, в основном по настройке поля по умолчанию. Я не хочу устанавливать поле по умолчанию, скорее я хочу установить фокус, когда, например, выбран определенный переключатель.


person vagabond    schedule 13.04.2010    source источник


Ответы (7)


Как только вы создадите свое поведение для установки фокуса, вы сможете добавить его к компоненту для любого события, просто убедитесь, что этот компонент является частью AjaxRequestTarget. Я не понимаю, почему это не сработает...

myRadioButton.add(new AjaxEventBehavior("onchange") {
 @Override
 protected void onEvent(AjaxRequestTarget target) {
    myOtherComponent.add(new DefaultFocusBehavior());
        target.addComponent(myForm);
 }
});

Вот ссылка, которая показывает, как создать поведение фокуса по умолчанию, если у вас его еще нет: http://javathoughts.capesugarbird.com/2009/01/wicket-and-default-focus-behavior.html

person schmimd04    schedule 14.04.2010
comment
Я бы посоветовал вам скопировать код в ответ (конечно, сохранив исходную ссылку), чтобы он не зависел от внешних ресурсов. - person tetsuo; 16.02.2011
comment
проблема с этим решением заключается в том, что после того, как вы прикрепили его, то каждый раз, когда он обновляется (AjaxRequestTarget#addComponent), он сфокусирован (или, по крайней мере, оценивается javascript фокуса), используя AjaxRequestTarget#focusComponent, это однократный фокус, поэтому он лучше подходит для запрашиваемого поведения (радио кнопка выбрана) - person Michal Bernhard; 05.06.2013

Я предлагаю использовать родной org.apache.wicket.ajax.AjaxRequestTarget#focusComponent(). Например:

/**
 * Sets the focus in the browser to the given component. The markup id must be set. If            
 * the component is null the focus will not be set to any component.
 * 
 * @param component
 *            The component to get the focus or null.
 */
 org.apache.wicket.ajax.AjaxRequestTarget#focusComponent(Component component)
person martin-g    schedule 10.04.2012
comment
Послушайте, что говорит marting-g ;-) - person Jesse; 25.04.2013
comment
Решение martin-g было единственным решением, которое заставило его работать для моего сценария - модальное/всплывающее окно. Я думаю, что автофокус работает только при загрузке страницы, а не модальной загрузки, поэтому любые попытки умело установить атрибут автофокуса в HTML просто терпят неудачу - всегда. Убедитесь, что вы вызываете myInput.setOutoutMarkupId(true), а затем переопределяете show(ART target) { super.show(target); target.focusComponent(myInput) } Работает как купленный! Возможно, я сделаю полный ответ. - person Volksman; 29.04.2020

Если вы хотите установить фокус только через javascript и не хотите перезагружать форму или компонент, вы можете использовать следующий код:

import org.apache.wicket.Component;

public class JavascriptUtils {
    private JavascriptUtils() {

    }

    public static String getFocusScript(Component component) {
        return "document.getElementById('" + component.getMarkupId() + "').focus();";
    }
}

И затем в любом методе Ajax вы можете использовать:

target.appendJavascript(JavascriptUtils.getFocusScript(componentToFocus));
person Marcelo    schedule 20.04.2010

Для всплывающего окна, такого как modalWindow, моим обходным решением было использование атрибута "autofocus" в первом входном теге. Простое решение — добавить его непосредственно в html.

<input ..... autofocus>

Другое решение — добавить его в само окно modalWindow:

@Override
public void show(AjaxRequestTarget target) {
    super.show(target);
    setUpFocus();
}

protected void setUpFocus() {
    DeepChildFirstVisitor visitor = new DeepChildFirstVisitor() {

        @Override
        public void component(Component component, IVisit<Void> iVisit) {
            if (isAutofocusable(component)) {
                component.add(new AttributeAppender("autofocus", ""));
                iVisit.stop();
            }
        }

        @Override
        public boolean preCheck(Component component) {
            return false;
        }
    };
    this.visitChildren(FormComponent.class, visitor);
}

    protected boolean isAutofocusable(Component component) {
        if (component instanceof TextArea ||
                component instanceof DropDownChoice ||
//                component instanceof RadioChoice ||
                component instanceof AjaxCheckBox ||
                component instanceof AjaxButton || 
                component instanceof TextField) {
            return true;
        }
        return false;
    }

RadioChoice закомментирован, потому что это решение не работает. Для RadioChoice я бы рекомендовал реализовать FocusedRadioChoice:

public class FocusedRadioChoice<T> extends RadioChoice<T> {
//constructors...
    @Override
    protected IValueMap getAdditionalAttributes(int index, T choice) {
        super.getAdditionalAttributes(0, choice);
        AttributeMap am = new AttributeMap();
        am.put("autofocus", "");
        return am;
    }
}
person BlondCode    schedule 02.08.2016
comment
Ни одно из этих решений не работает для меня: либо установка автофокуса непосредственно в HTML, либо использование приведенного выше кода для использования добавления атрибута для установки фокуса. Я думаю, может быть, атрибут автофокуса работает только при загрузке страницы, а не при загрузке модального диалога? - person Volksman; 29.04.2020

Есть ли способ добиться того же без JavaScript?

(Я реализую форму с панелью обратной связи, которая появляется только при отключенном Javascript, поэтому не имеет смысла зависеть там от JavaScript...,-)

Я мог найти только ответы, которые используют JS .focs()... возможно, Wicket 1.5 предоставит метод Component.setFocus()...

person Gregor    schedule 15.12.2010
comment
Невозможно установить фокус на элемент html без использования JavaScript. В HTML нет тега или атрибута, который позволил бы это сделать (пока). Если бы Wicket когда-либо реализовывал метод Component.setFocus(), он все равно генерировал бы некоторый JavaScript для его включения. - person Marcelo; 27.08.2011
comment
Вы можете использовать простой автофокус атрибута html. Вы можете напрямую добавить его в первый входной тег html или динамически добавить, например, component.add(new AttributeAppender(autofocus, )); Проверьте мой краткий ответ. - person BlondCode; 02.08.2016

Если вы используете кнопку Ajax, вы можете просто вызвать target.focusComponent(myComponent); в методе onSubmit кнопки.

person icecreamhead    schedule 03.04.2012

Решение @martin-g было единственным решением, которое заставило его работать для моего сценария - модальное/всплывающее окно.

Примечание: я думаю, что автофокусировка, явно встроенная в HTML, работает только при загрузке страницы, а не при загрузке модального окна, поэтому любые попытки умело установить атрибут автофокуса в HTML модального окна просто терпят неудачу - всегда.

Здесь я излагаю шаги для установки фокуса на поле ввода под названием «myInput», используя всю мощь Wicket (без JS!):

В onInitialize:

// Make sure the field has an ID in markup
myInput.setOutoutMarkupId(true);

Предоставьте переопределенный метод show, в котором вы вызываете метод focusComponent:

public void show(AjaxRequestTarget target)
{
    // Make sure you call the super method first!
    super.show(target);

    target.focusComponent(myInput);
}

Это требует, чтобы ваш компонент был атрибутом вашего класса модального контента, чтобы вы могли получить к нему доступ в методе show. Чтобы избежать создания атрибута класса для вашего компонента ввода, вы можете смешать это решение с решением из BlondCode, заменив это решение

component.add(new AttributeAppender("autofocus", ""));

с участием

target.focusComponent(component);

Это тоже работает!

person Volksman    schedule 29.04.2020