How to fire events in MVC [closed] - asp.net-mvc-4

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I want to execute button click event in MVC4. I am new for MVC4 and don't know where to write event, function and how to handle them b/w Model,View and Control.
is there any one have idea about same?
I will be grateful, if some one help me with detail explanation and example.
Thanks in advance.

MVC 4 is essentially stateless, so unlike Web Forms, there's no "automatic" way to wire a button click on the browser UI to your C# code.
The way it's handled generally is that when you click on a button (e.g. <button> maybe?), it fires off an HTTP request either via AJAX or standard browser redirect. That HTTP request gets handled by an action on your controller.
So say you've got this controller:
public class MyController : Controller {
public string Foo() {
return "Bar!";
}
}
You can wire up your markup and jQuery like so in Razor:
<button id="my-button">Call Foo!</button>
<script>
jQuery(function ($) {
$('#my-button').on('click', function () {
$.ajax({
url : '#Url.Action("Foo", "MyController")',
type : 'GET'
});
});
});
</script>
That's basically it in a very quick gist.

I would start with the basics. You don't need jquery... Have a read of http://weblogs.asp.net/scottgu/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx to understand how asp.net MVC works.
Define two methods inside your controller with the same name. The method defined with HttpVerbs.Post will be the method called when you click the button (a POST request).
Put a form around your button pointing to your method and when you click the button it will run the method named with the HttpVerbs.Post.
View
<form action="Home/MyMethod" method="post">
<input type="text" id="username" />
<button text="Click me" />
</form>
Controller
public class HomeController : Controller
{
public ActionResult MyMethod()
{
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyMethod(string username)
{
// notice the string username matches the <input id="username"...
// alternatively you can pass a FormCollection to this method.
return View();
}
}

Related

NavLink updating URL but does not reloading page in Blazor

I have a ProjectBase.razor page that is used to create, view & edit projects. The following routes all take you to this page:
/project/view/{projNum}
/project/create/
/project/edit/{projNum}
I also have a Navlink in my navigation menu that allows you to create a new project:
<NavLink class="nav-link" href="/Project/Create" Match="NavLinkMatch.All" >
<span aria-hidden="true">New Project</span>
</NavLink>
If I click on that link while on the view/edit features of the same page, the URL changes to "/Project/Create," but the page itself doesn't refresh or reload. Is there a way to force this through the NavLink? Or do I need to add an OnClick function to do this?
Create and use the OnParametersSetAsync task in your code block for the page. This event will fire when parameters change.
#code
protected override async Task OnParametersSetAsync()
{
// This event will fire when the parameters change
// Put your code here.
}
Yes, using something like Microsoft.AspNetCore.Components.NavigationManager and its NavigateTo function with forceLoad set to true will accomplish what you're looking for.
Of course yes, this will require you to set up an onclick function, but this is the way I ended up accomplishing something similar for a site-wide search page which never technically had its URL change outside of the query string search value I was passing it.
That being said, there may be a decent way of doing it with only NavLinks. I'll update my answer when I'm not on mobile.
In my component I had already overridden OnInitializedAsync in order to make an API call to get my data.
My solution looks like this:
protected override async Task OnInitializedAsync()
{
// Make your API call or whatever else you use to initialize your component here
}
protected override async Task OnParametersSetAsync()
{
await OnInitializedAsync();
}
I had same problem. Solution I have is...
Create new page
#page "/project/create/"
<ProjectBase></ProjectBase>
That's it! remove #page directive for(/project/create/) from ProjectBase page
Everything will work as expected... now do it for all pages you have.
In your case you have to make below changes as mention by Rod Weir, I am just extending the answer.
/project/view/{projNum}
/project/create/
/project/edit/{projNum}
For above query parameter you have to define [Parameter] in your code.
[Parameter]
public string projNum {get;set;}
Then add method
protected override async Task OnParametersSetAsync()
{
var projectDetail = await getProjectDetails(projNum); // ProgNum will change as it get changes in url, you don't have to do anything extra here.
}
Force page to reload will land you in some other problems, it will get the correct result but the page behavior will change. There are other components on the page like header/left Nav/ etc these will not changes if they are dynamic. It will force you to make changes and hanlde force reload in all the components. Also user experience is affected.
Hope this help.
That is by design.The page itself doesn't refresh or reload because the <NavLink> does not send request to the server (F12 to check) and it redirect to the same page on the client, so nothing updates.
If you enter those URLs in the browser,they will send requests and then refresh page.
A workaround is that you could display different content based on the current route.
#page "/project/view/{projNum}"
#page "/project/create/"
#page "/project/edit/{projNum}"
#using Models
<h3>ProjectBase</h3>
#if (projNum == null)
{
<EditForm Model="#createModel" OnValidSubmit="#HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<InputText id="name" #bind-Value="createModel.Name" />
<button type="submit">Create</button>
</EditForm>
}
else
{
<EditForm Model="#exampleModel" OnValidSubmit="#HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<InputText id="name" #bind-Value="exampleModel.Name" />
<button type="submit">Submit</button>
</EditForm>
}
#code {
[Parameter]
public string projNum { get; set; }
private ExampleModel createModel = new ExampleModel();
private ExampleModel exampleModel = new ExampleModel();
protected override void OnInitialized()
{
exampleModel.Name = projNum;
}
private void HandleValidSubmit()
{
//your logic
Console.WriteLine("OnValidSubmit");
}
}

