First two #Html.TextBox elements not clickable - asp.net-mvc-4

I have an MVC application I'm rewriting from MVC1 to MVC4. On the search form, the first two #Html.TextBox() elements aren't clickable. You can tab to them, but not click. If you put more textbox elements above them they become clickable, if you change the order only the first two are broken.
here is my code:
#{
ViewBag.Title = "Search";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Search</h2>
#if (ViewData["ErrorMessage"] != null)
{
#Html.ValidationSummary(ViewData["ErrorMessage"].ToString(), new { #style = "color: #FF0000" })
}
<fieldset>
<legend>Criteria</legend>
#using (#Html.BeginForm())
{
<label>Social Security Number:</label>
#Html.TextBox("SSN", null, new { #class = "input-box", style = "width:100%" })
#Html.ValidationMessage("SSN", "*", new { #style = "color: #FF0000" })
<label>Date of Birth:</label>
#Html.TextBox("DOB", null, new { #class = "input-box", style = "width:100%" })
#Html.ValidationMessage("DOB", "*", new { #style = "color: #FF0000" })
<label>First Name:</label>
#Html.TextBox("FirstName", null, new { #class = "input-box", style = "width:100%" })
#Html.ValidationMessage("FirstName", "*", new { #style = "color: #FF0000" })
<label>Last Name:</label>
#Html.TextBox("LastName", null, new { #class = "input-box", style = "width:100%" })
#Html.ValidationMessage("LastName", "*", new { #style = "color: #FF0000" })
<p style="text-align:center;">
<input class="button" type="submit" value="Search" style="align-items:center"/>
</p>
}
</fieldset>
<p>#Html.ActionLink("Create New", "Create")</p>

The problem was that there were unclosed div elements in the Layout page. After rewriting the Layout, the application worked fine.

Related

Auto Adjust height of multiline editor for in MVC using bootstrap

I have below editorfor which is multiline, I need to auto adjust height when user starts adding multiple email address in separate lines using bootstrap. Any code example is highly appreciated.
Model:
[DataType(DataType.MultilineText)]
public string AdditionalEmailAddressesText { get; set; }
View:
<div class="form-group">
#Html.LabelFor(m => m.AdditionalEmailAddressesText, new { #class = "col-sm-2 control-label" })
<div class="col-sm-10">
#Html.EditorFor(m => m.AdditionalEmailAddressesText, new { htmlAttributes = new { #class = "form-control", placeholder = #Strings.Porting_AdditionalEmailAddressesSubtext } })
#Html.ValidationMessageFor(m => m.AdditionalEmailAddressesText)
</div>
</div>
For textarea tag, there's no auto-height attribute to make it adjust the height automatically. And for the [DataType(DataType.MultilineText)] annotation, it doesn't provide feature for setting rows and colums as well. So you have to write script code to add oninput event listener to change the style.
#model NewEvent
<h1>#ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>
<div class="form-group">
#Html.LabelFor(m => m.Body, new { #class = "col-sm-2 control-label" })
<div class="col-sm-10">
#Html.EditorFor(m => m.Body, new { htmlAttributes = new { #class = "form-control", placeholder = "placeholder" } })
#Html.TextAreaFor(model => model.Body, new {cols = 2, rows = 5})
#Html.ValidationMessageFor(m => m.Body)
</div>
</div>
#section scripts {
<script>
$("#Body").each(function () {
this.setAttribute("style", "height:" + (this.scrollHeight) + "px;overflow-y:hidden;");
}).on("input", function () {
this.style.height = "auto";
this.style.height = (this.scrollHeight) + "px";
});
</script>
}

Getting selected value from dropdownlistfor

