reCAPTCHA not visible in a MVC partialview page - c#

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.

Related

Validation not firing in modal popup

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
});
})

form serialize is empty on MVC 5 ajax

i'm trying to login through a model inc asp net MVC 5, however, i can't seem to get the data from the form using serialize, there are no errors, it just shows nothing inside data
#using (Html.BeginForm("Login", "Account", new { returnUrl = Request.QueryString["ReturnUrl"] }, FormMethod.Post, new { id = "formModal" }))
{
#Html.AntiForgeryToken();
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="container">
<div class="form-login">
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">Login</div>
</div>
<div class="panel-body">
<div class="form-group">
<div class="input-group mb-3">
<div class="input-group-prepend">
<div class="input-group-text">
<i class="fas fa-user"></i>
</div>
</div>
#Html.EditorFor(model => model.Username, new { htmlAttributes = new { #class = "form-control", placeholder = "Username", autofocus = true } })
#Html.ValidationMessageFor(model => model.Username, "", new { #class = "text-danger" })
</div>
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<div class="input-group-text">
<i class="fas fa-lock"></i>
</div>
</div>
#Html.EditorFor(model => model.Password, new { htmlAttributes = new { #class = "form-control", placeholder = "Password" } })
#Html.ValidationMessageFor(model => model.Password, "", new { #class = "text-danger" })
</div>
<div class="form-group">
<button id="btnSubmit" type="submit" class="btn primary btn-lg">
Entrar
</button>
</div>
</div>
</div>
</div>
</div>
}
<script type="text/javascript">
$("#btnSubmit").click(function () {
debugger
var formData = $('#formModal').serialize();
$.ajax({
type: 'POST',
url: '/Account/Login',
data: formData,
async: true,
success: function (data) {
}
});
return false;
});
what am i doing wrong? i saw some videos and i did exactly the same... I can reach the controller but there is no data
this is the controller
public class AccountController : Controller
{
public ActionResult Index()
{
return PartialView("_PartialLogin");
}
[HttpPost]
public ActionResult Login(LoginViewModel model, string ReturnUrl)
{
var user = Authenticate(model);
var ticket = new FormsAuthenticationTicket(
1,
user.Id.ToString(),
DateTime.Now,
DateTime.Now.AddHours(5),
model.RememberMe,
user.Roles.Select(c => c.Nome).FirstOrDefault()
);
return Redirect(ReturnUrl);
}
}
and here is view model
public class LoginViewModel
{
[Required]
[StringLength(8)]
public string Username { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
public bool RememberMe { get; set; }
}
no matter what, i cannot seem to get data from form using jquery, it's always null when i use serialize
EDIT
I forgot to mention, this form is inside a partialview, in a modal
#model Logistica.ViewModels.LoginViewModel
#{
Layout = null;
}
<link href="~/Content/bootstrap.css" rel="stylesheet" />
<link href="~/Content/login.css" rel="stylesheet" />
<link href="~/Content/fontawesome-all.css" />
<script src="~/scripts/jquery-3.3.1.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="~/Scripts/bootstrap.js"></script>
<script src="~/Scripts/fontawesome/all.js"></script>
<!-- Modal -->
<div class="modal fade" id="modalLogin" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
</div>
</div>
</div>
</div>
I can't believe i could be so stupid, I thought this would be one of the possible options for my problem, form inside a form...
I am calling the login modal from _Layout and it was inside a form... I can't believe i wasted a day for this. It's my first time going backwards on making a mvc 5 project cause our IIS server does not allow host for Asp .NET Core 2.2 yet and totally forgot about the form on layout.
<form class="form-inline my-2 my-lg-0">
#if (User.Identity.IsAuthenticated)
{
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
}
else
{
<ul class="navbar-nav mr-auto">
<li class="nav-item">
#Html.Action("Index", "Account")
<a class="nav-link" href="#" data-toggle="modal" data-target="#modalLogin">Log In</a>
</li>
</ul>
}
</form>
Change url from url: '/Login/Account' to url: '/Account/Login' because your controller is Account not Login. I tried reproduce in local and it worked
$("#btnSubmit").click(function () {
debugger
var formData = $('#formModal').serialize();
$.ajax({
type: 'POST',
url: '/Account/Login',
data: formData,
async: true,
success: function (data) {
}
});
return false;
});
the data you post needs to map to one object { model: {}, ReturnUrl: "" }, ReturnUrl can come from the query string, but your action and form models are different.
Your form model is model: {}, and your action model is { model: {}, ReturnUrl: "" }
your name attributes on your form inputs should be model.Username, model.Password, vs Username, Password

