2011-02-25 47 views
6

我目前使用afterSaveCell來手動更新網格中的某些單元格。如果用戶使用回車來保存當前編輯的單元格,我的工作正常。jqGrid正在編輯時訪問單元格數據

不幸的是,如果他們點擊或退出單元格,他們直接編輯到另一個單元格中,我不能再獲取新編輯的單元格的單元格值,因爲getCell將僅返回輸入控件的html。

總之,有沒有什麼辦法可以訪問單元格的值,即使它正在被編輯?

jQuery(document).ready(function() { 
    var mydata = [ 
     {id:"1", invdate:"2007-10-01",name:"test", note:"note", amount:"200.00",tax:"10.00",total:"210.00"}, 
     {id:"2", invdate:"2007-10-02",name:"test2", note:"note2", amount:"300.00",tax:"20.00",total:"320.00"}, 
     {id:"3", invdate:"2007-09-01",name:"test3", note:"note3", amount:"400.00",tax:"30.00",total:"430.00"}, 
     {id:"4", invdate:"2007-10-04",name:"test", note:"note4", amount:"200.00",tax:"10.00",total:"210.00"}, 
     {id:"5", invdate:"2007-10-05",name:"test5", note:"note5", amount:"300.00",tax:"20.00",total:"320.00"}, 
     {id:"6", invdate:"2007-09-06",name:"test", note:"note6", amount:"400.00",tax:"30.00",total:"430.00"}, 
     {id:"7", invdate:"2007-10-04",name:"test7", note:"note7", amount:"200.00",tax:"10.00",total:"210.00"}, 
     {id:"8", invdate:"2007-10-03",name:"test8", note:"note8", amount:"300.00",tax:"20.00",total:"320.00"}, 
     {id:"9", invdate:"2007-09-01",name:"test", note:"note9", amount:"400.00",tax:"30.00",total:"430.00"}, 
     {id:"10",invdate:"2007-09-08",name:"test10",note:"note10",amount:"500.00",tax:"30.00",total:"530.00"}, 
     {id:"11",invdate:"2007-09-08",name:"test11",note:"note11",amount:"500.00",tax:"30.00",total:"530.00"}, 
     {id:"12",invdate:"",name:"TOTAL", note:"",amount:"",tax:"",total:""} 
    ]; 

    var grid = $("#list"); 

    grid.jqGrid({ 
     cellsubmit: 'remote', 
     cellurl: '/Example/GridSave', 
     datatype: "local", 
     data: mydata, 
     mtype: 'POST', 
     colNames: ['Inv No', 'Date', 'Client', 'Amount', 'Tax', 'Total', 'Notes'], 
     colModel: [ 
      { name: 'id', index: 'id', width: 65, sorttype: 'int', hidden: true }, 
      { name: 'invdate', index: 'invdate', width: 120, align: 'center', formatter: 'date', formatoptions: { newformat: 'd-M-Y' }, sortable: false }, 
      { name: 'name', index: 'name', editable: true, width: 90, sortable: false }, 
      { name: 'amount', index: 'amount', editable: true, width: 70, formatter: 'number', align: 'right', sortable: false }, 
      { name: 'tax', index: 'tax', editable: true, width: 60, formatter: 'number', align: 'right', sortable: false }, 
      { name: 'total', index: 'total', editable: true, width: 60, formatter: 'number', align: 'right', sortable: false }, 
      { name: 'note', index: 'note', width: 100, sortable: false } 
     ], 
     rowNum: 1000, 
     pager: '#pager', 
     viewrecords: true, 
     sortorder: "desc", 
     caption: "afterSaveCell Issue", 
     height: "100%", 
     cellEdit: true, 
     gridComplete: function() { 
      calculateTotal(); 
     }, 
     afterSaveCell: function (rowid, name, val, iRow, iCol) { 
      calculateTotal(); 
     } 
    }); 
}); 

