bootstrap modal to appear when dropdownlist item is selected in mvc - asp.net-mvc

I want a bootstrap modal with partial view to popup when a user selects the dropdownlist item.
For each selected item the popup should refresh with new content when the user selects a different item in the dropdownlist. From the code below, I could able to make the ajax and then redirect to partial view with model values but unable to display the modal popup
Index.cshtml
<div class="form-group">
#Html.LabelFor(model => model.SelectedIssue, htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-9">
#Html.DropDownListFor(model => model.SelectedIssue, Model.IssueDetails, "Please Select", new { #class = "form-control", #id = "IssueId" })
#Html.ValidationMessageFor(model => model.SelectedIssue, "", new { #class = "text-danger" })
</div>
</div>
$("#IssueId").change(function () {
$.ajax({
type: 'GET',
url: '#Url.Action("GetActionDetails")',
dataType: 'html',
data: { id: $("#IssueId").val() },
success: function (data) {
$('#modal-content').html(data);
$('#modal-container').modal('show');
},
error: function (ex) {
alert('Failed to retrieve action details' + ex);
}
});
return false;
});
The dropdown selection is making an ajax call and calling the below method in the controller
public ActionResult GetActionDetails(string id)
{
ActionDetails model = new ActionDetails();
model.ActionTaken = "Action Taken ";
model.AdviceGiven = "Advice Given to";
return PartialView("ActionDetails", model);
}
This is then redirecting to PartialView ActionDetails view which is below.
#model OnCallLogging.Models.ActionDetails
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
<h3 class="modal-title">Action Details</h3>
</div>
<div class="modal-body">
<div class="form-horizontal">
<div class="form-group">
#Html.LabelFor(m => Model.ActionTaken, new { #class = "control-label col-sm-3"})
<div class="col-sm-9">
#Html.DisplayFor(m => m.ActionTaken, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => Model.AdviceGiven, new { #class = "control-label col-sm-3" })
<div class="col-sm-9">
#Html.DisplayFor(m => m.AdviceGiven, new { #class = "form-control" })
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-warning" data-dismiss="modal">Close</button>
</div>
And in the Layout.cshtml, the following markup is written before the body closing tag.
<div id="modal-container" class="modal fade hidden-print" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
</div>
</div>
</div>
and in the script.css
.modal-content {
width: 600px !important;
margin: 30px auto !important;
}
When I run the code, the screen goes dim but no popup appears. When I debug I could see ajax calling the controller action and redirecting to partial view, but the popup does not appear.
Not sure what am I missing to show the popup with model properties. Could anyone please help.

Since you are seeing the controller action being called while debugging, the harder part is working. The most likely explanation for your issue is in your javascript "success:":
//change from this:
$('#modal-content').html(data);
//to this:
$('.modal-content').html(data);
You can optionally, change your <div class="modal-content"> to <div id="modal-content">

Related

remote validation does not work for partial view

I have order with several order items and I use partial view to load order items. I want to validate OrderLineItemEntity's ProductCode but it does not work. Every other property validation works which is not in partial view. How can I force to validate partial view too?
Order View:
<div id="orderLineItemsContainer" class="form-group">
#Html.EditorFor(model => model.OrderLineItems)
</div>
OrderLineItems View:
#model SalesManagementSystem.Models.OrderEntity
#Html.EditorFor(model => model.OrderLineItems)
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
OrderLineItem View:
#model SalesManagementSystem.Models.OrderLineItemEntity
<div class="form-inline col-md-12" style="margin-bottom: 5px">
<div class="form-group col-md-6">
#Html.LabelFor(model => model.ProductCode, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.ProductCode, new { htmlAttributes = new { #class = "form-control", id = "ProductCode" } })
#Html.ValidationMessageFor(model => model.ProductCode, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group col-md-6">
#Html.LabelFor(model => model.Quantity, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { #class = "form-control", id = "ProductQuantity" } })
#Html.ValidationMessageFor(model => model.Quantity, "", new { #class = "text-danger" })
</div>
</div>
#if (Model != null)
{
<a onclick="deleteRow('#Model.ProductCode')">Delete</a>
}
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
ValidationController:
public JsonResult IsProductCodeValid(int ProductCode){...}
This is how I update my order items when new item is added. I think I need to add something here.
$("#btnAdd").click(function () {
var order = {
'Id': $("#Id").val(),
'Date': $("#Date").val(),
'ConsultantId': $("#ConsultantId").val(),
'OrderLineItems': getOrderLineItems()
};
$.ajax({
url: '#Url.Action("AddOrderItem", "Orders")',
type: "POST",
data: {
order: order
},
success: function (partialView) {
$("#orderLineItemsContainer").html(partialView);
},
failure: function (response) {
alert("failed");
}
});
});
Update:
I tried adding
jQuery.validator.unobtrusive.parse("#ProductCode");
And
<script src="~/Scripts/jquery-3.4.1.min.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
Still not working
you can add a name and id (like ProductForm) property to your partial view form
after that, in cshtml file's script section
you can add a screen control method like this
function ScreenControl() {
if ($('#ProductForm')[0].checkValidity()) {
// do what do you want
} else {
$("#btnSave2").click();
}
}
and you should add 2 buttons to bottom of the form, one of them should be hidden like
<label class="col-md-1 control-label"></label>
<div class="col-md-1">
<button class="btn btn-sm btn-primary" style="float: right" type="button" id="btnSave" name="btnSave" value="Save" onclick="ScreenControl()">
<i class="fa fa-save"></i>
Save
</button>
</div>
<button class="btn btn-sm btn-primary" type="submit" id="btnSave2" name="btnSave2" value="Save" style="display: none">
<i class="fa fa-save"></i> Save
</button>

