Html.ActionLink as a button or an image, not a link
Asked Answered
H

23

338

In the latest (RC1) release of ASP.NET MVC, how do I get Html.ActionLink to render as a button or an image instead of a link?

Hotbed answered 27/2, 2009 at 20:11 Comment(3)
With MVC 3.0 you can try this way <a href="@Url.Action("Index","Home")"><img src="@Url.Content("~/Themes/Gold/images/try-onit.png")" alt="Home" /></a> More info, Try this mycodingerrors.blogspot.com/2012/08/…Coincidentally
Having just spent a few hours doing this "properly" (e.g. by extending AjaxHelper with an ActionButton) I thought I would share it below.Charin
It's hilarious to me that seven years later, this question is still getting upvotes. Apparently in 2016 there's still no simple, intuitive way to do this.Hotbed
M
335

Late response but you could just keep it simple and apply a CSS class to the htmlAttributes object.

<%= Html.ActionLink("Button Name", "Index", null, new { @class="classname" }) %>

and then create a class in your stylesheet

a.classname
{
    background: url(../Images/image.gif) no-repeat top left;
     display: block;
     width: 150px;
     height: 150px;
     text-indent: -9999px; /* hides the link text */
}
Miniaturize answered 20/3, 2009 at 20:23 Comment(9)
This works perfectly for me, though you may need to replace null with a routeValues object depending on where you are linking to.Afterdinner
How do you handle the Button name string you assign in the action link parameter then. This did not work for me.Intelligence
Same problem, for me too, the linkText param can't be null or and empty string however I'm looking for an image button replacment.Rosinweed
For SEO and Accessibility you would need the link button text.. i've updated the CSS in the question to handle this...Miniaturize
It works perfect but this button image doesnt appears in the print of the webpage.Lotion
that is bad in all sorts of ways, it dose not work in all browsers, and you are using a side effect as functionality. witch makes it a very bad practice don't use it. Just because it works it does not make it a good solution.Roentgenotherapy
@Pedro - How about you suggest a useful alternative as I'm sure it DOSE in fact work in all browsers and additionally keeps the HTML lean and semantic. Care to elaborate?Miniaturize
@Miniaturize - jslatts solution is the correct one and no it wont work in IE11 and just because it work's in the current browsers it is a very bad practice as you are using a side effect as functionality and if the implementation changes the side effect WILL stop working.Roentgenotherapy
Instead of hiding the button text using the text-indent: -9999px; why not do this: <%= Html.ActionLink(" ", "Index", null, new { @class="classname" }) %> Using a space for the name.Exploratory
R
357

I like to use Url.Action() and Url.Content() like this:

<a href='@Url.Action("MyAction", "MyController")'>
    <img src='@Url.Content("~/Content/Images/MyLinkImage.png")' />
</a>

Strictly speaking, the Url.Content is only needed for pathing is not really part of the answer to your question.

Thanks to @BrianLegg for pointing out that this should use the new Razor view syntax. Example has been updated accordingly.

Ruble answered 5/5, 2010 at 14:42 Comment(3)
If you want a html helper for that: fsmpi.uni-bayreuth.de/~dun3/archives/…Bruin
This works perfectly. Just note that in MVC5 the syntax has changed and should be <a href='@Url.Action("MyAction", "MyController")'> and <img src='@Url.Content("~/Content/Images/MyLinkImage.png")' />. ThanksHallucinogen
it produced it with NAN text? what to doVeasey
M
335

Late response but you could just keep it simple and apply a CSS class to the htmlAttributes object.

<%= Html.ActionLink("Button Name", "Index", null, new { @class="classname" }) %>

and then create a class in your stylesheet