function calculateTotal() { 
    var totalAmount = 0; 
    var totalTax = 0; 

    var grid = jQuery("#list"); 

    var ids = grid.jqGrid('getDataIDs'); 
    for (var i = 0; i < ids.length; i++) { 
     var id = ids[i]; 

     if (grid.jqGrid('getCell', id, 'name') === "TOTAL") { 
      grid.jqGrid('setRowData', id, { 
       'amount': totalAmount, 
       'tax': totalTax, 
       'total': totalAmount + totalTax 
      }); 
     } 
     else { 
      totalAmount += Number(grid.jqGrid('getCell', id, 'amount')); 
      totalTax += Number(grid.jqGrid('getCell', id, 'tax')); 
     } 
    } 
} 

在此先感謝!

+0

如果你需要節省TAB當前單元格,你將覆蓋'nextCell'和'prevCell'的默認實現,這將在TAB被稱爲或Shift-TAB。請參閱這裏的函數的代碼:https://github.com/tonytomov/jqGrid/blob/master/js/grid.celledit.js#L305 – Oleg 2011-02-25 20:37:27

+0

謝謝@ Oleg,這肯定會幫助TAB問題,但仍然留下當模糊到同一網格中的另一個單元格時出現問題。 – Shawn 2011-02-25 21:00:21

+0

