Full Ajax な CRUD アプリケーション その5
今回は既存データの編集、削除機能を実装します。
編集・削除ウィンドウの作成
編集・削除ウィンドウは新規追加ウィンドウを再利用します。機能は一覧から一つのレコードを選択し値をフォームに読み込むようにします。
まずは選択できる行を一つだけにします。以下のようにExt.grid.RowSelectionModelを定義します。
var selModel = new Ext.grid.RowSelectionModel({ singleSelect:true }); ~ var grid = new Ext.grid.GridPanel({ title:'社員管理', stripeRows: true, autoExpandColumn: 'name', height:523, width:600, store: store, colModel: colModel, selModel: selModel, tbar: tbar, bbar: bbar }); ~
続いて編集・削除のハンドラーを定義します。gridで選択した行の値を取得しフォームへ代入します。変更不可の項目はreadOnly属性をtrueにします。
編集のハンドラー
var editActionHandler = function(){ var list = grid.selModel.getSelections(); if (list.length > 0) { formWindow.show('編集', './update'); var e = list[0]; Ext.getDom('id').value = e.get('id'); Ext.getDom('name').value = e.get('name'); Ext.getDom('jobType').value = e.get('jobType'); Ext.getDom('salary').value = e.get('salary'); Ext.getDom('department').value = e.get('department'); Ext.getDom('id').readOnly = true; } }
削除のハンドラー
var deleteActionHandler = function(){ var list = grid.selModel.getSelections(); if (list.length > 0) { formWindow.show('削除', './delete'); var e = list[0]; Ext.getDom('id').value = e.get('id'); Ext.getDom('name').value = e.get('name'); Ext.getDom('jobType').value = e.get('jobType'); Ext.getDom('salary').value = e.get('salary'); Ext.getDom('department').value = e.get('department'); Ext.getDom('id').readOnly = true; Ext.getDom('name').readOnly = true; Ext.getDom('jobType').readOnly = true; Ext.getDom('salary').readOnly = true; Ext.getDom('department').readOnly = true; } }
各ハンドラーをツールバーのボタンに割り当てます。
var editAction = new Ext.Action({ text: '編集', iconCls: 'editIcon', handler: editActionHandler }); var deleteAction = new Ext.Action({ text: '削除', iconCls: 'deleteIcon', handler: deleteActionHandler });
employee.js - 編集・削除機能の追加
Ext.onReady(function(){ // HANDLER var addActionHandler = function(){ formWindow.show('新規追加', './create'); Ext.getDom('id').readOnly = true; } var editActionHandler = function(){ var list = grid.selModel.getSelections(); if (list.length > 0) { formWindow.show('編集', './update'); var e = list[0]; Ext.getDom('id').value = e.get('id'); Ext.getDom('name').value = e.get('name'); Ext.getDom('jobType').value = e.get('jobType'); Ext.getDom('salary').value = e.get('salary'); Ext.getDom('department').value = e.get('department'); Ext.getDom('id').readOnly = true; } } var deleteActionHandler = function(){ var list = grid.selModel.getSelections(); if (list.length > 0) { formWindow.show('削除', './delete'); var e = list[0]; Ext.getDom('id').value = e.get('id'); Ext.getDom('name').value = e.get('name'); Ext.getDom('jobType').value = e.get('jobType'); Ext.getDom('salary').value = e.get('salary'); Ext.getDom('department').value = e.get('department'); Ext.getDom('id').readOnly = true; Ext.getDom('name').readOnly = true; Ext.getDom('jobType').readOnly = true; Ext.getDom('salary').readOnly = true; Ext.getDom('department').readOnly = true; } } // MODEL, CONTROL var fields = [ 'id', 'name', 'jobType', 'salary', 'department' ]; var store = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({ url: './employee.json', method: 'GET' }), reader: new Ext.data.JsonReader({ root: 'root', totalProperty: 'totalProperty', fields: fields }) }); // VIEW Ext.QuickTips.init(); Ext.form.Field.prototype.msgTarget = 'side'; var FormWindow = function(){ var extWin = null; this.show = function(title, url){ if (extWin == null) { var form = new Ext.FormPanel({ method: 'POST', id: 'employee-form', baseCls: 'x-plain', labelWidth: 40, defaults: {width: 190}, defaultType: 'textfield', bodyStyle:'padding:5px 10px 0', items: [{ fieldLabel: 'Id', id: 'id', xtype: 'numberfield' },{ fieldLabel: '氏名', id: 'name', allowBlank: false },{ fieldLabel: '職種', id: 'jobType' }, { fieldLabel: '給料', id: 'salary', xtype: 'numberfield' }, { fieldLabel: '部署', id: 'department' }] }); extWin = new Ext.Window({ title: '会社員情報 : ' + title, width: 300, height:220, minWidth: 300, minHeight: 250, layout: 'fit', closeAction :'hide', plain:true, bodyStyle:'padding:5px;', buttonAlign:'center', items: form, buttons: [{ text: 'OK', handler: function(){ form.getForm().submit({ url: url, waitMsg: 'サブミットしています...', // Submit時に表示するメッセージ。二重サブミット防止にもなる。 success: function(form, action) { Ext.select('.x-tbar-loading').item(0).dom.click(); extWin.close(); extWin = null; }, failure: function(form, action) { if (action.failureType == 'client') { // do nothing } else if (action.failureType == 'connect') { Ext.MessageBox.alert('コネクションエラー', '通信時にエラーが発生しました。'); } else { Ext.MessageBox.alert('失敗', title + 'できませんでした。'); Ext.select('.x-tbar-loading').item(0).dom.click(); extWin.close(); extWin = null; } } }); } },{ text: 'キャンセル', handler: function(){ form.getForm().reset(); extWin.close(); extWin = null; } }] }); } extWin.show(); } }; var formWindow = new FormWindow(); var colModel = new Ext.grid.ColumnModel([ {header: "Id", width: 75, sortable: true, dataIndex: 'id'}, {id:'name', header: "氏名", width: 160, sortable: true, dataIndex: 'name'}, {header: "職種", width: 75, sortable: true, dataIndex: 'jobType'}, {header: "給与", width: 75, sortable: true, dataIndex: 'salary'}, {header: "部署", width: 85, sortable: true, dataIndex: 'department'} ]); var selModel = new Ext.grid.RowSelectionModel({ singleSelect:true }); var addAction = new Ext.Action({ text: '追加', iconCls: 'addIcon', handler: addActionHandler }); var editAction = new Ext.Action({ text: '編集', iconCls: 'editIcon', handler: editActionHandler }); var deleteAction = new Ext.Action({ text: '削除', iconCls: 'deleteIcon', handler: deleteActionHandler }); var findAction = new Ext.Action({ text: '検索', iconCls: 'findIcon' }); var tbar = [ addAction, '-', editAction, deleteAction, '-', findAction ]; var pageSize = 20; var bbar = new Ext.PagingToolbar({ id: 'pagingToolbar', pageSize: pageSize, store: store, displayInfo: true, displayMsg: '社員の一覧 {2} 件中 {0} - {1} 件目', emptyMsg: "社員の一覧はありません" }); var grid = new Ext.grid.GridPanel({ title:'社員管理', stripeRows: true, autoExpandColumn: 'name', height:523, width:600, store: store, colModel: colModel, selModel: selModel, tbar: tbar, bbar: bbar }); // INIT grid.render('grid-employee'); store.load({params:{start:0, limit:pageSize}}); });
employee.jsは以上です。続いて呼び出されるフォームアクションを作成します。ソースは以下の通りです。
EmployeeAction.java
package webapplication.action; import javax.annotation.Resource; import org.seasar.framework.beans.util.Beans; import org.seasar.struts.annotation.ActionForm; import org.seasar.struts.annotation.Execute; import org.seasar.struts.util.ResponseUtil; import webapplication.entity.Employee; import webapplication.form.EmployeeForm; import webapplication.service.EmployeeService; public class EmployeeAction { @ActionForm @Resource protected EmployeeForm employeeForm; @Resource protected EmployeeService employeeService; @Execute(validator = false) public String create() { Employee entity = Beans.createAndCopy(Employee.class, employeeForm) .execute(); employeeService.insert(entity); ResponseUtil.write("{success:true}", "application/json"); return null; } @Execute(validator = false) public String update() { Employee entity = Beans.createAndCopy(Employee.class, employeeForm) .execute(); employeeService.update(entity); ResponseUtil.write("{success:true}", "application/json"); return null; } @Execute(validator = false) public String delete() { Employee entity = Beans.createAndCopy(Employee.class, employeeForm) .execute(); employeeService.delete(entity); ResponseUtil.write("{success:true}", "application/json"); return null; } }
以上で実装は完了です。ブラウザでhttp://localhost:8080/ajax-app/employee/index.htmlをアクセスし編集・削除ボタンを実行して確認します。