Validation not firing in modal popup - c#

My Validation is not firing on my popup its showing the popup just fine just not doing the validation
<div>
<form id="myForm">
#Html.HiddenFor(m => m.Id)
#Html.TextBoxFor(model => model.Name, new { #class = "form-control", #placeholder = "Name" })
<span asp-validation-for="#Model.Name" class="text-danger"></span>
#Html.TextBoxFor(model => model.Resitance, new { #class = "form-control", #placeholder = "Address" })
<span asp-validation-for="#Model.Resitance" class="text-danger"></span>
#Html.TextBoxFor(model => model.Passed, new { #class = "form-control", #placeholder = "Passed" })
<span asp-validation-for="#Model.Passed" class="text-danger"></span>
<select asp-for="CirtcutType"
asp-items="#Html.GetEnumSelectList(typeof(ElectricalSurvey.DAL.Models.CircuitModel.CirtcutTypes))"
class="form-control"></select>
<div class="modal-footer">
#if (Model.Id > 0) {<span>Update</span> } else {<span>Save</span>}
</div>
</form>
<div style="text-align:center;display:none" id="loaderDiv">
<img src="~/Content/InternetSlowdown_Day.gif" width="150" />
</div>
</div>
<script>
$(document).ready(function () {
$("#btnSubmit").click(function () {
$("#loaderDiv").show();
var myformdata = $("#myForm").serialize();
$.ajax({
type: "POST",
url: "/Electrician/SaveCircuit",
data: myformdata,
success: function () {
$("#loaderDiv").hide();
$("#MyEditUpateModal").modal("hide");
window.location.href = "/Electrician/Index";
}
})
})
})
_ValidationScriptsPartial.cshtml
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
To Note I am handing the dialog in html via following method.
<script>
var AddOrUpdateCircuit = function (id) {
var url = "/Electrician/AddOrUpdateCircut?id=" + id;
$("#myModalBodyDiv1").load(url, function () {
$("#MyEditUpateModal").modal("show");
})
}

This one will help you get started
<form id="myForm" class="needs-validation" novalidate>
and
$("#btnSubmit").click(function (e) {
e.preventDefault(); // do not execute actual submit.
var form = $("#myForm")[0];
form.classList.remove('was-validated');
if (form.checkValidity() === false) {
form.classList.add('was-validated');
return;
}
$.ajax({
//perform ajax
});
})

Related

Submit Form when value is entered on LabelFor

I'm making a webapp which receives text when a barcode is scanned and submit it, which would be the same as submitting it when writing any letter in the textbox with a keyboard. I've tried with this code, but it submit it when the focus is changed from the textbox, not when the value is entered:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Escaneado</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Texto, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Texto, new { htmlAttributes = new { #class = "form-control", #autofocus = "autofocus" } })
#Html.ValidationMessageFor(model => model.Texto, "", new { #class = "text-danger" })
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Cargar escaneados", "LoadScans")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(document).ready(function () {
$('#Texto').change(function () {
$('form').submit();
});
});
</script>
}
I've tried using a .trigger in the script, looking like this:
<script type="text/javascript">
$(document).ready(function () {
$('#Texto').change(function () {
$('form').submit();
});
$('#Texto').trigger("change");
});
</script>
which submits, but when the page reloads after submitting, it enters in an infinite loop of submitting
With this script, the info is submitted and it doesn't loop:
<script type="text/javascript">
$(document).ready(function () {
$('#Texto').on('input', function () {
$('form').submit();
});
});
</script>
Change() event fires when the user types into the input and then loses focus. you will need to trigger the event when you pass that data, something like .trigger("change")

Modal/Partial view uk date conflict MVC5

