Калитка: Уведомить, если модель страницы была изменена - PullRequest
6 голосов
/ 26 июля 2010

Проблема в следующем;Веб-страница содержит несколько элементов формы, которые могут быть изменены и сохранены пользователем с помощью кнопки сохранения, или изменения могут быть отклонены.

Если пользователь пытается отойти от страницы без сохранения изменений, мне нужномодальное окно с вопросом, хочет ли пользователь сохранить изменения перед тем, как покинуть страницу.

Как мне проверить, была ли модель страницы / формы изменена пользователем с тех пор, как она была изменена?впервые загружен, и как я могу инициировать эту проверку при нажатии любой ссылки на странице?

Любой ответ или предложения будут высоко оценены,

Спасибо.

1 Ответ

4 голосов
/ 26 июля 2010

Я думаю, вы бы искали решение только для javascript, обычно упакованное как поведение калитки.

реализация зависит от используемой вами библиотеки javascript, вот несколько прототипов кода:

var windowdirty = false;
var windowdirtyinitialized = false;

function initwindowdirty(){
    if(windowdirtyinitialized)return;
    windowdirtyinitialized=true;

    Event.observe(window,"beforeunload",function(){
        return (!windowdirty || 
          confirm("You have started entering values, do you really want to leave");
    });
}

function monitor(componentId){
    $(componentId).observe("change",function(){
        windowdirty = true;
    });
}

function undirty(){
    windowdirty=false;
}

Мы поместим это в файл с именем DontLeaveBehavior.js

Вот поведение, которое использует этот файл javascript:

public class DontLeaveBehavior extends AbstractBehavior{

    /**
     * {@inheritDoc}
     */
    @Override
    public void renderHead(final IHeaderResponse response){
        response.renderJavascriptReference(new JavascriptResourceReference(DontLeaveBehavior.class,
            "DontLeaveBehavior.js"));
        response.renderOnDomReadyJavascript("initwindowdirty();");
        super.renderHead(response);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void bind(final Component component){
        super.bind(component);
        component.setOutputMarkupId(true);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onRendered(final Component component){
        final Response response = RequestCycle.get().getResponse();
        response.write(JavascriptUtils.SCRIPT_OPEN_TAG);
        response.write("monitor('" + component.getMarkupId() + "');");
        response.write(JavascriptUtils.SCRIPT_CLOSE_TAG);
    }

}

Теперь вот страница, которая автоматически назначает это поведение всем своим дочерним элементам, которые являются текстовыми компонентами:

public class Mypage extends WebPage{

    ...

    private boolean behaviorAssigned = false;

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onBeforeRender(){
        if(!behaviorAssigned){
            behaviorAssigned=true;
            visitChildren(new IVisitor<Component>(){

                @Override
                public Object component(Component component){
                    if(component instanceof AbstractTextComponent<?>){
                        component.add(new DontLeaveBehavior());
                    }
                    return null;
                }
            });
        }
        super.onBeforeRender();
    }

}

и, наконец, что не менее важно, ваша кнопка отправки должна вызвать undirty() конечно.

Ничего из этого не было проверено, потому что мне нужно идти домой, чтобы поужинать с женой и детьми (что, конечно, даже веселее, чем кодирование калитки), но это должно помочь вам начать.

Часть, относящаяся к прототипу, должна быть легко перенесена в любую другую библиотеку javascript, но вы, вероятно, не должны делать это без библиотеки, если не знаете, что делаете.


Edit:

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

Снова отредактируйте: там, теперь ссылка работает

...