views:

967

answers:

3

I would like to be able to change the default behaviour of an ASP.NET link button so that the JavaScript postback call happens in the onclick event rather than having it as the href attribute.

This would mean that a user hovering over the button would not see the JavaScript in the browsers status bar.

Is this possible or should I attempt to abandon the link button altogether?

+1  A: 

You can use the OnClientClick attribute to set the javascript click event, but by default the LinkButton will still fire a postback. If this isn't desired, you could always add "return false;" to the end of your OnClientClick javascript call. This would keep the link from leaving the page.

<asp:LinkButton OnClientClick="alert('hi');return false;" runat="server" PostBackUrl="#" ID="TEST">TEST</asp:LinkButton>

CodeRot
you have 'OnClientClient, not OnClientClick =)
DDaviesBrackett
+1  A: 

if all you need to do is change the text in the status bar, take a look at this

the text can be changed from an onMouseOver event

Jim
+1  A: 

You can do it by writing a control adapter that outputs the javascript in the onclick instead of the href. There are a couple of linkbutton adapters listed in the patches for the cssfriendly control adapter set on this page: http://cssfriendly.codeplex.com/SourceControl/PatchList.aspx?ViewAll=true

I don't know if a link button adapter has been added to the release version.

But you could download one from this page and used it as a reference when creating your own adapter.

. . .

Update 10/10/2009:

I've actually changed my answer a bit, the control adapter idea will still work, but it might be easier to just to create a new control that inherits from linkbutton. I say this because you could just get the rendered output and replace the href with onclick, then you don't have to worry about losing any of the functionality of the linkbutton formatting, the only thing you lose is OnClientClick

Here is a control I wrote to add a NavigateURL property to a linkbutton, and when the NavigateURL is set, it will render the postback javascript in the onclick. It is pretty close to what you want. The reason I wrote this control is because I have paging on certain pages, and I want to provide paging links that search engines can follow, but have the postback functionality for regular users so that their filters get posted back.

using System;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;


namespace CustomControls
{

    /// <summary>
    /// This control renders the postback javascript in the onclick event if a href is passed in
    /// this allow the control to work as normal for browsers, but will provide an alternate link for 
    /// crawlers to follow.  If the href is not set it works identically to the original link button
    /// </summary>
    /// 
    [Themeable(true), ToolboxData("<{0}:OnClickLinkButton runat=server></{0}:OnClickLinkButton>")]
    public class OnClickLinkButton : LinkButton
    {




     [Browsable(true), DefaultValue(""), Bindable(true), Category("Navigation"), Description("Set the hyperlink url for the linkbutton for browsers without javascript")]
     public string NavigateURL
     {
      get
      {
       return ViewState["NavigateURL"] == null ? string.Empty : (string)ViewState["NavigateURL"];
      }
      set
      {
       ViewState["NavigateURL"] = value;
      }
     }

     protected override void Render(HtmlTextWriter output)
     {
      if (NavigateURL == string.Empty)
      {
       base.Render(output);
      }
      else
      {
       //we need to clear out the on client click because we are 
       //abusing the onclient click for our own purposes
       OnClientClick = "";
       StringWriter sw = new StringWriter();
       HtmlTextWriter hw = new HtmlTextWriter(sw);

       base.Render(hw);

       string RenderedOutput = sw.ToString();

       Match m = Regex.Match(RenderedOutput, @"doPostBack\(.+\)", RegexOptions.IgnoreCase);
       if (m.Success)
       {

        RenderedOutput = RenderedOutput.Replace("href", string.Format("href=\"{0}\" onclick", NavigateURL))
         .Replace(m.Value, m.Value + "; return false;");

       }


       output.Write(RenderedOutput);
      }

     }

    }


}
Chris Mullins
Thanks Chris, much appreciated. The situation you have described is pretty much exactly what I want to do! I'll take your code and have a play about with it.
Robert Dougan
You're welcome glad I could help
Chris Mullins