Html.ActionLink as a button or an image, not a link - asp.net-mvc

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?

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.

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 */
}

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.

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 :)

Using bootstrap this is the shortest and cleanest approach to create a link to a controller action that appears as a dynamic button:
Click Me
Or to use Html helpers:
#Html.ActionLink("Click Me", "Action", "Controller", new { #class = "btn btn-primary" })

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.

Just simply :
<button onclick="#Url.Action("index", "Family", new {familyid = Model.FamilyID })">Cancel</button>

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
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

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

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" })

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

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.

<li><i class='fa fa-user'></i><span>Users View</span></li>
To display an icon with the link

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.

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
)

For Material Design Lite and MVC:
<a class="mdl-navigation__link" href='#Url.Action("MyAction", "MyController")'>Link Name</a>

#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?');" />
}

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.

use FORMACTION
<input type="submit" value="Delete" formaction="#Url.Action("Delete", new { id = Model.Id })" />

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

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');
});

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.

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>
}

Related

How do I make an MVC ActionLink call a POST method?

I have an HTML.ActionLink that is acting perfectly except it is not hitting the POST method.
#Html.ActionLink("Join Now!", "JoinFleet", "Members", new { ID =Model.ID , fleet = 1 }, new { #class = "btn btn-primary" })
it results with the following URL as expected.
http://localhost:64096/Members/JoinFleet/2403?fleet=1
I need it to work exactly like this but, hit my POST JoinFleet method.
I toyed with a few ways I could accomplish this task. I was also trying to pass the value of a checked radiobutton to a using as a param.
#using (Html.BeginForm("JoinFleet", "Members", new { fleet = 3 },
FormMethod.Post, new { #class = "form-group" }))
and then submit with a standard submit button
I would be very happy with either making that Action hit my post method in my controller or passing the value of the radio button as the param value for fleet in my using.
When creating a link to a controller action in ASP.NET MVC, using the generic ActionLink method is preferable, because it allows for strongly typed links that are refactoring friendly.
Default: ActionLink
#Html.ActionLink("Delete", "Delete", new { id = item.ID })
Using Button:
<input type="button" title="Delete" value="D" onclick="location.href='#Url.Action("Delete", "movies", new { id = item.ID })'" />
Using Image:
<a href="#Url.Action("Delete", "movies", new { id = item.ID })" title="Edit">
<img src="../../Content/Images/Delete.png" />
</a>

How to have a button in a form post to a different action

Let's say I have a form listing some items:
#using (Html.BeginForm("Index", "SagePayServerInframe", FormMethod.Post))
{
if (Model.Tokens.Any())
{
<h2>Select an existing card</h2>
for (int i = 0; i < Model.Tokens.Count; i++)
{
<div class="sagepay-wrapper">
<div><span>Card Type:</span> #Model.Tokens[i].CardType</div>
<div><span>Last 4 Digits:</span> #Model.Tokens[i].Last4Digits</div>
<div><span>Expiry Date:</span> #Model.Tokens[i].ExpiryDate</div>
<div>
#Html.RadioButtonFor(m => m.SelectedTokenId, Model.Tokens[i].Id, new { #id = "SelectedTokenId" + i })
<label for="SelectedTokenId#(i)">SELECT</label>
</div>
</div>
}
}
<input type="submit" value="Continue" class="uppercase"/>
}
Now, I want to put a Delete button against each entry as well. I can't seem to have another form within the existing form (it wouldn't show on the page when I tried a new Html.BeginForm).
How would I achieve this? Ideally, I'd like to be able to post back to a DeleteToken action. I get the feeling I'm missing something simple but not sure what it is.
Use a Jquery hack like (Code not tested, may have syntax error, sorry for that)
When button1 is pressed, access the form object and reset the form url.
$("#button1").click(form(){
$(this).form.URL = "../Controller1/Action1";
});
AND when button2 is clicked
$("#button2").click(form(){
$(this).form.URL = "../Controller2/Action2";
});

HTML.ActionLink vs Url.Action in ASP.NET Razor

