HTML button calling an MVC Controller and Action method - html

I know this isn't right, but for the sake of illustration I'd like to do something like this:
<%= Html.Button("Action", "Controller") %>
My goal is to make an HTML button that will call my MVC controller's action method.

No need to use a form at all unless you want to post to the action. An input button (not submit) will do the trick.
<input type="button"
value="Go Somewhere Else"
onclick="location.href='<%: Url.Action("Action", "Controller") %>'" />

Razor syntax is here:
<input type="button" value="Create" onclick="location.href='#Url.Action("Create", "User")'" />

<button type="button" onclick="location.href='#Url.Action("MyAction", "MyController")'" />
type="button" prevents page from submitting, instead it performs your action.

Try this:
#Html.ActionLink("DisplayText", "Action", "Controller", route, attribute)
This should work for you.

You can use Url.Action to specify generate the url to a controller action, so you could use either of the following:
<form method="post" action="<%: Url.Action("About", "Home") %>">
<input type="submit" value="Click me to go to /Home/About" />
</form>
or:
<form action="#">
<input type="submit" onclick="parent.location='<%: Url.Action("About", "Home") %>';return false;" value="Click me to go to /Home/About" />
<input type="submit" onclick="parent.location='<%: Url.Action("Register", "Account") %>';return false;" value="Click me to go to /Account/Register" />
</form>

This is how you can submit your form to a specific controller and action method in Razor.
<input type="submit" value="Upload" onclick="location.href='#Url.Action("ActionName", "ControllerName")'" />

Building on couple of the above answers, you could do this:
<button onclick="location.href='#Url.Action("ActionName", "ControllerName")'" />

Of all the suggestions, nobdy used the razor syntax (this is with bootstrap styles as well). This will make a button that redirects to the Login view in the Account controller:
<form>
<button class="btn btn-primary" asp-action="Login" asp-
controller="Account">#Localizer["Login"]</button>
</form>

it's better use this example
<a href="#Url.Action("Register","Account", new {id=Item.id })"
class="btn btn-primary btn-lg">Register</a>

The HTML <button> element can only postback to the form containing it.
Therefore, you need to make a form that POSTs to the action, then put a <button> or <input type="submit" /> in the form.

So, I'm using Razor but this will work using either. I'm basically wrapping a button in a link.
<a href="Controller/ActionMethod">
<input type="button" value="Click Me" />
</a>

Despite onclick Method you can also use formaction as follows:
<button type="submit" id="button1" name="button1" formaction='#Url.Action("Action", "Controller")'>Save</button>

Use this example :
<button name="nameButton" id="idButton" title="your title" class="btn btn-secondary" onclick="location.href='#Url.Action( "Index","Controller" new { id = Item.id })';return false;">valueButton</button>

In case if you are getting an error as "unterminated string constant", use the following razor syntax :
<input type="button" onclick="#("location.href='"+ Url.Action("Index","Test")+ "'")" />

When you implement the action in the controller, use
return View("Index");
or
return RedirectToAction("Index");
where Index.cshtml (or the page that generates the action) page is already defined. Otherwise you are likely encountering "the view or its master was not found..." error.
Source: https://blogs.msdn.microsoft.com/aspnetue/2010/09/17/best-practices-for-asp-net-mvc/

If you are in home page ("/Home/Index") and you would like to call Index action of Admin controller, following would work for you.
<li>Admin</li>

it's better use this example.
Call action and controller using a ActionLink:
#Html.ActionLink("Submit", "Action", "Controller", route, new { #class = "btn btn-block"})

OK, you basically need to pass the action to the button and call it when click happens, it doesn't need to be inside a from, you can use HTML onclick on button to trigger it when the button get clicked...
<button id="my-button" onclick="location.href='#Url.Action("YourActionName", "YourControllerName")'">Submit</button>

You can always play around with htmlHelpers and build some stuff
public static IHtmlContent BtnWithAction(this IHtmlHelper htmlHelper, string id, string text, string css="", string action="", string controller="")
{
try
{
string str = $"<button id=\"{id}\" class=\"{css}\" type=\"button\" ###>{text}</button>";
if (!string.IsNullOrEmpty(action) && !string.IsNullOrEmpty(controller))
{
string url = ((TagBuilder)htmlHelper.ActionLink("dummy", action, controller)).Attributes["href"];
var click = !string.IsNullOrEmpty(url) ? $"onclick=\"location.href='{url}'\"" : string.Empty;
return new HtmlString(str.Replace("###", click));
}
return new HtmlString(str.Replace("###", string.Empty));
}
catch (Exception ex)
{
Log.Error(ex, ex.Message);
var fkup = "<script>alert(\"assumption is the mother of all failures\")</script>";
return new HtmlString(fkup);
}
}
And then on the view call it like this
#Html.BtnWithAction("btnCaretakerBack", "Back", "btn btn-primary float-right", "Index", "Caretakers")