a.classname
{
    background: url(../Images/image.gif) no-repeat top left;
     display: block;
     width: 150px;
     height: 150px;
     text-indent: -9999px; /* hides the link text */
}
Miniaturize answered 20/3, 2009 at 20:23 Comment(9)
This works perfectly for me, though you may need to replace null with a routeValues object depending on where you are linking to.Afterdinner
How do you handle the Button name string you assign in the action link parameter then. This did not work for me.Intelligence
Same problem, for me too, the linkText param can't be null or and empty string however I'm looking for an image button replacment.Rosinweed
For SEO and Accessibility you would need the link button text.. i've updated the CSS in the question to handle this...Miniaturize
It works perfect but this button image doesnt appears in the print of the webpage.Lotion
that is bad in all sorts of ways, it dose not work in all browsers, and you are using a side effect as functionality. witch makes it a very bad practice don't use it. Just because it works it does not make it a good solution.Roentgenotherapy
@Pedro - How about you suggest a useful alternative as I'm sure it DOSE in fact work in all browsers and additionally keeps the HTML lean and semantic. Care to elaborate?Miniaturize
@Miniaturize - jslatts solution is the correct one and no it wont work in IE11 and just because it work's in the current browsers it is a very bad practice as you are using a side effect as functionality and if the implementation changes the side effect WILL stop working.Roentgenotherapy
Instead of hiding the button text using the text-indent: -9999px; why not do this: <%= Html.ActionLink(" ", "Index", null, new { @class="classname" }) %> Using a space for the name.Exploratory
C
96

Borrowing from Patrick's answer, I found that I had to do this:

<button onclick="location.href='@Url.Action("Index", "Users")';return false;">Cancel</button>

to avoid calling the form's post method.

Chilopod answered 20/9, 2012 at 13:43 Comment(0)
G
50

Call me simplistic, but I just do:

<a href="<%: Url.Action("ActionName", "ControllerName") %>">
    <button>Button Text</button>
</a>

And you just take care of the hyperlink highlight. Our users love it :)

Gpo answered 27/9, 2011 at 4:29 Comment(4)
@Ben one reason this doesn't have many votes is it was answered so much later than other answers. I was about to vote it up but tested out what @Slider345 said and can confirm this doesn't work as desired in IE 7 or 8. In any case, if you choose to use it, don't forget to set the css of the link (hover and active) to text-decoration:none to get rid of that stupid underline. This is necessary for some browsers (Firefox 11.0 for sure).Fisken
But you're not supposed to nest buttons inside a elements, visa versa. At least it's not a valid way of doing it in HTML 5Introjection
Yep, this doesn't work in even IE10, for the reasons Patrick explains.Shatter
No nesting of buttons inside of action element. #6394327Touber
C
25

Using bootstrap this is the shortest and cleanest approach to create a link to a controller action that appears as a dynamic button:

<a href='@Url.Action("Action", "Controller")' class="btn btn-primary">Click Me</a>

Or to use Html helpers:

@Html.ActionLink("Click Me", "Action", "Controller", null, new { @class = "btn btn-primary" })
Carboxylate answered 28/3, 2017 at 4:10 Comment(1)
I have to agree with the cleanness. 100.Anatole
G
16

if you don't want to use a link, use button. you can add image to button as well:

<button type="button" onclick="location.href='@Url.Action("Create", "Company")'" >
   Create New
   <img alt="New" title="New" src="~/Images/Button/plus.png">
</button>

type="button" performs your action instead of submitting form.

Gimcrack answered 2/10, 2014 at 2:41 Comment(0)
S
15

Just simply :

<button onclick="@Url.Action("index", "Family", new {familyid = Model.FamilyID })">Cancel</button>
Saylor answered 28/1, 2012 at 17:52 Comment(3)
this still invokes the post method of the view for me, any idea why?Chilopod
This isn't valid syntax. IE10 throws a JavaScript critical error with this line, "SCRIPT5017: Syntax error in regular expression".Shatter
Good answer, but without surrounding the onclick contents with location.href (so onclick="location.href='@Url.Action(....)'") I couldn't get it to work.Fluxion
D
15

A late answer but this is how I make my ActionLink into a button. We're using Bootstrap in our project as it makes it convenient. Never mind the @T since its only an translator we're using.

