无意中做出来的,本来是想实现单击列表中的上移、下移按钮后,实现该行上移一行或下移一行的,结果做成了左移或右移一个单元格的效果了
1.左移或右移单元格
js代码:
function UpRow(id) { debugger; var row = id.parentNode.parentNode; if (row.rowIndex != 1) { if (row.previousSibling) { swapNode(row, row.previousSibling); } } return false; } function DownRow(id) { var row = id.parentNode.parentNode; if (row.nextSibling) { swapNode(row, row.nextSibling); } return false; } function swapNode(node1, node2) { var parent = node1.parentNode; var t1 = node1.nextSibling; var t2 = node2.nextSibling; if (t1) { parent.insertBefore(node2, t1); } else { parent.appendChild(node2); } if (t2) { parent.insertBefore(node1, t2); } else { parent.appendChild(node1); } }
前台列表代码:
<asp:TemplateField HeaderText="排序" ItemStyle-HorizontalAlign="Center"> <ItemTemplate> <asp:LinkButton ID="lbtnUp" runat="server" Text="上移"> <img alt="上移" title="上移" onclick="return UpRow(this);" src="../../Themes/Images/btn_dg_edit.gif" /> </asp:LinkButton> <asp:LinkButton ID="lbtnDown" runat="server" Text="下移"> <img alt="下移" title="下移" onclick="return DownRow(this);" src="../../Themes/Images/btn_dg_edit.gif" /> </asp:LinkButton> </ItemTemplate>
效果图:
最后找出原因,因为按钮是在linkbutton中加的img标签里的,所以row = id.parentNode.parentNode表示的是单元格,row = id.parentNode.parentNode.parentNode才表示当前行。将函数的row修改下,实现所要的功能
2.JS上移或下移列表行
function UpRow(id) { var row = id.parentNode.parentNode.parentNode; if (row.rowIndex != 1) { if (row.previousSibling) { swapNode(row, row.previousSibling); } } return false; } function DownRow(id) { var row = id.parentNode.parentNode.parentNode; if (row.nextSibling) { swapNode(row,row.nextSibling); } return false; } function swapNode(node1, node2) { var parent = node1.parentNode; var t1 = node1.nextSibling; var t2 = node2.nextSibling; if (t1) { parent.insertBefore(node2, t1); } else { parent.appendChild(node2); } //将t2插在t1前 if (t2) { parent.insertBefore(node1, t2); } else { parent.appendChild(node1); } ListNum(); } //重新给列表加上序号 function ListNum() { var oTable = document.getElementById("<%=gridView.ClientID%>"); for (var i = 1; i < oTable.rows.length; i++) { oTable.rows[i].cells[0].innerHTML = (i); if (i % 2 == 0) //偶数行 oTable.rows[i].className = "ys01"; } }
3.后台交换列表行并保存
客户有新的需求,移动列表行,排序后要求保存调整后的排序,在数据比较少,操作不是很频繁的情况下,可以再后台处理,这种方法比较简单。
前台代码:
<asp:TemplateField HeaderText="排序" ItemStyle-HorizontalAlign="Center" Visible="false"> <ItemTemplate> <asp:LinkButton ID="lbtnUp" runat="server" Text="上移" CommandName="SortIndexUp" CommandArgument='<%#DataBinder.Eval(Container.DataItem,"SupplierEvaluateMappingID") %>'> <img alt="上移" title="上移" src="../../Themes/Images/up.gif" style="CURSOR: hand" /> </asp:LinkButton> <asp:LinkButton ID="lbtnDown" runat="server" Text="下移" CommandName="SortIndexDown" CommandArgument='<%#DataBinder.Eval(Container.DataItem,"SupplierEvaluateMappingID") %>'> <img alt="下移" title="下移" src="../../Themes/Images/down.gif" style="CURSOR: hand" /> </asp:LinkButton> </ItemTemplate> </asp:TemplateField>
后台主要在gridView_RowCommand()中实现交换行并及时保存
代码如下:
protected void gridView_RowCommand(object sender, GridViewCommandEventArgs e) { SaveMainBusiness(); LoadSupply(); DataTable dtSortIndex = ViewState["dataTable"] as DataTable; if (e.CommandName == "ItemDelete") { string supplyEntityID = e.CommandArgument.ToString(); SaveMappingSortIndex(); XmlDocument xmlDocument = new XmlDocument(); xmlDocument.LoadXml(this.hiSupplyXml.Value); XmlNode node = xmlDocument.SelectSingleNode(string.Format("root/supply[@SupplyEntityID='{0}']", supplyEntityID)); xmlDocument.DocumentElement.RemoveChild(node); this.hiSupplyXml.Value = xmlDocument.OuterXml; SaveSupply(); LoadSupply(); } else if (e.CommandName == "SortIndexUp") { //当前行 string supplyMappingID = e.CommandArgument.ToString(); Control cmdSource = e.CommandSource as Control; GridViewRow row = cmdSource.NamingContainer as GridViewRow; int rowIndex = row.RowIndex; if (rowIndex>0) { //上一行 string key = gridView.DataKeys[rowIndex - 1].Value.ToString(); foreach (DataRow dr in dtSortIndex.Rows) { //当前行索引减1向上 if (dr["SupplierEvaluateMappingID"].ToString().ToLower().Equals(supplyMappingID)) { dr["SortIndex"] = rowIndex - 1 + 1; } //上一行索引加1向下 else if (dr["SupplierEvaluateMappingID"].ToString().ToLower().Equals(key)) { dr["SortIndex"] = rowIndex + 1; } } dtSortIndex.DefaultView.Sort = "SortIndex,SupplyType,ImportantType"; gridView.DataSource = dtSortIndex.DefaultView; gridView.PagingData(); ViewState["dataTable"] = dtSortIndex; } } else if (e.CommandName == "SortIndexDown") { //当前行 string supplyMappingID = e.CommandArgument.ToString(); Control cmdSource = e.CommandSource as Control; GridViewRow row = cmdSource.NamingContainer as GridViewRow; int rowIndex = row.RowIndex; if (rowIndex < gridView.Rows.Count-1) { //下一行 string key = gridView.DataKeys[rowIndex+1].Value.ToString(); foreach (DataRow dr in dtSortIndex.Rows) { //当前行加,向下 if (dr["SupplierEvaluateMappingID"].ToString().ToLower().Equals(supplyMappingID)) { dr["SortIndex"] = rowIndex + 1 + 1; } //下一行,向上 else if (dr["SupplierEvaluateMappingID"].ToString().ToLower().Equals(key)) { dr["SortIndex"] = rowIndex + 1; } } dtSortIndex.DefaultView.Sort = "SortIndex,SupplyType,ImportantType"; gridView.DataSource = dtSortIndex.DefaultView; gridView.PagingData(); ViewState["dataTable"] = dtSortIndex; } } }
注意点是,获取当前列表的数据源,用viewState比较简单,在绑定列表的同时,获取绑定的数据源,放入viewState:
DataTable dt = KPMSDB.ExecuteDataSet(CommandType.Text, sql).Tables[0]; this.gridView.UseDefaultDataSource = true; this.gridView.DataSource = dt.DefaultView; this.gridView.PagingData(); ViewState["dataTable"] = dt;