Is there any difference between HTML.ActionLink vs Url.Action or they are just two ways of doing the same thing?
When should I prefer one over the other?
Yes, there is a difference. Html.ActionLink generates an tag whereas Url.Action returns only an url.
For example:
#Html.ActionLink("link text", "someaction", "somecontroller", new { id = "123" }, null)
generates:
link text
and Url.Action("someaction", "somecontroller", new { id = "123" }) generates:
/somecontroller/someaction/123
There is also Html.Action which executes a child controller action.
Html.ActionLink generates an tag automatically.
Url.Action generates only an url.
For example:
#Html.ActionLink("link text", "actionName", "controllerName", new { id = "<id>" }, null)
generates:
link text
and
#Url.Action("actionName", "controllerName", new { id = "<id>" })
generates:
/controllerName/actionName/<id>
Best plus point which I like is using Url.Action(...)
You are creating anchor tag by your own where you can set your own linked text easily even with some other html tag.
<a href="#Url.Action("actionName", "controllerName", new { id = "<id>" })">
<img src="<ImageUrl>" style"width:<somewidth>;height:<someheight> />
#Html.DisplayFor(model => model.<SomeModelField>)
</a>
#HTML.ActionLink generates a HTML anchor tag. While #Url.Action generates a URL for you. You can easily understand it by;
// 1. Item Definition
#HTML.ActionLink("Item Definition", "ActionMethod", "ControllerName")
// 2. /ControllerName/ActionMethod
#Url.Action("ActionMethod", "ControllerName")
// 3. Item Definition
Item Definition
Both of these approaches are different and it totally depends upon your need.
<p>
#Html.ActionLink("Create New", "Create")
</p>
#using (Html.BeginForm("Index", "Company", FormMethod.Get))
{
<p>
Find by Name: #Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Search" />
<input type="button" value="Clear" onclick="location.href='#Url.Action("Index","Company")'"/>
</p>
}
In the above example you can see that If I specifically need a button to do some action, I have to do it with #Url.Action whereas if I just want a link I will use #Html.ActionLink.
The point is when you have to use some element(HTML) with action url is used.
You can easily present Html.ActionLink as a button by using the appropriate CSS style.
For example:
#Html.ActionLink("Save", "ActionMethod", "Controller", new { #class = "btn btn-primary" })
I used the code below to create a Button and it worked for me.
<input type="button" value="PDF" onclick="location.href='#Url.Action("Export","tblOrder")'"/>

Problem binding action parameters using FCKeditor, AJAX and ASP.NET MVC

I have a simple ASP.Net MVC View which contains an FCKeditor text box (created using FCKeditor's Javascript ReplaceTextArea() function). These are included within an Ajax.BeginForm helper:
<% using (Ajax.BeginForm("AddText", "Letters",
new AjaxOptions() { UpdateTargetId = "addTextResult" }))
{%>
<div>
<input type="submit" value="Save" />
</div>
<div>
<%=Html.TextArea("testBox", "Content", new { #name = "testBox" })%>
<script type=""text/javascript"">
window.onload = function()
{
var oFCKeditor = new FCKeditor('testBox') ;
var sBasePath = '<%= Url.Content("~/Content/FCKeditor/") %>';
oFCKeditor.BasePath = sBasePath;
oFCKeditor.ToolbarSet = "Basic";
oFCKeditor.Height = 400;
oFCKeditor.ReplaceTextarea() ;
}
</script>
<div id="addTextResult">
</div>
<%} %>
The controller action hanlding this is:
[ValidateInput(false)]
public ActionResult AddText(string testBox)
{
return Content(testBox);
}
Upon initial submission of the Ajax Form the testBox string in the AddText action is always "Content", whatever the contents of the FCKeditor have been changed to. If the Ajax form is submitted again a second time (without further changes) the testBox paramater correctly contains the actual contents of the FCKeditor.
If I use a Html.TextArea without replacing with FCKeditor it works correctly, and if I use a standard Post form submit inplace of AJAX all works as expected.
Am I doing something wrong?
If not is there a suitable/straight-forward workaround for this problem?
The problem is unrelated to MVC but caused by using FCKeditor in conjunction with AJAX. To fix in the code above I added the following to the submit button's onclick event:
<input type="submit" value="Save" onclick="FCKeditorAPI.GetInstance('TestBox').UpdateLinkedField();" />
For more information see here.

Correct way to have an image link in asp.net mvc?

Something like this might had worked
<%= Html.RouteLink("", new { controller = "Article", action = "Details", id = A.ArticleID}, new { #class = "image-link" })%>
Except it doesnt like an empty title.
This could work.
<a href="<%= Url.Action("Article", "Details", new {id = A.ArticleID}) %>">
<img src="<% //Your image src here %>" />
</a>
Several people (my company included) have dabbled with creating something that does this in a HtmlHelper, but in the end, it seemed best to do it like this.

Resources