I am having a problem with jquery validation within a Modal/Partial View as it's conflicting with my main view. The main issue is with #Scripts.Render("~/bundles/jqueryval") as when I add it to my main view, the main form will no longer submit (doesn't hit the controller) as the validation is rejecting UK style dates (as you can see in my code, I am using DateITA to solve this problem in my Modal and submits with no issues)
I have tried moving #Scripts.Render("~/bundles/jqueryval") to the partial view & the main page will now submit, but it breaks my submit for the Modal. I have also tried naming the main view form & modal form to apply the validation to just the modal, but this hasn't helped.
Thanks
Main view
#model Puspers2.ViewModels.ContractViewModel
#{
ViewBag.Title = "Contract";
}
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "mainForm" }))
{
<div class="form-group form-inline datepickerWidth">
<div class='input-group date mydatepicker datepickerWidth'>
#Html.TextBoxFor(m => m.TblContract.OrderPlacedDate, new { title = "Order Placed Date", placeholder = "dd/mm/yyyy", #class = "form-control datepickerWidth", onclick = "this.select()", id = "orderPlacedDate" })
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<div class='form-group form-inline datepickerWidth'>
<div class='input-group date mydatepicker datepickerWidth'>
#Html.TextBoxFor(m => m.TblContract.ContractStartDate, new { title = "Contract Start Date", placeholder = "dd/mm/yyyy", #class = "form-control datepickerWidth", id = "contractStartDate", onclick = "this.select()" })
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<!--SAVE BUTTON-->
<br /><br /><br /><br />
<div class="form-group absolute">
<hr />
<button type="submit" class="btn btn-primary btn-lg saveButtonPadding" value="save" formaction="ContractUpdate" formmethod="post" id="saveButton">Save</button>
</div>
<!--SAVE BUTTON-->
}
<!--div to hold the Partial view that forms the modal-->
<div class="form-group">
#Html.Partial("_ContractContributionDetails")
</div>
<!--end div to hold the Partial view that forms the modal-->
#section scripts{
#Scripts.Render("~/bundles/jqueryval")
<script>
//Modal
$(document).on('click', '#SaveContractContribution', function () {
var $form = $('#modalForm')
.validate({
rules: {
TblContractContributionHistory_CommencementDeductions: {
dateITA: true
}
}
});
if ($form.valid()) {
$.ajax({
async: false,
type: 'POST',
url: 'ContractContributionHistoryAdd',
datatype: "json",
data: {
contractNumber: $("#contractNumber").val(),
commencementDeductions: $('#TblContractContributionHistory_CommencementDeductions').val(),
deductionsCategoryId: $('#deductionsCategory').val(),
numberOfContributions: $('#TblContractContributionHistory_NumberOfContributions').val(),
employeeContributionReference: $('#TblContractContributionHistory_EmployeeContributionReference').val(),
teamMember: $('#TblContractContributionHistory_TeamMemberId').val()
},
success: function (data) {
location.reload();
}
});
}
});
// >> JS snippet to handle datepicker functionality >>
$(function () {
$('.mydatepicker').datetimepicker({
locale: 'en-gb',
format: 'DD/MM/YYYY',
showTodayButton: true,
showClear: true,
})
.on('dp.hide', function () { // on hiding data picker, record associated entryfield to allow focus to be set when built-in blur happens
dateField = $(this).find('input');
$("#contractStartDate,#contractEndDate,#actualTerminationDate").trigger("change")
PickerClosing = true;
});
// on exit from date field, check if caused by picker closing. If Yes, set focus back in field
$('.mydatepicker input').blur(function (e) {
if (PickerClosing == true) {
PickerClosing = false;
dateField.focus();
}
});
});
// << JS snippet to handle datepicker functionality <<
</script>
}
Partial View
#model Puspers2.ViewModels.ContractViewModel
#Scripts.Render("~/Scripts/jquery-1.10.2.js")
#Scripts.Render("~/Scripts/jquery-3.3.1.js")
#Scripts.Render("~/scripts/jquery-ui-1.12.1.min.js")
#Scripts.Render("~/scripts/bootbox.js")
#Scripts.Render("~/Scripts/bootstrap.js")
#Scripts.Render("~/Scripts/respond.js")
#Scripts.Render("~/Scripts/moment.js")
#Scripts.Render("~/Scripts/moment-with-locales.js")
#Scripts.Render("~/Scripts/bootstrap-datetimepicker.js")
#{
}
#using (Ajax.BeginForm("ContractContributionHistoryAdd", "Home", new AjaxOptions
{ }, new { id = "modalForm" }))
{
<div>
<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content modalContentDeductions">
<h2 class="modal-header">Add Deduction</h2>
<div class="modal-body">
<p class="dateLabels"><strong>Deductions Commenced On</strong></p>
<div class='form-group form-inline modalDatepickerWidth'>
<div class='input-group date mydatepicker modalDatepickerWidth'>
#Html.TextBoxFor(m => m.TblContractContributionHistory.CommencementDeductions, new { title = "Commencement Deductions", #class = "form-control inputSizeMedium" })
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<div class='form-group'>
#Html.LabelFor(m => m.TblContractContributionHistory.DeductionsCategoryId, new { title = "Payment" })
#Html.DropDownListFor(m => m.TblContractContributionHistory.DeductionsCategoryId, new SelectList(Model.TblDeductionsCategoryLOOKUP, "DeductionsCategoryId", "Category"), "Select Option", new { #class = "form-control inputSizeMedium", #id="deductionsCategory"})
#Html.ValidationMessageFor(m => m.TblContractContributionHistory.DeductionsCategoryId)
</div>
<div class="form-group">
#Html.LabelFor(m => m.TblContractContributionHistory.EmployeeContributionReference, new { title = "Monthly Cost To Employee" })
#Html.TextBoxFor(m => m.TblContractContributionHistory.EmployeeContributionReference, new { title = "Monthly Cost To Employee", #class = "form-control inputSizeMedium" })
</div>
<div class="form-group">
#Html.LabelFor(m => m.TblContractContributionHistory.NumberOfContributions, new { title = "" })
#Html.TextBoxFor(m => m.TblContractContributionHistory.NumberOfContributions, new { title = "", #class = "form-control inputSizeMedium" })
</div>
<div class='form-group'>
#Html.LabelFor(m => m.TblContractContributionHistory.TeamMemberId, new { title = "" })
#Html.DropDownListFor(m => m.TblContractContributionHistory.TeamMemberId, new SelectList(Model.TblTeamMembersLOOKUP, "TeamMemberId", "TeamMemberName"), "Select Option", new { #class = "form-control inputSizeMedium" })
#Html.ValidationMessageFor(m => m.TblContractContributionHistory.TeamMemberId)
</div>
<br />
<div>
<button id="SaveContractContribution" class="btn btn-primary btn-lg" value="save" formmethod="post">Save</button>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
}
#section scripts
{
<script>
$(function () {
$.validator.unobtrusive.parse('#modalForm');
});
$(function () {
$('.mydatepicker').datetimepicker({
locale: 'en-gb',
format: 'DD/MM/YYYY',
showTodayButton: true,
showClear: true,
})
.on('dp.hide', function () { // on hiding data picker, record associated entryfield to allow focus to be set when built-in blur happens
dateField = $(this).find('input');
$("#contractStartDate,#contractEndDate,#actualTerminationDate").trigger("change")
PickerClosing = true;
});
// on exit from date field, check if caused by picker closing. If Yes, set focus back in field
$('.mydatepicker input').blur(function (e) {
if (PickerClosing == true) {
PickerClosing = false;
dateField.focus();
}
});
})
</script>
}
DateITA
$.validator.addMethod( "dateITA", function( value, element ) {
var check = false,
re = /^\d{1,2}\/\d{1,2}\/\d{4}$/,
adata, gg, mm, aaaa, xdata;
if ( re.test( value ) ) {
adata = value.split( "/" );
gg = parseInt( adata[ 0 ], 10 );
mm = parseInt( adata[ 1 ], 10 );
aaaa = parseInt( adata[ 2 ], 10 );
xdata = new Date( Date.UTC( aaaa, mm - 1, gg, 12, 0, 0, 0 ) );
if ( ( xdata.getUTCFullYear() === aaaa ) && ( xdata.getUTCMonth() === mm - 1 ) && ( xdata.getUTCDate() === gg ) ) {
check = true;
} else {
check = false;
}
} else {
check = false;
}
return this.optional( element ) || check;
}, $.validator.messages.date );

