/* This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV This program is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, see http://www.gnu.org/licenses or write to the Free Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ package com.servoy.j2db.server.headlessclient.dataui; import org.apache.wicket.Component; import org.apache.wicket.Page; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.IAjaxCallDecorator; import org.apache.wicket.ajax.calldecorator.AjaxCallDecorator; import org.apache.wicket.markup.MarkupStream; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.AbstractWrapModel; import org.apache.wicket.model.IComponentAssignedModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.IWrapModel; import org.apache.wicket.model.Model; import com.servoy.j2db.ISupportNavigator; import com.servoy.j2db.dataprocessing.FoundSet; import com.servoy.j2db.dataprocessing.ISaveConstants; import com.servoy.j2db.server.headlessclient.MainPage; import com.servoy.j2db.server.headlessclient.WebForm; import com.servoy.j2db.ui.IProviderStylePropertyChanges; import com.servoy.j2db.ui.IStylePropertyChanges; import com.servoy.j2db.util.ISupplyFocusChildren; import com.servoy.j2db.util.Utils; /** * The default Navigator for the webclient. * * @author jcompagner,jblok */ public class WebDefaultRecordNavigator extends Panel implements IProviderStylePropertyChanges, ISupplyFocusChildren<Component> { private static final long serialVersionUID = 1L; public static final int DEFAULT_WIDTH = ISupportNavigator.DEFAULT_NAVIGATOR_WIDTH; public static final int DEFAULT_HEIGHT_WEB = 160; private final FoundSetIndexModel foundSetIndexModel; private String totalRecords; protected ChangesRecorder jsChangeRecorder = new ChangesRecorder(null, null); private String selectedRecord; private final TextField tf; private final ServoySubmitLink prevLink; private final ServoySubmitLink nextLink; public WebDefaultRecordNavigator(WebForm form) { super("default_navigator"); boolean useAJAX = Utils.getAsBoolean(form.getController().getApplication().getRuntimeProperties().get("useAJAX")); setOutputMarkupPlaceholderTag(true); foundSetIndexModel = new FoundSetIndexModel(form); add(new Label("firstRecordIndex", foundSetIndexModel)); tf = new NavigatorTextField("currentRecordIndex", foundSetIndexModel) { private static final long serialVersionUID = 1L; private String inputId; /** * @see wicket.markup.html.form.FormComponent#getInputName() */ @Override public String getInputName() { if (inputId == null) { Page page = findPage(); if (page instanceof MainPage) { inputId = ((MainPage)page).nextInputNameId(); } else { return super.getInputName(); } } return inputId; } }; if (useAJAX) { tf.setOutputMarkupPlaceholderTag(true); tf.add(new ServoyAjaxFormComponentUpdatingBehavior("onchange") { private static final long serialVersionUID = 1L; @Override protected void onUpdate(AjaxRequestTarget target) { WebEventExecutor.generateResponse(target, findPage()); } }); tf.add(new ServoyAjaxFormComponentUpdatingBehavior("onkeydown") { private static final long serialVersionUID = 1L; @Override protected void onUpdate(AjaxRequestTarget target) { WebEventExecutor.generateResponse(target, findPage()); } @Override protected IAjaxCallDecorator getAjaxCallDecorator() { return new AjaxCallDecorator() { private static final long serialVersionUID = 1L; @Override public CharSequence decorateScript(CharSequence script) { return "return testEnterKey(event, function() {" + script + "});"; } }; } }); } add(tf); add(new Label("totalRecords", foundSetIndexModel)); prevLink = new NavigatorServoySubmitLink("prev", useAJAX) { private static final long serialVersionUID = 1L; /** * @see wicket.ajax.markup.html.AjaxFallbackLink#onClick(wicket.ajax.AjaxRequestTarget) */ @Override public void onClick(AjaxRequestTarget target) { foundSetIndexModel.prev(); if (target != null) { Page page = getPage(); target.addComponent(tf); WebEventExecutor.generateResponse(target, page); } } }; add(prevLink); nextLink = new NavigatorServoySubmitLink("next", useAJAX) { private static final long serialVersionUID = 1L; /** * @see wicket.ajax.markup.html.AjaxFallbackLink#onClick(wicket.ajax.AjaxRequestTarget) */ @Override public void onClick(AjaxRequestTarget target) { foundSetIndexModel.next(); if (target != null) { Page page = getPage(); target.addComponent(tf); WebEventExecutor.generateResponse(target, page); } } }; add(nextLink); } /** * @see wicket.MarkupContainer#onRender(wicket.markup.MarkupStream) */ @Override protected void onRender(MarkupStream markupStream) { super.onRender(markupStream); FoundSet fs = foundSetIndexModel.getFoundSet(); if (fs != null) { totalRecords = (fs.getSize() == 0 ? "" : (fs.getSize() + (fs.hadMoreRows() ? "+" : ""))); selectedRecord = (fs.getSelectedIndex() == -1 ? "" : "" + (fs.getSelectedIndex() + 1)); } } public IStylePropertyChanges getStylePropertyChanges() { // the recorder is only used for isChanged, set the correct value before returning the instance FoundSet fs = foundSetIndexModel.getFoundSet(); if (fs == null) { jsChangeRecorder.setRendered(); } else if ((fs.getSize() == 0 ? "" : (fs.getSize() + (fs.hadMoreRows() ? "+" : ""))).equals(totalRecords) && ((fs.getSelectedIndex() == -1 ? "" : "" + (fs.getSelectedIndex() + 1)).equals(selectedRecord))) { jsChangeRecorder.setRendered(); } else jsChangeRecorder.setChanged(); return jsChangeRecorder; } public Component[] getFocusChildren() { return new Component[] { prevLink, nextLink, tf }; } private class NavigatorTextField extends TextField implements IProviderStylePropertyChanges { public NavigatorTextField(String id, IModel object) { super(id, object); } private final ChangesRecorder jsChangeRecorder = new ChangesRecorder(null, null); public IStylePropertyChanges getStylePropertyChanges() { return jsChangeRecorder; } /** * @see org.apache.wicket.MarkupContainer#onRender(org.apache.wicket.markup.MarkupStream) */ @Override protected void onRender(MarkupStream markupStream) { super.onRender(markupStream); getStylePropertyChanges().setRendered(); } } private abstract class NavigatorServoySubmitLink extends ServoySubmitLink implements IProviderStylePropertyChanges { public NavigatorServoySubmitLink(String id, boolean useAJAX) { super(id, useAJAX); } private final ChangesRecorder jsChangeRecorder = new ChangesRecorder(null, null); public IStylePropertyChanges getStylePropertyChanges() { return jsChangeRecorder; } /** * @see org.apache.wicket.MarkupContainer#onRender(org.apache.wicket.markup.MarkupStream) */ @Override protected void onRender(MarkupStream markupStream) { super.onRender(markupStream); getStylePropertyChanges().setRendered(); } } } class FoundSetIndexModel extends Model implements IComponentAssignedModel { private static final long serialVersionUID = 1L; /** The ListView's list model */ private final WebForm form; /** * Construct * * @param listView The ListView * @param index The index of this model */ public FoundSetIndexModel(final WebForm listView) { form = listView; } public FoundSet getFoundSet() { return form.getController().getFormModel(); } /** * @see wicket.model.IAssignmentAwareModel#wrapOnAssignment(wicket.Component) */ public IWrapModel wrapOnAssignment(Component component) { return new WrapModel(component); } public void next() { FoundSet fs = form.getController().getFormModel(); if (fs != null) { int index = fs.getSelectedIndex(); if (index + 1 < fs.getSize() && ((form.getController().getApplication().getFoundSetManager().getEditRecordList().stopEditing(false) & (ISaveConstants.STOPPED + ISaveConstants.AUTO_SAVE_BLOCKED)) != 0)) { fs.setSelectedIndex(index + 1); } } } public void prev() { FoundSet fs = form.getController().getFormModel(); if (fs != null && fs.getSelectedIndex() > 0 && ((form.getController().getApplication().getFoundSetManager().getEditRecordList().stopEditing(false) & (ISaveConstants.STOPPED + ISaveConstants.AUTO_SAVE_BLOCKED)) != 0)) { fs.setSelectedIndex(fs.getSelectedIndex() - 1); } } class WrapModel extends AbstractWrapModel { private static final long serialVersionUID = 1L; private final Component component; WrapModel(Component component) { this.component = component; } /** * @see wicket.model.IWrapModel#getNestedModel() */ public IModel getWrappedModel() { return FoundSetIndexModel.this; } @Override public void detach() { FoundSetIndexModel.this.detach(); } /** * @see wicket.model.IModel#getObject() */ @Override public Object getObject() { FoundSet fs = form.getController().getFormModel(); if (fs != null) { if ("firstRecordIndex".equals(component.getId())) { return (fs.getSize() == 0 ? "0" : "1"); } if ("totalRecords".equals(component.getId())) { return (fs.getSize() == 0 ? "" : (fs.getSize() + (fs.hadMoreRows() ? "+" : ""))); } if ("currentRecordIndex".equals(component.getId())) { return (fs.getSelectedIndex() == -1 ? "" : "" + (fs.getSelectedIndex() + 1)); } } return null; } /** * @see wicket.model.IModel#setObject(java.lang.Object) */ @Override public void setObject(Object object) { FoundSet fs = form.getController().getFormModel(); if (fs != null) { if ("currentRecordIndex".equals(component.getId())) { int index = Utils.getAsInteger(object); if (index < 1) { index = 1; } else if (index > fs.getSize()) { index = fs.getSize(); } if (index != fs.getSelectedIndex() + 1 && ((form.getController().getApplication().getFoundSetManager().getEditRecordList().stopEditing(false) & (ISaveConstants.STOPPED + ISaveConstants.AUTO_SAVE_BLOCKED)) != 0)) { fs.setSelectedIndex(index - 1); } } } } } }