Related

taking input from button in thymeleaf

I am displaying a form to user with some details and then user clicks approve and reject. In the backend, I want to take this in one property - userAction, which can be "approve" or "reject".
How can I add input to the buttons that user clicks? And then this input is part of the object requestDto.
<form th:action="#{/mission/store/{uuid}(uuid=${uuid})}" th:object="${requestDto}" method="post" class="mission_form">
<div class="wizard-header">
<h3 class="wizard-title">
Approve Mission
</h3>
<h5>Should you chose to accept this mission, press approve.</h5>
</div>
<div class="wizard-footer">
<!--<div class="pull-right">-->
<input type='button' class="btn btn-success" name='approve' value='Approve' />
<!--</div>-->
<div class="pull-left">
<input type='button' th:field="*{}" class='btn btn-danger' name='previous' value='Decline' />
</div>
<div class="clearfix"></div>
</div>
</form>
First define a proper DataTransferObject:
public class MyRequestDto {
private String userAction;
// don't forget getters and setters
}
Then add a object of that class to your model
// if you are return a M&V-object:
ModelAndView mv = new ModelAndView("viewName")
ModelAndView.addObject("requestDto", new MyRequestDto());
// if you define a Model-Object as input-parameter:
Model.addAttribute("requestDto", new MyRequestDto());
Define a form like this (I used button-elements). The point is not to use the th:field attribute:
<form th:action="...." method="POST" th:object="${requestDto}">
<button name="userAction" value="approve" >Approve</button>
<button name="userAction" value="reject" >Reject</button>
</form>
Recieve the DataTransferObject by adding this to your controllers input-paramters (the controller that handels the post request):
... #Valid RequestDto requestDto, BindingResult bindingResult, ....
Now you can access requestDto's userAction-Attribute. The value is approve if you click the first button and it is reject if you click the second button. First you can check if there are binding errors by checking bindingResults.hasErrors().

Opening a different tab on button click and redirecting to another html

