PDA

View Full Version : Example of using composite field of Date and Time fields as a grid column editor



anup
Sep 06, 2010, 2:18 PM
This is an example following on from this thread:
http://forums.ext.net/showthread.php?9898-Issues-using-CompositeField-of-DateField-and-TimeField-as-grid-column-Editor

Original problem:
- I was trying to figure out how I can edit data and time in the same column of an editable grid
- I tried a Composite field made up of Date and Time field.
- It kinda worked but the column needed to by dynamically resized when going into edit mode, and coming out of it.
- With help from the Ext.Net Dev team I was able to get it working
- So I posted a working sample.

But here I thought I'd post a slight modified version. The original sample I posted above had JavaScript in the various handlers. In this example below, it is the same JavaScript but moved into the script block so that the idea can be reused by both a grid generated by code behind and a grid generated with markup, more easily.

Important: The JavaScript itself is not final (needs more validation etc) but a useful pattern or structure perhaps.


<%@ Page Language="C#" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!ExtNet.IsAjaxRequest)
{
Store store = GridPanel1.Store.Primary;
store.DataSource = new object[] {
new object[] {"Joe", DateTime.Now},
new object[] {"Bob", DateTime.Now},
new object[] {"Fred", DateTime.Now}
};
store.DataBind();
}
}
</script>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Ext.Net Example of CompositeField for Date and Time entry</title>

<script type="text/javascript">
var Examples = {
dateTime: function (value) {
return value.format ? value.format('Y-m-d H:i:s') : value;
},

dateTimeCompositeField: {
beforeStartEdit: function (gridPanel) {
var columnModel = gridPanel.getColumnModel();

this.originalWidthBeforeEditing = columnModel.getColumnWidth(this.col);
columnModel.setColumnWidth(this.col, 150);
},

startEdit: function (value) {
var items = this.field.items,
dateField = items.map[items.keys[0]],
timeField = items.map[items.keys[1]];

dateField.setValue(value.format('Y-m-d'));
timeField.setValue(value.format('H:i:s'));
},

beforeComplete: function (gridPanel) {
var items = this.field.items,
dateField = items.map[items.keys[0]],
timeField = items.map[items.keys[1]],
newDate = dateField.getValue(),
newTime = Date.parseDate(timeField.getValue(), 'H:i:s');

newDate.setHours(newTime.getHours());
newDate.setMinutes(newTime.getMinutes());
newDate.setSeconds(newTime.getSeconds());
this.setValue(newDate);
gridPanel.getColumnModel().setColumnWidth(this.col , this.originalWidthBeforeEditing);
},

cancelEdit: function (gridPanel) {
gridPanel.getColumnModel().setColumnWidth(this.col , this.originalWidthBeforeEditing);
}
}
}
</script>
</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" />
<ext:GridPanel ID="GridPanel1" runat="server" AutoHeight="true">
<Store>
<ext:Store ID="Store1" runat="server">
<Reader>
<ext:ArrayReader>
<Fields>
<ext:RecordField Name="Name" />
<ext:RecordField Name="LastUpdated" Type="Date" />
</Fields>
</ext:ArrayReader>
</Reader>
</ext:Store>
</Store>
<ColumnModel ID="ColumnModel1" runat="server">
<Columns>
<ext:Column Header="Name" DataIndex="Name" />
<ext:Column Header="Last Updated" DataIndex="LastUpdated" Width="110">
<Renderer Fn="Examples.dateTime" />
<Editor>
<ext:CompositeField ID="DateField1" runat="server">
<Items>
<ext:DateField ID="CompositeDateField1" runat="server" />
<ext:TextField ID="CompositeTimeField1" runat="server" />
</Items>
</ext:CompositeField>
</Editor>
<EditorOptions AllowBlur="false">
<Listeners>
<BeforeStartEdit Handler="Examples.dateTimeCompositeField.beforeStartEdit.ca ll(this, #{GridPanel1});" />
<StartEdit Handler="Examples.dateTimeCompositeField.startEdit.call(thi s, value);" />
<BeforeComplete Handler="Examples.dateTimeCompositeField.beforeComplete.cal l(this, #{GridPanel1});" />
<CancelEdit Handler="Examples.dateTimeCompositeField.cancelEdit.call(th is, #{GridPanel1});" />
</Listeners>
</EditorOptions>
</ext:Column>
</Columns>
</ColumnModel>
</ext:GridPanel>
</form>
</body>
</html>In the listeners, you will see I have used JavaScript's "call" method so that I can continue using "this" in the actual method (easier to spot in color-coded text editors and Visual Studio!).

Does anyone know of way to use "Fn" instead of "Handler" and pass in the GridPanel? The reason I ask is that using Handler creates an inline function, and in my case I just want to call another function, so it would be nice to avoid creating the inline function just for that). I've looked at the ExtJs documentation for startEdit and some of the other handlers, and it looks like the arguments they receive are fixed, so I am guessing we can't pass GridPanel to the method this way?

anup
Sep 06, 2010, 3:08 PM
I should add a note here that in the composite field, the time bit is a TextField, not a TimeField, because (at least in my case) i need hours, minutes and seconds. If you don't need seconds then you can probably modify it to work with a TimeField. You will likely need to modify the JavaScript accordingly, because where "newTime" is being set, that may have to change.

Hilariously, I caught myself out on this as I was using the above example to create a code behind version and was adding a TimeField instead of a TextField :o

haiduong87
Sep 27, 2010, 4:23 AM
Can you show me how to add new record (have a date field in store) with javascript?

Daniil
Jul 24, 2012, 8:40 PM
Here is the related discussion regarding Ext.NET v2.
http://forums.ext.net/showthread.php?20189