Announcement

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

    Time self-update after finish row edit in ListGrid

    Hello

    I use:
    SmartClient Version: SNAPSHOT_v8.3d_2012-06-12/LGPL Development Only (built 2012-06-12)
    browser IE8

    After I finish edit a row in ListGrid and select another row the time in updated DateTime fields self-updates with new values.
    For example if I enter "2012-06-21 12:00:00" it becomes "2012-06-21 14:00:00" (my current timezone is UTC+2).

    How can I avoid this useless ListGrid behavior ?

    Thanks in advance
    Attached Files

    #2
    This will happen if your fields are not declared to be the right type (eg date instead of datetime) or if your server is not saving the value sent by the client correctly. See the Date and Time Storage overview, and post runnable code for more troubleshooting advice.

    Comment


      #3
      Thank you to point me to Date and Time Storage overview. I have learned it in addition to many posts on this site. Unfortunately it does not clarify the situation for me. At the moment I use RestDataSource but when I was using GWT-RPC I experienced the same problem with datetime field. Thus it looks like the root cause lies in code close by my listGrid.

      listGrid fields defined as:

      Code:
      ListGridField activityStartField = new ListGridField("activityStart");
      ListGridField activityFinishField = new istGridField("activityFinish");
      DataSource class extends RestDataSource and has constructor like this

      Code:
      public BasicRestDataSource(String serviceName) {
      	super();
        
      	setServiceName(serviceName);
        
      	setAddGlobalId(false);
      	setClientOnly(false);
        
      	setDataFormat(DSDataFormat.XML);
        
      	OperationBinding fetch = new OperationBinding();
      	fetch.setOperationType(DSOperationType.FETCH);
      	fetch.setDataProtocol(DSProtocol.POSTMESSAGE);
      	OperationBinding add = new OperationBinding();
      	add.setOperationType(DSOperationType.ADD);
      	add.setDataProtocol(DSProtocol.POSTMESSAGE);
      	OperationBinding update = new OperationBinding();
      	update.setOperationType(DSOperationType.UPDATE);
      	update.setDataProtocol(DSProtocol.POSTMESSAGE);
      	OperationBinding remove = new OperationBinding();
      	remove.setOperationType(DSOperationType.REMOVE);
      	remove.setDataProtocol(DSProtocol.POSTMESSAGE);
      	setOperationBindings(fetch, add, update, remove);
        
      	setFetchDataURL(uri + "/" + serviceName + "/fetch/");
      	setAddDataURL(uri + "/" + serviceName + "/add/");
      	setUpdateDataURL(uri + "/" + serviceName + "/update/");
      	setRemoveDataURL(uri + "/" + serviceName + "/remove/");
      }
      Fields definition:

      Code:
      DataSourceDateTimeField activityStartField = new DataSourceDateTimeField("activityStart");
      activityStartField.setRequired(true);
      addField(activityStartField);
      
      DataSourceDateTimeField activityFinishField = new DataSourceDateTimeField("activityFinish");
      activityFinishField.setRequired(true);
      addField(activityFinishField);
      Application entry point has following datetime configuration

      Code:
      public void onModuleLoad() {
        
      	final String DATETIMEFORMAT = "yyyy-MM-dd HH:mm:ss";
      	DateUtil.setAdjustForDST(true);
      	
      	DateUtil.setDateInputFormat(DATETIMEFORMAT);
        
      	DateUtil.setShortDateDisplayFormatter(new DateDisplayFormatter() {
      		@Override
      		public String format(Date date) {
      			if (date == null)
      				return null;
      			final DateTimeFormat dateFormatter = DateTimeFormat
      					.getFormat("yyyy-MM-dd");
      			String format = dateFormatter.format(date);
      			return format;
      		}
      	});
      	DateUtil.setShortDatetimeDisplayFormatter(new DateDisplayFormatter() {
      		public String format(Date date) {
      			if (date == null)
      				return null;
      			final DateTimeFormat dateFormatter = DateTimeFormat
      					.getFormat(DATETIMEFORMAT);
      			String format = dateFormatter.format(date);
      			String format = dateFormatter.format(date, TimeZone.createTimeZone(0));
      			return format;
      		}
      	});
        
          ....
      }

      Comment


        #4
        At a glance it looks like something is wrong with your formatter and how it deals with timezones. If you remove it, you may see the problem go away, then you can analyze what's wrong with the formatting logic.

        Also, in the latest docs, the DateFormatAndStorage overview has a new section on troubleshooting since so many people have difficulty here - here are the raw docs, which will soon appear in nightlies:

        // <h3>Troubleshooting Date and Time values</h3>
        // <P>
        // Date and time storage and timezones can be confusing, and Isomorphic receives a steady
        // stream of false bug reports from users that are incorrectly analyzing logs and diagnostics.
        // Please consider the following points when troubleshooting issues such as date values
        // changing to a different day, or datetime value shifting when saved and reloaded:
        // <P>
        // <h4>1. compare values for "datetime" fields via date.getTime()</h4>
        // <P>
        // Whenever you use Date.toString() (client or server-side) the value you get is based on the
        // server or browser timezone.
        // <P>
        // Perhaps you are troubleshooting an issue with datetimes and you try to log the value of a
        // Date like this:
        // <pre>
        // Date someDate = &lt;<i>some expression</i>&gt;;
        // log("date value is: " + someDate);
        // </pre>
        // Code like this will show the datetime value in the server's timezone if executed
        // server-side, and in the client's timezone if executed client-side. If they are in different
        // timezones, the hour or day will be different, <b>whereas the actual datetime value -
        // milliseconds since epoch as retrieved by Date.getTime() - is the same</b>. To correctly
        // compare two datetime values, compare the result of getTime().
        // <P>
        // <h4>2. "date" and "time" field values <b>cannot</b> be compared via getTime()</h4>
        // <P>
        // This is the inverse situation as for "datetime" values. As explained above, "date" values
        // have no meaningful values for time fields (hours/minutes/seconds) and "time" values have no
        // meaningful values for date fields (month/day/year). Here, the result of Date.getTime() is
        // not meaningful, and values should be compared via getHours(), getMonth() et al.
        // <P>
        // <h4>3. the display timezone does not affect Date.getHours(), Date.getDay() et al</h4>
        // <P>
        // If you've called setDefaultDisplayTimezone() to cause all datetime values to be rendered in
        // a particular timezone, this does not affect the return values of Date.getHours(), which will
        // still return values for the browser's current timezone. Hence it is not a bug if you have a
        // "datetime" value which is displaying as 4am, but getHours() returns 10 or some other
        // number. This just reflects the timezone offset between the timezone passed to
        // setDefaultDisplayTimezone() and the browser's local timezone.
        // <P>
        // <h4>4. use correct DataSourceField types and use the matching FormItem type</h4>
        // <P>
        // If you declare a field as type "date" but values you provide actually contain specific
        // hours, minutes and seconds, these will not be preserved. The system will discard or reset
        // the hours, minutes and seconds in the course of serialization or editing. Likewise
        // if you declare a field as type "time" but actually provide values where year, month and day
        // have meaning, these values will be dropped.
        // <P>
        // Similarly, DateItem expects values for "date" fields, TimeItem expects values for "time"
        // fields, and DateTimeItem expects values for "datetime" fields. Providing the wrong type of
        // value to a control, such as providing a value from a "datetime" field to a DateItem, will
        // have unspecified results.
        // <P>
        // <var class="smartclient">
        // If you want to take the date and time aspects of a "datetime" value and edit them in separate
        // FormItems, use +link{Date.getLogicalDateOnly()} and +link{Date.getLogicalTimeOnly()} to
        // split a datetime value into date and time values, and use
        // +link{Date.combineLogicalDateAndTime()} to re-combine such values. Otherwise it is very
        // easy to make mistakes related to timezone offsets.
        // </var>
        // <var class="smartgwt">
        // If you want to take the date and time aspects of a "datetime" value and edit them in separate
        // FormItems, use
        // <code>getLogicalDateOnly()</code> and <code>DateUtil.getLogicalTimeOnly()</code> to
        // split a datetime value into date and time values, and use
        // <code>DateUtil.combineLogicalDateAndTime()</code> to re-combine
        // such values. Otherwise it is very
        // easy to make mistakes related to timezone offsets.
        // </var>
        // <P>
        // <h4>5. check data at every phase when troubleshooting</h4>
        // <P>
        // If you're having a problem with round-tripping "datetime" values or "date" values shifting
        // to another day, you need to isolate the problem to a specific layer. Bearing in mind the
        // techniques above for comparing values, you potentially need to look at any/all of the
        // following:
        // <ol>
        // <li> what value do I have on the server-side before it's sent to the client?
        // <li> what value is being transmitted to the client? (use the RPC Tab of the Developer
        // Console to see the actual data sent)
        // <ul>
        // <li> was the value shifted to a different time/date by my serialization approach?
        // <li> does it have the right format? (see above for correct JSON/XML formats)
        // </ul>
        // <li> what value do I have on the client before it gets to any widgets (eg, do a direct call
        // to +link{DataSource.fetchData()} and inspect the data in the callback)
        // <li> what value does the FormItem or other editing widget report before saving is attempted?
        // <li> what value is reported right before the value is serialized for transmission to the
        // server (+link{DataSource.transformRequest()} is a good place to check)
        // <li> what value is being transmitted to the server? (use the RPC tab - same concerns as for
        // server-to-client transmission above)
        // <li> what value does the server have after de-serialization, before saving to the database
        // or other permanent storage?
        // <li> what value is sent to the database or permanent storage? If generating SQL or another
        // similar query language, does the value in the SQL statement include an explicit timezone?
        // If not, how will the database interpret it?
        // </ol>
        //

        Comment


          #5
          Isomorphic, you are right. When I remove all formatting the problem goes away and appears again as only I put formatting code back.

          If I set DATETIMEFORMAT = "yyyy-MM-dd HH:mm" it just reset any time to 12:00 after I finish edit the row:
          Code:
          final String DATETIMEFORMAT = "yyyy-MM-dd HH:mm";
          DateUtil.setAdjustForDST(true);
          
          DateUtil.setShortDatetimeDisplayFormatter(new DateDisplayFormatter() {
          	public String format(Date date) {
          		if (date == null)
          			return null;
          		final DateTimeFormat dateFormatter = DateTimeFormat
          				.getFormat(DATETIMEFORMAT);
          		String format = dateFormatter.format(date);
          
          		return format;
          	}
          });
          I also played around deprecated DateUtil.setShortDatetimeDisplayFormat but experienced different kind of bugs as well (like "Must be a date" alert).

          Thus I haven't found any possibility to use any other datetime format except US.

          Is it bug or could you please give formatter example for proper handling "yyyy-MM-dd HH:mm" values in application?
          Last edited by Oleg; 22 Jun 2012, 03:48.

          Comment


            #6
            It's not a bug (obviously).

            If you have not setDefaultDisplayTimezone() then datetime values are displayed in the browser's local timezone. When using DateTimeFormat be sure to format in the current timezone, or in case, match whatever timezone you have passed to setDefaultDisplayTimezone().

            Comment


              #7
              Isomorphic, thank you for the help!
              It seems the cause was wrong values passed to setDateInputFormat method
              After I replaced it with
              Code:
               
              DateUtil.setDateInputFormat("YMD");
              the problem has gone.

              Comment

              Working...
              X