package com.smartgwt.sample.showcase.client.forms; import com.google.gwt.core.client.JavaScriptObject; 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.data.DataSourceField; import com.smartgwt.client.data.Record; import com.smartgwt.client.data.RecordList; import com.smartgwt.client.types.FieldType; import com.smartgwt.client.types.SortDirection; import com.smartgwt.client.util.DateUtil; import com.smartgwt.client.util.JSONEncoder; import com.smartgwt.client.util.SC; import com.smartgwt.client.util.StringUtil; import com.smartgwt.client.widgets.Canvas; import com.smartgwt.client.widgets.form.DynamicForm; import com.smartgwt.client.widgets.form.fields.ButtonItem; import com.smartgwt.client.widgets.form.fields.CanvasItem; import com.smartgwt.client.widgets.form.fields.DateItem; import com.smartgwt.client.widgets.form.fields.FormItem; import com.smartgwt.client.widgets.form.fields.StaticTextItem; import com.smartgwt.client.widgets.form.fields.events.FormItemInitHandler; import com.smartgwt.client.widgets.form.fields.events.ShowValueEvent; import com.smartgwt.client.widgets.form.fields.events.ShowValueHandler; import com.smartgwt.client.widgets.grid.ListGrid; import com.smartgwt.client.widgets.grid.ListGridField; import com.smartgwt.client.widgets.grid.ListGridRecord; import com.smartgwt.client.widgets.grid.events.CellSavedEvent; import com.smartgwt.client.widgets.grid.events.CellSavedHandler; import com.smartgwt.sample.showcase.client.PanelFactory; import com.smartgwt.sample.showcase.client.ShowcasePanel; public class NestedEditorSample extends ShowcasePanel { private static final String DESCRIPTION = "<p>This example shows a reusable CanvasItem that edits nested data structures.</p>" + "<p>Here, a record representing an Order contains multiple OrderItem records — " + "in the Record for an Order the \"items\" field value is set to an Array of Records " + "representing OrderItems.</p>" + "<p>The CanvasItem embeds an editable ListGrid to provide an editing interaction " + "for the OrderItems right in the midst of the form. It can be used with any " + "DataSource that has nested records.</p>"; public static class Factory implements PanelFactory { private String id; public Canvas create() { NestedEditorSample panel = new NestedEditorSample(); id = panel.getID(); return panel; } public String getID() { return id; } public String getDescription() { return DESCRIPTION; } } protected boolean isTopIntro() { return true; } public class GridEditorItem extends CanvasItem { GridEditorItem (String name) { super(name); setWidth("*"); setHeight("*"); setColSpan("*"); setEndRow(true); setStartRow(true); // this is going to be an editable data item setShouldSaveValue(true); setInitHandler(new FormItemInitHandler() { @Override public void onInit(FormItem item) { ListGrid grid = new ListGrid(); // dataSource and fields to use, provided to a listGridItem as // listGridItem.gridDataSource and optional gridFields grid.setDataSource(getGridDataSource()); if (gridFields != null) grid.setFields(getGridFields()); if (gridSortField != null) grid.setSortField(getGridSortField()); grid.setSortDirection(SortDirection.ASCENDING); // The form item's data is set to a list of records RecordList value = (RecordList) item.getValue(); if (value != null) grid.setData(value); grid.setCanEdit(true); grid.setSaveLocally(true); grid.addCellSavedHandler(new CellSavedHandler() { @Override public void onCellSaved(CellSavedEvent event) { ListGrid grid = (ListGrid) event.getSource(); GridEditorItem item = (GridEditorItem) grid.getCanvasItem(); RecordList data = grid.getDataAsRecordList(); item.storeValue(data); if (item.getGridSortField() == null) return; grid.sort(item.getGridSortField(), SortDirection.ASCENDING); } }); setCanvas(grid); addShowValueHandler(new ShowValueHandler() { @Override public void onShowValue(ShowValueEvent event) { ListGrid grid = (ListGrid)((CanvasItem)event.getSource()).getCanvas(); RecordList records = event.getDataValueAsRecordList(); if (records != null && grid != null) grid.setData(records); } }); } }); } private DataSource gridDataSource; public DataSource getGridDataSource() { return this.gridDataSource; } public void setGridDataSource(DataSource gridDataSource) { this.gridDataSource = gridDataSource; } private ListGridField[] gridFields; public ListGridField[] getGridFields() { return gridFields; } public void setGridFields(ListGridField... gridFields) { this.gridFields = gridFields; } private String gridSortField; public String getGridSortField() { return gridSortField; } public void setGridSortField(String gridSortField) { this.gridSortField = gridSortField; } }; public Canvas getViewPanel() { // Define a couple of simple nested dataSources. Make these client-only for simplicity DataSource orderItemDS = getOrderItemDS(); DataSource orderDS = getOrderDS(); DynamicForm exampleForm = new DynamicForm(); exampleForm.setID("exampleForm"); exampleForm.setWidth(350); exampleForm.setHeight(350); exampleForm.setDataSource(orderDS); StaticTextItem orderID = new StaticTextItem("orderID"); DateItem orderDate = new DateItem("orderDate"); GridEditorItem items = new GridEditorItem("items"); items.setShowTitle(false); items.setGridDataSource(orderItemDS); ListGridField itemDescription = new ListGridField("itemDescription"); ListGridField unitPrice = new ListGridField("unitPrice"); items.setGridFields(itemDescription, unitPrice); items.setGridSortField("itemDescription"); ButtonItem saveBtn = new ButtonItem("Save"); saveBtn.addClickHandler(new com.smartgwt.client.widgets.form.fields.events.ClickHandler() { @Override public void onClick(com.smartgwt.client.widgets.form.fields.events.ClickEvent event) { event.getForm().saveData(new DSCallback() { @Override public void execute(DSResponse response, Object rawData, DSRequest request) { Record rec = response.getData()[0]; JavaScriptObject rawItems = rec.getAttributeAsJavaScriptObject("items"); String html = StringUtil.asHTML(new JSONEncoder().encode(rawItems)); SC.say("Record saved with items:" + html); } }); } }); exampleForm.setItems(orderID, orderDate, items, saveBtn); Criteria orderCriteria = new Criteria(); orderCriteria.addCriteria("orderID", 1); orderDS.fetchData(orderCriteria, new DSCallback() { @Override public void execute(DSResponse response, Object rawData, DSRequest request) { DynamicForm exampleForm = (DynamicForm) Canvas.getById("exampleForm"); exampleForm.editRecord(response.getData()[0]); } }); return exampleForm; } private DataSource orderItemDS; private DataSource getOrderItemDS () { if (orderItemDS != null) return orderItemDS; orderItemDS = new DataSource(); orderItemDS.setClientOnly(true); DataSourceField pkField = new DataSourceField("pk", FieldType.SEQUENCE); pkField.setPrimaryKey(true); DataSourceField orderID = new DataSourceField("orderID", FieldType.INTEGER); orderID.setCanEdit(false); DataSourceField itemDescription = new DataSourceField("itemDescription", FieldType.TEXT); DataSourceField unitPrice = new DataSourceField("unitPrice", FieldType.FLOAT); orderItemDS.setFields(pkField, orderID, itemDescription, unitPrice); // No need to populate with test data - this is a schema only - the data is // nested directly in each order record. return orderItemDS; } private RecordList orderItemData; private RecordList getOrderItemData(int orderID) { if (orderItemData == null) { orderItemData = new RecordList(); orderItemData.addList(new ListGridRecord[] { new ListGridRecord () {{ setAttribute("pk", 0); setAttribute("orderID", 0); setAttribute("itemDescription", "Yellow Widget"); setAttribute("unitPrice", 23.01); }}, new ListGridRecord () {{ setAttribute("pk", 1); setAttribute("orderID", 0); setAttribute("itemDescription", "Green Widget"); setAttribute("unitPrice", 28.99); }}, new ListGridRecord () {{ setAttribute("pk", 2); setAttribute("orderID", 1); setAttribute("itemDescription", "Red Widget"); setAttribute("unitPrice", 100); }}, new ListGridRecord () {{ setAttribute("pk", 3); setAttribute("orderID", 1); setAttribute("itemDescription", "Orange Widget"); setAttribute("unitPrice", 48.22); }}, new ListGridRecord () {{ setAttribute("pk", 4); setAttribute("orderID", 2); setAttribute("itemDescription", "Yellow Widget"); setAttribute("unitPrice", 23.01); }} }); } return new RecordList(orderItemData.findAll("orderID", orderID)); } private DataSource orderDS; private DataSource getOrderDS () { if (orderDS != null) return orderDS; orderDS = new DataSource(); orderDS.setClientOnly(true); DataSourceField orderID = new DataSourceField("orderID", FieldType.SEQUENCE); orderID.setPrimaryKey(true); DataSourceField customerName = new DataSourceField("customerName", FieldType.TEXT); DataSourceField orderDate = new DataSourceField("orderDate", FieldType.DATE); DataSourceField items = new DataSourceField(); items.setName("items"); items.setTypeAsDataSource(getOrderItemDS()); items.setMultiple(true); orderDS.setFields(orderID, customerName, orderDate, items); orderDS.setTestData(getOrderData()); return orderDS; } private ListGridRecord[] getOrderData () { ListGridRecord[] orderData = new ListGridRecord[] { new ListGridRecord() {{ setAttribute("orderID", 0); setAttribute("customerName", "Richard Jones"); setAttribute("orderDate", DateUtil.parseInput("11/01/2011")); setAttribute("items", getOrderItemData(0)); }}, new ListGridRecord() {{ setAttribute("orderID", 1); setAttribute("customerName", "Sarah Holden"); setAttribute("orderDate", DateUtil.parseInput("02/04/2011")); setAttribute("items", getOrderItemData(1)); }}, new ListGridRecord() {{ setAttribute("orderID", 2); setAttribute("customerName", "James Edwards"); setAttribute("orderDate", DateUtil.parseInput("04/29/2011")); setAttribute("items", getOrderItemData(2)); }} }; return orderData; } public String getIntro() { return DESCRIPTION; } }