MVC - why code after ajax.beginform being executed

Form for AJAX call:
#using(Ajax.BeginForm("RefineSearchResults", "Search", new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "resultsSec" }))
{
<input type="submit" value="submit" />
<div id="resultsSec"></div>
}
after form tag:
#{Html.RenderAction("Index", "NewsLetter", new { area = "" });}
but, it throws exception on second piece of code when posted back although it's not supposed to be execued because it's an AJAX call and it's outside the Ajax form.
Exception message:
Error executing child request for handler
'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.
Can anyone please tell me what's going wrong here. Thanks!
oops!!! My mistake!
Actually, I was returning the main view again that's why code that wasn't supposed to be rendered was being rendered.
Now I have added the view code that was to be refereshed through Ajax.BeginForm() to a partial view.
My openion:
You should apply Ajax form on partial view preferably because from
controller when you return a view then the target view have to be rendered
again (it's ok when you have to show only a string through Content()
method.)
So, refreshing the partial view through Ajax form would be an ideal way to use Ajax.BeginForm() in my humble openion.

Invoke paritcular ActionResult using button click?

When I click on button I need to invoke ResetValues method in controller. But am able to invoke the DocDetails method.
Can anyone help me out!!
#using (Html.BeginForm("DocDetails", "FormAdmin", FormMethod.Get))
{
//some other controls and logic related to that
#{ Html.BeginForm("ResetValues", "FormAdmin", FormMethod.Post);}
<button onclick="location.href='#Url.Action("ResetValues","FormAdmin")'" >Search2</button>
#{ Html.EndForm();}
}
Do not embed one form inside another.
Instead, you can use #Html.ActionLink() to create a link that redirects the user to a different action, then style the link to look like a button:
[Edited to show usage without nesting forms]
#using (Html.BeginForm("DocDetails", "FormAdmin", FormMethod.Get)) {
//some other controls and logic related to that
#Html.ActionLink("Search2", "ResetValues", new {}, new { #class = "button" })
}

Working with Multiple forms in MVC4

I am creating a small application in MVC 4. I have 2 forms form1 and form2 in single view. When one form is posted I proceed to the next form where I redirect from view to a action method Employee in which I perform some task and then again from action method I return back to view, in the view I want to go for form2 without touching form1 how do I do that.
Below I will show sample of how my code looks like
Controller
public ActionResult Index()
{
//some task
resturn view();
}
public ActionResult Employee()
{
//some task
}
View
#html.BeginForm("Index","Show",FormMethod.Post,new {#name=form1})
{
//Shown something
}
#Html.Action("Employee","Show")
#html.BeginForm("Employee","Show",FormMethod.Post,new {#name=form2})
{
//Shown something
}
Create a Javascript that checks if any of the required values in form 1 is set. If so, set focus on whatever element you want in form 2. Here's an example:
The html forms:
<form id="one">
<input type="text" id="requiredFormField" value="some value previously entered" />
</form>
<form id="two">
<input type="text" id="form2text" />
</form>
And the javascript:
$(document).ready(setFocusIfForm1Completed());
function setFocusIfForm1Completed()
{
var expectedValue = $("#requiredFormField").val();
if(expectedValue.length > 0)
{
$("#form2text").focus();
}
}
I should add that I assume that you fill in form 1, then you submit (do a POST request to the server) which does some work, and then returns the same view but with at least some required value from form 1 populated (otherwise, this solution breaks).