I want to draw a circle with different state image depending on my selected value from the dropdownforlist.
How can I access the value in my razor page?
Here is my code
<div class="form-group">
#Html.LabelFor(model => model.CustomerNeed.NeedState, htmlAttributes: new { #class = "form-group" })
<div class="form-group">
#Html.DropDownListFor(model => model.CustomerNeed.NeedState, new List<SelectListItem>
{
new SelectListItem {Text = "Bedarf erfasst", Value = "Need specified", Selected = true },
new SelectListItem {Text = "Qualifikation", Value = "Qualification"},
new SelectListItem {Text = "Talent Zuweisung", Value = "Talent assignment" },
new SelectListItem {Text = "Am Offerieren", Value = "Quotation" },
new SelectListItem {Text = "Auftrag bestätigt", Value = "Order Confirmed" },
new SelectListItem {Text = "Wird ausgeführt", Value = "In Action" },
new SelectListItem {Text = "Abgeschlossen", Value = "Finished" },
}, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CustomerNeed.NeedState, "", new { #class = "text-danger" })
#{
if (x == "Need specified")
{
<div class="finished">
<div class="imgcircleSeleted">
<img src="/images/Finished.png" alt="finished">
</div>
<label>#Localizer["Demand fulfilled"]</label>
</div>
}
else
{
<div class="signed">
<div class="imgcircleSelected">
<img src="/images/Signed.PNG" alt="customer signed contract">
</div>
<span class="line"></span>
<label>#Localizer["Contract signed"]</label>
</div>
}
}
</div>
</div>
Thank you for helping
Firstly,you cannot get the value of drop down list dynamically with #{if (x == "Need specified")},x in the code will be rendered with the default selected value of drop down list,and it will not be changed even though the selected value changes.So You can try to use js to get the value.and set the div to hidden or shown.
Here is a demo:
View:
<div class="form-group">
#Html.LabelFor(model => model.CustomerNeed.NeedState, htmlAttributes: new { #class = "form-group" })
<div class="form-group">
#Html.DropDownListFor(model => model.CustomerNeed.NeedState, new List<SelectListItem>
{
new SelectListItem {Text = "Bedarf erfasst", Value = "Need specified", Selected = true },
new SelectListItem {Text = "Qualifikation", Value = "Qualification"},
new SelectListItem {Text = "Talent Zuweisung", Value = "Talent assignment" },
new SelectListItem {Text = "Am Offerieren", Value = "Quotation" },
new SelectListItem {Text = "Auftrag bestätigt", Value = "Order Confirmed" },
new SelectListItem {Text = "Wird ausgeführt", Value = "In Action" },
new SelectListItem {Text = "Abgeschlossen", Value = "Finished" },
}, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CustomerNeed.NeedState, "", new { #class = "text-danger" })
<div class="finished" id="finished">
<div class="imgcircleSeleted">
<img src="/images/Finished.png" alt="finished">
</div>
<label>#Localizer["Demand fulfilled"]</label>
</div>
<div class="signed" id="signed" hidden>
<div class="imgcircleSelected">
<img src="/images/Signed.PNG" alt="customer signed contract">
</div>
<span class="line"></span>
<label>#Localizer["Contract signed"]</label>
</div>
</div>
</div>
js:
<script>
$("#CustomerNeed_NeedState").change(function () {
if ($(this).val() == "Need specified") {
$("#finished").removeAttr("hidden");
$("#signed").attr("hidden", "hidden");
} else {
$("#signed").removeAttr("hidden");
$("#finished").attr("hidden", "hidden");
}
})
</script>
result:

File upload in MVC 5 when used in bootstrap modal returns null

I'm trying to allow file uploading on modal popup using bootstrap modal popup.
But it always returns null for type = "file"
I've tried following solutions but no luck:
File upload in MVC when used in bootstrap modal returns null
it always return null. If I run this directly as separate page then it works fine but only having problem with popup.
I tried to change the content type on ajax but then its giving me this error "required anti-forgery form field __requestverificationtoken is not present"
I've tested what does page post using development tools:
enter image description here
here are my codes:
controller:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task Create([Bind(Include = "ID,FileName,Link,SourceType,Comments,SourceDate,DateCreated,DateModified,ProjectID")] ProjectSource projectSource, HttpPostedFileBase uploadFile)
{
if (ModelState.IsValid)
{
//upload method 1
var fileSavePath = "";
if (HttpContext.Request.Files.AllKeys.Any())
{
// Get the uploaded image from the Files collection
var httpPostedFile = HttpContext.Request.Files[0];
if (httpPostedFile != null)
{
// Validate the uploaded image(optional)
// Get the complete file path
fileSavePath = (HttpContext.Server.MapPath("~/xyz/") + httpPostedFile.FileName);
// Save the uploaded file to "UploadedFiles" folder
httpPostedFile.SaveAs(fileSavePath);
}
}
//upload method 2
if (uploadFile != null && uploadFile.ContentLength > 0)
{
try
{
string path = Path.Combine(Server.MapPath("~/xyz/"),
Path.GetFileName(uploadFile.FileName));
uploadFile.SaveAs(path);
ViewBag.Message = "File uploaded successfully";
}
catch (Exception ex)
{
ViewBag.Message = "ERROR:" + ex.Message.ToString();
}
}
else
{
ViewBag.Message = "You have not specified a file.";
}
db.ProjectSources.Add(projectSource);
await db.SaveChangesAsync();
return " File : " + ViewBag.Message + " == " + fileSavePath;
}
return " File : " + ViewBag.Message +" === "+sb.ToString();
}
view:
#model CharterPortal.Models.ProjectSource
#{
Layout = "";
#Scripts.Render("~/Scripts/jquery-2.2.3.min.js")
#Scripts.Render("~/Scripts/moment.min.js")
#Scripts.Render("~/Scripts/bootstrap.min.js")
#Scripts.Render("~/Scripts/bootstrap-datetimepicker.min.js")
#Scripts.Render("~/Scripts/bootstrap.fd.js")
}
×
Add new Source
#using (Html.BeginForm("Create", "ProjectSource", FormMethod.Post, new { enctype = "multipart/form-data" , #id="ajaxForm"}))
{
#Html.AntiForgeryToken()
<div class="modal-body">
<div class="form-horizontal">
#*#Html.ValidationSummary(true, "", new { #class = "text-danger" })*#
<div class="form-group">
#Html.Label("Source file", htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-6">
#Html.EditorFor(model => model.FileName, new { htmlAttributes = new { #class = "form-control" } })
#*<input type="file" name="uploadFile" />*#
#Html.TextBox("uploadFile",null, new { #class = "form-control", type = "file" })
#*Add file*#
#Html.ValidationMessageFor(model => model.FileName, "", new { #class = "text-danger" })
</div>
</div>
#*<div class="form-group">
<div class="col-md-10" id="files" style="padding-left:40px;">
</div>
</div>*#
<div class="form-group">
#Html.LabelFor(model => model.Link, htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-6">
#Html.EditorFor(model => model.Link, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Link, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SourceType, htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-6">
#Html.EditorFor(model => model.SourceType, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SourceType, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Comments, htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-6" style="color:black;">
#Html.TextAreaFor(model => model.Comments, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Comments, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SourceDate, htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-6" style="color:black;">
#Html.EditorFor(model => model.SourceDate, new { htmlAttributes = new { #class = "form-control datepicker datefield" } })
#Html.ValidationMessageFor(model => model.SourceDate, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-med btn-orange" data-dismiss="modal">Cancel</button>
<input class="btn btn-med btn-orange" type="submit" name="submit" value="Add" />
</div>
}
ajax:
$('form', dialog).submit(function (event) {
event.preventDefault();
$.ajax({
url: this.action,
type: this.method,
async: true,
data: $(this).serialize(),
contentType:this.enctype,
success: function (result) {
if (result) {
alert(result)
//Refresh
} else {
alert(result)
}
}
});
return false;
});
I hope to get good working solution for this:
thanks in advance for your time.
Thanks
Ive been using this block of code to solve this problem and ModelState.IsValid in partials for about a year. cheers.
$(function () {
window.addEventListener("submit", function (e) {
var form = e.target;
if (form.getAttribute("enctype") === "multipart/form-data") {
if (form.dataset.ajax) {
e.preventDefault();
e.stopImmediatePropagation();
var xhr = new XMLHttpRequest();
xhr.open(form.method, form.action);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
if (form.dataset.ajaxUpdate) {
var updateTarget = document.querySelector(form.dataset.ajaxUpdate);
if (updateTarget) {
updateTarget.innerHTML = xhr.responseText;
}
}
}
};
xhr.send(new FormData(form));
}
}
}, true);
$('#modal').on('shown.bs.modal', function () {
$.validator.unobtrusive.parse($(this));
});
$('#modal').on('hidden.bs.modal', function () {
$('#spinner').remove();
});
$.ajaxSetup({ cache: false });
});

