I have this:
<form id="import_form" method="post" enctype="multipart/form-data" action="/Blah/Blah">
<input type="file" id="fileUpload" name="fileUpload"/>
<input type="submit" name="submit" value="Import"/>
</form>
$('#import_form').submit(function () {
...
});
Here is the c# method:
[AcceptVerbs(HttpVerbs.Post)]
public string Blah(HttpPostedFileBase fileUpload, FormCollection form)
{ ... }
I want when Blah finishes executing a javacript code to start executing. How to do this?
The submit event is called before it.
This depends on how the form is being submitted.
If you're submitting the form via AJAX then you can execute some JavaScript in the handler for the response. However, given that there's a submit button, I'm assuming for the moment that you're not doing this via AJAX and are instead posting the whole page to the server and rendering a response.
In this case, to execute some JavaScript after the form post, you're going to need to render that JavaScript in the response from the server as part of the next page. When the server constructs the view, include the JavaScript you want to execute in that view.
Keep in mind the request/response nature of the web. When something on the server executes, the client is unaware of it and disconnected from it. The end result of any server-side processing should be an HTTP response to the client. In the event of submitting a form or clicking a link or anything which results in a page reload, that response is in the form of a new page (view). So anything that you want to do on the client after the server-side processing needs to happen as part of that response.
Edit: I just noticed that Blah is returning a string. Is this even working for you? How does the form submit result in a new view? Or am I unaware of a feature in ASP.NET MVC?
This is what I did in the end.
My form returns the exact same view with whom it was called.
I add a ViewData in the Blah method.
In the view, in the $(function()) event I check if ViewData has a value, I execute the javascript code.
Related
So, I have a button in my .cshtml file:
<div>
<button id='btn-next' name='next' type='button' onclick='function f() {
#{
Console.WriteLine("BeforeCalling");
myClass test = new myClass();
test.TestMethod("123");
Console.WriteLine("AfterCalling");
}
}' class='btn btn-block btn-secondary'>justAButton</button>
</div>
Why does it 'clicked' (I see the console output in terminal) when my page reloads? But, if I click the button manually - nothing happens. It works only on page reload.
onclick is a client-side JavaScript event handler. So whatever you want to do there happens in the user’s browser.
However, Razor syntax is executed by the server before anything is sent to the client. Razor is what is being executed in order to generate the HTML that the server sends to the user which then gets interpreted by the browser. But at the time the browser renders the HTML (and registers any JavaScript event handlers), the server is already done.
So what this basically means is that you cannot have server-side code run as part of client-side events. The Razor code you have there runs when the HTML gets generated and none of that logic is sent to the client (you can check that by looking at the HTML source in your browser).
If you want the server to do something when a client-side event occurs, you will need to have the client (=the browser) communicate back to the server, e.g. using AJAX requests. Alternatively, you could look into Blazor if you want to approach this without having to deal with JavaScript.
Can someone explain the following unexpected behaviour. I've tested this in both core 2.2 and 3.1.
I'm trying to make sense of posting 2 different forms on the same razor page.
Here's the HTML:
<form method="post">
<button type="submit">post</button>
</form>
<form method="post">
<button type="submit" asp-page-handler="WTF" >post wtf</button>
</form>
Here's the razor page behind:
public void OnGet()
{
Debug.WriteLine("Get");
}
public void OnPost()
{
Debug.WriteLine("Post");
}
public void OnPostWTF()
{
Debug.WriteLine("PostWTF");
}
I expect that when I press the 'post' button, the OnPost action gets called. When I press the 'post wtf' button, the OnPostWTF action gets called. That kind of happens. If I press the 'post' button initially, the expected action is called. But, as soon as I press the 'post wtf' button, ALL subsequent posts only call the OnPostWTF action, regardless which button is pressed!
Very nice guide here: https://www.learnrazorpages.com/razor-pages/handler-methods
The name of the handler is added to the form's action as a query string parameter.
So when you are posting without a handler then the current url is being posted to.
In your case it will be the one you have switched to with the query parameter handler=WTF.
The best practice when you have multiple forms in the same page, is to setup a handler for each request to avoid such troubles.
I have a 'mail server configuration' kind of view. On this view are 2 buttons:
[SOME FORM FIELDS]
<input class="button" type="submit" value="#T("Save")" />
<input class="button" type="submit" value="#T("Send Test Email")" />
The first button calls off to my controller and returns the same view with any validation/success messages (this is a form):
[HttpPost]
public ActionResult Index(MailServerSettingsViewModel viewModel)
{
...
That works brilliantly, but obviously the 'Send Test Email' button will do the same.
Assuming I don't want to come away from the page (i.e. load a different view), but want to call off to another controller to send a test e-mail, is the 'proper' way to do this to use the ActionLink helper? From this other controller can I then return this same form view? Or can I somehow use the same controller but determine which button was pressed to decide whether to validate the view model or just call off to another service/class/whatever to send the test e-mail and responding appropriately?
You can probably tell from the way I'm asking this that I come from a WebForms background and it's still a case of me getting used to what's what with MVC.
What I've Tried
For now, I'm actually calling off to this other controller asynchronously with AJAX. It actually works well, and is probably most appropriate, but this won't always be the case so I want to know how I'd achieve the above for other scenarios.
If you don't want ajax you can start a thread to send the email in your controller.
#Html.ActionLink("Send Test Email",
"actionName", "ControllerName",
new { MailServerSettingsViewModel }, new { #class = "button" })
If you set the 'name' attribute on both submit buttons to the same value, you can detect which was clicked in your controller by inspecting the value.
MVC newbie question; I'm learning by playing around rather than Reading The Manual... :)
I see when I create an "Edit" view that the auto-generated view includes a "submit" button:
<input type="submit" value="Save" />
But what code gets called behind the scenes to do this save? Specifically, the model underlying this view has its own fancy save logic in code that I would want to call. How do I get the view to invoke my code instead of whatever standard code is being called invisibly behind the scenes?
It's not the button that defines what happens, but the form itself. The button of type submit (one per form) just triggers the form submission, which is handled by the form itself.
A form has an action - e.g.:
<form name="input" action="users/save" method="post">
<!-- Form content goes here -->
<input type="submit" value="Submit" />
</form>
The action is an URL and what happens is that the browser collects the values of all the fields in the form (<input...>) and posts them to the specified url.
In ASP.NET MVC forms are usually defined using the Html helpers, so that building the URL for the form action is delegated to ASP.NET MVC. For the above for example:
<% using(Html.BeginForm("Save", "Users")) %>
<% { %>
<!-- Form content goes here -->
<input type="submit" value="Save" />
<% } %>
Which in this case will create a url /users/save and the form will post to that url. That in terms will trigger the ASP.NET routing which will handle the /users/save url and break it into chunks so that it knows that it has to invoke the "Save" action method on the "Users" controller class. It will then read all the incoming field name-value pairs and try to map them to the method parameter names if any.
It would call whatever public action method the form action is pointing to on your controller. You can then call save on the view model.
public virtual ActionResult Save(MyViewModel model) {
model.Save();
--- more code to do stuff here
}
Set your form action to MyController/Save
You can also use using (Html.BeginForm... in your code to point the form to a specific action method on a specific controller.
when you click submit button, request goes to the HTTp Module which directs it to corresponding controller action. when edit view is created from template the post address of the form is same as of the edit form i.e if you are visiting /home/edit you can see following html in form's opening tag
<form method="post" action="/home/edit">
you can have another action method that only accepts post requests like
[HttpPost]
public ActionResult Edit(int id, ViewModel model)
{
//put your logic here handling submitted values
}
HttpPost attribute tells that it will only handle post request as opposed to get requested used to render the form
it calls the Action method defined in the action part of the form element
eg:
<form action="/Account/LogOn" id="loginForm" method="post">
The LogOn action in the Account controller will be invoked in this form
The ViewPage has a BeginForm Method using (Html.BeginForm() at the top which would render the FormTag. This method has a overload which takes ActionName and controller Name. So you can specify the action in your controller which has to be called.
Assume I have on a page an article with the possibility to comment it. I have a submit form that submits via ajax and the OnComplete javascript method intercepts the result of the form submit.
Each comment is smth like:
<div class="text">
<p class="details">
User Always_Dreaming at 01/01/2009 - 11:13:52 </p>
<p>Here goes my text :D</p>
</div>
I made an .ascx file from it, and I do tml.RenderPartial foreach comment. Now the question is how can I use this .ascx control to output the inserted content to the OnComplete method from client side.
PS. I want to use this approach and not to serialize the Comment object and to return the serialized data, take it wioth my js code and generate on the fly the html with data from the deserialized Comment object.
What you need to do is use the PartialViewResult from the action that's invoked by your javascript call. The client side code can append it to the html using something like the jQuery append or html method calls.
for those who are interested, I found a sample :)
here