@Html.Actionlink("Some_button_text", "ActionMethod", "Controller", "Optional parameter", "html_code_you_want_to_apply_to_the_actionlink");

The above gives a link like this and it looks as the picture below:

localhost:XXXXX/Firms/AddAffiliation/F0500

picture demonstrating button with bootstrap

In my view:

@using (Html.BeginForm())
{
<div class="section-header">
    <div class="title">
        @T("Admin.Users.Users")
    </div>
    <div class="addAffiliation">
        <p />
        @Html.ActionLink("" + @T("Admin.Users.AddAffiliation"), "AddAffiliation", "Firms", new { id = (string)@WorkContext.CurrentFirm.ExternalId }, new { @class="btn btn-primary" })
    </div>
</div>

}

Hope this helps somebody

Distended answered 9/1, 2014 at 13:46 Comment(1)
Works cool! nice and simple, the htmlAttribute new { @class="btn btn-primary" }) +oneVolley
S
12

You can't do this with Html.ActionLink. You should use Url.RouteUrl and use the URL to construct the element you want.

Stroll answered 27/2, 2009 at 20:12 Comment(2)
Hi, sorry I am very new to MVC. How would I use the Url.RouteURL to achieve the image?Snailfish
What I meant is you can't generate a nested img tag (or button tag) with a simple call to ActionLink. Of course, CSS styling the a tag itself is a way to get around it, but nonetheless you can't get an img tag.Stroll
K
12

A simple way to do make your Html.ActionLink into a button (as long as you have BootStrap plugged in - which you probably have) is like this:

@Html.ActionLink("Button text", "ActionName", "ControllerName", new { @class = "btn btn-primary" })
Klee answered 30/6, 2017 at 14:46 Comment(0)
H
9

<button onclick="location.href='@Url.Action("NewCustomer", "Customers")'">Checkout >></button>

Huntingdonshire answered 5/3, 2012 at 14:4 Comment(2)
This worked for me on IE10. This is a good solution if you simply want to use a button rather than an image, although having to use using inline JavaScript for a simple link is probably not ideal.Shatter
(and just to be sure, I tested it on Opera, Safari, Chrome and Firefox and it worked)Shatter
K
8

Even later response, but I just ran into a similar issue and ended up writing my own Image link HtmlHelper extension.

You can find an implementation of it on my blog in the link above.

Just added in case someone is hunting down an implementation.

Kwapong answered 15/6, 2009 at 18:42 Comment(1)
Link appears to be inactive nowPrognostication
W
5
<li><a href="@Url.Action(  "View", "Controller" )"><i class='fa fa-user'></i><span>Users View</span></a></li>

To display an icon with the link

Wrestle answered 26/5, 2015 at 12:35 Comment(0)
L
4

Do what Mehrdad says - or use the url helper from an HtmlHelper extension method like Stephen Walther describes here and make your own extension method which can be used to render all of your links.

Then it will be easy to render all links as buttons/anchors or whichever you prefer - and, most importantly, you can change your mind later when you find out that you actually prefer some other way of making your links.

Lineberry answered 27/2, 2009 at 20:25 Comment(0)
V
3

you can create your own extension method
take look at my implementation

public static class HtmlHelperExtensions
{
    public static MvcHtmlString ActionImage(this HtmlHelper html, string action, object routeValues, string imagePath, string alt, object htmlAttributesForAnchor, object htmlAttributesForImage)
    {
        var url = new UrlHelper(html.ViewContext.RequestContext);

        // build the <img> tag
        var imgBuilder = new TagBuilder("img");
        imgBuilder.MergeAttribute("src", url.Content(imagePath));
        imgBuilder.MergeAttribute("alt", alt);
        imgBuilder.MergeAttributes(new RouteValueDictionary(htmlAttributesForImage));
        string imgHtml = imgBuilder.ToString(TagRenderMode.SelfClosing);

        // build the <a> tag
        var anchorBuilder = new TagBuilder("a");
        anchorBuilder.MergeAttribute("href", action != null ? url.Action(action, routeValues) : "#");
        anchorBuilder.InnerHtml = imgHtml; // include the <img> tag inside
        anchorBuilder.MergeAttributes(new RouteValueDictionary(htmlAttributesForAnchor));

        string anchorHtml = anchorBuilder.ToString(TagRenderMode.Normal);
        return MvcHtmlString.Create(anchorHtml);
    }
}