Recaptcha doesn't work with ajax and partial views

I'm using Recaptcha in my MVC4 web app. It was working correctly when it was embedded in the form but when I moved the #Html.Raw(Html.GenerateCaptchaHelper()) to partial view and trying to call this partial view via ajax request, it doesn't work!
Extension code :
public static string GenerateCaptchaHelper(this HtmlHelper helper)
{
var captchaControl = new Recaptcha.RecaptchaControl
{
ID = "recaptcha",
Theme = "clean",
PublicKey = ************,
PrivateKey = **********************,
Language = "En"
};
var htmlWriter = new HtmlTextWriter(new StringWriter());
captchaControl.RenderControl(htmlWriter);
return htmlWriter.InnerWriter.ToString();
}
my partial view is has the code like :
<p>#Html.Raw(Html.GenerateCaptchaHelper())</p>
and inside my controller
public PartialViewResult Captcha()
{
return PartialView();
}
and inside my main view:
#using (Html.BeginForm("Login", "Account", new { returnUrl = ViewData["ReturnUrl"] }, FormMethod.Post,null))
{
#Html.AntiForgeryToken()
<form role="form">
<div class="form-group">
<label>#Html.LabelFor(m => m.Email)</label><br />
#Html.TextBoxFor(m => m.Email, null, new { #class = "form-control", autocomplete = "off" })
</div>
<div class="form-group">
<label>#Html.LabelFor(m => m.Password)</label><br />
#Html.PasswordFor(m => m.Password, new { #class = "form-control", autocomplete = "off" })
</div>
<div id="captchaView" class="form-group">
</div>
<button type="submit">Login</button>
</div>
</div>
</form>
}
and the javascript is :
$.ajax({
url: '/Account/Captcha',
type: 'GET',
success: function(data) {
$('#captchaView').html(data);
}
});
Could you please help me to figure out why?