ASP.NET MVC - A potentially dangerous Request.Form value was detected from the client

Am trying to click save button to update what I have in text editor using ckeditor but I got this error
A potentially dangerous Request.Form value was detected from the client (OPTION_VALUE="Welcome to the Na...").
The controller is shown below
Controller
public ActionResult EditRegistrationGuideline(long id)
{
OPTIONS options = _optionsService.GetOption(id);
return View(options);
}
//
// POST: /Product/Edit/5
[HttpPost]
public ActionResult EditRegistrationGuideline(long id, OPTIONS options)
{
try
{
// TODO: Add update logic here
if (ModelState.IsValid)
{
options.OPTION_ID = id;
options.ACTION_STATUS = 0;
options.CREATED_DATE = DateTime.Now;
_optionsService.AddOption(options);
return RedirectToAction("Index");
}
}
catch
{
//return View();
ModelState.AddModelError("", "We cannot edit this Option. Verify your data entries !");
}
return View();
}
and the view is here
View
#{
//ViewBag.Title = "CreateRegistrationGuideline";
}
<div class="content-header clearfix">
<h1 class="pull-left">
<i class="fa fa-plus"> </i> Edit Registration Guideline
</h1>
<div class="col-xs-3 pull-right">
<input type="button" class="btn btn-block btn-warning" value="Back" onclick="location.href='#Url.Action("IndexRegistrationGuideline", "Options")'" />
</div>
<div class=" box box-body box-primary">
#using (Html.BeginForm("EditRegistrationGuideline", "Options", FormMethod.Post, new { #class = "form-horizontal", #enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#*<h4>OPTIONS</h4>
<hr />*#
#*#Html.ValidationSummary(true)*#
#Html.ValidationSummary(false, null, new { #class = "text-danger" })
<div class="row .col">
<div style="margin-top:20px" class="mainbox col-md-12 col-md-offset-0 col-sm-8 col-sm-offset-2">
<div class="panel panel-info">
<div class="panel-heading">
<div class="panel-title">Edit Option</div>
</div>
<div class="panel-body">
#*<div class="form-group">
#Html.LabelFor(model => model.OPTION_NAME, new { #class = "control-label col-md-2" })
<div class="col-md-10">*#
#*#Html.LabelFor(model => model.OPTION_NAME, new { #class = "control-label col-md-2" })
<div class="col-md-10">*#
#*#Html.EditorFor(model => model.OPTION_NAME)*#
#*#Html.HiddenFor(model => model.faculty_activation_date, new { #Value = System.DateTime.Now })*#
#Html.HiddenFor(model => model.OPTION_NAME)
#Html.ValidationMessageFor(model => model.OPTION_NAME)
<div class="form-group">
#*#Html.LabelFor(model => model.OPTION_VALUE, new { #class = "control-label col-md-2" })*#
<div class="col-md-10">
#Html.LabelFor(model => model.OPTION_VALUE, "Option Value")
#*<textarea class="form-control" placeholder="Enter Option Value" name="OPTION_VALUE" id="editor1"></textarea>*#
#Html.TextAreaFor(model => model.OPTION_VALUE, new { #class = "form-control", #id = "editor1" })
#Html.ValidationMessageFor(model => model.OPTION_VALUE, "", new { #class = "text-danger" })
</div>
</div>
#*<div>
#Html.LabelFor(model => model.OPTION_VALUE, "Option Value")
#Html.TextAreaFor(model => model.OPTION_VALUE, new { #type = "textarea", #id="editor1", #class = "form-control", #placeholder = "Enter Option Value", #autocomplete = "on" })
#Html.ValidationMessageFor(model => model.OPTION_VALUE, null, new { #class = "text-danger" })
</div>*#
#*<div class="form-group">
#Html.LabelFor(model => model.ACTION_STATUS, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ACTION_STATUS)
#Html.ValidationMessageFor(model => model.ACTION_STATUS)
</div>
</div>*#
</div>
<div class="panel-footer">
<div class="panel-title">
<div class="form-actions no-color">
<input type="submit" value="Save" class="btn btn-success" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
}
#*<div>
#Html.ActionLink("Back to List", "Index")
</div>*#
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script src="~/Scripts/jquery-3.1.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script src="https://cdn.ckeditor.com/4.5.7/standard/ckeditor.js"></script>
<script>
$(function () {
CKEDITOR.replace('editor1');
});
</script>
}
Please what do I do.
I use CKEDITOR
XSS error ("A potentially dangerous Request.Form value was detected from the client(...)").
Solution:
[ValidateInput(false)]
Differnce b/w them
AllowHtml:
The AllowHtml attribute can be applied to a Model property and it will disable the validation by ASP.Net MVC only for that particular property
Advantages
The AllowHtml attribute is developed for Model class.
The Scope is limited to specific property of the Model class.
It is the safe and recommended solution.
ValidateInput
The ValidateInput attribute can be applied to a Controller’s Action method and it will disable the validation by ASP.Net MVC only for that particular Action method.
Advantages
The Scope is limited to specific Action method of the Controller class.
If you have multiple properties accepting HTML content, then this method will reduce redundancy.
When Model class is not used for designing Form elements then this attribute is needed.For complete details Link
Just place ValidateInput(false) attribute on controller's action.
[HttpPost]
[ValidateInput(false)]
public ActionResult EditRegistrationGuideline(long id, OPTIONS options)
The other option is to place [AllowHtml] attribute on Model Property, have a look on SO post to get difference between them
ValidateInput(false) vs AllowHtml
I was experiencing a similar issue with the following error message A potentially dangerous Request.Form value was detected from the client.
As an alternative to the previous answers, I found encoding the value passed back to the controller worked. CKEditor allows you to do this by setting the config config.htmlEncodeOutput = true;.
The documentation for this can be found at: https://docs-old.ckeditor.com/ckeditor_api/symbols/CKEDITOR.config.html#.htmlEncodeOutput
I got this error while testing XSS on my site.
This is a very good feature that the model gives us that prevents XSS, CSRF from penetrating your site.
Do not disable it as much as possible.

