Validation in ASP.Net MVC4 for unbound textboxes - asp.net-mvc-4

I have the following code for a view, in which I am submitting some data from 3 different text-boxes. This is just a practice sample that I created. I am using Razor syntax with MVC4 in ASP.Net.
My question: How can I validate the text-boxes so they are always required?
#{
ViewBag.Title = "HelloWorld";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>HelloWorld</h2>
<div>This is a sample Hello World page</div>
<h1>#ViewBag.Title</h1>
<h2>#ViewBag.Message</h2>
#using (Html.BeginForm("HandleSubmit", "Home"))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<fieldset>
<legend>Registration Form</legend>
<ol>
<li>
#Html.Label("username", "UserName")
#Html.TextBox("username")
</li>
<li>
#Html.Label("pwd", "Password")
#Html.Password("pwd")
</li>
<li>
#Html.Label("cpwd", "Confirm Password")
#Html.Password("cpwd")
</li>
</ol>
<input type="submit" value="TestPost" />
<div style="color:red;font-weight:bold">#ViewBag.Feedback</div>
</fieldset>
}
UPDATE 1: Another way to validate textbox and show a custom invalid message is as below.
#Html.TextBox("username", null, new { #required = "required",
#oninvalid = "this.setCustomValidity('This data is a must')" })

Set the required attribute in the html attributes parameter for the helper
#Html.TextBox("username", null, new { #required="required", #oninvalid="setCustomValidity('I\'m required')" })
To customize this and get the same effect as the MVC templates you need jquery.validate.js and jquery.validate.unobtrusive.js
#Html.TextBox("username", null, new { #data_val_required="I'm required", #data_val="true" })
<span data-valmsg-replace="true" data-valmsg-for="username"></span>

Related

How to pass a dynamicy changed model to Partial view?

