I have a view that has a button for applying for a job, and this button is redirected to a HttpPost action method that handles the apply logic and then returns a JSON result to the same view. as shown below:
// POST: Application/Apply
[HttpPost]
public ActionResult Apply(string idUser, int idAnnouncement)
{
try
{
// TODO: Add insert logic here
// Search for the candidate that has the same Hash code as idUser param
Candidate appliedCandidate = db.Candidates.Where(c => c.CandidateSecondID.Equals(idUser)).FirstOrDefault();
// todo: check if Candidate is already applyed to job
var check = db.Applications.Where(a => a.CandidateID.Equals(appliedCandidate.CandidateID) && a.AnnouncementID.Equals(idAnnouncement)).FirstOrDefault();
if (check == null)
{
Application newApp = new Application
{
AnnouncementID = idAnnouncement,
CandidateID = appliedCandidate.CandidateID,
ApplicationDate = DateTime.Now,
};
db.Applications.Add(newApp);
db.SaveChanges();
return this.Json(new
{
EnableSuccess = true,
SuccessTitle = "Success",
SuccessMsg = "Your application has been sent successfully!"
});
}
else
{
return this.Json(new
{
EnableSuccess = false,
ErrorTitle = "Warning",
ErrorMsg = "You are already applayed for this Job!"
});
}
}
catch
{
return View();
}
}
Here is the AJAX call:
$.ajax({
method: "POST",
url: action,
success: function (result) {
if (result.EnableSuccess) {
swal(
result.SuccessTitle,
result.SuccessMsg,
'success'
)
} else {
swal(
result.ErrorTitle,
result.ErrorMsg,
'warning'
)
}
},
error: function (err) {
console.log(err);
}
})
and here is the full view :
#model IEnumerable<JobPostingProject.Models.Announcement>
#using Microsoft.AspNet.Identity;
#using Microsoft.AspNet.Identity.Owin;
#{
ViewBag.Title = "List of jobs";
}
#using (Html.BeginForm("Index", "Announcement", FormMethod.Get))
{
<div class="row mb-3">
<div class="col-lg-3 ">
<div class="title">
<i class="fas fa-search mr-2"></i>
<input type="text" name="titleInput" class="title__input form-control border-0" placeholder="Job Title" value="#ViewBag.Job" />
</div>
</div>
<div class="col-lg-3">
<div class="city">
<i class="fas fa-map-marker-alt mr-2"></i>
<input type="text" name="cityInput" class="city__input form-control border-0" placeholder="Location" value="#ViewBag.City" />
</div>
</div>
<div class="col-lg-3">
<div class="categorie">
#Html.DropDownList("Categories", null, "Job Category", new { #class = "form-control" })
</div>
</div>
</div>
<div class="row my-4">
<div class="col-lg-3">
<div class="date mb-4">
#*<i class="fas fa-search mr-2"></i>*#
<input type="date" name="dateInf" class="title__input form-control" style="border: 1px solid #ced4da; padding-left: 10px;" />
</div>
</div>
<div class="col-lg-3">
<div class="date mb-4">
#*<i class="fas fa-search mr-2"></i>*#
<input type="date" name="dateSup" class="title__input form-control" style=" border: 1px solid #ced4da;
padding-left: 10px;
" />
</div>
</div>
<div class="col-lg-3">
<div class="level">
#Html.DropDownList("Levels", ViewBag.Levels as SelectList, "Level", new { #class = "form-control" })
</div>
</div>
</div>
<div class="search">
<input type="submit" value="Search" class="text-white text-decoration-none btn btn-primary search__button" />
#*#Html.ActionLink("Search", "Index", "Announcement", null, new { #class = "text-white text-decoration-none btn btn-primary search__button" })*#
</div>
}
<!--list of all jobs searched for-->
<div class="container mt-5">
#{
if (!Model.Any())
{
<p class="text-center p-3 text-secondary">No job found with the chosen critiria</p>
}
else
{
<p class="text-secondary">#ViewBag.TotalResults job results found</p>
foreach (var item in Model)
{
<div class="row">
<div class="col-lg-7">
<div class="jobs">
#using (Html.BeginForm("Apply", "Application", new { idUser = User.Identity.GetUserId(), idAnnouncement = item.AnnouncementID }, FormMethod.Post, new { #class = "w-100 AnnonceForm" }))
{
<div class="job">
<div class="job__header d-flex align-items-center justify-content-between flex-wrap mb-0">
<h5 class="job__title">#item.Title</h5>
<h2 class="job__city">#item.Location</h2>
</div>
<h5 class="job__datetime">Posted in #item.PublicationDate.ToString("dd/mm/yyyy")</h5>
<h5 class="job__company-name mb-4">By #item.Company.Name</h5>
<div class="job__actions d-flex align-items-center">
<p class="job__apply my-0 mr-2">
#Html.ActionLink("More details", "AnnouncementDetails", "Application", new { idAnnouncement = item.AnnouncementID }, new { #class = "btn btn-primary" })
</p>
#if (!User.IsInRole("Company"))
{
<input type="submit" value="Apply Now" class="btn btn-outline-primary submit-btn">
}
</div>
</div>
}
</div>
</div>
<div class="col-lg-5"></div>
</div>
}
}
}
</div>
#section AnnouncementIndex {
<link href="#Url.Content("~/Content/Home.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/Announcement/AnnouncementIndex.css")" rel="stylesheet" type="text/css" />
}
#section Scripts{
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<script>
let submitButtons = document.querySelectorAll(".submit-btn");
for (let i = 0; i < submitForms.length; i++) {
submitButtons[i].addEventListener("submit", e => {
e.preventDefault();
var el = this.parentElement;
while (el.className != 'AnnonceForm') {
el = el.parentElement;
}
//el is now your parent
let action = el.attr("action");
$.ajax({
method: "POST",
url: action,
data: {},
dataType: "json",
success: function (result) {
console.log("entered success block");
if (result.EnableSuccess) {
swal(
result.SuccessTitle,
result.SuccessMsg,
'success'
)
} else {
swal(
result.ErrorTitle,
result.ErrorMsg,
'warning'
)
}
},
error: function (err) {
console.log(err);
}
})
return false;
})
}
</script>
}
BUT, for some reason, I get this plain JSON result instead of actually returning to the success function in the AJAX call.
Related
I'm a new mvc developper, I make a list in my controller, my view show this list and for each row i have a button for a modal view.I want to pass the data of the ViewBag in my list according for each row in my modal.
This is my modal html:
<div class="modal" id="addBadgetoStudentModal-#item.ID" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg animated bounceInDown">
<div class="modal-content">
#using (Html.BeginForm("AddBadgeToStudent", "Badges", new { ID = item.ID }, FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="modal-header">
<h4 class="modal-title">Badges</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<div class="form-group">
<div class="">
<div class="row">
#if (ViewBag.Badges != null)
{
for (var i = 0; i < ViewBag.Badges.Count; i++)
{
<div class="col-lg-3 col-sm-6 col-md-4">
<div class="team-member ">
<div class="row margin-0">
<div class="team-info" style="text-align:center; border: 1.2pt solid #1874BF;">
<img src="#ViewBag.Badges[i].ImageURL" style="width:80%;" class="img-fluid" />
</div>
<div class="team-info" style="text-align:center; width:100%;">
#ViewBag.Badges[i].Label
<br />
<input id="Badge_#ViewBag.Badges[i].ID" class="checkBoxBadgeClass" type="checkbox" />
</div>
</div>
</div>
</div>
}
}
</div>
</div>
</div>
</div>
<div class="modal-footer">
<i class="fa fa-plus-circle"></i> #Resource.Add
</div>
}
</div>
</div>
</div>
<a class="fa fa-pencil-alt" data-toggle="modal" href="#addBadgetoStudentModal-#item.ID" onclick="btnModal()"></a>
This is my List Html View:
#foreach (var item in Model)
{
<tr id="#item.ID">
<td style="text-align:center; width:5%;">
#Html.DisplayFor(modelItem => item.ID)
</td>
<td style="text-align: center; width:25%;">
#item.FullName
</td>
<td style="width:450px;">
#for (var i = 0; i < item.BadgesAssigned.Count; i++)
{
<img src="#item.BadgesAssigned[i].ImageUrl" width="50" title="#item.BadgesAssigned[i].Name" style="float:left;" />
}
<input type="hidden" id="studentBadges_#item.ID" value="#String.Join(",", item.BadgesAssigned.Select(x => x.ID.ToString()))"/>
</td>
}
and this my controller to get my student list and in another table get the badge assigned to a student, so in the list view the student can have 20 badges/25:
public ActionResult BadgeManagement(int? CohortId, int? id)
{
ViewBag.CohortId = db.Cohorts.Select(p => new SelectListItem
{
Text = p.Name,
Value = p.ID.ToString()
});
if (CohortId != null ? CohortId > 0 : false)
{
var cs = db.CohortSubscriptions.Where(student => student.CohortId == CohortId).Include(c => c.Cohorts).Include(c => c.Registrations);
List<BadgesByStudentViewModel> badgesByStudentList = new List<BadgesByStudentViewModel>();
foreach (var student in cs) {
badgesByStudentList.Add(new BadgesByStudentViewModel
{
ID = student.ID,
FullName = student.Registrations.FullName,
BadgesAssigned = db.Enrolled_Students_Badges.Where(x => x.CohortSubscriptionId == student.ID).Select(x => new BadgesAssigned
{
ID = x.ID,
Name = x.Label,
ImageUrl = x.ImageURL
}).ToList()
});
}
ViewBag.Badges = db.Badges.ToList();
return View(badgesByStudentList.ToList());
}
return View(new List<BadgesByStudentViewModel>());
}
I found my solution
This is my html:
<tbody>
#foreach (var item in Model)
{
<tr id="#item.ID">
<td style="text-align:center; width:5%;">
#Html.DisplayFor(modelItem => item.ID)
</td>
<td style="text-align: center; width:25%;">
#item.FullName
</td>
<td style="width:450px;">
#for (var i = 0; i < item.BadgesAssigned.Count; i++)
{
<img src="#item.BadgesAssigned[i].ImageUrl" width="50" title="#item.BadgesAssigned[i].Name" style="float:left;" />
}
</td>
<td style="text-align:center; width:5%;">
<button style="border:none;background: transparent;" data-studentid="#item.ID" data-studentname="#item.FullName" data-badges="#String.Join(",", item.BadgesAssigned.Select(x => x.ID.ToString()))" data-toggle="modal" data-target="#addBadgetoStudentModal" class="modalLink"><i class="fa fa-pencil-alt"></i></button>
</td>
</tr>
}
</tbody>
</table>
<div class="modal" id="addBadgetoStudentModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg animated bounceInDown">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Badges</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<div class="form-group">
<div class="">
<u>#Resource.AddBadgeToStudent:</u>
<br />
<br />
<div class="row">
#if (ViewBag.Badges != null)
{
for (var i = 0; i < ViewBag.Badges.Count; i++)
{
<div class="col-lg-3 col-sm-6 col-md-4">
<div class="team-member ">
<div class="row margin-0">
<div class="team-info" style="text-align:center; border: 1.2pt solid #1874BF;">
<img src="#ViewBag.Badges[i].ImageURL" style="width:80%;" class="img-fluid" />
</div>
<div class="team-info" style="text-align:center; width:100%;">
#ViewBag.Badges[i].Label
<br />
<input id="Badge_#ViewBag.Badges[i].ID" data-badgeid="#ViewBag.Badges[i].ID" data-label="#ViewBag.Badges[i].Label" class="checkBoxBadgeClass" type="checkbox" />
</div>
</div>
</div>
</div>
}
}
</div>
</div>
</div>
</div>
<div class="modal-footer">
<i class="fa fa-plus-circle"></i> #Resource.Edit
</div>
</div>
</div>
</div>
and this is my jquery:
currentStudentId = null;
currentAssignedBadge = [];
$('#BadgeAssignmentTable').dataTable({
responsive: true,
aLengthMenu: [
[10, 25, 50, 100, -1],
[10, 25, 50, 100, "All"]
]
});
$(".modalLink").on("click", function () {
var $pencil = $(this);
var studentId = $pencil.data('studentid');
var badges = $pencil.data('badges');
var studentName = $pencil.data("studentname");
PrepareBadgesModal(studentId, badges.split(","), studentName);
});
PrepareBadgesModal = function (studentId, assignedBadges, studentName) {
currentStudentId = studentId;
console.log(assignedBadges);
currentAssignedBadge = [];
$.each(assignedBadges, function (k, v) { return currentAssignedBadge.push(parseInt(v, 10)); });
$.each(assignedBadges, function (k, v) {
var $badge = $("#Badge_" + v);
$badge.prop("checked", true);
var label = $badge.data("label");
$badge.on("click", function (event) {
var res = ConfirmRemoveBadge($(this), label, studentName);
event.stopPropagation();
});
});
}
ConfirmRemoveBadge = function ($badge, label, studentName) {
var txt = "ATTENTION\r\rÊtes-vous certain de vouloir retirer le badge \"" + label + "\" à " + studentName + "?";
var r = confirm(txt);
if (r == true) {
$badge.prop("checked", false);
$badge.unbind("click");
} else {
$badge.prop("checked", true);
}
}
$("#AssignBadges").click(function () {
ModifyBadgesAction();
});
ModifyBadgesAction = function (badgeList) {
var selBadgeLst = $('input[id^=Badge_]:checked').map(function (k, v) { return parseInt($(v).data('badgeid'), 10); });
//TODO: Close the modal
var removedLst = $.grep(currentAssignedBadge, function (v, k) {
return $.grep(selBadgeLst, function (vv, kk) {
return v == vv;
}).length == 0;
});
var AddedList = $.grep(selBadgeLst, function (v, k) {
return $.grep(currentAssignedBadge, function (vv, kk) {
return v == vv;
}).length == 0;
});
var jsonData = JSON.stringify({ studentId : currentStudentId, AddedList: AddedList, removedLst: removedLst });
$.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: 'POST',
url: '/Badges/ModifyBadgesAction',
data: jsonData,
success: function (data, textStatus, jqXHR) {
//console.log(data, textStatus, jqXHR);
if (data.code == 0) {
ApplyBadgeActionSuccess(data);
}
else {
ApplyBadgeActionError(data);
}
},
error: function (jqXHR, textStatus, errorThrown) {
ApplyBadgeActionError({ code: jqXHR.status, message: "Technical Error", data: [{ jqXHR: jqXHR, error: errorThrown }] });
}
});
};
ApplyBadgeActionSuccess = function (data) {
alert(data.message);
window.location.reload(true);
}
ApplyBadgeActionError = function (data) {
alert(data.message);
}
I want javascript click event that's called from an "inner" mvc form to clear the element of the "outer"/"parent" form but clicking clear produces no results (see wireframe).
Javascript works on the outer form but not when called from scripts file reference in the inner form although I know that the script is wired up correctly b/c other behavior from the script is occurring.:
$("#clearField").on('click', function ()
{
document.getElementById("playerCardNumber").value = "";
});
Environment: asp.net mvc
Code for the outer/parent cshtml page:
#model adminLte.Models.playerCardData
<section class="content">
<div class="inputPlayerInfo">
#using (Ajax.BeginForm("WriteToGroup", "IT", new AjaxOptions //action, view
{
HttpMethod = "GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "innerPlayerInfoForm", //css tag (see below)
OnComplete = "ReturnData",
OnBegin = "ClearResults",
LoadingElementId = "divloading"
}))
{
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="divTable playerGroupTbl">
<div class="divTableBody">
<div class="divTableRow">
#Html.LabelFor(model => model.playerCardNumber , htmlAttributes: new { #class = "divTableCell" })
<div class="divTableCell">
#Html.EditorFor(model => model.playerCardNumber, new { htmlAttributes = new { #id= "playerCardNumber", #type ="password", #class = "form-control" } })
#Html.ValidationMessageFor(model => model.playerCardNumber , "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
<br />
<input type="submit" name="Command" value="Lookup Player" class="btn btn-default btn-lg" />
<button type="button" class="btn btn-default btn-lg" id="clearField" >Clear Previous Swipe</button>
}
</div>
<br />
#*form is inserted here*#
<div id="divloading" style="display:none">
<img src="~/images/giphy.gif" /> </div>
<div id="innerPlayerInfoForm"></div>
</section>
#section scripts{
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script>
function ReturnData()
{
$('#innerPlayerInfoForm').show();
}
function ClearResults()
{
$('#innerPlayerInfoForm').empty();
}
$('#playerEvent').selectpicker({
size: 4
});
$("#clearField").on('click', function () {
document.getElementById("playerCardNumber").value = "";
});
</script>
}
Code for the partial view:
#model adminLte.Models.eventModelParent
<div class="inputPlayerInfo">
#using (Ajax.BeginForm("sproc_PlayerGroupInsert", "IT", new AjaxOptions //action, view
{
HttpMethod = "GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "innerPlayerInfoForm", //css tag (see below)
OnComplete = "ReturnData",
OnBegin = "ClearResults"
}))
{
#Html.AntiForgeryToken()
HtmlHelper.UnobtrusiveJavaScriptEnabled = true;
<div class="divTable playerGroupTbl">
<div class="divTableBody">
<div class="divTableRow">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="divTableCell">
Event:
</div>
<div class="divTableCell">
#foreach (var _event in Model.vips)
{
#Html.RadioButtonFor(m => m.events.SelectedEvent, _event.eventId,
_event.eventchecked == 1 ? new { #checked = "checked" } : null
) #:  #_event.eventName
<br />
}
#Html.ValidationMessageFor(model => model.events.SelectedEvent , "", new { #class = "text-danger" })
</div>
</div>
<div class="divTableRow" >
<div class="divTableCell"> Player ID: </div>
#foreach (var item in Model.playerData)
{
<div class="divTableCell">
<input style="border:none;background:transparent;" id="PlayerID" name="PlayerID" value=#item.PlayerID readonly>
</div>
}
</div>
<div class="divTableRow someDivXYZ">
<div class="divTableCell"> Player First Name: </div>
#foreach (var item in Model.playerData)
{
<div class="divTableCell">
<input style="border:none;background:transparent;" id="playerFirstName" name="playerFirstName" value=#item.playerFirstName readonly>
</div>
}
</div>
<div class="divTableRow someDivXYZ">
<div class="divTableCell"> Player Last Name: </div>
#foreach (var item in Model.playerData)
{
<div class="divTableCell">
<input style="border:none;background:transparent;" id="playerLastName" name="playerLastName" value=#item.playerLastName readonly>
</div>
}
</div>
</div>
</div>
<br />
<input type="submit" id="updatePlayerGroup" value="Write This Player to Group" class="btn btn-default btn-lg" />
<button onclick="ClearResults()" class="btn btn-default btn-lg" id="clearField">Clear Selected Data</button>
}
</div>
<div id="PlayerGroupInsertStatus"></div>
#Scripts.Render("~/scripts/renderJS.js")
External js file:
$('#playerEvent').selectpicker({
size: 4
});
$('#formEvent_playerEvent').selectpicker({
size: 4
});
function ReturnData() {
$('#PlayerGroupInsertStatus').show();
}
function beforeSend() {
var PlayerID = document.getElementById("PlayerID").value;
}
$("#clearField").on('click', function ()
{
document.getElementById("playerCardNumber") = "";
});
Any help is greatly appreciated - thanks in advance!
Hello i am using MVC 5 c# with ado net code , i am inserting master data and master detail data when i insert data and click save all then event fire but value not pass to controller obj show null value , i try a lot but i could not find problem that's why i am sharing code and help senior people maybe you could understand better and easy find problem. i am sharing javascript code view code and controller code function code . when i debug javascript code i did not find any problem in javascript and there is no error in javascript code .
View
<main class="pt-5 mx-lg-5">
<div class="container-fluid mt-5">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="x_panel">
<div class="x_content">
<div class="panel panel-primary">
<div class="panel-heading">
</div>
<div class="panel-body" style="background-color:#F0FFFF">
<button type="button" id="btnAddnew" class="btn btn-primary" data-toggle="modal" data-target="#centralModalLGInfoDemo" style="float:right">Add New</button>
<table id="example1" class="table table-bordered table-striped">
<thead>
<tr>
<th>Sr No</th>
<th>Item Desc</th>
<th>Qty</th>
<th>Remarks</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Requisitions)
{
<tr>
<td>#Html.DisplayFor(module => item.Srno)</td>
<td>#Html.DisplayFor(module => item.ItemDesc)</td>
<td>#Html.DisplayFor(modelItem => item.Qty)</td>
<td>#Html.DisplayFor(modelItem => item.Remarks)</td>
<td>
<a onclick="GetDetails(#item.ReqNo)">
<i class="fa fa-edit"></i>
</a>
<a>
#Html.ActionLink(" ", "DeleteCustomer", "Home", new { id = item.ReqNo }, new { onclick = "return confirm('Are sure wants to delete?');", #class = "fa fa-trash-o" })
</a>
</td>
</tr>
}
</tbody>
<tfoot>
</tfoot>
</table>
</div>
</div>
</div>
<!---End-->
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="centralModalLGInfoDemo" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-notify modal-info" role="document">
<!--Content-->
<div class="modal-content" style="width:140%">
<!--Header-->
<div class="modal-header">
<p class="heading lead">Add New Requisition</p>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true" class="white-text">×</span>
</button>
</div>
<!--Body-->
<form id="NewOrderForm">
<div class="modal-body">
<div class="form-row">
<div class="col">
<!-- Requisition Date -->
<div class="md-form">
#Html.TextBox("ReqNo", (String)ViewBag.ReqNo, new { #class = "form-control mr-sm-3", #id = "txtRequisitionno" })
<label for="lblRequisition">Requisition No.</label>
</div>
</div>
<div class="col">
<!-- Requisition Date -->
<div class="md-form">
#Html.TextBoxFor(m => m.ReqDate, new { #class = "form-control", #id = "txtRequisitionDatepicker" })
<label for="lblRequisitionDatepicker">Requisition Date</label>
</div>
</div>
<div class="col">
<!-- Job -->
<div class="md-form">
#Html.TextBoxFor(m => m.Job, new { #class = "form-control", #id = "txtjob" })
<label for="lbljob">Job</label>
</div>
</div>
<div class="col">
<!-- Job -->
<div class="md-form">
#Html.TextBoxFor(m => m.Approvedby, new { #class = "form-control", #id = "txtApprovedby" })
<label for="lblApprovedby">Approved by</label>
</div>
</div>
<div class="col">
<!-- Job -->
<div class="md-form">
<div class="custom-control custom-checkbox">
<span style="float:right">
#Html.CheckBoxFor(m => m.IsApproved, new { #class = "custom-control-input", #id = "defaultChecked2" })
<label class="custom-control-label" for="defaultChecked2">Approved</label>
</span>
</div>
</div>
</div>
</div>
<!--Detail-->
<h5 style="margin-top:10px;color:#ff6347">Requisition Details</h5>
<hr />
<div>
<div class="form-row">
<div class="col-md-1">
<!-- Requisition Date -->
<div class="md-form">
<input type="text" id="SrNo" name="SrNo" placeholder="Srno" class="form-control" />
<label for="lblSrno">Sr No.</label>
</div>
</div>
<div class="col-md-4">
<!-- Requisition Date -->
<div class="md-form">
#Html.DropDownListFor(m => m.ItemCode, ViewBag.Items as List<SelectListItem>, new { #class = "form-control", id = "txtItemcode" })
</div>
</div>
<div class="col">
<!-- Job -->
<div class="md-form">
<input type="number" id="Qty" name="Qty" placeholder="Qty" class="form-control" />
<label for="lbljob">Qty</label>
</div>
</div>
<div class="col">
<!-- Job -->
<div class="md-form">
<input type="text" id="Reemarks" name="Reemarks" placeholder="Remarks" class="form-control" />
<label for="lblRemarks">Remarks</label>
</div>
</div>
<div class="col-md-2 col-lg-offset-4">
<a id="addToList" class="btn btn-primary">Add To List</a>
</div>
</div>
<table id="detailsTable" class="table">
<thead style="background-color:#33b5e5; color:white">
<tr>
<th style="width:2%">SrNo.</th>
<th style="width:40%">Items</th>
<th style="width:15%">Qty</th>
<th style="width:30%">Remarks</th>
<th style="width:10%"></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div class="modal-footer">
<button type="reset" class="btn btn-default" data-dismiss="modal">Close</button>
<button id="saveRequisition" type="submit" class="btn btn-danger">Save Order</button>
</div>
</div>
</form>
</div>
<!--/.Content-->
</div>
</div>
</div>
</main>
javascript
<script>
//Show model
function addNewOrder()
{
$("#NewOrderForm").modal();
}
// Add Multiple Record
$("#addToList").click(function (e) {
e.preventDefault();
if ($.trim($("#SrNo").val()) == "" || $.trim($("#txtItemcode").val()) == "" || $.trim($("#Qty").val()) == "" || $.trim($("#Reemarks").val()) == "") return;
var Srno = $("#SrNo").val(),
items = $("#txtItemcode").val(),
qty = $("#Qty").val(),
remark = $("#Reemarks").val(),
detailsTableBody = $("#detailsTable tbody");
var ReqItems = '<tr><td>' + Srno + '</td><td>' + items + '</td><td>' + qty + '</td><td>' + remark + '</td><td> <a data-itemId="0" href="#" class="deleteItem">Remove</a></td></tr>';
detailsTableBody.append(ReqItems);
clearItem();
//After Add A New Order In The List
function clearItem()
{
$("#SrNo").val('');
$("#txtItemcode").val('');
$("#Qty").val('');
$("#Reemarks").val('');
}
// After Add A New Order In The List, If You Want, You Can Remove
$(document).on('click', 'a.deleteItem', function (e)
{
e.preventDefault();
var $self = $(this);
if ($(this).attr('data-itemId') == "0") {
$(this).parents('tr').css("background-color", "white").fadeOut(800, function () {
$(this).remove();
});
}
});
//After Click Save Button Pass All Data View To Controller For Save Database
function saveRequisition(data) {
return $.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: 'POST',
url: "/Home/RequisitionInsert", // function save
data: data,
success: function (result) {
alert(result);
location.reload();
},
error: function () {
alert("Error!")
}
});
}
//Collect Multiple Order List For Pass To Controller
$("#saveRequisition").click(function (e)
{
e.preventDefault();
var requisitionArr = [];
requisitionArr.length = 0;
$.each($("#detailsTable tbody tr"), function () {
requisitionArr.push({
Srno: $(this).find('td:eq(0)').html(),
items: $(this).find('td:eq(1)').html(),
qty: $(this).find('td:eq(2)').html(),
remark: $(this).find('td:eq(3)').html(),
});
});
var data = JSON.stringify({
txtRequisitionno: $("#txtRequisitionno").val(),
txtRequisitionDatepicker: $("#txtRequisitionDatepicker").val(),
txtjob: $("#txtjob").val(),
txtApprovedby: $("#txtApprovedby").val(),
defaultChecked2: $("#defaultChecked2").val(),
item: requisitionArr
});
$.when(saveRequisition(data)).then(function (response) {
console.log(response);
}).fail(function (err) {
console.log(err);
});
});
});
</script>
Controller
[HttpPost]
public ActionResult RequisitionInsert(Requisition objModel, List<Requisition> oblist)
{
try
{
int result = objclsRequisition.RequisitionInsert(objModel, oblist);
if(result==1)
{
ViewBag.Message = "Your record has been inserted Successfully";
ModelState.Clear();
}
else
{
ViewBag.Message = "Unsucessfull";
ModelState.Clear();
}
return RedirectToAction("Requisition", "Home");
}
catch (Exception)
{
throw;
}
}
Function
public int RequisitionInsert(Requisition Req, List<Requisition> objlist)
{
try
{
con.Open();
tr = con.BeginTransaction();
cmd = new SqlCommand("Sp_RequisitionMainInsert", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#ReqNo", Req.ReqNo);
cmd.Parameters.AddWithValue("#Comp_ID", "1");
cmd.Parameters.AddWithValue("#GL_Year", "2018-2019");
cmd.Parameters.AddWithValue("#ReqDate", Req.ReqDate.ToString("yyyy-MM-dd"));
cmd.Parameters.AddWithValue("#Job", Req.Job);
cmd.Parameters.AddWithValue("#ApprovedBy", Req.Approvedby);
cmd.Parameters.AddWithValue("#UserName", System.Web.HttpContext.Current.Session["AgentName"]);
cmd.Parameters.AddWithValue("#IsApproved", Req.IsApproved);
cmd.Transaction = tr;
cmd.ExecuteNonQuery();
for (int i = 0; i < objlist.Count; i++)
{
cmd = new SqlCommand("Sp_RequisitionDetailInsert", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#ReqNo", Req.ReqNo);
cmd.Parameters.AddWithValue("#Comp_ID", "1");
cmd.Parameters.AddWithValue("#GL_Year", "2018-2019");
cmd.Parameters.AddWithValue("#SrNo", Req.Srno);
cmd.Parameters.AddWithValue("#ItemCode", Req.ItemCode);
cmd.Parameters.AddWithValue("#Qty", Convert.ToDecimal(Req.Qty));
cmd.Parameters.AddWithValue("#Remarks", Req.Remarks);
}
cmd.Transaction = tr;
cmd.ExecuteNonQuery();
tr.Commit();
return i;
}
catch (SqlException sqlex)
{
tr.Rollback();
throw sqlex; // read all sql error
}
catch (Exception ex)
{
tr.Rollback();
throw ex; // General execption
}
finally
{
con.Close();
}
}
The issue lays in the api model definition.
You have declared your methods parameters as this
[HttpPost]
public ActionResult RequisitionInsert(Requisition objModel, List<Requisition> oblist)
But, when posting data in MVC you can only have one input model as that model will be parsed straight from the complete request body.
To solve this, create a request model where you define the properties to read from the body.
public class RequestModel
{
public string TxtRequisitionno { get; set; }
public string TxtRequisitionDatepicker { get; set; }
public string Txtjob { get; set; }
public string TxtApprovedby { get; set; }
public string DefaultChecked2 { get; set; }
public List<Requisition> Items { get; set; }
}
And then use it
[HttpPost]
public ActionResult RequisitionInsert(RequestModel model)
NOTE: I have declared the properties in the RequestModel as the same you try to send from the client
Your client model:
{
txtRequisitionno: $("#txtRequisitionno").val(),
txtRequisitionDatepicker: $("#txtRequisitionDatepicker").val(),
txtjob: $("#txtjob").val(),
txtApprovedby: $("#txtApprovedby").val(),
defaultChecked2: $("#defaultChecked2").val(),
item: requisitionArr
};
I have a page that allows you to create Income Types, but if you click the Create button, in succession then it creates multiple entries, Is there a way to have it limit this to you press it once and that is it?
I have looked at the code it uses an ajax method to get the information then post the form to the database. Some of my code below:
Index
#section scripts {
<script language="javascript" type="text/javascript">
#* DOM ready? *#
$(function () {
#* Pagination Async Partial Handling *#
$(document).on("click", "#indexPager a", function () {
if ($(this).parent().hasClass('disabled') || $(this).parent().hasClass('active'))
return false;
$.ajax({
url: $(this).attr("href"),
type: 'GET',
cache: false,
success: function (result) {
$('#tableContainer').html(result);
addBootstrapTooltips("#tableContainer");
}
});
return false;
});
$(document).on("change", "#pageSizeSelector", function () {
var selectedValue = $(this).val();
$.ajax({
url: selectedValue,
type: 'GET',
cache: false,
success: function(result) {
$('#tableContainer').html(result);
addBootstrapTooltips("#tableContainer");
}
});
});
#* Sorting Async Partial Handling *#
$(document).on("click", "#tableHeader a", function () {
$.ajax({
url: $(this).attr("href"),
type: 'GET',
cache: false,
success: function (result) {
$('#tableContainer').html(result);
addBootstrapTooltips("#tableContainer");
}
});
return false;
});
#* Apply ACTION colours for hover *#
addTableStylingScripts();
});
</script>
}
#section additionalStyles {
#Styles.Render("~/plugins/datatables/media/css/cssDatatables")
}
#section modal {
}
<article class="row">
<h1 class="pageTitle artistHeader fw200 mb20 mt10">#ViewBag.Title</h1>
<div class="col-md-12">
<div class="panel panel-visible" id="tableContainer">
#Html.Partial("_IncomeTypeManagementList", Model)
</div>
</div>
</article>
IncomeTypeManagementList
#* Header *#
<div class="panel-heading createContentTitle">
<div class="panel-title createLink">
<a href="#Url.Action("Create", "IncomeTypeManagement", new
{
page = Model.PagingInfo.Page,
take = Model.PagingInfo.Take,
sortBy = Model.PagingInfo.SortPropertyName,
sortAsc = Model.PagingInfo.SortAscending
})" data-container="body" data-toggle="tooltip" title="Add Income Type" id="createIncomeTypeLink">
<span class="fa fa-file"></span> Add Income Type
</a>
</div>
</div>
#* Body *#
<div class="panel-body pn">
<table class="table table-striped table-hover dataTable incomeTypesTable admin-form theme-primary" cellspacing="0" width="100%" role="grid">
<thead id="tableHeader">
<tr>
<th class="hidden-xs sorting #Html.SortTitleItem("IncomeTypeGroupId", Model.PagingInfo.SortPropertyName, Model.PagingInfo.SortAscending)">
<a href="#Url.Action("Index", "IncomeTypeManagement", new
{
page = 1,
take = Model.PagingInfo.Take,
sortBy = "IncomeTypeGroupId",
sortAsc = Model.PagingInfo.SortPropertyName != "IncomeTypeGroupId" || !Model.PagingInfo.SortAscending
})" data-container="body" data-toggle="tooltip" title="Sort by group">Group</a>
</th>
<th class="sorting #Html.SortTitleItem("Name", Model.PagingInfo.SortPropertyName, Model.PagingInfo.SortAscending)">
<a href="#Url.Action("Index", "IncomeTypeManagement", new
{
page = 1,
take = Model.PagingInfo.Take,
sortBy = "Name",
sortAsc = Model.PagingInfo.SortPropertyName != "Name" || !Model.PagingInfo.SortAscending
})" data-container="body" data-toggle="tooltip" title="Sort by name">Name</a>
</th>
<th class="hidden-xs sorting hidden-xs #Html.SortTitleItem("CreatedDate", Model.PagingInfo.SortPropertyName, Model.PagingInfo.SortAscending)">
<a href="#Url.Action("Index", "IncomeTypeManagement", new
{
page = 1,
take = Model.PagingInfo.Take,
sortBy = "CreatedDate",
sortAsc = Model.PagingInfo.SortPropertyName != "CreatedDate" || !Model.PagingInfo.SortAscending
})" data-container="body" data-toggle="tooltip" title="Sort by date">Created</a>
</th>
<th class="bg-white">
<div class="text-center">Action</div>
</th>
</tr>
</thead>
<tbody>
#foreach (var it in Model.IncomeTypes)
{
var actionId = "action_" + tableRowIndex;
var editIncomeTypeId = "editIncomeType_" + tableRowIndex;
<tr data-id="#it.ID"
data-isdeleted="#it.IsDeleted"
data-rowversion="#it.RowVersion"
data-createddate="#it.CreatedDate"
data-name="#it.Name"
data-incometypegroupid="#it.IncomeTypeGroupId"
data-incometypegroupname="#it.IncomeGroupName">
<td class="hidden-xs">
#it.IncomeGroupName
</td>
<td>
#it.Name.Truncate(50)
</td>
<td class="hidden-xs">
#it.CreatedDate.ToShortDateString()
</td>
<td class="updateTableRow text-center">
<div class="dropdownContainer btn-group text-right">
<button type="button" class="btn btn-primary br2 btn-xs fs12 dropdown-toggle" data-toggle="dropdown" aria-expanded="false" id="#actionId">
Action
<span class="caret ml5"></span>
</button>
<ul class="dropdown-menu dropdown-menu-right" role="menu">
<li>
<a href="#Url.Action("Update", "IncomeTypeManagement", new
{
id = it.ID,
page = Model.PagingInfo.Page,
take = Model.PagingInfo.Take,
sortBy = Model.PagingInfo.SortPropertyName,
sortAsc = Model.PagingInfo.SortAscending
})" data-container="body" data-toggle="tooltip" id="#editIncomeTypeId" title="Edit" data-rowhover="editTableRow">
Edit
</a>
</li>
</ul>
</div>
</td>
</tr>
tableRowIndex++;
}
</tbody>
</table>
#Html.Partial("_Pagination", Model.PagingInfo)
</div>
Create
#section scripts {
#Scripts.Render("~/bundles/jqueryajaxval")
#Scripts.Render("~/bundles/jqueryval")
<script language="javascript" type="text/javascript">
$(document).ready(function () {
#* Cancel *#
$(document).on("click", "#CancelForm", function (e) {
var uri = '#Html.Raw(Url.Action("Index", "IncomeTypeManagement", new
{
page = Model.PagingInfo.Page,
take = Model.PagingInfo.Take,
sortBy = Model.PagingInfo.SortPropertyName,
sortAsc = Model.PagingInfo.SortAscending
}))';
window.location = uri;
e.preventDefault();
});
});
</script>
}
#section additionalStyles {
}
#section modal {
}
<article class="row">
<h1 class="pageTitle incomeTypeHeader fw200 mb20 mt10">#ViewBag.Title</h1>
<div class="col-md-1"></div>
<div id="incomeTypeResults" class="col-md-10 formContainer">
<div class="panel">
<div class="panel-heading">
<span class="panel-title">
<i class="glyphicon glyphicon-pencil"></i> Details Of New Income Type
</span>
</div>
#using (Html.BeginForm("Create",
"IncomeTypeManagement", FormMethod.Post,
new { id = "createIncomeType", role = "form", #class = "theme-primary form-horizontal" }))
{
#Html.AntiForgeryToken()
#* Pagination / Sorting *#
#Html.HiddenFor(m => m.PagingInfo.Page)
#Html.HiddenFor(m => m.PagingInfo.Take)
#Html.HiddenFor(m => m.PagingInfo.SortPropertyName)
#Html.HiddenFor(m => m.PagingInfo.SortAscending)
<fieldset>
<legend style="display: none">Create Income Type Form</legend>
#Html.HiddenFor(m => m.IsDeleted)
<div class="panel-body p25 fill bt0">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(m => m.IncomeTypeGroupId, new { #class = "control-label col-lg-2" })
<div class="col-lg-8">
#{
// get drop down values for DropDownFor()
var selectableItems = incomeTypeGroups.Select((v, idx) => new SelectListItem
{
Text = v.Value,
Value = v.Key,
Selected = idx == 0
});
}
#Html.DropDownListFor(m => m.IncomeTypeGroupId, selectableItems, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.IncomeTypeGroupId, string.Empty, new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Name, new { #class = "control-label col-lg-2" })
<div class="col-lg-8">
#Html.TextBoxFor(m => m.Name, new { #class = "form-control", id = "Name", placeholder = "Name..." })
#Html.ValidationMessageFor(m => m.Name, string.Empty, new { #class = "text-danger" })
</div>
</div>
</div>
<div class="panel-footer">
<div class="text-center">
<input type="button" class="btn btn-primary" id="CancelForm" value="Cancel" />
<input type="submit" class="btn btn-primary" id="SubmitForm" value="Create" />
</div>
</div>
</fieldset>
}
</div>
</div>
</article>
Update
section scripts {
#Scripts.Render("~/bundles/jqueryajaxval")
#Scripts.Render("~/bundles/jqueryval")
<script language="javascript" type="text/javascript">
$(document).ready(function () {
#* Cancel *#
$(document).on("click", "#CancelForm", function (e) {
var uri = '#Html.Raw(Url.Action("Index", "IncomeTypeManagement", new
{
page = Model.PagingInfo.Page,
take = Model.PagingInfo.Take,
sortBy = Model.PagingInfo.SortPropertyName,
sortAsc = Model.PagingInfo.SortAscending
}))';
window.location = uri;
e.preventDefault();
});
});
</script>
}
#section additionalStyles {
}
#section modal {
}
<article class="row">
<h1 class="pageTitle incomeTypeHeader fw200 mb20 mt10">#ViewBag.Title</h1>
<div class="col-md-1"></div>
<div id="incomeTypeResults" class="col-md-10 formContainer">
<div class="panel">
<div class="panel-heading">
<span class="panel-title">
<i class="glyphicon glyphicon-pencil"></i> Details Of '#Model.Name'
</span>
</div>
#using (Html.BeginForm("Update",
"IncomeTypeManagement", FormMethod.Post,
new { id = "updateIncomeType", role = "form", #class = "theme-primary form-horizontal" }))
{
#Html.AntiForgeryToken()
#* Pagination / Sorting *#
#Html.HiddenFor(m => m.PagingInfo.Page)
#Html.HiddenFor(m => m.PagingInfo.Take)
#Html.HiddenFor(m => m.PagingInfo.SortPropertyName)
#Html.HiddenFor(m => m.PagingInfo.SortAscending)
<fieldset>
<legend style="display: none">Edit Income Type Form</legend>
#Html.HiddenFor(m => m.ID)
#Html.HiddenFor(m => m.RowVersion)
#Html.HiddenFor(m => m.IsDeleted)
<div class="panel-body p25 fill bt0">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(m => m.IncomeTypeGroupId, new { #class = "control-label col-lg-2" })
<div class="col-lg-8">
#{
// get drop down values for DropDownFor()
var selectableItems = incomeTypeGroups.Select((v, idx) => new SelectListItem
{
Text = v.Value,
Value = v.Key,
Selected = Model.IncomeTypeGroupId.ToString() == v.Key
});
}
#Html.DropDownListFor(m => m.IncomeTypeGroupId, selectableItems, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.IncomeTypeGroupId, string.Empty, new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Name, new { #class = "control-label col-lg-2" })
<div class="col-lg-8">
#Html.TextBoxFor(m => m.Name, new { #class = "form-control", id = "Name", placeholder = "Name..." })
#Html.ValidationMessageFor(m => m.Name, string.Empty, new { #class = "text-danger" })
</div>
</div>
</div>
<div class="panel-footer">
<div class="text-center">
<input type="button" class="btn btn-primary" onclick="this.disabled = true" id="CancelForm" value="Cancel" />
<input type="submit" class="btn btn-primary" id="SubmitForm" value="Update" />
</div>
</div>
</fieldset>
}
</div>
</div>
</article>
So I have tried adding <input type="submit" class="btn btn-primary" id="SubmitForm" value="Update" onclick="this.disabled = true" />
On the Create page When you click on Add Income Tye you are directed to the Create page, but when I have tied testing it the button is disabled, but then it does not submit anything and just remains on the Create page
To answer your question you kind of have to tackle the problem from 2 angles:
once click happens on your button you can either disable it or show an overlay so that no other elements on the page can be interacted with
you also have to think of what happens if some malicious user replays that request multiple times (by bypassing or altering the UI - which is dead easy to do) - on the server side you can use a processing queue of requests and every time you want to add a new request for processing, you can check to see if a duplicate exists
Unfortunately there isn't an easy answer for this. The 2nd part of the answer you have to think about it and assess if you're exposed to this issue. If your application is public and anyone can access it, don't assume that users will do everything on your system just via the UI.
Hope this helps.
This is what I come up with:
<script language="javascript" type="text/javascript">
$('.form-disable').on('submit', function () {
var self = $(this),
button = self.find('input[type="submit"], button'),
submitValue = button.data('submit-value');
button.attr('disabled', 'disabled').val((submitValue) ? submitValue : 'Please Wait...');
});
</script>
I added a class to the form so that when you click on a button that handles the submit, it disables the button and then waits with a message. But it only allows the button to be clicked once.
I have been trying to send data to a controller using ajax but it redirects me to another url instead of posting data into the controller.
#section CustomScripts
{
<script type="text/javascript">
function save() {
var BookingDetails =
{
VehicleModel: document.getElementById('VehicleModel').value,
VehicleRegNo: document.getElementById('VehicleRegNo').value,
AppointmentTime: '1',
CustomerName: document.getElementById('CustomerName').value,
ContactNo: document.getElementById('ContactNo').value
}
var bd = JSON.stringify(BookingDetails);
$.ajax
({
url: '#Url.Action("Appointment", "AddAppointment")',
type: 'POST',
contentType: "application/json; charset= utf-8",
data: bd,
dataType: 'json',
success: function (results) {
#*window.location = '#Url.Action("Appointment", "AddAppointment")';*#
}
});
}
</script>
}
Controller:
[HttpPost]
public ActionResult AddAppointment(AddBookingsViewModel AddBookingVM)
{
BookingsRepository BookingRep = new BookingsRepository();
int ReturnRowsCount = BookingRep.InsertCustomerAppointments(AddBookingVM, out ReturnStatus, out ReturnMessage);
if (ReturnRowsCount > 0)
{
//ShowMessage(MessageBox.Success, OperationType.Saved, ReturnMessage);
ViewBag.Message = ReturnMessage;
return RedirectToAction("AddAppointment", "Appointment");
}
else
{
ShowMessage(MessageBox.Error, OperationType.Error, ReturnMessage);
}
return View(AddBookingVM);
}
I have using a input with type submit which is calling save(); on onclick event.
<input type="submit" onclick="save();" class="btn btn-default pull-right" value="Book Now"/>
Here is the full view code:
#model ZahidCarWash.ViewModels.AddBookingsViewModel
#{
ViewBag.Title = "Add Appointment";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<!-- page banner -->
<div id="page-banner" class="page-banner-main" style="background-image: url('Content/images/bg/page-banner.jpg')">
<div class="container">
<div class="page-banner-block">
<div class="section">
<h3 class="section-heading">Appointments</h3>
</div>
<ol class="breadcrumb">
<li>Home</li>
<li>Page</li>
<li class="active"><a>Appointments</a></li>
</ol>
</div>
</div>
</div>
<!-- end page banner -->
#*#using (Html.BeginForm("AddAppointment", "Appointment", FormMethod.Post, new { enctype = "multipart/form-data" }))
{*#
<!-- appointments -->
<div id="appointments" class="appointment-main-block appointment-two-main-block">
<div class="container">
<div class="row">
<div class="section text-center">
<h3 class="section-heading text-center">Get an Appointment</h3>
#*<p class="sub-heading text-center">Etiam imperdiet imperdiet orci nunc nec neque phasellus leo dolor tempus non auctor.</p>*#
</div>
<div class="col-md-4 hidden-sm">
<div class="appointment-img">
<img src="~/Content/images/appointment.jpg" class="img-responsive" alt="Appointment">
</div>
</div>
<div class="col-md-8 col-sm-12">
<div class="appointment-block">
<form id="appointment-form" class="appointment-form" method="post" action="https://mediacity.co.in/autoplus/car-wash/version1/appointment.php">
<h5 class="form-heading-title"><span class="form-heading-no">1.</span>Vehicle Information</h5>
<div class="row">
<div class="col-sm-4">
<div class="dropdown">
#Html.DropDownListFor(Model => Model.fk_VehicleMakeID, new SelectList(ZahidCarWash.DAL.VehicleMakesRepository.getVehicleMakes(), "VehicleMakeID", "MakeTitle"),
new { #class = "form-control" })
</div>
</div>
<div class="col-sm-4">
#Html.EditorFor(Model => Model.VehicleModel, new { htmlAttributes = new { #class = "form-control", placeholder = "Enter Vehicle Model" } } )
</div>
<div class="col-sm-4">
#Html.EditorFor(Model => Model.VehicleRegNo, new { htmlAttributes = new { #class = "form-control", placeholder = "Enter Vehicle Reg No." } })
</div>
</div>
<h5 class="form-heading-title"><span class="form-heading-no">2.</span>Available Timings</h5>
<div class="row">
#*<div class="col-sm-6">
<input type="text" class="form-control date-pick" id="appointment-date" name="appointment-date" placeholder="Appointment Date" required>
</div>*#
<div class="col-sm-6">
<div class="dropdown">
#Html.DropDownListFor(Model => Model.fk_TimeSlotID, new SelectList(ZahidCarWash.DAL.TimeSlotsRepository.getTimeSlots(), "TimeSlotID", "FromTo"), new { #class = "form-control" })
#Html.ValidationMessageFor(Model => Model.fk_TimeSlotID, "", new { #class = "ErrorMessages" })
</div>
</div>
</div>
<h5 class="form-heading-title"><span class="form-heading-no">3.</span>Contact Details</h5>
<div class="row">
<div class="col-sm-4">
#Html.EditorFor(Model => Model.CustomerName, new { htmlAttributes = new { #class = "form-control", placeholder = "Customer Name" } })
#Html.ValidationMessageFor(Model => Model.CustomerName, "", new { #class = "ErrorMessages" })
</div>
<div class="col-sm-4">
#Html.EditorFor(Model => Model.ContactNo, new { htmlAttributes = new { #class = "form-control", placeholder = "Enter Contact Number." } })
#Html.ValidationMessageFor(Model => Model.ContactNo, "", new { #class = "ErrorMessages" })
</div>
#*<div class="col-sm-12">
<textarea id="message" name="message" rows="6" placeholder="Message"></textarea>
</div>*#
</div>
<input type="submit" onclick="save();" class="btn btn-default pull-right" value="Book Now"/>
</form>
</div>
</div>
</div>
</div>
</div>
As discussed, change the type of your button to be a "button". Remove the onclick attribute and add an "id". We'll use this id to capture the button click.
<input type="button" id="btnSubmit" class="btn btn-default pull-right" value="Book Now"/>
Change the form declaration to the below. Looks like you have it commented out!
#using (Html.BeginForm("", "", FormMethod.Post, new { id = "frmMyForm" }))
{
//HTML here
}
Capture the click in Jquery, serialize the form and post the form to the controller.
$(document).on("click", "#btnSubmit", function () {
var data = $("#frmMyForm").serialize();
$.ajax({
async: true,
type: "POST",
data: data,
url: "/Appointment/AddAppointment/",
success: function () {
//Do stuff here if needed
},
complete: function () {
//Stuff here if needed
}
});
});
Hope that helps you on your way,
You have url: '#Url.Action("Appointment", "AddAppointment")', but your Controller Action name is: public ActionResult AddAppointment(AddBookingsViewModel AddBookingVM)
(updated)
But you also have a RedirectToAction in your Action for the $.ajax - the $.ajax should have a response.
Try just sending a HttpPost transaction by changing your script to this:
function save() {
var BookingDetails =
{
VehicleModel: document.getElementById('VehicleModel').value,
VehicleRegNo: document.getElementById('VehicleRegNo').value,
AppointmentTime: '1',
CustomerName: document.getElementById('CustomerName').value,
ContactNo: document.getElementById('ContactNo').value
}
var form = document.createElement("form");
var url = '#Url.Action("Appointment", "AddAppointment")';
form.setAttribute("method", "POST");
form.setAttribute("action", url);
for (var key in BookingDetails) {
if (data.hasOwnProperty(key)) {
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", key);
hiddenField.setAttribute("value", data[key]);
form.appendChild(hiddenField);
}
}
document.body.appendChild(form);
form.submit();
form.remove();
}
This is a straight HttpPost with no return expected in the script. It creates a form, attaches the data (by creating hidden inputs) to be sent to the action, adds the form to the DOM, submits and then removes it.