Customizing RadioButtonList

Last post 03-10-2007 12:06 PM by aivanoff. 4 replies.

Sort Posts:

  • Customizing RadioButtonList

    03-09-2007, 11:53 PM
    • Member
      148 point Member
    • aivanoff
    • Member since 02-28-2006, 12:08 PM
    • Posts 45

    I am trying to develop a server control which behaves like RadioButtonList but uses div or span instead of RadioButton. I tried to inherit RadioButtonList and override RenderItem but ran into a problem when SelectedIndexChanged stops firing.

    I wonder if RadioButtonList can even be extended in this way. And if not what are my other choices?

    Thank you,
    Alex

    Alex
  • Re: Customizing RadioButtonList

    03-10-2007, 4:08 AM
    • All-Star
      46,032 point All-Star
    • joteke
    • Member since 06-16-2002, 3:24 PM
    • Kyro, Finland
    • Posts 6,879
    • ASPInsiders
      Moderator
      TrustedFriends-MVPs

    How did you implement it? Did you call base.RenderItem in your impl somewhere. For example this works quite fine (in ASP.NET 2.0)

    public class MyRadioButtonList : RadioButtonList
        {
            protected override void RenderItem(ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
            {
                writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "1px");
                writer.AddStyleAttribute(HtmlTextWriterStyle.BorderColor, "black");
                writer.AddStyleAttribute(HtmlTextWriterStyle.BorderStyle, "solid");
                writer.RenderBeginTag(HtmlTextWriterTag.Div); 
                base.RenderItem(itemType, repeatIndex, repeatInfo, writer);
                writer.RenderEndTag(); 
            }
        }
      Butr certainly it works as it calls the base implementation which uses RadioButton controls internally. basically you could be able to do it without rdb, but you need to deal with the IPostBackDataHandler implementation of the RadioButtonList which expects event argument toi LoadPostdata to be value of the selected item. E.g you'd need to be able to pass the value of the selected item so that it is posted back to the server, so that RadioButtonList "recognizes" it to be a selection and changes for example the selected item and raises SelectedIndexChanged event.

     

    Thanks,

    Teemu Keiski
    Finland, EU
  • Re: Customizing RadioButtonList

    03-10-2007, 9:31 AM
    • Member
      148 point Member
    • aivanoff
    • Member since 02-28-2006, 12:08 PM
    • Posts 45

    Can you provide some pointers how to properly deal with IPostBackDataHandler, LoadPostData etc.? This is where I failed. And this is exactly what I need: replace radio button with something else.

    Alex
  • Re: Customizing RadioButtonList

    03-10-2007, 10:54 AM
    Answer
    • All-Star
      46,032 point All-Star
    • joteke
    • Member since 06-16-2002, 3:24 PM
    • Kyro, Finland
    • Posts 6,879
    • ASPInsiders
      Moderator
      TrustedFriends-MVPs

    Edit: Updated to support both AutoPostBack and non-AutoPostBack scenarios

    Replace with what? Are you going to show some sort of image instead of RB? There could be multiple ways of doing it and the impact is then on implementation of RenderItem and possibly overriding LoadPostdata and perhaps registering some script to accomplish it. For example writing the text and value of ListItem into custom attribute on DIV element and then setting into hidden field with javascript (hidden field named based on the index of the ListItem that was clicked and value then it's value). The plumbing could also be helped in how you put it to pass the valöues tpo the server. For example one hack:

     
    public class MyRadioButtonList : RadioButtonList
        {
    
            private string HiddenValueFieldName
            {
                get
                {
                    return this.ClientID + "_theValue";
                }
            }
    
            private string DivArrayName
            {
                get
                {
                    return this.ClientID + "_theDivs";
                }
            }
    
            protected override void OnPreRender(EventArgs e)
            {
                base.OnPreRender(e);
                
                string script = "";
                script += "function setValue(theDiv){";
                script += "document.getElementById('" + HiddenValueFieldName + "').value = theDiv.getAttribute('value');";
    
                if(this.AutoPostBack) 
                    script += Page.ClientScript.GetPostBackEventReference(this, "", false);
                else{
                    script += "theDiv.style.backgroundColor='gray';";
                    script += "for(i=0;i<" + DivArrayName + ".length;i++){";
                    script += "var theVal=" + DivArrayName + "[i];";
                    script += "if(theDiv.getAttribute('id') != theVal)";
                    script += "document.getElementById(theVal).style.backgroundColor='white';";
                    script += "}";
                }
    
                script += "}";
                Page.ClientScript.RegisterStartupScript(this.GetType(),"setValue",script,true);
    
                //register the hidden field
                Page.ClientScript.RegisterHiddenField(HiddenValueFieldName, "");
    
                //register that LoadPostdata will be called even if control's UniqueID is not on post data collection
                Page.RegisterRequiresPostBack(this); 
    
                //this is playing for the client-side color selection :-)
                System.Text.StringBuilder sb = new System.Text.StringBuilder();
                foreach(ListItem litem in this.Items)
                {
                    sb.Append("'"); 
                    sb.Append(this.ClientID);
                    sb.Append(this.IdSeparator);
                    sb.Append(litem.Value);
                    sb.Append("'"); 
                    sb.Append(","); 
                }
    
                string s = sb.ToString().TrimEnd(',');
                Page.ClientScript.RegisterArrayDeclaration(this.ClientID + "_theDivs", s); 
                
            }
    
            protected override bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
            {
                //wrap the existing loading logic to get the LiostItem value from our hidden field
                return base.LoadPostData(HiddenValueFieldName, postCollection);
            }
    
            protected override void RenderItem(ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
            {
                //render the thing out as a DIV
                ListItem item=this.Items[repeatIndex];
                writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "1px");
                writer.AddStyleAttribute(HtmlTextWriterStyle.BorderColor, "black");
                writer.AddStyleAttribute(HtmlTextWriterStyle.BorderStyle, "solid");
    
                writer.AddAttribute(HtmlTextWriterAttribute.Value, item.Value);
                writer.AddAttribute(HtmlTextWriterAttribute.Onclick, "setValue(this)");
                writer.AddAttribute(HtmlTextWriterAttribute.Id, this.UniqueID + this.IdSeparator + item.Value);  
         
                if (item.Selected)
                    writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, "gray");
    
                writer.RenderBeginTag(HtmlTextWriterTag.Div);
                writer.Write(item.Text); 
                writer.RenderEndTag(); 
               
            }
        }
     

     

    Note: I just played this out based on my imagination so it *really* might not be what you need but demonstrates the idea. :-)

    Thanks,

    Teemu Keiski
    Finland, EU
  • Re: Customizing RadioButtonList

    03-10-2007, 12:06 PM
    Answer
    • Member
      148 point Member
    • aivanoff
    • Member since 02-28-2006, 12:08 PM
    • Posts 45

    I found a simpler solution. A simple javascript sets the width of <input type="radio"> to 0px making it disappear. So now RadionButtonList looks like a list of labels but behaves like RadionButtonList. Next step is customizing labels using javascript with styles.

    Looks like I am going to create extender control next.

    Alex
Page 1 of 1 (5 items)