My question is that, i do SweetAlerts in my project but not working

i am trying to implement sweetalert in my project but i can not pick the problem where it exist, i do every thing properly but still not chase my goal in this scenario.
This is my View:
#model SSC_MVC.Models.Department
#{
// ViewBag.Title = "Create";
ViewBag.Title = Model.dpt_id == null ? "Create" : "Edit";
}
<script src="~/Scripts/jquery-1.12.4.min.js">
</script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<link href="~/bootstrap-3.3.6-dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="~/bootstrap-3.3.6-dist/js/bootstrap.js"></script>
<script src="https://lipis.github.io/bootstrap-sweetalert/lib/sweet-alert.js"></script>
<link href="~/Content/sweetalert/sweet-alert.css" rel="stylesheet" />
<script type="text/javascript">
function validateData()
{
debugger;
if ($("#dpt_nam").val() == "")
{
swal("Please enter Name !");
return false;
} else
{
return true;
}
}
</script>
<h2>Create</h2>
#using (Html.BeginForm(FormMethod.Post) )
{
#Html.AntiForgeryToken()
<div class="col-md-12 form-horizontal">
<h4>Department</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.dpt_id)
<div class="form-group">
<div class="col-md-2">
#Html.Label("Name", htmlAttributes: new { #class = "control-label col-md-2 " })
</div>
<div class="col-md-8">
#Html.EditorFor(model => model.dpt_nam, new { htmlAttributes = new { #class = "form-control validateData" } })
#Html.ValidationMessageFor(model => model.dpt_nam, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
#if (Model.dpt_id == null)
{
<input type="submit" onclick="Validate(this, event);" value="Create" class="btn btn-primary" />
}
else
{
<input type="submit" value="Edit" class="btn btn-success" />
}
</div>
</div>
#{
var message = TempData["AlertMessage"] ?? string.Empty;
}
<script type="text/javascript">
var message = '#message';
if(message)
alert(message);
</script>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#*#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}*#
There is my Model:
public string dpt_id { get; set; }
public string dpt_nam { get; set; }
public string dpt_typ { get; set; }
In view #dpt_nam is my model property, actually i want, when I click on submit button and if the user not complete the department Name the alert shows, like: Please enter Name !, so in that case i made a function named as ValidateData, u can see it in a view.
any one here who help me out?

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 );

Dropzone, how do I submit form with data and multiple images?