I have a list of "workbooks" displayed in a table. Each workbook has a "Share" button next to the workbook's title. When the user clicks on the share button a modal dialog is shown containing a form.
The form allows the user to enter a list of the recipient's emails separated by a comma which is validated on the client-side.
As the dialog is located in a partial view _ShareView.cshtml that allows me to pass a modal WorkbookShareModel that has some fields like WorkbookId and Title. The goal here is to pass the details of each workbook when the user presses the share button (i.e. construct a modal and pass it to the already rendered model).
I am not sure how to pass a model to an already rendered view?
The solution have to be done on the client (i.e. dont involve actions on the server that return the partial view provided the parameters are passed). I want to avoid unnesessary calls to the server - we have all the data on the client regarding a workbook and I need to do a POST when the user types in list of emails.
This is my index.cshtml:
#section BodyFill
{
<div id="shareFormContainer">
#{ await Html.RenderPartialAsync("_ShareView", new WorkbookShareModel());}
</div>
<div class="landing-container">
<div class="workbook-container">
<table class="table">
<tbody>
#foreach (var workbook in Model.Workbooks)
{
string trClassName, linkText;
if (workbook.Metadata.SharedBy == null)
{
trClassName = "saved-workbooks";
linkText = workbook.Name;
} else {
trClassName = "shared-with-me";
linkText = string.Format(
BaseLanguage.SharedWithMeWorkbook,
workbook.Name,
workbook.Metadata.SharedBy,
workbook.Metadata.SharedDate.ToShortDateString()
);
}
<tr class="#trClassName">
<td>#Html.ActionLink(linkText, "Open", "OpenAnalytics", new { id = Model.Id, workbook = workbook.Name })</td>
<td class="last-modified-date" title="Last Modified Date">#workbook.ModifiedDate.ToShortDateString()</td>
<td class="share">
<button title="Share" class="share-button" onclick='showSharingView("#workbook.Name", "#workbook.Id", "#Model.Id")'> </button>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
}
#section Scripts
{
<!--Load JQuery 'unobtrusive' validation -->
#await Html.PartialAsync("_ValidationScriptsPartial")
<script type="text/javascript">
// hide the modal as soon as the page loads
$('#shareFormModal').modal("hide");
function showSharingView(title, workbookId, id) {
$('#shareFormModal').modal("show");
// how to pass a WorkbookShareModel to my partial view from here?
}
function hideDialog() {
var form = $("#partialform");
// only hide the dialog if the form is valid
if (form.valid()) {
activateShareButtons();
$('#shareFormModal').modal("hide");
}
}
// Helper method that validates list of emails
function IsEmailValid(emailList, element, parameters) {
var SPLIT_REGEXP = /[,;\s]\s*/;
var EMAIL_REGEXP =
/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+##[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/i;
var emails = emailList.split(SPLIT_REGEXP);
for (var i = emails.length; i--;) {
if (!EMAIL_REGEXP.test(emails[i].trim())) {
return false;
}
}
return true;
}
</script>
}
That is my dialog:
#using DNAAnalysisCore.Resources
#model DNAAnalysisCore.Models.WorkbookShareModel
#* Partial view that contains the 'Share Workbook dialog' modal *#
<!-- Modal -->
<div onclick="activateShareButtons()" class="modal fade" id="shareFormModal" role="dialog">
<div class="modal-dialog modal-md">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Share Workbook - #Model.Title</h4>
</div>
#using (Html.BeginForm("ShareWorkbook", "Home", FormMethod.Post, new { #id = "partialform" }))
{
<div class="modal-body">
<label>#BaseLanguage.Share_workbook_Instruction_text</label>
<div class="form-group">
<textarea class="form-control" asp-for="Emails" rows="4" cols="50" placeholder="#BaseLanguage.ShareDialogPlaceholder"></textarea>
<span asp-validation-for="Emails" class="text-danger"></span>
</div>
<input asp-for="Title" />
<input asp-for="Id" />
<input asp-for="WorkbookId"/>
</div>
<div class="modal-footer">
<button onclick="hideDialog()" type="submit" class="btn btn-primary">Share</button>
<button onclick="activateShareButtons()" id="btnCancelDialog" type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
}
</div>
</div>
</div>
There are two solutions to solve your problem :
Option 1 :
Since you have got the parameters(title, workbookId, id) , you can call server side function using AJAX to render the partial view , then replace the DIV contained in the partial view with the updated contents in the callback function of AJAX .
You can click here for code sample .
Option 2 :
Directly update related input/area using Jquery . For example , the input tag helper :
<input asp-for="<Expression Name>">
generates the id and name HTML attributes for the expression name specified in the asp-for attribute. So you can set the value using Jquery like :
$("#Title").val("Title")
Please click here for Tag Helpers in forms in ASP.NET Core
With Option 2 , you need to clear the Emails area firstly after user click the share button ; With Option 1 , you don't need to care that since the HTML will replace entirely .

Setting specific authentication type with mvc 5

ASP.NET comes default with the external login provider partial page which is set as:
var loginProviders = Context.GetOwinContext().Authentication.GetExternalAuthenticationTypes();
if (loginProviders.Count() == 0)
{
<div>
<p>
There are no external authentication services configured. See this article
for details on setting up this ASP.NET application to support logging in via external services.
</p>
</div>
}
else
{
using (Html.BeginForm("ExternalLogin", "Account", new { ReturnUrl = Model.ReturnUrl }))
{
#Html.AntiForgeryToken()
<div id="socialLoginList">
<p>
#foreach (AuthenticationDescription p in loginProviders)
{
<button type="submit" class="btn btn-default" id="#p.AuthenticationType" name="provider" value="#p.AuthenticationType" title="Log in using your #p.Caption account">#p.AuthenticationType</button>
}
</p>
</div>
}
}
What if i know exactly the authentication type i am going to use, say facebook? How can i set that up?

what is the use of insert mode on AJAXFORM in MVC?

When i am clicking the ajax from is loaded the partila view correctly inside the div have id as mytraget. But my question is what is the use of insertmode in ajax form.
On submitting the ajax form it always load the partial view inside of the div have id as mytraget on all type of insert mode. Then what is the of insert mode?
My original view named as MyView
#model Example.Models.mytest
<div id="mytraget"> </div>
#using(Ajax.BeginForm("myParialAjax", new AjaxOptions() { InsertionMode = InsertionMode.InsertBefore, UpdateTargetId = "mytraget" }))
{
<p>Name</p> #Html.TextBoxFor(m => m.string1)
<input type="submit" value="Submit" />
}
My Cobtroller Method
[HttpPost]
public PartialViewResult myParialAjax(mytest s)
{
return PartialView("Mypartial", s);
}
My Parial view which is named as Mypartial
#model Example.Models.mytest
<p>
#Html.TextBoxFor(m =>m.string1)
</p>
In all type of insert mode i get partial view inside of the the below div.
Output :
<div id="mytraget">
<p>
<input id="string1" type="text" value="asdf" name="string1">
</p>
</div>
I got myself the answer What i am missing is Need to insert some tags inside of the target tag.
Like below:
#model Example.Models.mytest
<div id="mytarget">
<p> my para </p>
</div>
#using(Ajax.BeginForm("myParialAjax", new AjaxOptions() { InsertionMode = InsertionMode.InsertBefore, UpdateTargetId = "mytarget" }))
{
<p>Name</p> #Html.TextBoxFor(m => m.string1)
<input type="submit" value="Submit" />
}
Now here InsertionMode.InsertBefore will insert my partial view above the paragraph tag and InsertionMode.InsertAfter will insert my partial view after the paragraph tag and InsertionMode.Replace will replace the whole things which is inside of the tag with my target id.

Saving a form post in Sitecore MVC generates a "method not found" error

Has anyone else run into such an error? It would be great if anyone can suggest a way to examine this further or maybe has a direction for a solution.
I have tried to debug this but could not figure it out. The action specified in the cshtml file is reached and the posted information is available. The error occurs when this line is executed.
masterService.Save(page);
The WikiEntryModel does contain a ImageField. This is not filled in when the form is called up and is also not specified as a field in the form.
Additional information
I am using GlassMapper v2.0 in combination with Sitecore 7.1.
This is the actual error description as displayed on the page.
Method not found: 'System.String Sitecore.Data.Fields.ImageField.get_MediaPath()'.
The cshtml file of the form.
#model WikiEntryModel
#using(Html.BeginRouteForm(Sitecore.Mvc.Configuration.MvcSettings.SitecoreRouteName, FormMethod.Post))
{
#Html.Sitecore().FormHandler("Forms","PostEditWikiEntry")
<ul>
<li>
#Html.LabelFor(model => model.Title)<br />
#Html.TextBoxFor(model => model.Title)
</li>
<li>
#Html.LabelFor(model => model.Introduction)<br />
#Html.TextAreaFor(model => model.Introduction)
</li>
<li>
<input type="submit" value="Save" />
</li>
</ul>
}
The code of the specified action in the controller.
[HttpPost]
public ActionResult PostEditWikiEntry(WikiEntryModel postedModel)
{
var contextService = new SitecoreContext();
var masterService = new SitecoreService("master");
var page = contextService.GetCurrentItem<WikiEntryModel>();
if (ModelState.IsValid)
{
page.Title = postedModel.Title;
page.Introduction = postedModel.Introduction;
using (new SecurityDisabler())
{
masterService.Save(page);
}
}
return RenderComponent<WikiEntryModel>("Forms/Edit wiki entry");
}

How to assign the checkbox value in action link in a cshtml page from another cshtml page?

Code:
Index.cshtml
<div class ="">
<input id="date" type="checkbox" />Date<br /><br />
</div>
Header.cshtml
#Html.ActionLink("Add", "Action", "Controller", new
{date = ??}, new
{
#class = "hidden",
#Id = "tasks"
})
How to assign the checkbox value in action link in date parameter(true(if checked) or false(if not checked)) in a cshtml page from another cshtml page?
Use a form and the html helper for checkbox
like this
#using (Html.BeginForm(action, controller, FormMethod.Post))
{
#Html.CheckBoxFor(model => model.date)
<input type="submit" value="Submit" />
}
Then in your post action, the date will be available in your posted model.