unobtrusive validation not working with dynamic content

I'm having problems trying to get the unobtrusive jquery validation to work with a partial view that is loaded dynamically through an AJAX call.
I've been spending days trying to get this code to work with no luck.
Here's the View:
#model MvcApplication2.Models.test
#using (Html.BeginForm())
{
#Html.ValidationSummary(true);
<div id="res"></div>
<input id="submit" type="submit" value="submit" />
}
The Partial View:
#model MvcApplication2.Models.test
#Html.TextAreaFor(m => m.MyProperty);
#Html.ValidationMessageFor(m => m.MyProperty);
<script type="text/javascript" >
$.validator.unobtrusive.parse(document);
</script>
The Model:
public class test
{
[Required(ErrorMessage= "required field")]
public int MyProperty { get; set; }
}
The Controller:
public ActionResult GetView()
{
return PartialView("Test");
}
and finally, the javascript:
$(doument).ready(function () {
$.ajax({
url: '/test/getview',
success: function (res) {
$("#res").html(res);
$.validator.unobtrusive.parse($("#res"));
}
});
$("#submit").click(function () {
if ($("form").valid()) {
alert('valid');
return true;
} else {
alert('not valid');
return false;
}
});
The validation does not work. Even if I don't fill any information in the texbox, the submit event shows the alert ('valid').
However, if instead of loading dynamically the view, I use #Html.Partial("test", Model) to render the partial View in the main View (and I don't do the AJAX call), then the validation works just fine.
This is probably because if I load the content dynamically, the controls don't exist in the DOM yet. But I do a call to $.validator.unobtrusive.parse($("#res")); which should be enough to let the validator about the newly loaded controls...
Can anyone help ?
If you try to parse a form that is already parsed it won't update
What you could do when you add dynamic element to the form is either
You could remove the form's validation and re validate it like this:
var form = $(formSelector)
.removeData("validator") /* added by the raw jquery.validate plugin */
.removeData("unobtrusiveValidation"); /* added by the jquery unobtrusive plugin*/
$.validator.unobtrusive.parse(form);
Access the form's unobtrusiveValidation data using the jquery data method:
$(form).data('unobtrusiveValidation')
then access the rules collection and add the new elements attributes (which is somewhat complicated).
You can also check out this article on Applying unobtrusive jquery validation to dynamic content in ASP.Net MVC for a plugin used for adding dynamic elements to a form. This plugin uses the 2nd solution.
As an addition to Nadeem Khedr's answer....
If you've loaded a form in to your DOM dynamically and then call
jQuery.validator.unobtrusive.parse(form);
(with the extra bits mentioned) and are then going to submit that form using ajax remember to call
$(form).valid()
which returns true or false (and runs the actual validation) before you submit your form.
Surprisingly, when I viewed this question, the official ASP.NET docs still did not have any info about the unobtrusive parse() method or how to use it with dynamic content. I took the liberty of creating an issue at the docs repo (referencing #Nadeem's original answer) and submitting a pull request to fix it. This information is now visible in the client side validation section of the model validation topic.
add this to your _Layout.cshtml
$(function () {
//parsing the unobtrusive attributes when we get content via ajax
$(document).ajaxComplete(function () {
$.validator.unobtrusive.parse(document);
});
});
test this:
if ($.validator.unobtrusive != undefined) {
$.validator.unobtrusive.parse("form");
}
I got struck in the same problem and nothing worked except this:
$(document).ready(function () {
rebindvalidators();
});
function rebindvalidators() {
var $form = $("#id-of-form");
$form.unbind();
$form.data("validator", null);
$.validator.unobtrusive.parse($form);
$form.validate($form.data("unobtrusiveValidation").options);
}
and add
// Check if the form is valid
var $form = $(this.form);
if (!$form.valid())
return;
where you are trying to save the form.
I was saving the form through Ajax call.
Hope this will help someone.
just copy this code again in end of modal code
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
;)