I can find many different ways to add confirmation to a form submission. The issue in my case is either they submit the form anyway or they just sit there and dont do anything. Any suggestions would be appreciated. I have added events to both the form onsubmit and the button onclick, no dice. The ActionResult in this case uses HttpPostRequest to send the form data. Works great, just want to add a confirmation dialogue that works.
<script>
function SubmitConfirm(){
if (confirm("Are you sure want to submit this form?"))
return true;
else
return false;
}
<form name="Form1" method="post" action="#Url.Action("PostForm", "MyController")" id="Form1">
...
<input type="submit" value="Submit Posting" onclick="SubmitConfirm()" />
You probably want to display that dialog without reloading the page, just when your submission is successful rather than taking them to a new page or implementing some sort of conditional refresh. So you could set up your form as such...
<form name="Form1" id="Form1">
...
<input type="button" id="submit" value="Submit Posting" />
</form>
And using jQuery set up your actual submit thusly...
$(document).ready(function () {
$('#submit').click(function() { submit(); });
});
function submit() {
if (SubmitConfirm())
{
var data = $('#Form1').serialize();
$.post('MyController/PostForm', data, function(result) {
if (result === 'success') {
// just using an alert here as a placeholder
alert('Your submission has been received!');
}
});
}
}
Which means that in your controller, you'll have the following...
[HttpPost]
public ActionResult PostForm([form arguments])
{
var success = // deal with form results, return true if everything is ok
return new Content(success ? "success" : "failure");
}
To recap, you'd submit your form data, process it, and give the user feedback as to whether it was successfully processed or not without the user ever leaving the page, which also opens the door to make it easier to re-submit data if necessary and do validation, again without the user leaving the page or having to wait for the page to reload.
EDIT: Fixed typo and modified submission logic.
Related
This is a follow on to similar question but taking suggestions into account.
Render part of page on dropdown selection
I have a chart on my main view which I would like to update partially when a dropdown selects different values.
The page renders correctly the first time, but when I select a new value in the dropdown, then I think the .submit script is failing in the script .submit() because when I put a break on window.submitAjaxForm it is never reached.
_PnlChart.cshtml
<img src="#Url.Action("CreateTraderPnlChart3")" width="600" height="600" align="middle" vspace="50" />
My mainview Index.cshtml:
<div class="w3-half">
<div id="ExportDiv">
#{ Html.RenderPartial("_PnlChart");}
</div>
#using (Ajax.BeginForm("GetEnvironment",
new RouteValueDictionary { { "Environment", "" } }, new AjaxOptions() { UpdateTargetId = "ExportDiv" }, new { id = "ajaxForm" } ))
{
#Html.DropDownList("PeriodSelection",
new SelectList((string[])Session["Periods"]),
(string)Session["Period"],
new
{ onchange = "submitAjaxForm()" })
}
</script>
<script type="text/javascript">
$('form#ajaxForm').submit(function(event) {
eval($(this).attr('onsubmit')); return false;
});
window.submitAjaxForm = function(){
$('form#ajaxForm').submit();
}
</script>
</div>
My controller:
public ActionResult PeriodSelection(string dropdownlistReturnValue) // dont know what dropdownlistReturnValue is doing?
{
Session["Period"] = dropdownlistReturnValue;
return PartialView("~/Views/Employee/_PnlChart.cshtml");
}
This line in your code,
eval($(this).attr('onsubmit')); return false;
I am not sure what you were intending to do here. But from your question, i assume you wanted to do a form submission. But that line will not submit the form. The expression $(this).attr('onsubmit') is going to return undefined as your form does not have an onsubmit attribute defined.
But you already have the form submit code in your other method (submitAjaxForm). So if you simply remove the $('form#ajaxForm').submit handler (apparently it does not do anything useful), your code will work. When you change the dropdown, it will make an ajax form submission.
But your form action is set to GetEnvironment action method. That means your ajax form submission will be to that action method. In your question you have a different action method which returns the updated chart content. It does not makes sense!
I personally prefer to write handwritten ajax calls instead of relying on the ajax action helper methods. The below is the code i would probably use (Except the dropdownlist code. read further)
<div id="ExportDiv">
#{ Html.RenderPartial("_PnlChart");}
</div>
#Html.DropDownList("PeriodSelection",
new SelectList((string[])Session["Periods"]),
(string)Session["Period"], new
{ data_charturl = Url.Action("PeriodSelection","Home")})
Now listen to the change event of the SELECT element.
$(function(){
$("#PeriodSelection").change(function(){
var v = $(this).val();
var url=$(this).data("charturl")+'?dropdownlistReturnValue='+v;
$("#ExportDiv").load(url);
});
});
You should consider using the a view model to pass the Dropdownlist data. Why not use the DropDownListFor helper method ? It looks much clean, Mixing a lot of C# code (See all the session casting and all.) makes it kind of dirty IMHO.
I have the following cshtml:
using (Html.BeginForm(MVC.ProbleemRapport.ActionNames.Form, MVC.ProbleemRapport.Name, FormMethod.Post, new { id = "probleemForm" }))
{
<button type="submit" id="verzendenBtn" class="btn actie" title="#StartSchermResource.BtnSend">#StartSchermResource.BtnSend</button>
}
I have a jquery that does the following :
$('#verzendenBtn').click(function () {
$('#probleemForm').find('.error').remove();
// do some validation
if (value === false) {
return value;
}
});
Now when i click my button, the validation works fine.
But when everything is completed and the post happens to the controller, I get a json-result. Which is normal since my action returns a json result containing "true" of "false".
When the result is "true", I need to hide the form.
When the result is "false", I need to hide the form and display a message that something went wrong.
but the only thing that is happening now, is that I get the request to open the json.
What am I forgetting?
you should be able to do $('#probleemForm').hide(); and if you want to show it again just change hide() to show()
for the message create something like <div id="myMessage"/>
then in $('#myMessage').val("something went wrong") this will keep the form open of course. If you want to close the form you can use a standard #URl.Action and redirect or you could just do a simple Javascript alert('error messsage')
I'm building a website application that will have two different types of users, let's call one A and the other is B. They have some similar data, such as: 'name', 'password', etc., and the rest are different. I have done 2 tables for them separately because I need it like that, but I have an idea and I'm not sure whether I can do it!
The idea is that when the user goes to the Registration Page, they will be shown a registration form that contains the data that is similar between A and B, and then I will let the user check a check box indicating whether it's an A user or a B user. Depending on what they have chosen, the rest of the form will appear in the same page to let them continue registration.
I'm working with ASP.NET in C# and I'm wondering whether this idea is applicable? My problem is with the check box - how do I let the rest of the registration form appear depending on what they have chosen, then add it to the right table?
MVC?
2 options:
Either have both of the forms in your html, with attribute ID = 'form a', 'form b'. Make sure to submit the forms to different actions.
Show hide either form like this:
$('.radioBtn').click(function() {
var formType = $(this).val();
//alert(formType);
if (formType == "A") {
$('#FormA').show();
$('#FormB').hide();
} else {
$('#FormB').show();
$('#FormA').hide();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<form style="display: none" id="FormA" action="/actionA">
.... your html FORM A
</form>
<form style="display: none" id="FormB" action="/actionB">
.... your html FORM B
</form>
<input type="radio" name="typeOfForm" class="radioBtn" value="A">Form A
<input type="radio" name="typeOfForm" class="radioBtn" value="B">Form B
Also, if you want to show the forms just don't do display:none
inside the form have a which is set to no display until a user makes a choice.
--
OR
Use ajax, have your forms as partial views and upload them into a target div once the radio is clicked. (let us know if this is needed)
I think the first show / hide is enough for your case. There is no reason to upload since the form is just an empty set of inputs.
EDIT
Next, we catch these submitted forms in your controller. Each form will submit to the same action, or you wish different actions, this does not make a difference - your preference.
option 1.
The form on the page:
<form action='#Url.Action("YourRegisterAction", "controller")' >
<input type="hidden" name="FormType" value="A"/> <!--place B for B form-->
<input type="text" name="Name" placeholder ="enter your name"/>
<input type="text" name="Password" placeholder ="enter your name"/>
<input type="submit" value="Register Me!"/>
</form>
The controller
[HttpPost]
public ActionResult YourRegisterAction(char formType, string name, string password)
{
if (formType == 'A')
bool success = BL.Server.Instance.SaveMyNewUserToDBTypeA(name, password);
else if (formType == 'B')
bool success = BL.Server.Instance.SaveMyNewUserToDBTypeB(name, password);
return View("ThankYou", success);
}
option 2.
Use models.
The model
public class YourRegisterAction
{
public string Name { get; set; }
public string Password { get; set; }
public char FormType { get; set; }
}
The view
#model Domain.UI.Models
<form action='#Url.Action("YourRegisterAction", "controller")' >
#Html.HiddenFor(m=>m.FormType)
#Html.TextBoxFor(m=>m.Name)
#Html.TextBoxFor(m=>m.Password)
<input type="submit" value="Register Me!"/>
</form>
The controller
[HttpPost]
public ActionResult YourRegisterAction(RegisterViewModel m)
{
if (m.FormType == 'A')
bool success = BL.Server.Instance.SaveMyNewUserToDBTypeA(m.Name, m.Password);
else if (m.FormType == 'B')
bool success = BL.Server.Instance.SaveMyNewUserToDBTypeB(m.Name, m.Password);
return View("ThankYou", success);
}
After you have the submitted form in your controller. Just persist in the DB as you normally would.
Also please use #using (Html.BeginForm) instead of the form tags. You can find plenty of info on this here.
Like #Fel said on Comment,
You should better use the radio buttons,
Let call them as rb1 and rb2, grouping the radio buttons by give them a same groupname.
And Also Give AutoPostBack="True" for both, So that only you can change the rest of the fields while the radiobutton is checked.
Create the rest of forms for both users separately as Panels p1 for A and p2 for B
In the rb1_checkedchanged event, show p1,
In the rb2_checkedchanged event, show p2
When click the Submit button
if (rb1.checked=true)
display form for A;
store it in a Table for A;
else
display form for B;
store it in a Table for B;
Hope this Helps...
All the Best...
I want to display the details of particular record on same page, user can choose the product from the list of Product name and as soon as user clicks on the links the details of the specific product should display on the other side of the page i.e. othe div. I tried it by creating partial View and Ajax but the details are not displayed on the separate page a new blank page is opened with the name of Partialview and the records are displayed there, but i want details on the same page.ProductName are comming from database, first time the page loads it must contains the details of first record by default, that is working OK. Please try to solve this problem. Thanks
HomeController.cs
public class HomeComtroller:Controller
{
dbProductEntity Productdbentity=new dbProductEntity();
public ActionResult ProductDetails(int id)
{
var query=Productdbentity.tbl_product.First(c=>c.ProductId==id);
return PartialView("PartialView",query);
}
public ActionResult Product()
{
return View(dbentity.tbl_product.ToList());
}
PartialView.cshtml
#model MvcProject.Models.tbl_product
<label> #Model.ProductName </label>
<label> #Model.ProductDesc </label>
Product Page
#model List<MvcProject.Models.tbl_product>
<html>
<head>
<script type="text/javascript">
$(document).ready(function(){
$(div.product a").click(function(e){
var url=this.ref;
$get(url,{},function(data) {
$('#product-detail').html(data);
});
});
});
</script>
</head>
<body>
<div class="product">
<ul class="list">
#foreach(var item in Model)
{
<li><a href="#Url.Action("ProductDetail","Home",new {id=item.ProductId})">
#item.ProductName</a></li>
}
</ul>
<div class="product-detail">
#{Html.RendererPartial("PartialView",Model.FirstOrDefault());}
</div>
</div>
</body>
</html>
You should cancel the default action of the anchor by returning false from your .click event handler:
$(document).ready(function() {
$(div.product a").click(function(e) {
var url=this.ref;
$get(url,{},function(data) {
$('#product-detail').html(data);
});
});
return false; // <-- That's the important bit you were missing
});
If you do not return false from the .click handler, the browser will simply follow the linking to which your anchor is pointing stopping any javascript execution you might have started. Returning false ensures that the browser will not redirect away from the current page, leaving you the possibility to execute an AJAX request and update the current view.
I think you are missing "." after the "$" in first line in below code. And in second line, since "product-detail" is a class name so in jQuery selector use "." (not "#") before class name. Below is the corrected code:
$.get(url,{},function(data) {
$('.product-detail').html(data);
});
For more have a look at http://api.jquery.com/jQuery.get/
You have to stop the default behavior of click event on a link.
<script>
$(function(){
$("div.product a").click(function(e){
e.preventDefault();
var url=this.ref;
$('.product-detail').load(url);
});
});
</script>
I have created a C# ASP.NET MVC application. In the Index view, i have added 3 buttons, when each button is clicked i want to execute 3 different functions from the Index controller.
Index View that resides in the Home folder
#using (Html.BeginForm()) {
<input type="submit" value="b1" />
<input type="submit" value="b2" />
<input type="submit" value="b3" />
}
Home Controller
public ActionResult Button1Click()
{
return View();
}
public ActionResult Button3Click()
{
return View();
}
public ActionResult Button2Click()
{
return View();
}
When each button is clicked how can i write code to execute the correct controller method ?
If you are posting then you can put each button in a separate form:
#using (Html.BeginForm("Button1Click","Index")) {
<input type="submit" value="b1" />
}
#using (Html.BeginForm("Button2Click","Index")) {
<input type="submit" value="b2" />
}
#using (Html.BeginForm("Button3Click","Index")) {
<input type="submit" value="b3" />
}
If there is no data to post, as shown in your method, and you still want to have all buttons in the same form then you can do an ajax post (this does not make sense though but hey I'm basing it on the code you gave in your question), with this though you may want to change your buttons from a submit into a button (input type="button").
$("#b1").click(function(){
$.post('/index/button1click', function() {
});
});
$("#b2").click(function(){
$.post('/index/button2click', function() {
});
});
$("#b3").click(function(){
$.post('/index/button3click', function() {
});
});
If you want to do a GET instead of a post then just replace .post with .get.
In MVC you need to remove the (Asp.Net) idea of linking button clicks to actions. ASP.Net is event driven MVC uses the classic HTTP REST approach.
So the buttons aren't actions, the buttons submit actions. The action that is submitted is controlled by your form. So your form POSTs data to the controller, using a HTTP post.
Now it's not clear what your trying to achieve here. You appear to be returning different views from each action. So using the REST idea, you should be a GETing not a POSTing (your getting HTML). So the simplest idea is to turn your input(submit) into Anchor tag, i.e. a HTTP GET:
#Html.ActionLink("Button1Click")
etc.
MVC doesn't work like Webforms where you have a ButtonClick event.
Do you want to post any values to the controller?
If not, you can use a link that you can style like a button. Use the buildin Html extensions.
//For links
#Html.ActionLink("Button1Text","Button1Click")
#Html.ActionLink("Button2Text","Button2Click")
#Html.ActionLink("Button3Text","Button3Click")
//If you need more styling options
Button1
Button2
Button3
That way you don't need any javascript or multiple forms in your view. You'll have to add some styling in your CSS files.
One easy way to execute different actions on different button within the same form is to distinguish button click by their name:
Example code is:
View:
#using (Html.BeginForm("MyMethod","Controller"))
{
<input type="submit" value="b1" name="b1" />
<input type="submit" value="b2" name="b2" />
<input type="submit" value="b3" name="b3" />
}
Controller:
[HttpPost]
public ActionResult MyMethod(string b1, string b2, string b3)
{
if (b1 != null)
{
return Button1Click();
}
else if (b2 != null)
{
return Button2Click();
}
else
{
return Button3Click();
}
}
public ActionResult Button1Click()
{
return RedirectToAction("Index");
}
public ActionResult Button3Click()
{
return RedirectToAction("Index");
}
public ActionResult Button2Click()
{
return RedirectToAction("Index");
}