From 00166aee1f11794514425e263a55eef3f44585a4 Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Tue, 7 Feb 2017 08:36:28 +0100 Subject: [PATCH] OO-2487: make the check box pure ajax and don't react to submit form --- .../elements/MultipleSelectionElement.java | 19 +++++-- .../MultipleSelectionElementImpl.java | 57 +++++++++++++------ .../elements/MultipleSelectionRenderer.java | 11 ++++ .../cl/ui/CheckListAssessmentController.java | 28 +++++++-- 4 files changed, 89 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/elements/MultipleSelectionElement.java b/src/main/java/org/olat/core/gui/components/form/flexible/elements/MultipleSelectionElement.java index 70d19668c2c..832d54b90a5 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/elements/MultipleSelectionElement.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/elements/MultipleSelectionElement.java @@ -31,15 +31,11 @@ import java.util.Set; /** - * Description:<br> - * TODO: patrickb Class Description for MultipleSelectionElement * - * <P> * Initial Date: 04.01.2007 <br> * @author felix * @author patrickb */ - public interface MultipleSelectionElement extends SelectionElement { /** @@ -120,6 +116,21 @@ public interface MultipleSelectionElement extends SelectionElement { */ public void setEscapeHtml(boolean escapeHtml); + /** + * @return true if the state of a check box is changed only by ajax + * events and not by the submission of a form. + */ + public boolean isAjaxOnly(); + + /** + * Set to true if the state of the element need to be only + * changed by an ajax event and not by the submission of + * a form. + * + * @param ajaxOnlyMode + */ + public void setAjaxOnly(boolean ajaxOnlyMode); + public enum Layout { horizontal, vertical diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultipleSelectionElementImpl.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultipleSelectionElementImpl.java index 1108e637b3c..96f6fd4d66a 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultipleSelectionElementImpl.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultipleSelectionElementImpl.java @@ -33,6 +33,7 @@ import java.util.Set; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; +import org.olat.core.gui.components.form.flexible.impl.Form; import org.olat.core.gui.components.form.flexible.impl.FormItemImpl; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; @@ -59,6 +60,7 @@ public class MultipleSelectionElementImpl extends FormItemImpl implements Multip private final int columns; protected MultipleSelectionComponent component; private String[] original = null; + private boolean ajaxOnlyMode = false; private boolean originalIsDefined = false; private boolean escapeHtml = true; private boolean domReplacementWrapperRequired = true; @@ -91,6 +93,17 @@ public class MultipleSelectionElementImpl extends FormItemImpl implements Multip } } + @Override + public boolean isAjaxOnly() { + return ajaxOnlyMode; + } + + @Override + public void setAjaxOnly(boolean ajaxOnlyMode) { + this.ajaxOnlyMode = ajaxOnlyMode; + + } + public Layout getLayout() { return layout; } @@ -228,23 +241,33 @@ public class MultipleSelectionElementImpl extends FormItemImpl implements Multip @Override public void evalFormRequest(UserRequest ureq) { - if(!isEnabled()){ - //if element is visible as disabled it would be resetted - return; - } - // which one was selected? - // selection change? - // mark corresponding comps as dirty - String[] reqVals = getRootForm().getRequestParameterValues(getName()); - if (reqVals == null) { - // selection box? - reqVals = getRootForm().getRequestParameterValues(getName() + "_SELBOX"); - } - // - selected = new HashSet<String>(); - if (reqVals != null) { - for (int i = 0; i < reqVals.length; i++) { - selected.add(reqVals[i]); + Form form = getRootForm(); + if(isAjaxOnly()) { + String dispatchuri = form.getRequestParameter("dispatchuri"); + if(dispatchuri != null && dispatchuri.equals(component.getFormDispatchId())) { + String key = form.getRequestParameter("achkbox"); + String checked = form.getRequestParameter("checked"); + if("true".equals(checked)) { + selected.add(key); + } else if("false".equals(checked)) { + selected.remove(key); + } + } + } else if(isEnabled() ) { + // which one was selected? + // selection change? + // mark corresponding comps as dirty + String[] reqVals = form.getRequestParameterValues(getName()); + if (reqVals == null) { + // selection box? + reqVals = form.getRequestParameterValues(getName() + "_SELBOX"); + } + // + selected = new HashSet<String>(); + if (reqVals != null) { + for (int i = 0; i < reqVals.length; i++) { + selected.add(reqVals[i]); + } } } } diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultipleSelectionRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultipleSelectionRenderer.java index bfd9ea4ee23..883149da99b 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultipleSelectionRenderer.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultipleSelectionRenderer.java @@ -24,6 +24,7 @@ import org.olat.core.gui.components.Component; import org.olat.core.gui.components.DefaultComponentRenderer; import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement.Layout; import org.olat.core.gui.components.form.flexible.impl.FormJSHelper; +import org.olat.core.gui.components.form.flexible.impl.NameValuePair; import org.olat.core.gui.render.RenderResult; import org.olat.core.gui.render.Renderer; import org.olat.core.gui.render.StringOutput; @@ -143,6 +144,16 @@ public class MultipleSelectionRenderer extends DefaultComponentRenderer { } if(!stC.isEnabled() || !check.isEnabled()) { sb.append(" disabled='disabled' "); + } else if(stF.isAjaxOnly()) { + // The implementation is conservative as it send the state of the check box, + // this is especially useful if an issue of double evaluation appears. + sb.append(" onclick=\"javascript: this.checked ?") + .append(FormJSHelper.getXHRFnCallFor(stF.getRootForm(), stC.getFormDispatchId(), 1, false, false, false, + new NameValuePair("achkbox", key), new NameValuePair("checked", "true"))) + .append(" : ") + .append(FormJSHelper.getXHRFnCallFor(stF.getRootForm(), stC.getFormDispatchId(), 1, false, false, false, + new NameValuePair("achkbox", key), new NameValuePair("checked", "false"))) + .append(";\""); } else { //use the selection form dispatch id and not the one of the element! sb.append(FormJSHelper.getRawJSFor(check.getRootForm(), check.getSelectionElementFormDispatchId(), check.getAction())); diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java index dfd27dd3827..82e3de07474 100644 --- a/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java +++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java @@ -38,12 +38,14 @@ import org.olat.basesecurity.BaseSecurityModule; import org.olat.basesecurity.GroupRoles; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.persistence.DBFactory; +import org.olat.core.commons.persistence.SortKey; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement; import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter; +import org.olat.core.gui.components.form.flexible.elements.FlexiTableSortOptions; import org.olat.core.gui.components.form.flexible.elements.FormLink; import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; @@ -187,6 +189,7 @@ public class CheckListAssessmentController extends FormBasicController implement maxScore = (Float)config.get(MSCourseNode.CONFIG_KEY_SCORE_MAX); initForm(ureq); + reloadTable(); } @Override @@ -200,10 +203,13 @@ public class CheckListAssessmentController extends FormBasicController implement layoutCont.contextPut("dueDate", dueDate); } } - + + FlexiTableSortOptions options = new FlexiTableSortOptions(); FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); if(isAdministrativeUser) { - columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.username.i18nKey(), Cols.username.ordinal())); + options.setDefaultOrderBy(new SortKey(Cols.username.name(), true)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.username.i18nKey(), Cols.username.ordinal(), + true, Cols.username.name())); } int i=0; @@ -224,6 +230,9 @@ public class CheckListAssessmentController extends FormBasicController implement col = new DefaultFlexiColumnModel(true, userPropertyHandler.i18nColumnDescriptorLabelKey(), colIndex, true, propName); } columnsModel.addFlexiColumnModel(col); + if(options.getDefaultOrderBy() == null) { + options.setDefaultOrderBy(new SortKey(propName, true)); + } } } @@ -243,8 +252,7 @@ public class CheckListAssessmentController extends FormBasicController implement } columnsModel.addFlexiColumnModel(new StaticFlexiColumnModel("table.header.edit.checkbox", translate("table.header.edit.checkbox"), "edit")); - List<CheckListAssessmentRow> datas = loadDatas(); - model = new CheckListAssessmentDataModel(checkboxList, datas, columnsModel); + model = new CheckListAssessmentDataModel(checkboxList, new ArrayList<>(), columnsModel); table = uifactory.addTableElement(getWindowControl(), "checkbox-list", model, getTranslator(), formLayout); if(coachCourseEnv instanceof UserCourseEnvironmentImpl) { UserCourseEnvironmentImpl env = (UserCourseEnvironmentImpl)coachCourseEnv; @@ -260,6 +268,8 @@ public class CheckListAssessmentController extends FormBasicController implement } table.setExportEnabled(true); table.setCustomizeColumns(true); + FlexiTableSortOptions sortOptions = new FlexiTableSortOptions(); + table.setSortSettings(sortOptions); table.setAndLoadPersistedPreferences(ureq, "checklist-assessment"); pdfExportButton = uifactory.addFormLink("pdf.export", formLayout, Link.BUTTON); @@ -431,7 +441,13 @@ public class CheckListAssessmentController extends FormBasicController implement } super.formInnerEvent(ureq, source, event); } - + + @Override + protected void propagateDirtinessToContainer(FormItem fiSrc) { + if(!(fiSrc instanceof MultipleSelectionElement)) { + super.propagateDirtinessToContainer(fiSrc); + } + } @Override protected void event(UserRequest ureq, Controller source, Event event) { @@ -508,6 +524,8 @@ public class CheckListAssessmentController extends FormBasicController implement for(int i=0; i<numOfCheckbox; i++) { String checkName = "c" + i + "-" + row.getIdentityKey(); checkedEls[i] = uifactory.addCheckboxesHorizontal(checkName, null, flc, onKeys, onValues); + checkedEls[i].setAjaxOnly(true); + checkedEls[i].setDomReplacementWrapperRequired(false); if(checked != null && i<checked.length && checked[i] != null && checked[i].booleanValue()) { checkedEls[i].select(onKeys[0], true); } -- GitLab