reCAPTCHA not visible in a MVC partialview page

I'm having troubles adding google reCAPTCHA to my page.
in the Layout I have added the Google Recaptcha js
_layout
<title>#ViewBag.Title</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts", required: false)
<script src='https://www.google.com/recaptcha/api.js'></script>
<script type="text/javascript">
<script type="text/javascript">
$(document).ready(function () {
$('#subject').on("change", function (e) {
e.preventDefault();
var selectedVal = $('#subject').val();
$.ajax({
// url: "/ContactUs/GetForm",
url: '#Url.Action("GetForm", "ContactUs")',
type: "POST",
data: { searchValue: selectedVal } ,
async: true,
success: function (data) {
$('#renderForms').empty();
$('#renderForms').append(data);
},
error: function (xhr, ajaxOptions, thrownError) {
alert("An error has occured!!! " + xhr.status + " && " + xhr.responseText);
}
});
});
});
</script>
then in my index I select which form I want to show:
#Html.DropDownListFor(model => model.contactSelectListItems, new List<SelectListItem>
{
new SelectListItem() {Text = "option1", Value="option1"},
new SelectListItem() {Text = "option2", Value="option2"},
new SelectListItem() {Text = "option3", Value="option3"},
}, "--Choose--", new { id = "subject", #class= "dropdown-item" })
</div>
<div id="renderForms">
</div>
in both partial page there is a form where I do something similiar yet different viewmodels:
#using (Html.BeginForm("SendCustomerTeam", "ContactUs", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>CustomerTeamViewModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="container">
<div class="form-group form-group-sm col-sm-6">
<div class="row">
#Html.LabelFor(model => model.Phone, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-sm-9">
#Html.EditorFor(model => model.Phone, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Phone, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group form-group-sm col-sm-12">
<div class="row">
#Html.LabelFor(model => model.Inquiry, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-sm-12">
#Html.EditorFor(model => model.Inquiry, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Inquiry, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group form-group-sm col-sm-12">
<div class="row">
<div class="col-sm-12">
<div id="NotRobot">
<label>Are you Human?</label>
<div id='recaptcha' class="col-sm-12 g-recaptcha"
data-sitekey="#System.Configuration.ConfigurationManager.AppSettings["RecaptchaPublicKey"]"
>
</div>
<div id="recaptchaMessage" data-verifyrecaptchatokenurl="#Url.Action("VerifyReCaptchaToken", "Home")" style="display:none;padding:10px;color:red;font-weight:bold;" class="error">You need to verify reCAPTCHA.</div>
</div>
</div>
</div>
</div>
<div class="form-group form-group-sm col-sm-6">
<div class="row">
<div class="col-sm-9">
<input id="Send" type="submit" value="Send" class="btn btn-default" />
</div>
</div>
</div> etc...
In my controller I handle it like this thou I would like to handle the reCAPTCHA as an ajax call I have yet to figure out how to do that.
public ActionResult Index()
{
ViewData["ReCaptchaKey"] = System.Configuration.ConfigurationManager.AppSettings["RecaptchaPublicKey"];
//do something here
}
public static bool ReCaptchaPassed(string gRecaptchaResponse, string secret)
{
HttpClient httpClient = new HttpClient();
var res = httpClient.GetAsync($"https://www.google.com/recaptcha/api/siteverify?secret={secret}&response={gRecaptchaResponse}").Result;
if (res.StatusCode != HttpStatusCode.OK)
{
//logger.LogError("Error while sending request to ReCaptcha");
return false;
}
string JSONres = res.Content.ReadAsStringAsync().Result;
dynamic JSONdata = JObject.Parse(JSONres);
if (JSONdata.success != "true")
{
return false;
}
return true;
}
[HttpPost]
public ActionResult SendCustomerTeam(CustomerTeamViewModel model)
{
ContactViewModel contactModel = new ContactViewModel();
contactModel.CustomerTeamModel = model;
ViewData["ReCaptchaKey"] = System.Configuration.ConfigurationManager.AppSettings["RecaptchaPublicKey"];
if (ModelState.IsValid)
{
if (!ReCaptchaPassed(
Request.Form["g-recaptcha-response"], // that's how you get it from the Request object
System.Configuration.ConfigurationManager.AppSettings["RecaptchaPrivateKey"]
))
{
ModelState.AddModelError(string.Empty, "You failed the CAPTCHA, stupid robot. Go play some 1x1 on SFs instead.");
return View(contactModel);
}
}
My problem is the reCAPTCHA never appears on my page.
Edit:
I've tried the following simplification to see if I could find the issue.
SimplePageViewModel
public class simplePageViewModel
{
public string Name { get; set; }
}
SimplePagePartialView
#model Contact_Portal.Models.simplePageViewModel
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>simplePageViewModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="container">
<div class="row">
<div class="form-group form-group-sm col-sm-6">
<div class="row">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-sm-9">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group form-group-sm col-sm-12">
<div class="row">
<div class="col-sm-12">
<div id="NotRobot">
<label>Are you Human?</label>
<div id='recaptcha' class="col-sm-12 g-recaptcha" style="padding:10px;"
data-sitekey="#System.Configuration.ConfigurationManager.AppSettings["RecaptchaPublicKey"]">
</div>
<div id="recaptchaMessage" data-verifyrecaptchatokenurl="#Url.Action("VerifyReCaptchaToken", "Home")" style="display:none;padding:10px;color:red;font-weight:bold;" class="error">You need to verify reCAPTCHA.</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
in the controller I get the partial view shown through this line
return PartialView("View", contactModel.simplePageModel);
Still the same problem persist.
Could it be because I'm displaying my partial page containing the reCAPTCHA as part of an Jquery Ajax call ? like this:
$(document).ready(function () {
$('#subject').on("change", function (e) {
e.preventDefault();
var selectedVal = $('#subject').val();
$.ajax({
// url: "/ContactUs/GetForm",
url: '#Url.Action("GetForm", "ContactUs")',
type: "POST",
data: { searchValue: selectedVal } ,
async: true,
success: function (data) {
$('#renderForms').empty();
$('#renderForms').append(data);
},
error: function (xhr, ajaxOptions, thrownError) {
alert("An error has occured!!! " + xhr.status + " && " + xhr.responseText);
}
});
});
I've now tried a entire new project where I've simplified it all the way down to one html file:
Index.cshtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - My ASP.NET Application</title>
<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
<link href="~/Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="~/Scripts/modernizr-2.6.2.js"></script>
<script src='https://www.google.com/recaptcha/api.js'></script>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
#Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { #class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
</ul>
</div>
</div>
</div>
<div class="container body-content">
<div id='recaptcha' class="col-sm-12 g-recaptcha" style="padding:10px;"
data-sitekey="#System.Configuration.ConfigurationManager.AppSettings["RecaptchaPublicKey"]"></div>
<hr />
<footer>
<p>© #DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
</body>
</html>
Still it is not visible it never appears. why is it not working ?
could it be that ASP.NET MVC is not supported by Recaptcha from google?
Your script src is wrong:
<script src='https://www.google.com/recaptcha/api.js async defer'></script>
to
<script src='https://www.google.com/recaptcha/api.js'></script>
Also could you check deveoper console, if there any error?
Well I found a solution I'm not happy with it but it works.
in my Layout file I've made a section like this:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script type="text/javascript">
function enableBtn() {
document.getElementById("subject").disabled = false;
}
$(document).ready(function () {
document.getElementById("subject").disabled = true;
});
</script>
Then in my view I created this
<div class="g-recaptcha" data-sitekey="*********PublicKEY*************" data-callback="enableBtn"></div>
And it seems to be working.
I wish I could make it work in the partial view because now I have to have it no matter what else will happen and not just on a submit.
I don't know if I can verify this one server side anymore as it is also outside my form. ?
Anyone with a better option would be welcomed.
EDIT:
I found a better solution for me. I changed my ajax call like this:
$('#subject').on("change", function (e) {
e.preventDefault();
var selectedVal = $('#subject').val();
$.ajax({
// url: "/ContactUs/GetForm",
url: '#Url.Action("GetForm", "ContactUs")',
type: "POST",
data: { searchValue: selectedVal } ,
async: true,
success: function (data) {
$('#renderForms').empty();
$('#renderForms').append(data);
if (!debug) {
document.getElementById("Send").disabled = true;
grecaptcha.render('Captcha', {
'sitekey': '**********PublicKey*********',
'callback': function() {
document.getElementById("Send").disabled = false;
},
'expired-callback': function() {
//document.getElementById("subject").selectedIndex = 0;
document.getElementById("Send").disabled = true;
//document.getElementById("renderForms").innerHTML = "";
}
});
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert("An error has occured!!! " + xhr.status + " && " + xhr.responseText);
}
});
});
Now it is working as I intended. At least in the user interface part.

How to insert data by a partial view in MVC

I want to insert data using partial view for this action method which I have mentioned below.
The problem is that when I submit the Form it doesn't gave me any response.
What can I do with that post the comments and redirect to this page when comment is post?
And my partial view is located in a shared folder.
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult Comments([Bind(Include = "CommentId,UserComments,UserId")] Comment comment)
{
if (ModelState.IsValid)
{
db.Comments.Add(comment);
db.SaveChanges();
return Json(comment, JsonRequestBehavior.AllowGet);
}
ViewBag.UserId = new SelectList(db.UserAccounts, "UserId", "FirstName", comment.UserId);
return Json(JsonRequestBehavior.AllowGet);
}
Rendering partial view in layout.
#Html.Partial("_Comments", new OnlineTaxiReservationSystem.Models.Comment())
and the partial view is here:
#model OnlineTaxiReservationSystem.Models.Comment
<script type="text/javascript">
$(document).on('click', '.btnSubmit', function () {
$.ajax({
url: '#Url.Action("Comments", "Home")',
cache: false,
async: true,
data: {
//put the data that you want to save from the partial here
UserId: $('#userId').val(),
UserComments: $('#content').val()
},
success: function (_result) {
window.location.href = "Home/Index";
}
});
});
#if (Session["user"] != null)
{
using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Your Feedback</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group" style="margin-left: 9%">
#Html.LabelFor(model => model.UserId, "User Name", htmlAttributes: new { #class = "control-label col-md-2" })
#*#Html.Label(Session["UserName"].ToString(), htmlAttributes: new { #class = "control-label label-primary col-md-1" })*#
<div class="col-md-4">
#Html.Editor("UserId", null, new { htmlAttributes = new { #class = "form-control", #id = "userId" } })
#Html.ValidationMessageFor(model => model.UserId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.UserComments, htmlAttributes: new { #class = "control-label col-md-1" })
<div class="col-lg-12">
#Html.TextAreaFor(model => model.UserComments, new { htmlAttributes = new { #class = "form-control", #id = "content"} })
#Html.ValidationMessageFor(model => model.UserComments, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-1 col-md-10">
<input type="submit" value="Submit" id="btnSubmit" class="btn btn-primary" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
}
I think you are making a call to the wrong URL:
You need to add e.preventDefault(); if you are not going to submit by button but from javascript instead:
$(document).on('click', '.btnSubmit', function () {
e.preventDefault(); //cancel the default behavior
//do this instead (the ajax call):
$.ajax({
url: '#Url.Action("Comments", "Home")',
cache: false,
async: true,
data: {
//put the data that you want to save from the partial here
UserId: $('#userId').val(),
UserComments: $('#content').val()
},
success: function (_result) {
window.location.href = "Home/Index";
}
});
});
If you can provide the full details of your 404 call, I can be more spesific.

Binding bootstrap datetimepicker to knockoutmodel

Im using a bootstrap datetimepicker to input appointment datetimes to a knockout viewmodel. the viewmodel has an object appointment which holds the observable values for all appointment object. Im sending the appointment to the controller via an ajax call, however after many null values for my dates i found that you must create a custom binding for the datepicker. after implementing the custom binding on the git page of the datepicker i am still receiving null values for both the start and end dates.
Have i implemented the custom binding incorrectly?
Code:
View:
<div class="form-horizontal">
<h4>Appointment</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Start, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="container">
<div class="row">
<div class='col-sm-3'>
<div class="form-group">
<div class='input-group date' id='startdatepicker'>
<input type='text' class="form-control" data-bind="date: appointment.start, format: 'DD MMM YYYY'" /><span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
</div>
#Html.ValidationMessageFor(model => model.Start, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.End, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="container">
<div class="row">
<div class='col-sm-3'>
<div class="form-group">
<div class='input-group date' id='enddatepicker'>
<input type='text' class="form-control" data-bind="date: appointment.end, format: 'DD MMM YYYY'" /><span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
</div>
#Html.ValidationMessageFor(model => model.End, "", new { #class = "text-danger" })
</div>
</div>
Scripts section at bottom of view
#section Scripts {
#Scripts.Render("~/bundles/jqueryval",
"/Scripts/ViewModels/AppointmentFormViewModel.js")
<script>
$(function () {
$('#startdatepicker').datetimepicker();
$('#enddatepicker').datetimepicker();
});
var viewModel = new AppointmentFormViewModel(#Html.HtmlConvertToJson(Model));
ko.applyBindings(viewModel);
</script>
}
Knockout viewmodel
function AppointmentFormViewModel(appointment) {
var self = this;
self.saveCompleted = ko.observable(false);
self.sending = ko.observable(false);
self.isCreating = appointment.id == 0;
self.appointment = {
id: appointment.id,
start: ko.observable(appointment.start),
end: ko.observable(appointment.end),
text: ko.observable(appointment.text),
clientid: ko.observable(appointment.clientid),
employeeid: ko.observable(appointment.employeeid),
roomid: ko.observable(appointment.roomid),
};
ko.bindingHandlers.date = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
ko.utils.registerEventHandler(element, 'change', function () {
var value = valueAccessor();
if (element.value !== null && element.value !== undefined && element.value.length > 0) {
value(element.value);
}
else {
value('');
}
});
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var value = valueAccessor();
var allBindings = allBindingsAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);
var pattern = allBindings.format || 'DD/MM/YYYY';
var output = "-";
if (valueUnwrapped !== null && valueUnwrapped !== undefined && valueUnwrapped.length > 0) {
output = moment(valueUnwrapped).format(pattern);
}
if ($(element).is("input") === true) {
$(element).val(output);
} else {
$(element).text(output);
}
}
};
here is the appointment model object that was sent from the knockout viewmodel
as you can see the date time is not what was selected
Here is how it posted to server
is creating is a variable to determine whether the form is editing or creating an appointment
self.appointment.__RequestVerificationToken = form[0].value;
$.ajax({
url: (self.isCreating) ? 'Create' : 'Edit',
type: 'post',
contentType: 'application/x-www-form-urlencoded',
data: ko.toJS(self.appointment)
})

Categories

Resources