i Have problem when i try the model validation by trying to fill the form by false.
And when i try to submit with the wrong value (not valid by model validator) it redirects to the page (without model).
Here's the screenshot :
Customer Index
redirect to Customer Create Page when i submit
Here's the code
CONTROLLER
//POST CREATE
[HttpPost]
[AutoValidateAntiforgeryToken]
public IActionResult Create(Models.Customer obj)
{
if (ModelState.IsValid)
{
_db.Customers.Add(obj);
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(obj);
}
//GET DELETE
public IActionResult Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var obj = _db.Customers.Find(id);
if (obj == null)
{
return NotFound();
}
return PartialView(obj);
}
Model
public class Customer
{
[Key]
public int Id { get; set; }
[DisplayName("Nama Customer")]
[Required]
[MaxLength(81, ErrorMessage ="Tidak boleh melebihi 81 Karakter")]
public string Nama { get; set; }
public string Alamat { get; set; }
[Phone]
[Required]
public string Telp { get; set; }
}
Index.HTML Button Create
<button id="btnAddCustomer" class="btn btn-primary">Tambah Customer</button>
JS
#section Scripts{
<script type="text/javascript">
$(document).ready(function () {
$("#btnAddCustomer").on("click", function (e) {
var $buttonClicked = $(this);
//var id = $buttonClicked.attr('data-id');
var options = { "backdrop": "static", keyboard: true };
$.ajax({
type: "GET",
url: '#Url.Action("Create", "Customer")',
contentType: "application/json; charset=utf-8",
data: null,
datatype: "json",
success: function (data) {
$('#modalBody').html(data);
$('#modalCustomer').modal(options);
$('#modalCustomer').modal('show');
},
error: function () {
alert("Dynamic content load failed.");
}
});
})
});
CREATE CSHTML
<form method="post" asp-action="Create">
<div class="border p-3">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group row">
<div class="col-4">
</div>
<div class="col-4">
<h2 class="text-black-50 pl-3">Add Customer</h2>
</div>
<div class="col-4">
</div>
</div>
<div class="row">
<div class="col-12 form-horizontal">
<div class="form-group row">
<div class="col-12 form-group">
<label asp-for="Nama"></label>
<input asp-for="Nama" class="form-control" />
<span asp-validation-for="Nama" class="text-danger"></span>
</div>
<br />
<div class="col-12 form-group">
<label asp-for="Telp"></label>
<input asp-for="Telp" class="form-control" />
<span asp-validation-for="Telp" class="text-danger"></span>
</div>
<br />
<div class="col-12 form-group">
<label asp-for="Alamat"></label>
<input type="text" asp-for="Alamat" class="form-control" />
#*validasi form*#
<span asp-validation-for="Alamat" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="col-6">
</div>
<div class="col-6">
</div>
<div class="col-6">
</div>
</div>
<div class="form-group row">
<div class="col-8 offset-2 row">
<div class="col">
<input type="submit" class="btn btn-info w-75" value="create" />
</div>
<div class="col">
<a asp-action="Index" class="btn btn-danger w-75">Back</a>
</div>
</div>
</div>
</div>
</div>
</div>
Thank you (:
And when i try to submit with the wrong value (not valid by model
validator) it redirects to the page (without model).
You use return View(obj); when modelstate is not valid. So it will return view with model and the view name should be the action name(Create) if you do not specific view name. So this result is correct by using your code.
Here is a working demo:
Index.cshtml:
<button id="btnAddCustomer" class="btn btn-primary"> Tambah Customer</button>
<div class="modal fade" id="modalCustomer" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" id="modalBody">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
#section Scripts{
<script>
$(document).ready(function () {
$("#btnAddCustomer").on("click", function (e) {
var $buttonClicked = $(this);
//var id = $buttonClicked.attr('data-id');
var options = { "backdrop": "static", keyboard: true };
$.ajax({
type: "GET",
url: '#Url.Action("Create", "Customer")',
contentType: "application/json; charset=utf-8",
data: null,
datatype: "json",
success: function (data) {
$('#modalBody').html(data);
//$('#modalCustomer').modal(options);
$('#modalCustomer').modal('show');
},
error: function () {
alert("Dynamic content load failed.");
}
});
})
});
</script>
}
Create.cshtml:
#model Customer
#{
Layout = null; //be sure add this...
}
<form method="post" asp-action="Create">
<div class="border p-3">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group row"><div class="col-4"></div><div class="col-4"><h2 class="text-black-50 pl-3">Add Customer</h2></div><div class="col-4"></div></div>
<div class="row">
<div class="col-12 form-horizontal">
<div class="form-group row">
<div class="col-12 form-group">
<label asp-for="Nama"></label>
<input asp-for="Nama" class="form-control" />
<span asp-validation-for="Nama" class="text-danger"></span>
</div>
<br />
<div class="col-12 form-group">
<label asp-for="Telp"></label>
<input asp-for="Telp" class="form-control" />
<span asp-validation-for="Telp" class="text-danger"></span>
</div>
<br />
<div class="col-12 form-group">
<label asp-for="Alamat"></label>
<input type="text" asp-for="Alamat" class="form-control" />
<span asp-validation-for="Alamat" class="text-danger"></span>
</div>
</div>
<div class="form-group row"><div class="col-6"></div><div class="col-6"></div><div class="col-6"></div></div>
<div class="form-group row">
<div class="col-8 offset-2 row">
<div class="col">
#*change here..........*#
<input type="button" id="btn" class="btn btn-info w-75" value="create" />
</div>
<div class="col">
<a asp-action="Index" class="btn btn-danger w-75">Back</a>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
JS in Create.cshtml:
<script>
$(document).on('click', '#modalCustomer #btn', function () {
var options = {};
options.type = "POST";
options.url = "/Customer/create";
options.dataType = "JSON";
options.cache = false;
options.async = true;
options.data = $("form").serialize();
options.success = function (data) {
//do your stuff...
$('#modalCustomer').modal('hide');
//if you don't want to stay in Index
//add the following code..
// window.location.href = "/home/privacy";
};
options.error = function (res) {
$('#modalBody').html(res.responseText);
};
$.ajax(options);
});
</script>
Update:
If modelstate is invalid, it will get into options.error and display the error message in modal. If modelstate is valid, it will get into options.success, you could redirect by using window.location.href or hide the modal by $('#modalCustomer').modal('hide');, just do your stuff.
Backend code should be like below:
[HttpPost]
[AutoValidateAntiforgeryToken]
public IActionResult Create(Customers obj)
{
if (ModelState.IsValid)
{
_db.Customers.Add(obj);
_db.SaveChanges();
return Json(new { success = true }); //change this...
}
return View(obj);
}
Related
I am posting form data to my controller using AJAX, the form is located in a partial view which is called and displayed in a modal. When first submit the form to update my data it works fine, then if I post it again I notice in the console log that it posts the data twice, if I post it again, it posts three times, and so on. The only way to prevent that behavior is to refresh the page.
Here is the code for my partial view.
#model UserView
<div class="modal fade" id="edit-custom-view" tabindex="-1" role="dialog" aria-labelledby="edit-custom-view" aria-modal="true">
<div class="modal-dialog modal-dialog-scrollable modal-lg modal-notify modal-primary" role="document">
<div class="modal-content">
<form id="ModalFormEditCustomView" enctype="multipart/form-data">
<div class="modal-body">
<div class="row">
<input type="text" asp-for="Id" hidden readonly />
<div class="col">
<div class="md-form form-group">
<label asp-for="ViewName">View Name</label>
<input type="text" required class="form-control" asp-for="ViewName" />
</div>
</div>
</div>
</div>
<div class="modal-footer justify-content-center">
<button type="button" data-save="edit-view" class="btn btn-info waves-effect waves-light">Update</button>
<button type="button" class="btn btn-secondary waves-effect waves-light" data-dismiss="modal">Close</button>
</div><!--/modal-footer-->
</form>
</div>
</div>
</div>
My function that posts the data. Please note, placeholderElement is a div that is the modal window.
placeholderElement.on('click', '[data-save="edit-view"]', function (event) {
//Prevent the standard behaviour
event.preventDefault();
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var dataToSend = form.serialize();
$.post(actionUrl , dataToSend).done(function (data) {
var newBody = $('.modal-body', data);
placeholderElement.find('.modal-body').replaceWith(newBody);
placeholderElement.find('.modal').modal('hide');
});
});
Here is my controller
[HttpPost]
public JsonResult EditCustomView(UserView model) {
... update code goes here
return Json(model);
}
This is the button that opens the modal with the form in it.
<button data-view-id='#=Id#' onclick='editViewModal(this, event)' data-area='Home' data-context='Position' data-toggle='ajax-modal' data-target='#edit-custom-view' data-action='EditCustomView' data-url='/Home/EditViewModal/'>Button</button>
And finally, the code that opens the modal and fetches the partial view.
public IActionResult EditViewModal(int id)
{
string partial = "_EditCustomView";
UserView userView = _userViewService.GetUserView(id);
return PartialView(partial, userView);
}
So, when I click on submit, the ajax function is triggered to submit the data, and the modal closes. If I edit the same item again without refreshing the page, the form gets submitted twice and so on, adding an additional post-event each time. My question is, why? I can't see any reason as to why it would do this. Any help is appreciated.
I cannot reproduce your problem since the code you provided is not complete. Maybe you can show us the placeholderElement and the scripts of editViewModal(this, event) function in the button click event.
Besides, in your case, we can call and display the a modal in the following way.
Here is a work demo:
Model:
public class UserView
{
public int Id { get; set; }
public string ViewName { get; set; }
public string Address { get; set; }
public string Tel { get; set; }
}
Partial View:
#model UserView
<div class="modal fade" id="edit-custom-view" tabindex="-1" role="dialog" aria-labelledby="edit-custom-view" aria-modal="true">
<div class="modal-dialog modal-dialog-scrollable modal-lg modal-notify modal-primary" role="document">
<div class="modal-content">
<form id="ModalFormEditCustomView" data-action="/Home/EditCustomView" enctype="multipart/form-data">
<div class="modal-body">
<div class="row">
<input type="text" asp-for="Id" hidden readonly />
<div class="col">
<div class="md-form form-group">
<label asp-for="ViewName">View Name</label>
<input type="text" required class="form-control" asp-for="ViewName" />
</div>
<div class="md-form form-group">
<label asp-for="Address">Address</label>
<input type="text" required class="form-control" asp-for="Address" />
</div>
<div class="md-form form-group">
<label asp-for="Tel">Tel</label>
<input type="text" required class="form-control" asp-for="Tel" />
</div>
</div>
</div>
</div>
<div class="modal-footer justify-content-center">
<button type="button" data-save="edit-view" class="btn btn-info waves-effect waves-light">Update</button>
<button type="button" class="btn btn-secondary waves-effect waves-light" data-dismiss="modal">Close</button>
</div><!--/modal-footer-->
</form>
</div>
</div>
</div>
Edit View:
#model UserView
<div class="row">
<div class="col-md-4">
<input type="hidden" asp-for="Id" />
<div class="form-group">
<label asp-for="ViewName" class="control-label"></label> :
<input asp-for="ViewName" class="form-control" readonly />
</div>
<div class="form-group">
<label asp-for="Address" class="control-label"></label> :
<input asp-for="Address" class="form-control" readonly />
</div>
<div class="form-group">
<label asp-for="Tel" class="control-label"></label> :
<input asp-for="Tel" class="form-control" readonly />
</div>
<div class="form-group">
<button name="btn" value="#Model.Id" class="btn btn-primary">Edit</button>
</div>
</div>
</div>
<div id="placeholderElement">
</div>
#section Scripts
{
<script>
$(".btn.btn-primary").on("click", function () {
var id = $(this).val();
$.ajax({
type: "get",
url: "/Home/EditViewModal?id=" + id,
success: function (result) {
$("#placeholderElement").html(result);
$("#edit-custom-view").modal('show');
}
});
})
$("#placeholderElement").on('click', '[data-save="edit-view"]', function (event) {
event.preventDefault();
var form = $(this).parents('.modal').find('form');
var actionUrl = form.data('action');
var dataToSend = form.serialize();
$.post(actionUrl, dataToSend).done(function (data) {
$("#placeholderElement").find('.modal').modal('hide');
$("#ViewName").val(data.viewName);
$("#Address").val(data.address);
$("#Tel").val(data.tel);
});
});
</script>
}
Controller:
public IActionResult Edit()
{
var model = _db.UserViews.Find(1);
return View(model);
}
public IActionResult EditViewModal(int id)
{
string partial = "_EditCustomView";
var userView = _db.UserViews.Find(id);
return PartialView(partial, userView);
}
[HttpPost]
public JsonResult EditCustomView(UserView model)
{
var model1 = _db.UserViews.Find(model.Id);
model1.ViewName = model.ViewName;
model1.Address = model.Address;
model1.Tel = model.Tel;
_db.Update(model1);
_db.SaveChanges();
return Json(model1);
}
Where is this script located? If it is inside of the partial that is what is causing the issue for you. Every time the partial is pulled in an extra event is attached to the element.
This would cause the behavior that you are describing.
I have a modal form that has a submit button already. Now I want to do a server-side validation for one of the data on the form. this validation will is meant to return a response to the user on the modal form if the data exist or not.
I am using an HTML action link to call an action method with ajax.
<div class="modal-body">
#using (Html.BeginForm("CreateSchool", "School", FormMethod.Post, new { enctype = "multipart/form-data", #class = "modal-form", id = "createSchoolForm" }))
{
#Html.AntiForgeryToken()
<div class="row forms">
<div class="form-group col-xs-12">
<label class="control-label col-xs-12" for="createSchool_Name">
School Name <span class="text-danger">*</span>
</label>
<input type="text" class="form-control col-xs-10" name="Name" id="createSchool_Name" />
</div>
<div class="form-group col-xs-12">
<label class="control-label col-xs-12" for="image">
School Logo
</label>
<div class="col-md-10">
<input type="file" accept="image/*" name="image" id="createSchool_image" />
<img id="img-header-create" class="img-responsive" style="height: 100px;" />
</div>
</div>
<div class="form-group col-xs-12">
<label class="control-label col-xs-12" for="createSchool_Email">
Contact Email <span class="text-danger">*</span>
</label>
<input type="text" name="ContactEmail" class="form-control col-xs-12" id="createSchool_Email" />
</div>
<div class="form-group col-xs-12">
<label class="control-label col-xs-12" for="createSchool_Number">
Contact Number <span class="text-danger">*</span>
</label>
<input type="text" name="ContactNumber" class="form-control col-xs-12" id="createSchool_Number" />
</div>
<div class="form-group col-xs-12">
<label class="control-label col-xs-4" for="createSchool_Subdomain">
School Subdomain <span id="domainspan"></span>
</label>
#Html.ActionLink("Check if Sub-Domain is available", "CheckDomain", null, new { #class = "col-xs-3", id = "CheckDomain" })
<p id="subdomainresult" class="col-sm-3">me</p>
#*<input type="submit" id="CheckDomain" name="CheckDomain" value="Check Sub Domain" class=" text-uppercase" />*#
#*<input id="CheckDomain_submit"> Check SubDOmain</input>*#
<input type="text" name="Subdomain" class="form-control col-xs-12" id="createSchool_Subdomain" />
</div>
<div class="form-group col-xs-12" style="margin-bottom: 25px;">
<label class="control-label col-xs-12" for="createSchool_StudentsCanEnrollForModules">
Students Are Allowed To Enroll For Modules (Learn More)
</label>
<div class="col-xs-10">
<div class="forms__checkbox">
<input type="checkbox" name="StudentsCanEnrollForModules" class="checkbox" id="createSchool_StudentsCanEnrollForModules" checked />
</div>
</div>
</div>
<div class="form-group col-xs-12" style="margin-bottom: 25px;">
<label class="control-label col-xs-12" for="createSchool_PrivateSchool">
This is a Private School (Learn More)
</label>
<div class="col-xs-10">
<div class="forms__checkbox">
<input type="checkbox" name="PrivateSchool" class="checkbox" id="createSchool_PrivateSchool" />
</div>
</div>
</div>
<div class="form-group col-xs-12">
<label class="control-label">
Description
</label>
#*<textarea type="text" name="Description" class="form-control col-xs-12" id="createSchool_Description"></textarea>*#
<div id="createSchool_Description_div" style="height:300px;"></div>
</div>
<div class="form-group col-xs-12">
<input type="button" id="createSchool_submit" value="Create" class="btn btn-success text-uppercase" />
<button type="button" class="btn btn-default text-uppercase" data-dismiss="modal">Close</button>
<img class="preloader_image" style="height: 30px" src="~/images/loadingicon_large.gif" />
</div>
</div>
}
</div>
This is my jquery ajax code that calls the action method to validate the user input
$("#CheckDomain").click(function () {
debugger;
var sch = new Object();
sch.SubDomain = $('#createSchool_Subdomain').val();
if (sch != null) {
$.ajax({
url: "/School/CheckDomain",
//url: "#Url.Action("CheckDomain", "School")",
type: "POST",
data: JSON.stringify(sch),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
debugger;
if (response != null) {
switch (response) {
case true:
//$("#subdomainresult").html("Submdomain already exists ");
alert("Submdomain already exists " );
break;
case false:
alert("Submdomain is available ");
//$("#subdomainresult").html("Submdomain is available ");
break;
default:
}
} else {
alert("Please enter a subdomain to check availability");
}
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
}
});
this is my action method
[HttpPost]
public ActionResult CheckDomain(CreateSchoolViewModel sch)
{
string SubDomain= sch.Subdomain;
if (!string.IsNullOrWhiteSpace(SubDomain))
{
var IsSubdomianAvailable = Util.getSchoolFromSubdomain(databaseHandler, SubDomain);
if (IsSubdomianAvailable == null)
{
return Json(false, JsonRequestBehavior.AllowGet);
}
else
{
return Json(true, JsonRequestBehavior.AllowGet);
}
}
return Json(null, JsonRequestBehavior.AllowGet);
}
the page always tries to redirect to the action name( checkdomian) view rather than remain on the page
This line
#Html.ActionLink("Check if Sub-Domain is available", "CheckDomain", null, new { #class = "col-xs-3", id = "CheckDomain" })
can be replaced with a link with href set to javascript:void(0)
<a id='CheckDomain' href='javascript:void(0)' class='col-xs-3'>Check if Sub-Domain is available</a>
The link can be void, since there is a JQuery click event handler attached to it.
I want to pop up my div class that contains user at password text box but nothings happen and I test also my function if its running correctly that's why I put alert in my function. This my code bellow. I try so many solution and yet still not show my div. Can any give me a best solution regarding this matter or other way to pop up the web form without leaving my current page.
#model TBSWebApp.Models.User
#{
ViewBag.Title = "UserLogin";
Layout = "~/Layout/_webLayout.cshtml";
}
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
<div>
<fieldset>
<div class="container">
<div class="row">
<div class="col-xs-12">
<button id="btnShowModal" type="button" class="btn btn-sm btn-default pull-left col-lg-11 button button4">
Sign-in
</button>
<div class="modal fade" tabindex="-1" id="loginModal" data-keyboard="false" data-backdrop="static">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
×
</button>
<h4 class="modal-title">Satya Login</h4>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<input class="form-control" type="text" placeholder="Login Username" id="inputUserName" />
</div>
<div class="form-group">
<input class="form-control" placeholder="Login Password" type="password" id="inputPassword" />
</div>
</form>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary button button4">Sign</button>
<button type="button" id="btnHideModal" class="btn btn-primary button button4">
Hide
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</fieldset>
</div>
<footer>
<p style="background-color: Yellow; font-weight: bold; color:blue; text-align: center; font-style: oblique">
©
<script>document.write(new Date().toDateString());</script>
</p>
</footer>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript">
//$(document).ready(function () {
$("#btnShowModal").click(function () {
alert("test");
$("#loginModal").modal('show');
});
$("#btnHideModal").click(function () {
$("#loginModal").modal('hide');
});
// });
</script>
I already solved my problem
<script>
$(document).ready(function () {
$("#submitButton").click(function () {
if (($("#userNameTextBox").val() != "") && ($("#passwordTextBox").val() != ""))
$.ajax(
{
type: "POST", //HTTP POST Method
url: "UserLogin/UserLogin", // Controller/View
dataType: "text/html",
data:
{ //Passing data
UserID: $("#userNameTextBox").val(),
Password: $("#passwordTextBox").val(),
}
});
});
});
//$(document).ajaxStart(function () { $("#loadingImg").show(); });
//$(document).ajaxStop(function () { $("#loadingImg").hide(); });
</script>
I have a controller I am calling through jQuery AJAX. It takes the data in my page and returns a partial view. The purpose of the view is to pre-fill some Input fields with data which I am pulling from a data source.
The problem is, that when the partial view gets rendered in the browser, the form field input values do not get populated with the values I have added to the viewmodel.
I can put a breakpoint on the Return line and see that vm is correctly populated with my properties as I would want them.
But when I view the response in the network tab of Chrome Developer Tools the values are empty.
Anyone with any ideas why?
Controller
[HttpPost]
public async Task<IActionResult> ViewEditRaceOption(RaceViewModel race)
{
var vm = race;
var option = race.RaceOptionData.FirstOrDefault(o => o.Number == race.EditOption);
vm.OptionAffiliatedDiscountValue = option.AffiliatedDiscountValue;
vm.OptionColour = option.OptionColour;
vm.OptionEmbedMapURL = option.EmbedMapURL;
vm.OptionEntryPremium = option.Premium;
vm.OptionEntryPrice= option.AffiliatedDiscountValue;
vm.OptionMaxEntries= option.MaxEntries;
vm.OptionName= option.Name;
vm.OptionRaceDistance = option.RaceDistance;
vm.OptionStartTime = option.StartTime;
vm.OptionCertificateFileName = option.CourseMeasurementCertificateFileName;
return PartialView("OptionModal", vm);
}
Main View (Contains the Ajax JS), truncated
#using TechsportiseOnline.Helpers
#model TechsportiseOnline.ViewModels.RaceViewModel
#{
ViewData["Title"] = "Race";
}
<script>
$(function () {
$("#racedatepicker").datepicker({
dateFormat: "d MM yy",
changeMonth: true,
changeYear: true
});
});
</script>
#if (Model.FormAction == "Create")
{
<h2>Create a new race</h2>
}
else
{
<h2>#Model.RaceData.Name | <span class="text-muted">Edit Race</span></h2>
<h4>#Model.RaceData.RaceDate.ToString("dd MMMM yyyy")</h4>
}
<form asp-action="#Model.FormAction" enctype="multipart/form-data" id="race">
<input type="hidden" name="FormAction" value="#Model.FormAction" />
<input id="DeleteOption" name="DeleteOption" type="hidden" value="0" />
<input id="EditOption" name="EditOption" type="hidden" value="0" />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="modal fade bd-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true" id="optionsmodal">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h2 class="modal-title">Race Option</h2>
<input type="hidden" name="NewOption" value="false" id="NewOption" />
</div>
<div class="modal-body">
#{Html.RenderPartial("_StatusMessage", Model.Message);}
<div id="optionmodal">
#{Html.RenderPartial("OptionModal", Model);}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default cancelmodal">Cancel</button>
<button type="button" class="btn btn-primary" id="addoption">Add</button>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">Race Details</div>
<div class="panel-body">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label asp-for="RaceData.Name" class="control-label"></label>
<br /><small class="text-muted">The name or title of your race</small>
<input asp-for="RaceData.Name" class="form-control" />
<span asp-validation-for="RaceData.Name" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label asp-for="RaceData.ContactName" class="control-label"></label>
<br /><small class="text-muted">The name of the Race Director whom people should contact with queries</small>
<input asp-for="RaceData.ContactName" class="form-control" />
<span asp-validation-for="RaceData.ContactName" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label asp-for="RaceData.ContactEmail" class="control-label"></label>
<br /><small class="text-muted">The email address of the Race Director whom people should contact with queries</small>
<input asp-for="RaceData.ContactEmail" class="form-control" />
<span asp-validation-for="RaceData.ContactEmail" class="text-danger"></span>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label asp-for="RaceData.ContactNumber" class="control-label"></label>
<br /><small class="text-muted">The phone number of the Race Director whom people should contact with queries</small>
<input asp-for="RaceData.ContactNumber" class="form-control" />
<span asp-validation-for="RaceData.ContactNumber" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label asp-for="RaceData.RaceDate" class="control-label"></label>
<div class="input-group">
<span class="input-group-addon"><i class="icon-calendar"></i> </span>
<input name="RaceData.RaceDate" value="#Model.RaceData.RaceDate.ToString("dd MMMM yyyy")" type="text" class="form-control" id="racedatepicker" autocomplete="off">
</div>
<span asp-validation-for="RaceData.RaceDate" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<label asp-for="RaceData.Description" class="control-label"></label>
<br /><small class="text-muted">As much description as you want to add for your race to give your participants as much as they need to know</small>
<textarea asp-for="RaceData.Description" class="form-control" rows="10" id="description">#Model.RaceData.Description</textarea>
<span asp-validation-for="RaceData.Description" class="text-danger"></span>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">Race Options</div>
<div class="panel-body">
<div id="container">
Create your different Race Options here, if you want to have more than one distance/race in the same event. You must have at least 1 Race Option.
<div id="dvRaceOptionsResults">
#{Html.RenderPartial("RaceOptions", Model);}
</div>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target=".bd-example-modal-lg">Add Race Option</button>
</div>
</div>
</div>
</div>
TRUNCATED HERE
<div class="form-group">
#if (Model.FormAction == "Create")
{
<input type="submit" value="Create" class="btn btn-primary" />
}
else
{
<input type="submit" value="Save" class="btn btn-primary" />
}
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
</form>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/1000hz-bootstrap-validator/0.11.9/validator.min.js"></script>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript">
$(document).on('click', '.cancelmodal', function () {
console.log("cancel modal")
var premiumrace = document.getElementById("RaceData_Premium").value
document.getElementById("OptionName").value = ""
document.getElementById("OptionRaceDistance").value = ""
document.getElementById("OptionMaxEntries").value = 0
document.getElementById("OptionStartTime").value = "19:00"
document.getElementById("OptionEmbedMapURL").value = ""
document.getElementById("OptionColour").value = "White"
document.getElementById("OptionEmbedMapURL").value = ""
if (premiumrace == true) {
document.getElementById("OptionEntryPremium").value = false
document.getElementById("OptionEntryPrice").value = "0"
document.getElementById("OptionAffiliatedDiscountValue").value = "2.00"
}
$("#optionsmodal").modal("hide")
});
</script>
<script type="text/javascript">
$(document).on('click', '.editmodal', function () {
var optionnumber = $(this).attr('number');
document.getElementById("EditOption").value = optionnumber;
var form = document.getElementById('race');
var formData = new FormData(form);
$.ajax({
url: '#Url.Action("ViewEditRaceOption", "Races")',
type: 'POST',
data: formData,
dataType: 'html',
processData: false,
contentType: false,
success: function(response) {
if (response) { // check if data is defined
$("#optionmodal").html(response);
console.log(response);
$("#optionsmodal").modal("show");
}
}
});
document.getElementById("EditOption").value = 0;
});
</script>
<script type="text/javascript">
$(document).on('click', '.editoption', function () {
var optionnumber = $(this).attr('number');
document.getElementById("EditOption").value = optionnumber;
var form = document.getElementById('race');
var formData = new FormData(form);
$.ajax({
url: '#Url.Action("EditRaceOption", "Races")',
type: 'POST',
data: formData,
dataType: 'html',
processData: false,
contentType: false,
success: function(response) {
if (response) { // check if data is defined
$("#dvRaceOptionsResults").html(response);
}
}
});
document.getElementById("EditOption").value = 0;
});
</script>
<script type="text/javascript">
$(document).on('click', '.removeoption', function () {
var optionnumber = $(this).attr('number');
document.getElementById("DeleteOption").value = optionnumber;
$.ajax({
url: '#Url.Action("RemoveRaceOption", "Races")',
type: 'POST',
data: $("#race").serialize(),
dataType: 'html',
success: function(response) {
if (response) { // check if data is defined
$("#dvRaceOptionsResults").html(response);
}
}
});
document.getElementById("DeleteOption").value = 0;
});
</script>
<script type="text/javascript">
$("#addoption").click(function () {
document.getElementById("NewOption").value = "true";
var form = document.getElementById('race');
var formData = new FormData(form);
$.ajax({
url: '#Url.Action("AddRaceOption", "Races")',
type: 'POST',
data: formData,
dataType: 'html',
processData: false,
contentType: false,
success: function(response) {
if (response) { // check if data is defined
$("#optionsmodal").modal("hide");
$("#dvRaceOptionsResults").html(response);
document.getElementById("OptionName").value = null;
document.getElementById("OptionRaceDistance").value = "";
}
}
});
document.getElementById("NewOption").value = "false";
});
</script>
<script type="text/javascript">
tinymce.init({
selector: 'textarea',
height: 400,
menubar: false,
plugins: [
'advlist autolink lists link image charmap print preview anchor textcolor',
'searchreplace visualblocks code fullscreen',
'insertdatetime media table contextmenu paste code help'
],
toolbar: 'preview | formatselect | bold italic underline strikethrough forecolor | alignleft aligncenter alignright alignjustify | bullist numlist | image link media | removeformat ',
content_css: [
'//fonts.googleapis.com/css?family=Lato:300,300i,400,400i',
'//www.tinymce.com/css/codepen.min.css']
});
// Prevent Bootstrap dialog from blocking focusin
$(document).on('focusin', function (e) {
if ($(e.target).closest(".mce-window").length) {
e.stopImmediatePropagation();
}
});
</script>
<script type="text/javascript" src="~/js/autocomplete/jquery.easy-autocomplete.min.js"></script>
<link rel="stylesheet" href="~/js/autocomplete/easy-autocomplete.min.css">
<script type="text/javascript">
var options = {
url: "../../resources/countries.json",
getValue: "name",
list: {
match: {
enabled: true
}
},
theme: "square"
};
$("#countries").easyAutocomplete(options);
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCZMX9gUpf7jFKwPe6r6dtqmrv-EnnXsU4&libraries=places&callback=initAutocomplete"
async defer></script>
<script type="text/javascript">
var placeSearch, autocomplete;
var componentForm = {
street_number: 'short_name',
route: 'long_name',
administrative_area_level_1: 'short_name',
administrative_area_level_2: 'short_name',
postal_town: 'short_name',
country: 'long_name',
postal_code: 'short_name'
};
function initAutocomplete() {
// Create the autocomplete object, restricting the search to geographical
// location types.
autocomplete = new google.maps.places.Autocomplete(
/** type {!HTMLInputElement} */(document.getElementById('autocomplete')),
{ types: ['geocode'] });
// When the user selects an address from the dropdown, populate the address
// fields in the form.
autocomplete.addListener('place_changed', fillInAddress);
}
function fillInAddress() {
// Get the place details from the autocomplete object.
var place = autocomplete.getPlace();
for (var component in componentForm) {
document.getElementById(component).value = '';
document.getElementById(component).disabled = false;
}
// Get each component of the address from the place details
// and fill the corresponding field on the form.
for (var i = 0; i < place.address_components.length; i++) {
var addressType = place.address_components[i].types[0];
if (componentForm[addressType]) {
var val = place.address_components[i][componentForm[addressType]];
document.getElementById(addressType).value = val;
}
}
}
// Bias the autocomplete object to the user's geographical location,
// as supplied by the browser's 'navigator.geolocation' object.
function geolocate() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
var geolocation = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
var circle = new google.maps.Circle({
center: geolocation,
radius: position.coords.accuracy
});
autocomplete.setBounds(circle.getBounds());
});
}
}
</script>
}
Partial View
#model TechsportiseOnline.ViewModels.RaceViewModel
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label value="OptionName" class="control-label">Option Name</label>
<br /><small class="text-muted">The name of this Race Option</small>
<input asp-for="OptionName" name = "OptionName" placeholder="Your 10k" type="text" class="form-control" aria-label="Name">
<span asp-validation-for="OptionName" class="text-danger"></span>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label name="OptionRaceDistance" value="Race Distance" class="control-label">Distance</label>
<br /><small class="text-muted">Choose a race distance, used for Age Grading </small>
<select asp-for="OptionRaceDistance" required class="form-control">
<option value="" selected>--select--</option>
<option value="M1">1 mile</option>
<option value="KM5">5 km</option>
<option value="KM6">6 km</option>
<option value="M4">4 miles</option>
<option value="KM8">8 km</option>
<option value="M5">5 miles</option>
<option value="KM10">10 km</option>
<option value="KM12">12 km</option>
<option value="KM15">15 km</option>
<option value="M10">10 miles</option>
<option value="KM20">20 km</option>
<option value="Half">Half Marathon</option>
<option value="KM25">25 km</option>
<option value="KM30">30 km</option>
<option value="Marathon">Marathon</option>
<option value="KM50">50 km</option>
<option value="M50">50 miles</option>
<option value="KM100">100 km</option>
<option value="KM150">150 km</option>
<option value="M100">100 miles</option>
<option value="KM200">200 km</option>
<option value="Other">Other</option>
</select><br />
<span asp-validation-for="OptionRaceDistance" class="text-danger"></span>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label name="OptionMaxEntries" value="Maximum Entries" class="control-label">Maximum Entries</label>
<br /><small class="text-muted">The maximum capacity of the race</small>
<input asp-for="OptionMaxEntries" class="form-control" type="number" />
<span asp-validation-for="OptionMaxEntries" class="text-danger"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label name="OptionStartTime" value="Start Time" class="control-label">Race Start Time</label>
<br /><small class="text-muted">Start time in HH:MM</small>
<input asp-for="OptionStartTime" value="19:00" asp-format="{0:hh:mm}" class="form-control" type="time" />
<span asp-validation-for="OptionStartTime" class="text-danger"></span>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="control-label">Colour</label>
<br /><small class="text-muted">Choose the colour for this option. </small>
<select asp-for="OptionColour" class="form-control">
<option value="White" selected>White</option>
<option value="Red">Red</option>
<option value="Blue">Blue</option>
<option value="Yellow">Yellow</option>
<option value="Green">Green</option>
<option value="Silver">Silver</option>
<option value="Orange">Orange</option>
</select><br />
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="control-label">Course Measurement Certificate</label>
<br /><small class="text-muted">PDF file of certificate for this race option</small>
<input asp-for="OptionCourseMeasurementCertificateFile" type="file" class="form-control" />
<span asp-validation-for="OptionCourseMeasurementCertificateFile" class="text-danger"></span>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="control-label">Course Map URL</label>
<br /><small class="text-muted">Provide a URL to a Garmin, Strava or other course mapping tool</small>
<input asp-for="OptionEmbedMapURL" class="form-control" />
<span asp-validation-for="OptionEmbedMapURL" class="text-danger"></span>
</div>
</div>
</div>
#if (Model.RaceData.CanBePremium)
{
<div class="row">
<div class="col-md-4">
<div class="form-group">
<div class="checkbox">
<label>
<input asp-for="OptionEntryPremium" /> Premium Race Option
<br /><small class="text-muted">This is a premium race option and will cost #Model.BaseCurrency.Symbol#Model.BaseFee.ToString("0.00") per race entry</small>
</label>
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label value="OptionEntryPrice" class="control-label">Entry Price</label>
<br /><small class="text-muted">The price of the normal race entry</small>
<input asp-for="OptionEntryPrice" type="number" class="form-control" aria-label="Amount" placeholder="10.00" asp-format="{0:0.00}" >
<span asp-validation-for="OptionEntryPrice" class="text-danger"></span>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="control-label">Affiliation Discount</label>
<br /><small class="text-muted">Value of discount for affiliation</small>
<input asp-for="OptionAffiliatedDiscountValue" type="number" class="form-control" aria-label="Amount" value="2.00" asp-format="{0:0.00}" >
<span asp-validation-for="OptionAffiliatedDiscountValue" class="text-danger"></span>
</div>
</div>
</div>
}
In AccountController, I notice that the sample registration code catches UserFriendlyException and returns the error message in the ViewBag.
How can I return it from a SweetAlert?
[HttpPost]
public virtual async Task<ActionResult> Register(RegisterViewModel model)
{
try
{
// Code omitted for brevity
}
catch (UserFriendlyException ex)
{
ViewBag.ErrorMessage = ex.Message; // I need to return this using SweetAlert
return View("Register", model);
}
}
html code
<form action="javascript:;" id="register-form" class="login-form" method="post">
<div class="alert alert-danger display-hide">
<button class="close" data-close="alert"></button>
<span>Enter required fields. </span>
</div>
#if (#ViewBag.ErrorMessage != null)
{
<div class="alert alert-danger">
<i class="fa fa-warning"></i> #ViewBag.ErrorMessage
</div>
<script>abp.message.error("#ViewBag.ErrorMessage");</script>
<input type="hidden" value=" #ViewBag.ErrorMessage" id="hf_error" >
}
<div class="row">
<div class="col-xs-12">
<input type="text" class="form-control form-control-solid placeholder-no-fix form-group" autocomplete="off" name="name" placeholder="#L("Name")" required autofocus id="name">
</div>
<div class="col-xs-12">
<input class="form-control form-control-solid placeholder-no-fix form-group" type="text" autocomplete="off" placeholder="#L("Surname")" name="surname" required id="surname" />
</div>
<div class="col-xs-12">
<input type="password" class="form-control form-control-solid placeholder-no-fix form-group" autocomplete="off" name="password" placeholder="#L("Password")" required autofocus id="password">
</div>
</div>
<div class="row">
<div class="col-sm-6 text-left">
<div class="forgot-password" style="margin-top: 5px;">
Login To Your Account
</div>
</div>
<div class="col-sm-6 text-right">
<button class="btn green" id="btnSubmit" type="submit">Register</button>
</div>
<hr />
</div>
</form>
jquery function below
var jsonObject = {
Name: name,
Surname: surname,
//EmailAddress: email,
// UserName: username,
Password: password
};
abp.ajax({
url: abp.appPath + 'Account/Register',
type: 'POST',
data: JSON.stringify(jsonObject)
}).done(function(data) {
alert("done");
}).fail(function(data) {
alert("fail");
});
Since that method returns a View result, it makes sense to use ViewBag for the error message.
To show a SweetAlert, add the following in #section Scripts in Register.cshtml:
#section Scripts {
// ...
#if (ViewBag.ErrorMessage != null)
{
<script>abp.message.error("#ViewBag.ErrorMessage");</script>
/*<script>swal("#ViewBag.ErrorMessage", "", "error");</script>*/
}
}
Both <script> tags trigger identical popups.