Hi Isomorphic,
I implement a similar Master-Detail example that appear in Server Examples / Transactions, embedded in a similar schema of the Office Supply Items with Items Details that you use in the Applications – Office Supply Catalog.
The add and delete options is perfect. My problem is with update option.
When I create (add) a campo, I provide a campo data and add some division. If I want to delete some division, I don’t have any problem, makinga click in remove icon. My detail (ListGrid) has enabled the option canRemoveRecords.
When I remove (del) a campo, I select a row from header with, and click the right boton. Its run ok.
When I want to update a campo, I read a campo and division data, and display it. I can update a campo data without problems. But my problem is when I want to remove a previous detail records
(that exist in the database for that campo). The record is removed from database but the grid is not refresh. I read at detail the thread http://forums.smartclient.com/showthread.php?t=344&highlight=Start+empty+listgrid and I am try with autoSaveEdits (true and false) and saveAllEdits (true and false) without success.
I enclose the js and the DMI
The detail datasource is:
The detail DMI is:
Please help me to resolve this problem
I implement a similar Master-Detail example that appear in Server Examples / Transactions, embedded in a similar schema of the Office Supply Items with Items Details that you use in the Applications – Office Supply Catalog.
The add and delete options is perfect. My problem is with update option.
When I create (add) a campo, I provide a campo data and add some division. If I want to delete some division, I don’t have any problem, makinga click in remove icon. My detail (ListGrid) has enabled the option canRemoveRecords.
When I remove (del) a campo, I select a row from header with, and click the right boton. Its run ok.
When I want to update a campo, I read a campo and division data, and display it. I can update a campo data without problems. But my problem is when I want to remove a previous detail records
(that exist in the database for that campo). The record is removed from database but the grid is not refresh. I read at detail the thread http://forums.smartclient.com/showthread.php?t=344&highlight=Start+empty+listgrid and I am try with autoSaveEdits (true and false) and saveAllEdits (true and false) without success.
I enclose the js and the DMI
Code:
isc.DataSource.create({ serverType:"generic", fields:[ { sqlType:"integer", sqlLength:"10", title:"Division", primaryKey:true, hidden:true, name:"divisionId", type:"sequence" }, { sqlType:"varchar", sqlLength:"30", title:"Nombre", name:"nombre", length:"30", type:"text" }, { sqlType:"integer", sqlLength:"10", title:"Edad Minima", name:"edadMinima", required:true, type:"number" }, { sqlType:"integer", sqlLength:"10", title:"Edad Maxima", name:"edadMaxima", required:true, type:"number" }, { sqlType:"char", sqlLength:"1", title:"Nivel de Juego", name:"nivel", length:"1", type:"text" }, { sqlType:"char", sqlLength:"1", title:"Sexo", name:"sexo", length:"1", type:"text" }, { sqlType:"integer", sqlLength:"10", title:"Minimo # Jugadores", name:"minimoJugadores", type:"number" }, { sqlType:"integer", sqlLength:"10", title:"Maximo # Jugadores", name:"maximoJugadores", type:"number" }, { sqlType:"char", sqlLength:"1", title:"Categoria Arbitro Principal", name:"categoriaArbitroPrincipal", length:"1", type:"text" }, { sqlType:"decimal", sqlLength:"18", title:"Pago Arbitro Principal", name:"pagoArbitroPrincipal", type:"float", validators:[ { errorMessage:"Please enter a valid cost", min:0, precision:2, type:"floatLimit" } ] }, { sqlType:"char", sqlLength:"1", title:"Categoria Arbitro Sustituto", name:"categoriaArbitroSustituto", length:"1", type:"text" }, { sqlType:"decimal", sqlLength:"18", title:"Pago Arbitro Sustituto", name:"pagoArbitroSustituto", type:"float", validators:[ { errorMessage:"Please enter a valid cost", min:0, precision:2, type:"floatLimit" } ] }, { sqlType:"char", sqlLength:"1", title:"Categoria Jueces Linea", name:"categoriaJuecesLinea", length:"1", type:"text" }, { sqlType:"decimal", sqlLength:"18", title:"Pago Jueces Linea", name:"pagoJuecesLinea", type:"float", validators:[ { errorMessage:"Please enter a valid cost", min:0, precision:2, type:"floatLimit" } ] }, { sqlType:"timestamp", sqlLength:"19", title:"Fecha de Registro", name:"fechaRegistro", type:"date" }, { sqlType:"integer", sqlLength:"10", title:"Se Viaja ?", name:"seViaja", type:"number", valueMap:{ 0:"No", 1:"Si" } }, { sqlType:"integer", sqlLength:"10", title:"Combinado", name:"combinado", type:"number", valueMap:{ 0:"No", 1:"Si" } }, { sqlType:"integer", sqlLength:"10", title:"Torneo", name:"torneoId", type:"number", required:true } ], ID:"division" }); isc.DataSource.create({ serverType:"generic", fields:[ { sqlType:"integer", sqlLength:"10", title:"Cancha", primaryKey:true, hidden:true, name:"canchaId", type:"sequence" }, { sqlType:"varchar", sqlLength:"128", length:"128", title:"Nombre", name:"nombre", type:"text" }, { sqlType:"varchar", sqlLength:"30", length:"30", title:"Calle1", name:"calle1", type:"text" }, { sqlType:"varchar", sqlLength:"30", length:"30", title:"Calle2", name:"calle2", type:"text" }, { sqlType:"varchar", sqlLength:"30", length:"30", title:"Colonia", name:"colonia", type:"text" }, { sqlType:"varchar", sqlLength:"35", length:"35", title:"Municipio", name:"municipio", type:"text" }, { sqlType:"varchar", sqlLength:"35", length:"35", title:"Entidad", name:"entidad", type:"text" }, { sqlType:"varchar", sqlLength:"30", length:"30", title:"Codigo Postal", name:"codigoPostal", type:"text" }, { sqlType:"varchar", sqlLength:"30", length:"30", title:"Pais", name:"pais", type:"text" }, { sqlType:"varchar", sqlLength:"10", length:"10", title:"Telefono1", name:"telefono1", type:"text" }, { sqlType:"varchar", sqlLength:"10", length:"10", title:"Telefono2", name:"telefono2", type:"text" }, { sqlType:"integer", sqlLength:"11", name:"Largo", name:"largo", type:"number" }, { sqlType:"integer", sqlLength:"11", title:"Ancho", name:"ancho", type:"number" }, { sqlType:"integer", sqlLength:"11", title:"Alumbrado", name:"alumbrado", type:"number", valueMap:{ "0":"No", "1":"Si" } }, { sqlType:"integer", sqlLength:"11", title:"Edad Minima", name:"edadMinima", type:"number" }, { sqlType:"integer", sqlLength:"11", title:"Edad Maxima", name:"edadMaxima", type:"number" }, { sqlType:"varchar", sqlLength:"256", length:"256", title:"Comentarios", name:"comentarios", type:"text" }, { sqlType:"integer", sqlLength:"10", hidden:true, title:"EmpresaId", name:"empresaId", type:"number" } ], ID:"campo" }); isc.DataSource.create({ serverType:"generic", fields:[ { sqlType:"integer", sqlLength:"10", title:"Division", name:"divisionId", type:"integer", required:true }, { sqlType:"integer", sqlLength:"10", title:"Campo", name:"campoId", type:"integer", required:false, hidden:true } ], ID:"divisionCampo" }); isc.ListGrid.create({ ID:"campoListGrid", dataSource:campo, useAllDataSourceFields:true, fields:[ { sqlType:"integer", sqlLength:"10", primaryKey:true, hidden:true, title:"Cancha", name:"canchaId", type:"sequence" }, { sqlType:"varchar", sqlLength:"128", length:"128", title:"Nombre", name:"nombre", type:"text" }, { sqlType:"varchar", sqlLength:"30", length:"30", hidden:true, title:"Calle1", name:"calle1", type:"text" }, { sqlType:"varchar", sqlLength:"30", length:"30", hidden:true, title:"Calle2", name:"calle2", type:"text" }, { sqlType:"varchar", sqlLength:"30", length:"30", hidden:true, title:"Colonia", name:"colonia", type:"text" }, { sqlType:"varchar", sqlLength:"35", length:"35", hidden:true, title:"Municipio", name:"municipio", type:"text" }, { sqlType:"varchar", sqlLength:"35", length:"35", hidden:true, title:"Entidad", name:"entidad", type:"text" }, { sqlType:"varchar", sqlLength:"30", length:"30", hidden:true, title:"Codigo Postal", name:"codigoPostal", type:"text" }, { sqlType:"varchar", sqlLength:"30", length:"30", hidden:true, title:"Pais", name:"pais", type:"text" }, { sqlType:"varchar", sqlLength:"10", length:"10", hidden:true, title:"Telefono1", name:"telefono1", type:"text" }, { sqlType:"varchar", sqlLength:"10", length:"10", hidden:true, title:"Telefono2", name:"telefono2", type:"text" }, { sqlType:"integer", sqlLength:"11", title:"Largo", name:"largo", type:"number" }, { sqlType:"integer", sqlLength:"11", title:"Ancho", name:"ancho", type:"number" }, { sqlType:"integer", sqlLength:"11", title:"Alumbrado", name:"alumbrado", type:"number", valueMap:{ "0":"No", "1":"Si" } }, { sqlType:"integer", sqlLength:"11", title:"Edad Minima", name:"edadMinima", type:"number" }, { sqlType:"integer", sqlLength:"11", title:"Edad Maxima", name:"edadMaxima", type:"number" }, { sqlType:"varchar", sqlLength:"256", length:"256", hidden:true, title:"Comentarios", name:"comentarios", type:"text" }, { sqlType:"integer", sqlLength:"10", hidden:true, title:"EmpresaId", name:"empresaId", type:"number" } ], recordClick:"this.updateDetails()", canEdit:true, modalEditing:true, cellChanged:"this.updateDetails()", alternateRecordStyles:true, canDragRecordsOut:true, hoverWidth:200, hoverHeight:20, selectionType:"single", cellContextClick:"return campoMenu.showContextMenu()", // Function to update details based on selection updateDetails : function () { var record = this.getSelectedRecord(); if (record == null) return campoTabSet.clearDetails(); alert("campoTabSet.getSelectedTabNumber() = " + campoTabSet.getSelectedTabNumber()); if (campoTabSet.getSelectedTabNumber() == 0) { // View tab: show selected record campoDetailViewer.setData(record) } else { alert("ahora si voy a actualizar"); alert("chanchaId = " + record.canchaId); // Edit tab: edit selected record campoTabSet.updateTab("editTab", campoVLayout); campoDynamicForm.editRecord(record); // divisionCampoListGrid.fetch({"canchaId":record.canchaId}); // divisionCampo.fetch({"canchaId":record.canchaId}); // divisionCampoListGrid.filterData({"canchaId":record.canchaId}); // divisionCampo.fetchData({"canchaId":record.canchaId}); isc.DataSource.get("divisionCampo").fetchData({"canchaId":record.canchaId}, "divisionCampoListGrid.setData(data)"); } } }); isc.Menu.create({ ID:"campoMenu", cellHeight:22, data:[ {title:"Adiciona Nueva Cancha", icon:"../images/icon_add.png", click:function () { campoListGrid.selection.deselectAll(); campoTabSet.selectTab(1); campoListGrid.updateDetails(); } }, {isSeparator:true}, {title:"Muestra Detalles", icon:"../images/icon_view.png", click:"campoTabSet.selectTab(0); campoListGrid.updateDetails()"}, {title:"Edita Cancha", icon:"../images/icon_edit.png", click:"campoTabSet.selectTab(1); campoListGrid.updateDetails()"}, {title:"Elimina Cancha", icon:"../images/icon_delete.png", click:"campoListGrid.removeSelectedData(); campoTabSet.clearDetails()"} ] }); isc.DetailViewer.create({ ID:"campoDetailViewer", dataSource:campo, width:"100%", margin:"25", emptyMessage:"Seleccione una campo para ver su detalle" }); isc.DynamicForm.create({ ID:"campoDynamicForm", dataSource:campo, useAllDataSourceFields:true, fields:[ { sqlType:"integer", sqlLength:"10", title:"Cancha", primaryKey:true, hidden:true, name:"canchaId", type:"sequence" }, { sqlType:"varchar", sqlLength:"128", length:"128", title:"Nombre", name:"nombre", type:"text", width:535, colSpan:4 }, { sqlType:"varchar", sqlLength:"30", length:"30", title:"Calle1", name:"calle1", type:"text" }, { sqlType:"varchar", sqlLength:"30", length:"30", title:"Calle2", name:"calle2", type:"text" }, { sqlType:"varchar", sqlLength:"30", length:"30", title:"Colonia", name:"colonia", type:"text" }, { sqlType:"varchar", sqlLength:"35", length:"35", title:"Municipio", name:"municipio", type:"text" }, { sqlType:"varchar", sqlLength:"35", length:"35", title:"Entidad", name:"entidad", type:"text" }, { sqlType:"varchar", sqlLength:"30", length:"30", title:"Codigo Postal", name:"codigoPostal", type:"text" }, { sqlType:"varchar", sqlLength:"30", length:"30", title:"Pais", name:"pais", type:"text" }, { name:"spacer0", type:"spacer" }, { sqlType:"varchar", sqlLength:"10", length:"10", title:"Telefono1", name:"telefono1", type:"text" }, { sqlType:"varchar", sqlLength:"10", length:"10", title:"Telefono2", name:"telefono2", type:"text" }, { sqlType:"integer", sqlLength:"11", name:"Largo", name:"largo", type:"number" }, { sqlType:"integer", sqlLength:"11", title:"Ancho", name:"ancho", type:"number" }, { sqlType:"integer", sqlLength:"11", title:"Alumbrado", name:"alumbrado", type:"number", valueMap:{ "0":"No", "1":"Si" } }, { name:"spacer1", type:"spacer" }, { sqlType:"integer", sqlLength:"11", title:"Edad Minima", name:"edadMinima", type:"number" }, { sqlType:"integer", sqlLength:"11", title:"Edad Maxima", name:"edadMaxima", type:"number" }, { sqlType:"varchar", sqlLength:"256", length:"256", title:"Comentarios", name:"comentarios", type:"text", width:535, colSpan:4 }, { sqlType:"integer", sqlLength:"10", hidden:true, title:"EmpresaId", name:"empresaId", type:"number" } ], width:800, height:200, numCols:4, colWidths:[200,200,200,200], margin:25, cellPadding:5, autoFocus:false }); isc.ListGrid.create({ ID: "divisionCampoListGrid", width: 300, height: 200, layoutAlign:"center", dataSource: divisionCampo, canEdit: true, canRemoveRecords: true, autoDraw: false, autoSaveEdits: false, fields:[ { sqlType:"integer", title:"Division", name:"divisionId", type:"integer", editorType:"comboBox", optionDataSource:"division", valueField:"divisionId", displayField:"nombre", pickListWidth:150 } ] }); isc.IButton.create({ ID: "addButton", autoDraw: false, width: 150, layoutAlign:"left", title: "Adiciona Division", click: "divisionCampoListGrid.startEditingNew()" }); isc.IButton.create({ ID: "delButton", autoDraw: false, width: 150, layoutAlign:"center", title: "Elimina Division", click: function() { divisionCampoListGrid.removeSelectedData(); var record = campoListGrid.getSelectedRecord(); isc.DataSource.get("divisionCampo").fetchData({"canchaId":record.canchaId}, "divisionCampoListGrid.setData(data)"); } }); isc.IButton.create({ ID: "saveButton", autoDraw: false, width: 150, layoutAlign:"right", title: "Almacena Cancha", click: function() { isc.RPCManager.startQueue(); campoDynamicForm.saveData(); divisionCampoListGrid.saveAllEdits(); isc.RPCManager.sendQueue(); campoDynamicForm.editNewRecord(); divisionCampoListGrid.setData(null); } }); isc.VLayout.create({ ID: "campoVLayout", membersMargin: 20, members: [ campoDynamicForm, divisionCampoListGrid, isc.HLayout.create( { membersMargin:10, members:[addButton, delButton, saveButton] } ) ] }); isc.Label.create({ ID:"campoLabel", autoDraw: false, width:"100%", height:"100%", align:"center", contents:"Seleccione una campo a editar" }); isc.TabSet.create({ ID:"campoTabSet", tabs:[ {title:"Ver", pane:campoDetailViewer, ID:"viewTab", width:70, icon:"../images/icon_view.png"}, {title:"Editar", pane:campoVLayout, ID:"editTab", width:70, icon:"../images/icon_edit.png"} ], tabSelected:"campoListGrid.updateDetails()", // Function to clear out selected items' details clearDetails : function () { alert("estoy en clearDetails de TabSet"); var selectedTab = this.getSelectedTabNumber(); if (selectedTab == 0) { // View tab: show empty message campoDetailViewer.setData(); } else if (selectedTab == 1) { // Edit tab: show new record editor, or empty message // if (categoryTree.getSelectedRecord() != null) { // alert("entro a categoryTree.getSelectedRecord() != null"); // alert("entro a selectedTab == 1"); this.updateTab("editTab", campoVLayout); campoDynamicForm.editNewRecord(); divisionCampoListGrid.setData(null); // } else { // alert("entro a categoryTree.getSelectedRecord() == null"); // this.updateTab("editTab", campoLabel); // } } } }); isc.SectionStack.create({ ID:"campoSectionStack", width:"100%", height:"100%", showResizeBar:false, visibilityMode:"multiple", animateSections:true, sections:[ {title:"Canchas Existentes", autoShow:true, items:[campoListGrid]}, {title:"Cancha Detalle", autoShow:true, items:[campoTabSet]} ] }); oneVLayout.addMember(campoSectionStack); campoSectionStack.show(); campoListGrid.filterData();
The detail datasource is:
Code:
<DataSource ID="divisionCampo" serverType="generic"> <fields> <field sqlType="integer" sqlLength="10" name="divisionId" type="integer"></field> <field sqlType="integer" sqlLength="10" name="canchaId" type="integer" hidden="true"></field> </fields> <operationBindings> <binding operationType="fetch" serverMethod="fetch"> <serverObject lookupStyle="new" className="dmi.DivisionCampoDMI"/> </binding> <operationBinding operationType="add"> <values fieldName="canchaId" value="$responseData.last('campo','add').canchaId" /> <serverObject lookupStyle="new" className="dmi.DivisionCampoDMI"/> </operationBinding> <operationBinding operationType="update"> <serverObject lookupStyle="new" className="dmi.DivisionCampoDMI"/> </operationBinding> <operationBinding operationType="remove"> <serverObject lookupStyle="new" className="dmi.DivisionCampoDMI"/> </operationBinding> </operationBindings> </DataSource>
The detail DMI is:
Code:
// By default, for a DSRequest of type "fetch", a method named "fetch" is invoked. You can // customize this via the <serverObject> declaration. public DSResponse fetch(DSRequest dsRequest, HttpSession session) throws Exception { log.info("procesing DMI fetch operation"); System.out.println("DivisionCampoDMI - fetch"); DivisionCanchaBO divisionCanchaBO = new DivisionCanchaBO(); // Fetch a List of matching SupplyItem Beans from some pre-existing Java object model // provided by you, represented by "SupplyItemStore" in this example DivisionCanchaVO divisionCanchaVO = new DivisionCanchaVO(); if(dsRequest.getFieldValue("divisionId") != null) { Long divisionId = (Long) dsRequest.getFieldValue("divisionId"); divisionCanchaVO.setDivisionId(new Integer(divisionId.intValue())); } else { divisionCanchaVO.setDivisionId(null); } if(dsRequest.getFieldValue("canchaId") != null) { Long canchaId = (Long) dsRequest.getFieldValue("canchaId"); divisionCanchaVO.setCanchaId(new Integer(canchaId.intValue())); } else { divisionCanchaVO.setCanchaId(null); } // Integer empresaId = (Integer) session.getAttribute("empresaId"); List divisionCanchaList = divisionCanchaBO.sel(divisionCanchaVO); // this implementation shows data paging (returning only ranges of requested records) long startRow = dsRequest.getStartRow(); long endRow = dsRequest.getEndRow(); long totalRows = divisionCanchaList.size(); DSResponse dsResponse = new DSResponse(dsRequest == null ? (DataSource)null : dsRequest.getDataSource()); dsResponse.setTotalRows(totalRows); dsResponse.setStartRow(startRow); endRow = Math.min(endRow, totalRows); dsResponse.setEndRow(endRow); // trim the data to the requested range of records. In a real application, the startRow // and endRow would be passed to the ORM layer or to SQL for maximum efficiency. List results; if (totalRows > 0) { if(endRow < startRow) { results = divisionCanchaList; } else { results = divisionCanchaList.subList((int)dsResponse.getStartRow(), (int)dsResponse.getEndRow()); } } else { results = divisionCanchaList; } // just return the List of matching beans dsResponse.setData(results); return dsResponse; } // Declared parameters of the method are automatically provided. For example, if your // method declares a parameter of type HttpServletRequest, the current HttpServletRequest // will be passed. // If you declare a parameter that is a Java Bean, SmartClient will create an instance of // the bean and apply the DSRequest data to the bean via Java reflection, matching // DataSource fields to Java setter methods. For example, for the DataSource field // "itemName", SupplyItem.setItemName() is called. public DivisionCanchaVO add(DivisionCanchaVO divisionCanchaVO, HttpSession session) throws Exception { log.info("procesing DMI add operation"); DivisionCanchaBO divisionCanchaBO = new DivisionCanchaBO(); System.out.println("DivisionCampoDMI - add"); // Integer canchaId = (Integer) session.getAttribute("canchaId"); // System.out.println("canchaId --------------------> " + canchaId); // divisionCanchaVO.setCanchaId(canchaId); // most ORM systems can store a new Object with a single call like this. divisionCanchaBO.add(divisionCanchaVO); // return the record-as-saved so SmartClient can update client-side caches. This // pattern ensures client-side components receive server-generated fields (such as an // auto-generated primaryKey value). SmartClient can then update caches in place // instead of re-fetching data. return divisionCanchaVO; } public DivisionCanchaVO remove(DivisionCanchaVO divisionCanchaVO, HttpSession session) throws Exception { log.info("procesing DMI remove operation"); DivisionCanchaBO divisionCanchaBO = new DivisionCanchaBO(); System.out.println("DivisionCampoDMI - remove"); divisionCanchaBO.del(divisionCanchaVO); // on a removal, just return System.out.println("divisionCanchaVO = " + divisionCanchaVO); return divisionCanchaVO; }
Please help me to resolve this problem