ASP MVC jquery validation in bootsrap tabs causes an undesired postback

I have a form with 3 bootstrap tabs in it. Client Validation works correctly when the tab where the validation error occurs is open and submit button is clicked. However, when i switch to a tab with no errors (while having errors in other tabs) a post back occurs and i get the correct validation messages.
Its a minor issue, but post back is not desired in this situation, because full client side validation must be completed before sending request to the server.
How can i correct this behavior?
Below is a copy of my form HTML:
#model RBZPOSMVC.ViewModel.CreateEditItem
....
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#Details">Item Details</a></li>
<li><a data-toggle="tab" href="#Sales">Sale Price Groups</a></li>
<li><a data-toggle="tab" href="#Purchases">Purchase Price Groups</a></li>
</ul>
<div class="tab-content">
<div id="Details" class="tab-pane fade in active">
<div class="form-group">
#Html.LabelFor(model => model.Item.ItemCode, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Item.ItemCode, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Item.ItemCode, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Item.ItemName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Item.ItemName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Item.ItemName, "", new { #class = "text-danger" })
</div>
</div>
.... // more form controls
</div>
<div class="hidden">
#for (var i = 0; i < Model.PriceGroupList.Count; i++)
{
<div class="form-group" id="#Model.PriceGroupList[i].PriceGroupTypeId">
#Html.HiddenFor(model => model.PriceGroupList[i].PriceGroupId)
#Html.LabelFor(model => model.PriceGroupList[i].PriceGroupName,
Model.PriceGroupList[i].PriceGroupName,
htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PriceGroupList[i].Price, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PriceGroupList[i].Price, "", new { #class = "text-danger" })
</div>
</div>
}
</div>
<div id="Sales" class="tab-pane fade in ">
</div>
<div id="Purchases" class="tab-pane fade in ">
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
<script>
$.validator.setDefaults({
ignore: ""
});
</script>
#Scripts.Render("~/bundles/items")
#Scripts.Render("~/bundles/jqueryval")
}
Since two of you tabs are hidden when you submit the form, you need to configure the $.validator to validate hidden elements (which are not validated by default).
You current use of $.validator.setDefaults({ ignore: "" }); is not correct for jquery version 2.2.0 (I believe that usage was depreciated in version 1.9) and it needs to be
$.validator.setDefaults({
ignore: []
});
Note: do not add the above inside $(document).ready()

How to toggle Partial View on Single Submit Button in MVC?

