简体   繁体   中英

ASP TextBox extra values after postback

In summary: I'm saving grid id and row number to some hidden textboxes inside a GridView so I can update the session data via jQuery. After a drag and drop operation on the GridView, one of the textboxes holds different data than it should. Does anyone know why this might be?

Edit: solved by doing the databinding in Page_PreRender instead of Page_Load.

I'm trying to build a page with 2 draggable and sortable GridViews. This is a 'teach myself jQuery in preparation for using those methods on production pages' kind of project. When a row is dragged and dropped, it calls a postback to update the underlying datasets and rebind the grids. Users should be able to reorder the gridviews and also drag rows from one to the other. I get the feeling that I'm making it way harder than it should be, but that's not my question.

To make the postbacks work, I'm creating 2 hidden textboxes that store the grid id and row number on each row. jQuery uses those as parameters to pass to the code-behind via a PageMethods call. All of that works, the first time.

If I try to do a drag-and-drop on a row I already dragged and dropped once, the row number textbox.text field becomes x,x instead of x like the other rows. For instance, dragging row 1 somewhere makes row 1's TextBox.Text become 1,1. I've verified that in RowDataBound the number is 1 and at Page_Unload it's 1,1. Why is this?

Javascript:

<script type="text/javascript">
$(document).ready(function () {
    $( ".draggable" ).draggable({
        helper: "clone",
        stack: ".draggable",
        snapto: ".droppable",
        create: function(event, ui){
            var GridID = $(this).find(".gridid").attr("value");
            $(this).data("source",GridID);  
            var RowID = $(this).find(".rowindex").attr("value");
            $(this).data("rowid",RowID);  
        }
    });
    $( ".droppable" ).droppable({
        tolerance: "intersect",
        greedy: true,
        create: function(event, ui){
            var GridID = $(this).find(".gridid").attr("value");
            $(this).data("source",GridID);  
            var RowID = $(this).find(".rowindex").attr("value");
            $(this).data("rowid",RowID); 
        },
        drop: function(event, ui){
            var SourceGrid = ui.draggable.data("source");
            var SourceRow = ui.draggable.data("rowid");
            var DestGrid = $(this).data("source");
            var DestRow = $(this).data("rowid");
            PageMethods.MoveRow(SourceGrid, DestGrid, SourceRow, DestRow);
            __doPostBack('','');
        }
    });
});

</script>

ASP:

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolderMain" runat="Server">
    <asp:GridView ID="gvSource" runat="server" ShowFooter="true" 
    OnRowDataBound="gvSource_RowDataBound">
    </asp:GridView>
    <asp:GridView ID="gvDest" runat="server" ShowFooter="true"
    OnRowDataBound="gvSource_RowDataBound">
    </asp:GridView>

Code-Behind (minus the DataBinding and fetching parts):

protected void gvSource_RowDataBound(object sender, GridViewRowEventArgs e) {
    TextBox gridid = new TextBox();
    gridid.Text = ((GridView)sender).ClientID;
    gridid.CssClass = "gridid hidden";
    TextBox rowindex = new TextBox();
    switch (e.Row.RowType) {
        case DataControlRowType.DataRow:
            rowindex.Text = e.Row.RowIndex.ToString();
            break;
        case DataControlRowType.Header:
            rowindex.Text = "0";
            break;
        case DataControlRowType.Footer:
            rowindex.Text = ((DataTable)((GridView)sender).DataSource).Rows.Count.ToString();
            break;
        default:
            rowindex.Text = "null";
            break;
    }
    rowindex.CssClass = "rowindex hidden";
    e.Row.Cells[0].Controls.Add(gridid);
    e.Row.Cells[0].Controls.Add(rowindex);
}
[WebMethod]
public static string MoveRow(string _sourcegrid, string _destgrid, string _sourcerow, string _destrow) {
        HttpContext ctx = HttpContext.Current;
        DataTable dtsrc = _sourcegrid == ((DataTable)ctx.Session["dtFrom"]).TableName ? (DataTable)ctx.Session["dtFrom"] : (DataTable)ctx.Session["dtTo"];
        DataTable dtdest = _destgrid == ((DataTable)ctx.Session["dtFrom"]).TableName ? (DataTable)ctx.Session["dtFrom"] : (DataTable)ctx.Session["dtTo"];
        DataRow row = dtsrc.Rows[Convert.ToInt32(_sourcerow)];
        DataRow newrow = dtdest.NewRow();
        int newrowpos = Convert.ToInt32(_destrow);
        newrow.ItemArray = row.ItemArray;
        dtsrc.Rows.Remove(row);
        dtdest.Rows.InsertAt(newrow, newrowpos);
        return "1";
}

CSS-wise, all rows have CssClass="droppable draggable". Headers and footers are just droppable. I left off some error checking code for brevity.

edit: added a summary, and I wanted to add that I've looked through SO and found only topics about a TextBox losing its data, not changing it.

The problem had something to do with binding the data in Page_Load. It looked like

protected void Page_Load(object sender, EventArgs e) {
    if (!IsPostBack) {
        GetData(); //Database fetch saves 2 DataTables to session variables
    }
    gvSource.DataSource = (DataTable)Session["dtFrom"];
    gvSource.DataBind();
    gvDest.DataSource = (DataTable)Session["dtTo"];
    gvDest.DataBind();
}

and it failed. Made it

protected void Page_Load(object sender, EventArgs e) {
    if (!IsPostBack) {
        GetData();  //Database fetch
    }
}
protected void Page_PreRender(object sender, EventArgs e) {
    gvSource.DataSource = (DataTable)Session["dtFrom"];
    gvSource.DataBind();
    gvDest.DataSource = (DataTable)Session["dtTo"];
    gvDest.DataBind();
}

and it worked. Why it worked is still open for debate. Thanks guys for helping this long-time lurker with basic SO usage and etiquette.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM