DisplayField - How to format for date?
I need to display a read only view of data. I've 开发者_运维技巧chosen the DisplayField component to do this. My problem is that I would like an easy way to call BasicForm.setValues(values)
and have a date string automagically render correctly in one of the displayFields. I haven't found anything that will do this for me (e.g. a renderer function), and am about to just format the date string manually prior to calling setValues(values)
. Is there some slick way to do this?
Thanks!
Ok if you are using a direct form load then you need to listen for the form's BasicForm 'actioncomplete' event. When this event fires the handler is supplied two arguments. The first is the BasicForm and the second argument is an Ext.form.Action object. We are specifically looking for an Ext.form.Action.Load object. From here we get access to the action's result.data object and we can massage the data values before this handler returns and the values are loaded into the form.
function fmtDate(sf, rec) {
if ( rec[sf] ) {
var dt = new Date(); dt.setTime(rec[sf] * 1000); return dt.format('l j F Y');
}
};
myForm.getForm().on({
actioncomplete: function(form, action) {
if (action.type === 'load') {
if (action.result.success) {
var data = action.result.data;
data.someFormattedDate = fmtDate('myDateTS', data);
} else {
//handle an error here
}
}
}
});
Now all you need in your form is a displayField named 'someFormattedDate' and Bob's your uncle (Aussie slang for it's all good). You can also achieve exactly the same thing by providing a 'success:' function to your myForm.getForm().load() call. See the ExtJS docs for Ext.form.Action.Load. Cheers, t00bs.
I ended up subclassing displayField. That seems to work best, but I wish there was an out-of-the-box fix for something as basic as displaying a formatted date. This is my first pass at it, so it is just an example.
FormattableDisplayField = Ext.extend(Ext.form.DisplayField, {
constructor:function(config) {
var config = config || {};
Ext.applyIf(config, {
dateFormat:'c',
type:null,
displayFormat:'M d, Y'
});
FormattableDisplayField.superclass.constructor.call(this, config);
},
setValue: function(value) {
if (! this.type) {
FormattableDisplayField.superclass.setValue(value);
}
else if (this.type == 'date') {
var parsedDate = Date.parseDate(value, this.dateFormat);
if (Ext.isDate(parsedDate)) {
this.setRawValue(parsedDate.format(this.displayFormat));
}
else {
this.setRawValue(value);
}
}
else if (this.formatter) {
var formattedValue = this.formatter(value);
this.setRawValue(formattedValue);
}
}
});Ext.reg('formattabledisplayfield', FormattableDisplayField);
I came across this same problem because I like to pass my dates around as Unix timestamps and I had a requirement to display them using various formats depending on context. Here's how I did it.
If you are loading the data via a store then you can use the convert function provided by Ext.data.Field. For example:
var fields = [
{name: 'sysTestedDateObj', mapping: 'sysTestedDateTS', type: 'date', dateFormat: 'timestamp'},
/** Converted Fields **/
{name: 'sysTestedDate', convert: function(v, rec){
return fmtDate('sysTestedDateTS', rec);
}},
{name: 'targetChangeStartDate', convert: function(v, rec){
return fmtDate('targetChangeStartDateTS', rec);
}},
{name: 'createDateTime', convert: function(v, rec){
return fmtDateTime('createDateTS', rec);
}},
{name: 'modifyDateTime', convert: function(v, rec){
return fmtDateTime('modifyDateTS', rec);
}},
];
var store = new Ext.data.JsonStore({
...
fields: fields
});
Here's some conversion functions:
function fmtDate(sf, rec) {
if ( rec[sf] ) {
var dt = new Date(); dt.setTime(rec[sf] * 1000); return dt.format('l j F Y');
}
};
function fmtDateShort(sf, rec) {
if ( rec[sf] ) {
var dt = new Date(); dt.setTime(rec[sf] * 1000); return dt.format('D j M Y');
}
};
function fmtDateTime(sf, rec) {
if ( rec[sf] ) {
var dt = new Date(); dt.setTime(rec[sf] * 1000); return dt.format('l j F Y h:i a');
}
};
function fmtDateTimeShort(sf, rec) {
if ( rec[sf] ) {
var dt = new Date(); dt.setTime(rec[sf] * 1000); return dt.format('D j M Y h:i a');
}
};
Where sf is the source field we are deriving the formatted date string from.
Note the following, it's important. The convert() function is presented with a copy of the data record as read by the reader (this is in the ExtJS docs). This means you can't use any mapped fields in your conversions. In the fields array above I have a field defined as,
{name: 'sysTestedDateObj', mapping: 'sysTestedDateTS', type: 'date', dateFormat: 'timestamp'}
So I'm creating the sysTestedDateObj date object from the sysTestedDateTS field and I've told the reader that I want it to give me a date object derived from an object containing a Unix timestamp. This is a nice object to have for later on but it won't be part of the data record passed to our conversion function.
Also note that a conversion function can reference fields in the record that are not defined for use by the store. In the example above I an using the field sysTestedDateTS in a conversion function because I know the server is supplying it in it's JSON response, yet because I haven't defined it in the fields array it won't be available via the store to the consuming component.
http://dev.sencha.com/deploy/dev/docs/?class=Ext.util.Format
I think dateRenderer is the renderer function that you are looking for?
Ext.form.field.Display.html#cfg-renderer
A function to transform the raw value for display in the field.
Ext.Date.html#method-format
Formats a date given the supplied format string.
var data = {
"OrderNo": "2017071200000246",
"Createtime": "2017/7/12 13:16:42"
}; // your read only data; or use bind store
var form = Ext.create({
xtype: 'form',
defaultType: 'displayfield',
defaults: {
labelWidth: 120,
labelSeparator: ':'
},
items: [
{ fieldLabel: 'Order Number', value: data.OrderNo },
{ fieldLabel: 'Create Time', value: data.Createtime,
renderer: function (value, field) {
var date = new Date(value);
var newVal = Ext.Date.format(date, 'Y-m-d H:i:s');
return newVal;
}
}
]
});
精彩评论