Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    DynamicForm.setCanEdit(false) and declarative field-level canEdit bug

    Hi Isomorphic,

    please see this testcase (v10.0p_2015-04-23):
    BuiltInDS.java:
    Code:
    package com.smartgwt.sample.client;
    
    import java.util.LinkedHashMap;
    
    import com.google.gwt.core.client.EntryPoint;
    import com.smartgwt.client.core.KeyIdentifier;
    import com.smartgwt.client.data.Criteria;
    import com.smartgwt.client.data.DSCallback;
    import com.smartgwt.client.data.DSRequest;
    import com.smartgwt.client.data.DSResponse;
    import com.smartgwt.client.data.DataSource;
    import com.smartgwt.client.util.PageKeyHandler;
    import com.smartgwt.client.util.Page;
    import com.smartgwt.client.util.SC;
    import com.smartgwt.client.widgets.form.DynamicForm;
    import com.smartgwt.client.widgets.form.fields.SelectItem;
    import com.smartgwt.client.widgets.form.fields.SpinnerItem;
    import com.smartgwt.client.widgets.form.fields.TextItem;
    import com.smartgwt.client.widgets.layout.VStack;
    
    public class BuiltInDS implements EntryPoint {
    	private DynamicForm boundForm;
    	private SelectItem foobar;
    	private SpinnerItem salary;
    	private TextItem orgUnit;
    	private SelectItem gender;
    
    	public void onModuleLoad() {
    		KeyIdentifier debugKey = new KeyIdentifier();
    		debugKey.setCtrlKey(true);
    		debugKey.setKeyName("D");
    
    		Page.registerKey(debugKey, new PageKeyHandler() {
    			public void execute(String keyName) {
    				SC.showConsole();
    			}
    		});
    
    		VStack vStack = new VStack();
    		vStack.setLeft(175);
    		vStack.setTop(75);
    		vStack.setWidth("70%");
    		vStack.setMembersMargin(20);
    
    		boundForm = new DynamicForm() {
    			{
    				setDataSource(DataSource.get("employees"));
    				setCanEdit(false);
    
    				foobar = new SelectItem("GenderCSE");
    				LinkedHashMap<String, String> hm = new LinkedHashMap<String, String>();
    				hm.put("F", "Foo");
    				hm.put("B", "Bar");
    				hm.put("FB", "Foobar");
    				foobar.setValueMap(hm);
    				salary = new SpinnerItem("Salary");
    				orgUnit = new TextItem("OrgUnit");
    				gender = new SelectItem("Gender");
    
    				setFields(foobar, salary, orgUnit, gender);
    			}
    		};
    		vStack.addMember(boundForm);
    		vStack.draw();
    		boundForm.fetchData(new Criteria("EmployeeId", "4"), new DSCallback() {
    			@Override
    			public void execute(DSResponse dsResponse, Object data, DSRequest dsRequest) {
    				foobar.setValue("B");
    			}
    		});
    	}
    }
    employees.ds.xml addition:
    Code:
    <field name="GenderCSE" title="GenderCSE" canSave="false" [B]canEdit="true"[/B] customSelectExpression="Gender" />
    I have a similar setup in my application:
    • The readOnly-setting is dependent on how the form is called.
    • The field GenderCSE is never saved (not available as column in the DB), but only a customSelectExpression. Therefore is is defined in .ds.xml as canSave="false" canEdit="true". This is because I have event handlers on it and if I omit the canEdit="true", it is always non-editable because of the canSave="false".
    • Now, if I call the DynamicForm with setCanEdit(false) the foobar-SelectItem is enabled nevertheless.
    • This makes it possible for the user to use the field and also fire the onChange-event handlers, which I do not want.
    • My expectation is that the foobar-field is - like all the other fields - enabled when DynamicForm.setCanEdit(true) and readOnly when DynamicForm.setCanEdit(false).


    Best regards
    Blama
    Last edited by Blama; 27 Apr 2015, 02:05.

    #2
    canEdit set in the DataSource behaves like formItem.canEdit, overriding dynamicForm.canEdit for a specific item.

    Use setCanEdit(false) on the individual item to override the default provided by the DataSource.

    Comment


      #3
      Hi Isomorphic,

      after re-reading I agree that the behavior is according to the docs. But why does a ds.xml-field setting of canSave="false" imply canEdit="false"?
      If it was still null, DynamicForm.setCanEdit() could be used to control the behavior of all FormItems inside of a DynamicForm.

      Best regards
      Blama

      Comment


        #4
        If you set canSave:false the server is going to reject any attempt to save values, so it seems that *of course* the default UI should be non-editable. But perhaps we are missing the gist of the question.

        Comment


          #5
          Hi Isomorphic,

          I have a read-only field (either via Oracle virtual column or some CASE WHEN in a customSelectExpression) along with many normal (=writeable) table columns. This field must not be present in a ADD or UPDATE, therefore it has to be canSave="false". But I want to be able to use the field as FormItem source and have event handlers on the form item.

          Real world example:
          c_id, d_id, r_id, only one can be set.
          customSelectExpression="CASE WHEN c_id IS NOT NULL THEN 'C' WHEN....".
          I display this as SelectItem. Now on switch away from one the options I hide the respective x_id-FormItem, null its value and unhide another FormItem.

          But I have to explicitly have canEdit="true" because of the implicit canEdit="false" triggered by the canSave="false".
          Now, on DynamicForm.setCanEdit(false) the field is still active and its EventHandlers do unwanted things.
          What I'd have to do is to also call field.setCanEdit(false) (like you suggested in your first answer).

          My suggestion is to have canSave="false" not to imply canEdit="false".
          Alternatively: Is it allowed to explicitly unset canEdit in .ds.xml, meaning canEdit="null"?

          If both is not possible, I'm fine with that, too.

          Best regards
          Blama

          Comment


            #6
            As previously explained, canSave="false" definitely should cause editing to be disabled by default. The most common use case by far is a field that is always read-only or read-only for a particular user role, and no additional settings should be required to achieve this.

            For your much rarer case of a field that can't be written to but requires an active FormItem in some forms, there are multiple simple solutions:

            1. setCanEdit(true) explicitly on the FormItem (already identified) if it can ever appear in a form that can be made readOnly as a whole

            2. don't use canSave and either:
            a. reject the value server-side with a DMI
            b. use shouldSaveValue:false on the FormItem so values are never sent to the server. If values are actually sent due to a user trying to circumvent your security rules, they will fail to save harmlessly since the field has no database storage

            Comment

            Working...
            X