repeater row highlight does not persist after post

2019-07-12 12:54发布

问题:

I'm working on highlighting a repeater row when i click anywhere on that row. And then when i click on another row, the previous row becomes unhighlighted. So it's working, but only for a split second. Once the modalpopup appears, the highlight is gone. By the way, i have a linkbutton in every row that makes the modalpopup show, and i made all the labels inside the repeater as associatedcontrols. So the texts inside the repeater all kind of serve as linkbuttons. I know that the highlight-unhighlight thing works because the effect persist when i only click on the areas without text. I know the postback caused by clicking the linkbutton removes the effect made by javascript. What i want to know is, what can i do about it? Please help me.

Here's my code.

Head:

<script type = "text/javascript">
    var T0;
    function CngClass(cls){
        this.lst=null;
        this.cls=cls;
    }

    CngClass.prototype.CngClass=function(obj){
        if (typeof(obj)=='string') obj=document.getElementById(obj);
        if (this.lst) this.lst.className='';
        obj.className=this.cls;
        this.lst=obj;
    }    

<style type="text/css">
    .selected
    {
        background-color: Red;
    }
</style>

Body:

<body onload="T0=new CngClass('selected');T0.CngClass('t0');">

ItemTemplate of the repeater:

<ItemTemplate> 
    <tr id="t0" runat="server" onclick="T0.CngClass(this);" onmouseover="style.backgroundColor='Gainsboro'" onmouseout="style.backgroundColor=''" style="cursor: pointer">
        <td><asp:Label ID="lblfullname" runat="server" Text='<%#DataBinder.Eval(Container.DataItem, "FULLNAME")%>' AssociatedControlID="lnkselect" />
            <asp:HiddenField ID="hiddenrecnum" runat="server" Value='<%# DataBinder.Eval(Container.DataItem, "RECORD_ID")%>' />
        </td>
        <td><asp:Label ID="lbldeptname" runat="server" Text='<%#DataBinder.Eval(Container.DataItem, "DEPT_NAME")%>' AssociatedControlID="lnkselect" /></td>
        <td><asp:Label ID="lbldivisions" runat="server" Text='<%#DataBinder.Eval(Container.DataItem, "DIVISIONS")%>' AssociatedControlID="lnkselect" /></td>
        <td><asp:Label ID="lblposition" runat="server" Text='<%#DataBinder.Eval(Container.DataItem, "POSITION")%>' AssociatedControlID="lnkselect" />
            <asp:LinkButton ID="lnkselect" runat="server" /></td>
    </tr>
</ItemTemplate>

回答1:

There are a few ways you could address this behavior.

  • Add a hidden field to the page which is set by JavaScript. Check the hidden field client or server-side and reapply the effect if the field has a value.

  • If clicking on the row is already causing a postback, you can set the selected style server-side and maintain the ID of the selected row in ViewState.

Ideally you would minimize the number of the time the page reloads. Remember that the whole POST collection (which includes ViewState, which will be quite large with all those label controls in the repeater) is being sent to the server and being written back to the client with every postback.

Example (Client + Server)

In page markup:

<!-- hidden field to store value -->
<input type="hidden" id="hdnSelectedRow" runat="server" />

<script>



// This example doesn't use any external libraries, but I suggest using
// jQuery if you want to do more complex manipulation client-side.
function setSelectedRow(sender, id){
    sender.className = "selected";
    // probably need to also deselect any existing selected item

    // 

    // Store the selected ID in the hidden field. Note that we use the 
    // server's ID for the control, since ASP.NET may add a prefix to the ID.
    document.getElementById("<%=this.hdnSelectedRow.ClientID%>").value = id;
}

</script>

<!-- This assumes that clicking on the row doesn't always postback the 
whole grid. If you are always posting back, you probably should just modify
the state of the grid server-side. -->
<ItemTemplate> 
        <tr id="t0" runat="server" 
                    onclick="selectSelected(this, '<%#Eval("RECORD_ID")%>')">
...

In codebehind:

protected override OnLoad( EventArgs e )
{
    string selectedId = this.hdnSelectedRow.Text;
    if( !string.IsNullOrWhiteSpace( selectedId ) )
    {
        // act
    }
}