I am using MVC in ASP.NET and want a Drag n Drop in my view. I would like to call a function in my controller when the images are dropped to verify them and show an OK to the user. When the user has finished typing in information and dropped the appropriate images he/she clicks "Fortsæt" (continue) and calls submit on the form.
This method should be called when an Image is dropped.
[HttpPost]
[Authorize(Roles = "host")]
public ActionResult UploadImages()
{
bool suc;
foreach (string s in Request.Files)
{
HttpPostedFileBase image = Request.Files[s];
string fileName = Request.Headers["X-File-Name"];
string fileExtension = "";
if (!string.IsNullOrEmpty(fileName))
fileExtension = Path.GetExtension(fileName);
suc = Verify(fileExtension);
}
return Json(suc);
}
This should be called when the user clicks "Continue"
[HttpPost]
[Authorize(Roles = "host")]
public ActionResult Create(FleaMarket model, HttpPostedFileBase[] images)
{
ConditionallySetUser(model, User);
foreach (var fileName in Request.Files)
{
HttpPostedFileBase file = Request.Files[fileName.ToString()];
if (file != null && file.ContentLength > 0)
{
var image = HttpPostedFileBaseToByteArray(file);
model.Images.Add(new FleaImage
{
Image = image, FleaMarketId = model.EventId
});
}
}
db.FleaMarkets.Add(model);
db.SaveChanges();
ViewBag.HostID = new SelectList(db.Hosts, "HostId", "Name", model.HostId);
TempData["market"] = model;
return
RedirectToAction("AddStallImage", "FleaMarket");
}
Here are some snips of my View
#model FleaPortal.Models.Database.FleaMarket
<link href="~/Content/basic.css" rel="stylesheet" />
<link href="~/Content/dropzone.css" rel="stylesheet" />
<script src="~/Scripts/dropzone.min.js"></script>
#using (Html.BeginForm("Create", "FleaMarket", method: FormMethod.Post, htmlAttributes: new { #encType = "multipart/form-data",#class="dropzone", #id="dropzoneForm"}))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.HostId)
<div class="row">
<div class="form-group col-sm-6">
#Html.LabelFor(model => model.HostId, "Arrangør")
<label class="text-box single-line form-control" id="Name">
#Html.DisplayFor(model => model.Host.UserProfile.UserName)
</label>
</div>
<div class="form-group col-sm-6">
#Html.LabelFor(model => model.Name)
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="form-group col-sm-12">
#Html.LabelFor(model => model.Description)
#Html.EditorFor(model => model.Description, new { #class = "TextAreaInput" })
#Html.ValidationMessageFor(model => model.Description)
</div>
...
...
<div class="form-group col-sm-12">
<label>Stemningsbilleder</label>
<div id="dropzonePreview">
drop your images here
<div class="dz-default dz-message" data-dz-message="">
</div>
</div>
</div>
...
...
<div class="btn-group two-bt-group col-sm-12">
<button name="ButtonType" value="Continue" id="submitAll" type="submit" class="btn btn-success two-bt">#Resources.Views_Global_Continue</button>
<button name="ButtonType" value="Cancel" type="button" class="btn btn-danger two-bt" onclick="location.href='#Url.Action("Manage", "Account")'">#Resources.Views_Global_Cancel</button>
</div>
#section Scripts {
#Scripts.Render("~/bundles/datepicker")
#Scripts.Render("~/bundles/booking")
#Scripts.Render("~/bundles/dropzonescripts")
<script type="text/javascript">
$(document).ready(function() {
$(".form_date").datetimepicker({ format: 'yyyy-mm-dd', startView: 2, minView: 2 });
$(".form_time").datetimepicker({ format: 'hh:ii', startView: 1, maxView: 1 });
});
</script>
<script>
Dropzone.options.dropzoneForm = {
clickable: false,
//url: '/FleaMarket/UploadImages',
autoProcessQueue: false,
uploadMultiple: true,
paramName: "images",// Must match the name of the HttpPostedFileBase argument that the Upload action expects
maxFiles: 100,
autoQueue: false,
previewsContainer: "#dropzonePreview",
parallelUploads:100,
init: function () {
debugger;
this.on("success", function (file, responseText) {
file.previewTemplate.appendChild(document.createTextNode(responseText));
});
}
};
</script>
I have spent way too much time trying to figure this out, and I believe there might be a simple solution - I just don't know. ? Can someone help me figuring this out?
Many thanks in advance.
I ended up calling a method in my controller every time an image was uploaded. I assigned an ID to the imaged and passed it to my view like this:
Dropzone.autoDiscover = false;
$("div#dropzonePreview").dropzone(
{
url: '/FleaMarket/UploadImage',
paramName: "images",
autoProcessQueue: true,
addRemoveLinks: true,
//clickable: "#dropzonePreview",
uploadMultiple: true,
acceptedFiles: "image/*",
maxFiles: 100,
parallelUploads: 10,
dictInvalidFileType: "Dette er ikke et billede",
dictFileTooBig: "Billedet er for stort",
success: function(file, response) {
$('#ImageIds').val($('#ImageIds').val() + "," + response.Ids);
done();
}
});
#Html.HiddenFor(model => model.ImageIds);
<div class="form-group col-sm-12">
<label>Stemningsbilleder</label>
<div id="dropzonePreview" class="dropzone">
</div>
</div>

Categories

Resources