Here is my Code
View
#using (Html.BeginForm("userrights", "Users", FormMethod.Post, new { #class = "form-horizontal", role = "form"}))
{
<div class="form-group">
<div class="col-md-7" style="padding-right:10px">
#Html.TextBoxFor(m => m.companyname, new { #class = "form-control", #placeholder = "Serach By Sponser Name" })
</div>
<div class="clearfix"></div>
</div>
<div class="form-group">
<div class="col-sm-2">
<button type="submit" id="btn_search" value="Search" name="btn_search" class="btn btn-default">Search</button>
</div>
<div class="clearfix"></div>
</div>
</div>
#Html.Partial("_userRightPartial", Model._UserRightPartialView)
<div class="clear"></div>
}
Controller Method
public ActionResult userrights()
{
IEnumerable<MenuListModel> _MenuListModel = _ftwCommonMethods.GetMenuItems();
IEnumerable<SubMenuListModel> _SubMenuListModel = _ftwCommonMethods.GetSubMenuItems("1");
UserRightViewSearch _UserRightViewSearch = new UserRightViewSearch();
UserRightPartialView _UserRightPartialView = new UserRightPartialView();
_UserRightPartialView._SubMenuListModel = _SubMenuListModel;
_UserRightViewSearch._UserRightPartialView = _UserRightPartialView;
_UserRightViewSearch._menu = _MenuListModel;
_UserRightViewSearch.selectedMenu = 0;
return View(_UserRightViewSearch);
}
I want when page first time loads, _userRightPartial partial view should be hidden. After Submitting By Search Button it should appear.
I know it can be possible by Hide and Show DIV. But i want is there other way to do it with MVC Code?

ASP.Net MVC 5 Form in a Twitter Bootstrap Modal - Return to modal if user does not enter correct field information

I have a contact form in a Twitter Bootstrap Modal and if the user happens to not enter a name or email address and hits submit I want to return to the Modal instead of just closing the Modal. Also if the form is valid I would like to let the user know that an we will be contacting them shortly in the same modal. Is this possible?
Here is my controler.
[HttpPost]
public ActionResult Index(Contact model)
{
ViewBag.IsValid = false;
ViewBag.CaptchaError = "";
RecaptchaVerificationHelper recaptchaHelper = this.GetRecaptchaVerificationHelper();
if (String.IsNullOrEmpty(recaptchaHelper.Response))
{
ViewBag.CaptchaError = "The Captcha cannot be empty";
return View();
}
RecaptchaVerificationResult recaptchaResult = recaptchaHelper.VerifyRecaptchaResponse();
if (recaptchaResult != RecaptchaVerificationResult.Success)
{
ViewBag.CaptchaError = "The Captcha was incorrect";
return View();
}
if (ModelState.IsValid)
{
SendSupportEmail(model);
ViewBag.isValid = true;
}
return View();
}
Here is my view with the Modal
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content col-md-12">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Contact Us</h4>
</div>
<center>
<div class="modal-body">
#using (Html.BeginForm())
{
if ((bool)ViewBag.IsValid)
{
}
else
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<div class="form-group">
<div class="col-md-12">
#Html.TextBoxFor(model => model.Name, new { #class = "form-control", placeholder = "Name" })
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="form-group">
<div class="col-md-12">
#Html.TextBoxFor(model => model.Phone, new { #class = "form-control", placeholder = "Phone" })
#Html.ValidationMessageFor(model => model.Phone)
</div>
</div>
<div class="form-group">
<div class="col-md-12">
#Html.TextBoxFor(model => model.Email, new { #class = "form-control", placeholder = "E-Mail Address" })
#Html.ValidationMessageFor(model => model.Email)
</div>
</div>
<div class="form-group">
<div class="col-md-12">
#Html.TextAreaFor(model => model.Comments, new { #class = "form-control", height = "40", placeholder = "Comments" })
#Html.ValidationMessageFor(model => model.Comments)
</div>
</div>
<div class="form-group">
#if (!string.IsNullOrEmpty(ViewBag.CaptchaError))
{
<span class="field-validation-error">#ViewBag.CaptchaError</span>
}
#Html.Recaptcha(theme: Recaptcha.Web.RecaptchaTheme.Clean)
</div>
<div class="form-group">
<div class="col-md-12">
<input type="submit" id="submit" value="Submit" class="btn btn-default btn-lg btn-primary col-sm-12" />
</div>
</div>
</div>
}
}
</div>
</center>
</div>
</div>
I have searched everywhere and was unable to find a solution.
Don't have enough rep to comment - hence the answer. I reckon the easiest way to do this would be to use ajax. User jquery validation plugin to validate user input on submit click. This way, the validation messages can be displayed on the modal itself and the page doesn't have to be refreshed.
On successful validation, the form can be posted to your controller action. You can send a success message as part of your response and display it as a popup or a notification using notifyjs or your own code.

Resources