I know there are similar questions, but the answers and suggestions are not working for me and i am unable to understand the error.
On click of a button, I want to load another HTML in a new tab. When I try, "www.google.com", I am able to do so. But when I try to load an HTML which I have, I am unable to do so.
Here is the relevant html code :
<div id="button">
<a href="www.google.com"
target="_blank"><input type="button" value="Visualisation"></a><!-- THIS WORKS -->
<form action="/Users/tarun/Work/marchDemo/public/views/tree_custom.html"
target="_blank">
<input type="submit"
value="Go to Google" />
</form><!-- THIS Fails -->
<input type=button
onClick="location.href='tree_custom.html'"
value='click here'
target="_blank"><!-- THIS Fails -->
</div>
The error I get is this, which I am not able to debug :
Error: Not Found
at /Users/tarun/Work/marchDemo/app.js:41:13
at Layer.handle [as handle_request] (/Users/tarun/Work/marchDemo/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/tarun/Work/marchDemo/node_modules/express/lib/router/index.js:312:13)
at /Users/tarun/Work/marchDemo/node_modules/express/lib/router/index.js:280:7
at Function.process_params (/Users/tarun/Work/marchDemo/node_modules/express/lib/router/index.js:330:12)
at next (/Users/tarun/Work/marchDemo/node_modules/express/lib/router/index.js:271:10)
at /Users/tarun/Work/marchDemo/node_modules/express/lib/router/index.js:618:15
at next (/Users/tarun/Work/marchDemo/node_modules/express/lib/router/index.js:256:14)
at Function.handle (/Users/tarun/Work/marchDemo/node_modules/express/lib/router/index.js:176:3)
at router (/Users/tarun/Work/marchDemo/node_modules/express/lib/router/index.js:46:12)
You can use onclick="window.open('tree_custom.html')" with target="_blank" instead of using location.href
<div id="button">
<a href="www.google.com"
target="_blank"><input type="button" value="Visualisation"></a><!-- THIS WORKS -->
<form action="/Users/tarun/Work/marchDemo/public/views/tree_custom.html"
target="_blank">
<input type="submit"
value="Go to Google" />
</form><!-- THIS works -->
<input type=button onclick="window.open('tree_custom.html')"
value='click here'
target="_blank"><!-- THIS WORKS -->
</div>
Check working plunker : https://plnkr.co/edit/PQk5al?p=preview
If you're using Angular, I would suggest using ng-click. Then you can bind a method that's defined in your controller to the ng-click. Which will open a new tab with the desired url when the user clicks your button.
body.html
<div ng-controller="exampleCtrl as ctrl">
<button ng-click="ctrl.directToGoogle()"></button>
</div>
index.js
angular.module('exampleModule', [])
.controller('exampleCtrl', ['$scope', '$window',
function ($scope, $window) {
$scope.directToGoogle = function () {
$window.open('https://www.google.com', '_blank')
}])
This would be a simple and contrived example of how to bind a method to ng-click and do what you described in your question earlier.

Submit a form with href

I set the if of the form is as follows:
#using (Html.BeginForm(new {#id="frmHomeInsurance"}))
and instead of using a submit button, I would like to have a submit link.
So, I would like to replace the following:
<input type="submit" value="Get your quote now!" class="btn btn-default"/>
with the following:
<span class="fa fa-comments-o"></span>Get your<br>quote now!
In theory, it should reach at my 'Create' action in my HomeInsurance controller, however, it's not.
Is there anything else I should declare before?
Update:
The action is as follows:
// POST: HomeInsurance/Create
[HttpPost]
public ActionResult Create(HomeInsuranceModel model)
{
}
You can't directly use the href to submit the form.
Create the form like this:
#using(Html.BeginForm("Create", "HomeInsurance", FormMethod.Post, new {enctype = "multipart/form-data"}))
{
<define you form>
}
and then use your anchor tag to submit it(no href is needed):
<a href="javascript:;" class="wow zoomIn" data-wow-delay="0.2s"
onclick="document.forms['frmHomeInsurance'].submit(); return false;">
<span class="fa fa-comments-o"></span>Get your<br>quote now!
</a>
if you want to use the href you can do this but its not very pretty:
<a href="#Url.Action("Create", "HomeInsurance")"
onclick="var e=document.getElementById('yourFormId').action=this.href;e.submit();return false">
Submit</a>

Html.BeginForm inside of Html.BeginForm MVC3

I have a main view that renders two partial views. The main view encompasses both of the partial views within a form. Each of the partial views also contain forms. All 3 views share the same viewmodel. What I want to do is encapsulate the data from all views with the main view, and run specific Controller action results with the partial views.
I want to know if this is even possible. When debugging I see that my content always posts to the HTTPPost of the Main views form. I have submit buttons for each of the forms accordingly. Sorry for the code post, its coming out all split up.
Main View:
#using (Html.BeginForm("Main", "Registration", FormMethod.Post,
new { #class="mainform" }))
{
<form>
<fieldset>
<div id ="option1" class="conglomerate">
#Html.Partial("_GetBusiness")
</div>
<div id ="option2" class="dealership">
#Html.Partial("_GetLocation")
</div>
<button type="submit" value="Create" class="buttonBlue" id="">
<span>Create a new dealer</span>
</button>
</fieldset>
</form>
Partial 1
#using (Html.BeginForm("CreateBusiness", "Business", FormMethod.Post,
new { #class="buisinessform" }))
{
<form>
<div class="editor-field">
#Html.DropDownListFor(m =>m.BusinessId, new SelectList(Model.Businesses,
"BusinessId", "BusinessName"), "")
</div>
<label>Your company not listed? Register yours below:</label>
<div class="editor-label">
#Html.LabelFor(model => model.BusinessName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.BusinessName)
#Html.ValidationMessageFor(model => model.BusinessName)
</div>
<button type="Button" value="" class="buttonBlue"id="TestSubmit">
<span>Add Dealer</span>
</button>
<div class ="confirm">
<button type="submit" value="Create" class="buttonBlue" id="">
<span>Click here to confirm dealer addition</span>
</button>
</div>
</form>
}
As Dave mentions, It is not valid HTML to nest forms. It's not just HTML5, but any version of HTML.
It might work in some browsers, in certain circumstances, but it is never valid. And you can never depend on what will happen even if it does seem to work. Your best course of action is to use multiple non-nested forms on a page.
Can you explain why you think you need nested forms?
No, you cannot have nested forms. Sorry.
See HTML5 guidelines
"Flow content, but with no form element descendants"

How to display the values from one partial view control(Search) to a web grid partial view control?

In my view i have two partial views (Search,webgrid). When i click the update button in the search , the values filtered are not binding in the webgrid ? How can i do this?
You could try something like this. Hope I understood your question correctly.
search partial:
...
#using(Ajax.BeginForm("Search", new AjaxOptions(){UpdateTargetId = "SearchResults",
HttpMethod = "post" InsertionMode=InsertionMode.Replace})){
<input id="searchString" type="text" value="Search for this ..." />
<input type="submit" value="Search" />
}
...
controller:
[HttpPost]
public PartialViewResult Search(string searchString){
IList<Results> results = _service.Search(searchString);
return new PartialView("Webgrid", results)
}
webgrid partial:
#Model IList<Result>
<div id="SearchResults">
// Display Results
</div>
Didn't compile the code. Hope it is almost compileable.