Mark the field as needed on the fly

Using ASP.NET MVC3, Razor, and jQuery Unobtrusive validation (as provided by Microsoft).

How can you mark fields as needed "on the fly", i.e. only in certain circumstances? For example, if the user is in the role of "publisher", there is a button "Publish date" and "Publish". The Publish Date field is required when the Publish button is clicked, but not when the Save Draft button is clicked. If the user is not included in this role, the Publish button is not displayed on the form and therefore is not required.

I am sure that this is not something that can be done out of the box, and additional code is required both on the client side (jQuery Validate) and on the server side. If possible, it is not clear how this can be done.

+4
source share
3 answers

If you did this in webform-land, you must create an instance of RequiredFieldValidator in the button click event handler and apply it to the field, which should become mandatory.

In mvc-land, this is not obvious. This SO question / answer demonstrates how to handle a button — you can expand it to create an instance of RequiredFieldValidator and apply it to the field.

In jquery you can add something like:

$("#buttonid").on("click", function() { $("#fieldToBeRequiredId").rules("add", { required: true }); } 
+1
source

It seems that it is less specific for a particular model and has a more specific look. Even if you could dynamically associate a requirement of this nature with a model, this would be contrary to the goal of MVC in separating model logic from presentation logic. I would recommend that you create a template for publishing controls that is included (along with validation support) when you have a model that contains the Publisher role.

0
source

I will explain this idea in a short example. We have the "IsMasterProject" flag to set in the "MasterProjectNo" field:

To accomplish the required “on the fly” you will need the following things:

Define your model using a field that is not strict. [Required]

 class ProjectList { public bool IsMasterProject { get; set; } // this field will be optionally required, // we do not need the [Required] attribute public string MasterProjectNo { get; set; } } 

Create a view with an example field code:

 <div class="data-field"> <div class="editor-label"> <div id="IsMasterProjectLabel"> Is Master Project </div> </div> <div class="editor-field"> <input id="IsMasterProject" class="check-box" type="checkbox" value="true" name="IsMasterProject" data-val-required="The IsMasterProject field is required." data-val="true" checked="checked"> </div> </div> <div class="data-field"> <div class="editor-label"> <div id="MasterProjectNoLabel"> Master Project No </div> </div> <div class="editor-field"> <input id="MasterProjectNo" type="text" value="" title="" style="width: 9.2em" placeholder="" name="MasterProjectNo" maxlength="15" data-val-length-max="15" data-val-length="The field MasterProjectNo must be a string with a maximum length of 15." data-val="true"> </div> </div> 

Add Java Script to handle the click code and add or remove the “required” label:

 $(function () { $("#IsMasterProject").change(function () { OnIsMasterProjectValueChange(); }); OnIsMasterProjectValueChange(); }); function OnIsMasterProjectValueChange() { if ($('#IsMasterProject').is(':checked')) { $('#IsMasterProjectLabel').append('<span class="label-required">*</span>'); } else { $('#IsMasterProjectLabel span').remove() } }; 

In the controller, you can prepare the show action:

 [Authorize] public ActionResult Edit(int id) { try { ProjectList project = prepare_ProjectList(id); return View(project); } catch (Exception ex) { sysHelper.LogError(ex, ModelState); ModelState.AddModelErrorException(ex, Request, "Probably selected data doesn't exist."); return View("Error"); } } 

In the save action, you can check the necessary conditions:

 [HttpPost] public ActionResult Edit(ProjectList project) { try { if (ModelState.IsValid) { /* ------------------------------------------------------------------------ */ /* HERE YOU CAN ADD YOUR CODE TO CHECK THE FIELD */ /* ------------------------------------------------------------------------ */ if (project.IsMasterProject && string.IsNullOrEmpty(project.MasterProjectNo)) { ModelState.AddModelError("Model", "The MasterProjectNo field is required."); } /* ------------------------------------------------------------------------ */ else { project.UserID = CurrentUser.ID; project.C_updated = DateTime.Now; db.ProjectList.Attach(project); db.Entry<ProjectList>(project).State = System.Data.Entity.EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } } } catch (Exception ex) { sysHelper.LogError(ex, ModelState); ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator."); } prepareViewBag(project); return View(project); } 

It works like a charm :) Good luck.

0
source

Source: https://habr.com/ru/post/1385876/


All Articles