then use it in your view take look at my call

 @Html.ActionImage(null, null, "../../Content/img/Button-Delete-icon.png", Resource_en.Delete,
               new{//htmlAttributesForAnchor
                   href = "#",
                   data_toggle = "modal",
                   data_target = "#confirm-delete",
                   data_id = user.ID,
                   data_name = user.Name,
                   data_usertype = user.UserTypeID
               }, new{ style = "margin-top: 24px"}//htmlAttributesForImage
                    )
Veasey answered 16/8, 2016 at 16:39 Comment(0)
M
2

For Material Design Lite and MVC:

<a class="mdl-navigation__link" href='@Url.Action("MyAction", "MyController")'>Link Name</a>
Mouseear answered 30/10, 2018 at 17:42 Comment(0)
S
1
@using (Html.BeginForm("DeleteMember", "Member", new { id = Model.MemberID }))
    {
        <input type="submit" value="Delete Member" onclick = "return confirm('Are you sure you want to delete the member?');" />
    }
Suborder answered 11/1, 2012 at 3:35 Comment(0)
A
1

There seems to be lots of solutions on how to created a link that displays as an image, but none that make it appear to be a button.

There is only good way that I have found to do this. Its a little bit hacky, but it works.

What you have to do is create a button and a separate action link. Make the action link invisible using css. When you click on the button, it can fire the click event of the action link.

<input type="button" value="Search" onclick="Search()" />
 @Ajax.ActionLink("Search", "ActionName", null, new AjaxOptions {}, new { id = "SearchLink", style="display:none;" })

function Search(){
    $("#SearchLink").click();
 }

It may be a pain in the butt to do this every time you add a link that needs to look like a button, but it does accomplish the desired result.

Alvinia answered 11/10, 2013 at 19:35 Comment(0)
M
1

use FORMACTION

<input type="submit" value="Delete" formaction="@Url.Action("Delete", new { id = Model.Id })" />
Moorfowl answered 7/12, 2015 at 11:25 Comment(0)
I
0

Url.Action() will get you the bare URL for most overloads of Html.ActionLink, but I think that the URL-from-lambda functionality is only available through Html.ActionLink so far. Hopefully they'll add a similar overload to Url.Action at some point.

Irra answered 29/11, 2010 at 10:35 Comment(0)
P
0

Just found this extension to do it - simple and effective.

Palaeo answered 6/1, 2012 at 12:34 Comment(1)
Link is broken.Anatole
C
0

The way I have done it is to have the actionLink and the image seperately. Set the actionlink image as hidden and then added a jQuery trigger call. This is more of a workaround.

'<%= Html.ActionLink("Button Name", "Index", null, new { @class="yourclassname" }) %>'
<img id="yourImage" src="myImage.jpg" />

Trigger example:

$("#yourImage").click(function () {
  $('.yourclassname').trigger('click');
});
Camiecamila answered 3/5, 2012 at 13:58 Comment(0)
I
0

This is how I did it without scripting:

@using (Html.BeginForm("Action", "Controller", FormMethod.Get))
{
    <button type="submit" 
            class="btn btn-default" 
            title="Action description">Button Label</button>
}

Same, but with parameter and confirmation dialog:

@using (Html.BeginForm("Action", "Controller", 
        new { paramName = paramValue }, 
        FormMethod.Get, 
        new { onsubmit = "return confirm('Are you sure?');" }))
{
    <button type="submit" 
            class="btn btn-default" 
            title="Action description">Button Label</button>
}
Incandescent answered 19/6, 2016 at 22:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.