你是對模糊的。可能將編輯元素綁定到「模糊」甚至「聚焦」事件的方式可以解決您的問題。您可以在'editoptions'中使用'dataEvents'(請參閱http://stackoverflow.com/questions/4407273/jqgrid-retrieve-data-of-cell-and-manipulate-it/4407958#4407958)以綁定到'focusout'事件並調用「saveCell」。您還可以使用'beforeEditCell'來保存'saveCell'中需要的最後一個'iRow','iCol'參數。 – Oleg 2011-02-25 22:11:52

回答

11

我在代碼中看到兩個問題。第一個更美觀,但正確的解決方案可以簡化將來的許多事情。

第一個問題是,您添加手動將「TOTAL」行作爲網格數據的一部分,並計算calculateTotal函數內的行中的值。更好的方法是使用footerrow:true選項,它將在網格底部添加額外的行,這將與網格數據不混合。對於基於服務器的數據,您可以使用userdata部分來自服務器的JSON或XML響應,並使用userDataOnFooter:true,直到從參數userData jqGrid參數到頁腳行爲止。在「本地」數據類型的情況下,可以使用footerData方法來設置(或獲取)頁腳中的數據。此外,方法getCol可用於計算列中元素的總和。所以你calculateTotal版本功能可以改寫爲

var grid = $("#list"); 
var calculateTotal = function() { 
    var totalAmount = grid.jqGrid('getCol','amount',false,'sum'), 
     totalTax = grid.jqGrid('getCol','tax',false,'sum'); 
    grid.jqGrid('footerData','set',{name:'TOTAL',amount:totalAmount,tax:totalTax}); 
} 

我們的主要問題。您使用單元格編輯模式。如果函數calculateTotal<input>元素,而不是(你原來還是我的簡化版本)將在當時被稱爲當一個人從「量」或「稅」的細胞是在編輯模式下,calculateTotal將讀取HTML片段帶號碼和計算的字符串將失敗。

我創建the small demo其稱之爲calculateTotal每一秒。因此,如果您點擊 「金額」或「稅」列中的任意單元格,您將看到在頁腳行0中將顯示爲總和。因此,cellsubmit:'clientArray'的演示與cellsubmit:'remote'的原始代碼具有相同的問題。

爲了解決這個問題,可以使用的jqGrid的data參數的總和計算期間:

var grid = $("#list"); 
var calculateTotal = function() { 
    var gridData = grid.jqGrid('getGridParam','data'), 
     i=0,totalAmount=0,totalTax=0; 
    for (;i<gridData.length;i++) { 
     var rowData = gridData[i]; 
     totalAmount += Number(rowData.amount); 
     totalTax += Number(rowData.tax); 
    } 
    grid.jqGrid('footerData','set',{name:'TOTAL',amount:totalAmount,tax:totalTax}); 
} 

相應的固定演示,你會發現here。在您的最終代碼,你可以刪除

setInterval(calculateTotal, 1000); 

我只用於演示目的,刷新只有afterSaveCell事件處理程序的頁腳。

已更新:如果使用遠程數據,則不能使用data參數。所以如果需要的話,必須從<input>元素獲取數據。我創建了one more demo,演示瞭如何做到這一點。的calculateTotal代碼會更長:

var getColumnIndexByName = function(grid,columnName) { 
    var cm = grid.jqGrid('getGridParam','colModel'); 
    for (var i=0,l=cm.length; i<l; i++) { 
     if (cm[i].name===columnName) { 
      return i; // return the index 
     } 
    } 
    return -1; 
}, 
getTextFromCell = function(cellNode) { 
    return cellNode.childNodes[0].nodeName === "INPUT"? 
      cellNode.childNodes[0].value: 
      cellNode.textContent || cellNode.innerText; 
}, 
calculateTotal = function() { 
    var totalAmount = 0, totalTax = 0, 
     i=getColumnIndexByName(grid,'amount'); 
    $("tbody > tr.jqgrow > td:nth-child("+(i+1)+")",grid[0]).each(function() { 
     totalAmount += Number(getTextFromCell(this)); 
    }); 

    i=getColumnIndexByName(grid,'tax'); 
    $("tbody > tr.jqgrow > td:nth-child("+(i+1)+")",grid[0]).each(function() { 
     totalTax += Number(getTextFromCell(this)); 
    }); 

    grid.jqGrid('footerData','set',{name:'TOTAL',amount:totalAmount,tax:totalTax}); 
}; 
+0

看起來'jqGrid('getGridParam','data')'只適用於本地數據。使用它與我的遠程JSON數據返回一個空字符串。 – Shawn 2011-02-27 00:13:24

+0

@Shawn:是的,這是正確的,但你的演示已經使用本地數據。如果您需要使用遠程數據,則必須檢查'getCell'中的數據是否爲帶有''的HTML片段。你可以使用更快速的jQuery方式,而不是枚舉雖然行ID,我描述http://stackoverflow.com/questions/5010761/linking-from-a-column-value-in-jqgrid-to-a-newpage - 使用 - 獲取/ 5017528#5017528。爲了讓你更容易,我創建了一個你需要的演示http://www.ok-soft-gmbh.com/jqGrid/CellEditAfterSaveCellProblem1.htm。 – Oleg 2011-02-27 00:55:24

+0

@奧列格:很好的回答!我還有一個問題 - 我已經在我的行中輸入了一個選擇類型的單元格 - 只有當選擇值是它內部的第一個值時,我怎樣才能總結總量?我的意思是我想根據選擇單元格內的值來計算總和。謝謝.. – user590586 2011-05-15 09:40:35

1

感謝奧列格對我來說將溶液施加和改變你把

var ListTabla="ListFormatos"; 
var request="../../tabla_general/tabla_general_mantenimiento.php"; 

var getColumnIndexByName = function(grid,columnName) { 
var cm = $("#"+grid).jqGrid('getGridParam','colModel'); 
for (var i=0,l=cm.length; i<l; i++) { 
    if (cm[i].name===columnName) { 
     return i; // return the index 
    } 
} 
return -1; 
}, 

getTextFromCell = function(cellNode) { 
return cellNode.childNodes[0].nodeName === "INPUT"? 
     cellNode.childNodes[0].value: 
     cellNode.textContent || cellNode.innerText; 
}, 

calculateTotal = function(grid) { 

total_hpr_suebas = retorna_suma('hpr_suebas',grid); 
total_hpr_asifam = retorna_suma('hpr_asifam',grid); 
total_hpr_bashpr = retorna_suma('hpr_bashpr',grid); 
total_hpr_remcom = retorna_suma('hpr_remcom',grid); 
total_hpr_basmes = retorna_suma('hpr_basmes',grid); 
total_hpr_provcts = retorna_suma('hpr_provcts',grid); 
total_hpr_provgrat = retorna_suma('hpr_provgrat',grid); 
total_hpr_provvac=retorna_suma('hpr_provvac',grid); 

    $("#"+grid).jqGrid('footerData','set',{sec_detsec:'TOTAL',hpr_suebas:total_hpr_suebas,hpr_asifam:total_hpr_asifam,hpr_bashpr:total_hpr_bashpr,hpr_remcom:total_hpr_remcom,hpr_basmes:total_hpr_basmes,hpr_provcts:total_hpr_provcts,hpr_provgrat:total_hpr_provgrat,hpr_provvac:total_hpr_provvac}); 
}; 

retorna_suma=function(campo,grid) 
{ 
    total=0; 
    i=getColumnIndexByName(grid,campo); 
    $("tbody > tr.jqgrow > td:nth-child("+(i+1)+")",$("#"+grid)[0]).each(function() { 
     total+= Number(getTextFromCell(this)); 
    }); 
    return total; 
} 

function fn_jqgrid_history_provisiones_trabajador(tra_idtra,fecha_inicio,fecha_fin) 
{ 
    jQuery("#"+ListTabla).jqGrid({ 
        url:request+"?action=search_history_provisiones_trabajador&tra_idtra="+tra_idtra+"&fecha_inicio="+fecha_inicio+"&fecha_fin="+fecha_fin, 
        async: false, 
        datatype: 'json', 
        colNames:['','ID','SECTOR','BASICO','ASIG. FAM','DIAS','BASE','REM. COMP.','BASE MES','P.CTS','P.GRAT.','P.VAC.','MES','ANIO','PORC.','SAL.VAC.','SAL.GRAT.'], 
        colModel:[ 
         {name:'act', index:'act', width:50, resizable:true, align:"center",hidden:true}, 
         {name:'id', index:'id', width:50, resizable:true, align:"center",hidden:true}, 
         {name:'sec_detsec', index:'sec_detsec', width:80}, 
         {name:'hpr_suebas', index:'hpr_suebas', width:60}, 
         {name:'hpr_asifam', index:'hpr_asifam', width:50}, 
         {name:'hpr_numdia', index:'hpr_numdia', width:30}, 
         {name:'hpr_bashpr',index:'hpr_bashpr', width:60}, 
         {name:'hpr_remcom,',index:'hpr_remcom', width:60}, 
         {name:'hpr_basmes', index:'hpr_basmes', width:60}, 
         {name:'hpr_provcts', index:'hpr_provcts', width:60}, 
         {name:'hpr_provgrat', index:'hpr_provgrat', width:60}, 
         {name:'hpr_provvac', index:'hpr_provvac', width:60}, 
         {name:'hpr_meshpr', index:'hpr_meshpr', width:30}, 
         {name:'hpr_aniohpr,',index:'hpr_aniohpr', width:30}, 
         {name:'hpr_salpor', index:'hpr_salpor', width:50}, 
         {name:'hpr_salval_vac', index:'hpr_salval_vac', width:50}, 
         {name:'hpr_salval_grat', index:'hpr_salval_grat', width:50} 
        ], 
        pager: '#paginacion', 
        rowNum:10, 
        rowList:[10,20,30], 
        sortname: 'ID', 
        ondblClickRow:function(rowid, iRow, iCol, e) 
        { 
           obj=jQuery("#"+ListTabla).jqGrid('getRowData',rowid); 
        } 
        , 
        sortorder: 'desc', 
        editurl:request, 
        viewrecords: true, 
        caption: 'Provisiones', 
        //rownumbers: true, 
        height: 250, 
        rowheight: 280, 
        footerrow : true, 
        gridComplete: function() { 
         calculateTotal(ListTabla); 
       }, 
        afterSaveCell: function (rowid, name, val, iRow, iCol) { 
         //calculateTotal(ListTabla); 
        } 
        }).navGrid('#paginacion',{add:false,edit:false, del:false}); 

         jQuery("#"+ListTabla).jqGrid('bindKeys', {"onEnter":function(rowid) { 
                    obj=jQuery("#"+ListTabla).jqGrid('getRowData',rowid); 
                    } }); 

       } 
1

如果你只是想重新計算總數,你可以使用觸發器重裝在afterSaveCell事件中的網格。就像這樣:

afterSaveCell: function (rowid, name, val, iRow, iCol) 

     { 
      jQuery("#list11").jqGrid('setGridParam',{datatype:'local',loadonce:true}).trigger('reloadGrid'); 
     } 
相關問題