Announcement

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

    IE converts CR+LF to LF in TextAreaItem

    Hi,

    IE seems to convert CR+LF to just LF in TextAreaItems. It also fires the forms ItemChangedHandler when editing such record on valuesManager.editRecord.

    Affected environment
    * 5.0p latest nightlies (2015-02-02)
    * IE 11.0.9600.17501

    The issue is not reproducable when using Chromium on Ubuntu.

    In the test case below you will see, that the forms ItemChangedHandler fires just on issuing valuesManager.editRecord(record), when record contains CRLF values in a field that is shown in a TextAreaItem. The ItemChangedHandler does NOT fire, when in another record the same field just contains LF-only linebreaks.

    We need those CRLF linebreaks and do not want the values changed. Also the user is irritated since the we show a dirty flag triggered by the ItemChangedHandler, but the user has not changed the data and is not able to see any change since LF and CRLF do not look different.

    TIA
    Andre

    Code:
    package de.scai.client.ticket1598.defect;
    
    import com.google.gwt.core.client.EntryPoint;
    import com.google.gwt.core.client.GWT;
    import com.google.gwt.user.client.ui.RootPanel;
    import com.smartgwt.client.data.*;
    import com.smartgwt.client.data.fields.DataSourceIntegerField;
    import com.smartgwt.client.data.fields.DataSourceTextField;
    import com.smartgwt.client.util.SC;
    import com.smartgwt.client.widgets.Button;
    import com.smartgwt.client.widgets.events.ClickEvent;
    import com.smartgwt.client.widgets.events.ClickHandler;
    import com.smartgwt.client.widgets.form.DynamicForm;
    import com.smartgwt.client.widgets.form.ValuesManager;
    import com.smartgwt.client.widgets.form.events.ItemChangedEvent;
    import com.smartgwt.client.widgets.form.events.ItemChangedHandler;
    import com.smartgwt.client.widgets.form.fields.TextAreaItem;
    import com.smartgwt.client.widgets.form.fields.TextItem;
    import com.smartgwt.client.widgets.grid.ListGridRecord;
    import com.smartgwt.client.widgets.layout.Layout;
    import com.smartgwt.client.widgets.layout.VLayout;
    
    public class DemoTicket1598 implements EntryPoint {
    
        private Layout layoutRoot;
    
        /**
         * This is the entry point method.
         */
        public void onModuleLoad() {
            layoutRoot = new VLayout();
    
            RootPanel.get("gwtContainer").add(layoutRoot);
    
            run();
        }
    
        private class UserDataSource extends DataSource {
            public static final String FIELDNAME_ID = "FIELD_id";
            public static final String FIELDNAME_USERNAME = "FIELD_userName";
            public static final String FIELDNAME_COMMENT = "FIELD_comment";
    
            protected DataSourceIntegerField id = new DataSourceIntegerField(FIELDNAME_ID, "Id");
            protected DataSourceTextField userName = new DataSourceTextField(FIELDNAME_USERNAME, "Username");
            protected DataSourceTextField comment = new DataSourceTextField(FIELDNAME_COMMENT, "Comment");
            private ListGridRecord listGridRecordError = new ListGridRecord();
            private ListGridRecord listGridRecordOK = new ListGridRecord();
    
            private UserDataSource() {
                super();
                id.setPrimaryKey(true);
                addField(id);
                addField(userName);
                addField(comment);
                setClientOnly(true);
                setCacheAllData(true);
                createRecord();
            }
    
            public void createRecord() {
                final ListGridRecord[] data = new ListGridRecord[2];
                listGridRecordError.setAttribute(FIELDNAME_ID, 1);
                listGridRecordError.setAttribute(FIELDNAME_USERNAME, "testUser1");
                listGridRecordError.setAttribute(FIELDNAME_COMMENT, "Problem will show since multiple CRLF are here\r\nRow2\r\n\r\nRow4");
                data[0] = listGridRecordError;
    
                listGridRecordOK.setAttribute(FIELDNAME_ID, 2);
                listGridRecordOK.setAttribute(FIELDNAME_USERNAME, "testUser2");
                listGridRecordOK.setAttribute(FIELDNAME_COMMENT, "No Problem\nsince it contains only LF");
                data[1] = listGridRecordOK;
    
                setCacheData(data);
            }
    
            public Record getRecordError() {
                return listGridRecordError;
            }
            public Record getRecordOK() {
                return listGridRecordOK;
            }
    
        }
    
        private class UserDynamicForm extends DynamicForm {
            protected TextItem userName = new TextItem(UserDataSource.FIELDNAME_USERNAME, "Username");
            protected TextAreaItem comment = new TextAreaItem(UserDataSource.FIELDNAME_COMMENT, "Comment");
    
            protected void init() {
    
                this.setFields(
                        userName,
                        comment
                );
            }
        }
    
        private UserDataSource userDataSource;
        private ValuesManager valuesManager;
        private UserDynamicForm userDynamicForm;
        private Button editOK;
        private Button editError;
    
        public void run() {
    
            userDataSource = new UserDataSource();
    
            valuesManager = new ValuesManager();
            valuesManager.setDataSource(userDataSource);
    
            initForm();
    
            Layout layout = new VLayout();
            layout.addMember(userDynamicForm);
            layoutRoot.addMember(layout);
    
            editOK = new Button("Edit OK");
            editOK.addClickHandler(new ClickHandler() {
                @Override
                public void onClick(ClickEvent clickEvent) {
                    Record record = userDataSource.getRecordOK();
                    valuesManager.editRecord(record);
                }
            });
            layout.addMember(editOK);
    
            editError = new Button("Edit Error");
            editError.addClickHandler(new ClickHandler() {
                @Override
                public void onClick(ClickEvent clickEvent) {
                    Record record = userDataSource.getRecordError();
                    valuesManager.editRecord(record);
                }
            });
            layout.addMember(editError);
    
            userDynamicForm.addItemChangedHandler(new ItemChangedHandler() {
                @Override
                public void onItemChanged(ItemChangedEvent event) {
                    SC.say(valuesManager.getChangedValues().toString());
                }
            });
    
            valuesManager.addMember(userDynamicForm);
        }
    
        private void initForm() {
            userDynamicForm = new UserDynamicForm();
            userDynamicForm.init();
            userDynamicForm.setDataSource(userDataSource);
        }
    
    }

    #2
    What the browser is doing here is producing text that follows the conventions of the platform (Windows vs Linux vs MacOS).

    If you have a particular convention you want to use for storage, you should transform the value after you've received it from the TextAreaItem control (and likewise, base your change detection on the transformed value).

    Comment


      #3
      Hmm, are you sure, that IE *should* convert from CR+LF to LF?

      If any conversion would be expected, I'd at least expected it to be the other way around (LF -> CRLF, i.e. "Unix to Windows"), but that does not happen.

      Additionally, the problem does also NOT appear in Firefox 35.0.1 on Windows 7/64.

      There seems to be more to it. Could you please check?

      Comment


        #4
        We agree that the reasoning of the IE team is sometimes a bit odd and that this is an area where web standards are vague.

        If you like, you can create a non-SmartGWT test case and look at the native behavior.

        Beyond that, if you would like SmartGWT to have some built-in capabilities of normalizing TextAreaItem end-of-line characters, consider Feature Sponsorship.

        Comment


          #5
          OK, honestly I came not to think that this would already be native behaviour :)

          If it is, it would be nice if SmartGWT would hide that behaviour as it already does in many other cases successfully. ;)

          We'll check the native behaviour and then see if we can come up with a workaround or will go for a Feature Sponsorship.

          Thank you for looking into this.

          Comment

          Working...
          X