Mixing Server and Client-side - is it hard to be elegant?

I had to write some functionality for a friend tonight based on the following request :

When double-clicking on a textbox, toggle the enabled/disabled state of the textbox and, if it's disabled set it's background to red. Also, make sure that the settings persist across postbacks.

All up the task took about 1/2 an hour to achieve and, I often think that it would be nice if the ASP Team gave us more "hooks" into client side programming to make this stuff easier. I'm not sure that this qualifies as elegant, in fact I'm sure that I'd class it as a dodgy-hack, but, here's what I went for:

<%@ Page language="c#" %>
<%@ import namespace="System.Drawing" %>
<script runat="server">
private void btnSubmit_Click(object sender, System.EventArgs e)
{
  string fields = this.hdnFields.Value ;
   
  foreach( Control ctl in this.Controls ) 
  {  
    if( ctl is HtmlForm ) 
    {
        foreach( Control childControl in ctl.Controls ) 
        {
            if( childControl is TextBox ) 
            {
                int pos = fields.IndexOf( childControl.ID + ":" ) ;
                if( pos >= 0 ) 
                {
                    string state = fields.Substring( pos, fields.IndexOf(';',pos) - pos ) ;
                    if( state.Length > 0 ) 
                    {
                        string val = state.Split(':')[1] ;
                        ((TextBox) childControl).Text = val ;
                    }
                }
                
                ((TextBox) childControl).Enabled = ( pos == -1 ) ;
                ((TextBox) childControl).BackColor = ( pos >=0 ) ? Color.Red : Color.White ;
            }
        }
    }
  }
}
</script>
<html>
  <head>
  <script language="javascript">
 
    function ToggleEnabled( e ) {
        var tb = e.children[0] ;
        var disabled = !tb.disabled ;
        
        tb.disabled = disabled ;
        tb.style.backgroundColor = ( disabled ) ? "Red" : "White" ; 
        
        if( !disabled ) tb.focus() ;
        
        UpdateHiddenField( tb, disabled ) ;
    }
    
    
    function UpdateHiddenField( e, disabled ) {
        var txt = Form1.hdnFields.value ;
        Form1.hdnFields.value = "" ;
    
        if( disabled )
            Form1.hdnFields.value = e.id + ":" + e.value + ";" ;
            
        var flds = txt.split( ";" ) ;
            
        for( var i=0; i<flds.length; i++ ) {
            if( e.id != flds[i].split(":")[0] && flds[i].length && flds[i].length > 0 )
                Form1.hdnFields.value += flds[i] + ";" ; 
        }
    }
</script>
</head>
<body>
<form id="Form1" method="post" runat="server">
<input type="hidden" id="hdnFields" runat="server" >
   
<p>
    <span id="foo1" ondblclick="ToggleEnabled( this ) ;">
        TextBox 1: <asp:textbox id="txtTest1" runat="server" />
    </span>
</p>
<p>
    <span id="foo2" ondblclick="ToggleEnabled( this ) ;">
        TextBox 2: <asp:textbox id="txtTest2" runat="server" />
    </span>
</p>
<p>
    <span id="foo3" ondblclick="ToggleEnabled( this ) ;">
        TextBox 3: <asp:textbox id="txtTest3" runat="server" />
    </span>
</p>
<p>
    <span id="foo4" ondblclick="ToggleEnabled( this ) ;">
        TextBox 4: <asp:textbox id="txtTest4" runat="server" />
    </span>
</p>
<p>
    <span id="foo5" ondblclick="ToggleEnabled( this ) ;">
        TextBox 5: <asp:textbox id="txtTest5" runat="server" />
    </span>
</p>
<p>
    <asp:button id="btnSubmit" onclick="btnSubmit_Click" runat="server" text="Submit" />
</p>
   
</form>
</body>
</html>

9 Comments

  • &quot;Elegance&quot; is overrated, IMHO. I wish could reclaim the time I've wasted trying to come up with an elegant solution when the &quot;dodgy&quot; one was just fine.

  • Hi Ricky, yes, your comments are quite true.



    In the real world I'd be happy enough shipping the stuff that I hacked together to do this.



    Thanks for the feedback!

  • The elegant solution isn't far off from what you have. Elegance is simplicity, and adding a custom control that renders it's own &lt;spans&gt;&lt;text&gt; and a hidden field per control would make things a bit easier. First the javascript would become easier since you aren't combining values into a single control. Second your code for handling the postback would also be encapsulated into the post back data handlers so you wouldn't have the big nested foreach loops.



    I'm not sure how long it would have taken you going this route. Looking at the problem, and having written a large number of composite controls, I could have probably hacked the sample up in 30 minutes as well.

  • Yeh, good point Justin, I think that I'll dummy up a custom control to see the difference in effort required.

  • Hi Darren



    I got question for you on this ? hehe



    Why not use simple Input controls ?



    If you are using your own Field to carry information is there any need on using webcontrol at all ?



    You can chnage the background colors using styles ?









  • 'language=&quot;JavaScript&quot;' should be replaced with 'type=&quot;text/javascript&quot;', btw. :-)

  • oooh! that's pretty pedantic :-) old habits die hard I guess!

  • Pedantic? Believe it or not, browsers and compilers tend to act that way.

  • Hey there! I'm at work browsing your blog from my new apple iphone! Just wanted to say I love reading through your blog and look forward to all your posts! Keep up the superb work!

Comments have been disabled for this content.