ajax beginform mvc callback

I have a single page with multiple partials set up. I want to be able to validate and update each partial seperatly. The validation works BUT when I type in a correct value and press save the page goes to the partial view instead of staying on the single page. What am I doing wrong here?
This is my main page :
#for (var i = 0; i < 10; i++)
{
var idTest = "Test_" + i;
<div id="#idTest">
#Html.Action("Detail", new { id = i })
</div>
}
The partial is created like this:
#{
var idTest = "Test_" + Model.Id;
var ajaxOptions = new AjaxOptions
{
UpdateTargetId = #idTest,
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace
};}
#using (Ajax.BeginForm("Detail", ajaxOptions))
{ #Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Test</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Gemeente, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.Gemeente, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Gemeente, "", new { #class = "text-danger" })
</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>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
This is the simple model:
public class Test
{
public int Id { get; set; }
[Required(ErrorMessage = "Gelieve een gemeente op te geven")]
public string Gemeente { get; set; }
}
These are the actions:
[HttpGet]
public ActionResult Detail(int id)
{
Models.Test model = new Models.Test();
model.Id = id;
return View(model);
}
[HttpPost]
public ActionResult Detail(Models.Test model)
{
if(ModelState.IsValid)
{
return PartialView(model);
}
return PartialView(model);
}
Add these lines to your view and also use #Html.Partial as shown below
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
so that your main view is
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
#for (var i = 0; i < 10; i++)
{
var idTest = "Test_" + i;
<div id="#idTest">
#Html.Partial("Detail", new Test { Id = i })}
</div>
}
Scripts would be for unobtrusive ajax so that your ajax button works and Html.Partial so that first time when you load your page in foreach only partial view is rendered (not the full view)