Fine-grained error messages in Angular Dart forms - dart

I have the following form with some simple validation rules:
<form name="signup_form" novalidate ng-submit="ctrl.signupForm()">
<div class="row">
<input placeholder="Username"
name="username"
ng-model="ctrl.username"
required
ng-minLength=3
ng-maxLength=8>
</div>
<div ng-show="signup_form['username'].dirty &&
signup_form['username'].invalid">
<!-- ... -->
</div>
<button type="submit">Submit</button>
</form>
I would like to display specific error messages for required, ng-minLength and ng-maxLength, but I'm not having success being able to drill down into signup_form['username'].errors to get the specific error.
I can access the errors map just fine in the controller, it is in the markup that I cannot get a handle on the specific error. I would like to be able to do roughly something like this:
<div ng-show="signup_form['username'].errors['minlength'].invalid>
<!-- ... -->
</div>
I.e., something like the following in angularJS:
<div ng-show="signup_form.username.$error.required">This field is required</div>

A working example for
Inspired by this filter I tried this approach again
Angular 0.9.9
#NgFilter(name: 'errors')
class ErrorFilter {
call(val) {
if(val != null) {
return val.map.keys;
}
return null;
}
}
and in the markup
{{signup_form['username'].errors | errors}}
EDIT for Angular 0.9.10
#NgFilter(name: 'errors')
class ErrorFilter {
call(val) {
if(val != null) {
return val.keys;
}
return null;
}
}
and in the markup
{{signup_form['username'].errorStates | errors}}
I learned from the discussions I have observed in the AngularDart Github repo that better solutions are on their way.
related open issue
When this https://github.com/angular/angular.dart/pull/771 is landed
hopefully better solutions are possible.

Related

Angular reactive formgroup clear error in component not clearing from template

I am dynamically clearing the errors of my reactive form like:
this.courseForm.setErrors(null);
But the errors are still displayed in my template:
<form [formGroup]="courseForm" autocomplete="off">
<div class="alert-group" *ngIf="submitted && formGroup.errors?.coursedates">
<div *ngFor="let err of formGroup.errors?.coursedates?.value" role="alert" class="error">
{{err}}
</div>
</div>
</form>
Is there a way to clear formgroup errors in template as well?
thanks
Errors for each control doesn't populate for formgroup errors. So clearing formgroup errors doesn't remove the errors from each of its form-controls.
We need to setErrors(null) for each control inside formgroup. Here is how we do it.
Object.keys(this.courseForm.controls).forEach(key => {
this.form.get(key).setErrors(null);
});
Make sure to mark it as answer if the solution fixes your issue.

Issue with if else in HTML helper in cshtml file

new to Razor/cshtml. I am facing error, that my if else is now working properly, means that the if is working fine but the else seems not working. my code shown below;
Can someone guide me what am I doing wrong?
#if (ViewBag.role == "Admin")
{
<div id="wrapper">
<div>
some code here
}
else if (ViewBag.role == "AppAdmin")
{
<div>
some code here
</div>
</div>
</div>
It seems that the "else" keyword is not recognized/highlighted, i.e., the above "if" block is not well formatted. Try to exclude all above collapsed blocks (with their possible razor operations) to determine the incorrect one.

Enabling MVC client side validation

I have
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
in my config and
Html.EnableClientValidation(true);
Html.EnableUnobtrusiveJavaScript(true);
in my view and
<script src="~/js/jquery.validate.min.js"></script>
<script src="~/js/jquery.validate.unobtrusive.min.js"></script>
are in the HTML source (as is jQuery) (no JS errors in the browser)
I have one form element with [Required] and the form element seems to be rendering OK with the associated data- attributes
<div class='form-group'>
<label class="col-md-2 control-label" for="Username">en-gb(Username)</label>
<div class='col-md-10'>
<div class='input-group'>
<div class='input-group-addon'><span class='fa fa-user'></span></div>
<input class="input-validation-error form-control" id="Username" name="Username" type="text" value="" />
</div>
<span class="field-validation-error help-block" data-valmsg-for="Username" data-valmsg-replace="true">en-gb(The en-gb(Username) field is required.)</span>
</div>
</div>
But no client side validation is occurring; the form is always submitted to the server.
What am I missing? What should I be checking?
Edit
TextBoxFor is in System.Web.Mvc.Html.InputHelpers and calls TextBoxHelper which in turn calls InputHelper in the same file. This calls
htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata) which looks like this:
public IDictionary<string, object> GetUnobtrusiveValidationAttributes(string name, ModelMetadata metadata)
{
Dictionary<string, object> results = new Dictionary<string, object>();
// The ordering of these 3 checks (and the early exits) is for performance reasons.
if (!ViewContext.UnobtrusiveJavaScriptEnabled)
{
return results;
}
FormContext formContext = ViewContext.GetFormContextForClientValidation();
if (formContext == null)
{
return results;
}
string fullName = ViewData.TemplateInfo.GetFullHtmlFieldName(name);
if (formContext.RenderedField(fullName))
{
return results;
}
formContext.RenderedField(fullName, true);
IEnumerable<ModelClientValidationRule> clientRules = ClientValidationRuleFactory(name, metadata);
UnobtrusiveValidationAttributesGenerator.GetValidationAttributes(clientRules, results);
return results;
}
(Source: http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/5cb74eb3b2f3#src/System.Web.Mvc/HtmlHelper.cs)
The problem I have is that formContext.RenderedField(fullName) returns true and therefore no validation attributes are added to my input element.
In your views, are you rendering the following code?
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Assuming you're using the default project template, you'll need to include that within the view that you're rendering to enable client side validation... Alternatively, add Scripts.Render("~/bundles/jqueryval") to the bottom of your layout file to enable it across all your views.
Also do ensure that bundles/jqueryval is defined in the Bundles configuration file.
formContext.RenderedField(fullName) was a red herring, I really don't know what all that was about.
The problem is that I've subclassed the ValidationAttribute classes in order to provide globalisation with lookup from a database rather than from resx. This means that they do not appear in the ModelMetadata.
One solution is to implement the interface System.Web.Mvc.IClientValidatable on the overridden attributes. However, the base classes do not implement this interface, so they must be configuring client side validation by some other mechanism -- and it's this other mechanism that isn't smart enough to pick up subclasses of the out-of-the-box ValidationAttributes.

How do I get results (successful/not successful) from a g:uploadForm in a GSP file?

I'm trying to get the results from a g:uploadForm action I have in my GSP file. I need to upload the file, then after it's successfully uploaded I need to tell if the upload was successful, then display another area in the GSP file.
<g:uploadForm action="save" method="post">
<h1>
<g:message code="upload"/>
</h1>
<h5>
<g:message code="upload.message"/>
</h5>
<br/>
<input type="file" id="Upload" name="Upload" class="input"/>
<br/>
<g:formButton type="submit" buttonClass="btn-primary btn-lg" buttonTextCode="upload.button" />
</g:uploadForm>
I just need something to say if it was successful or not.
Is this something I need to handle in the controller and just post to the GSP after that? I'm new to grails and groovy.
It's pretty common to use flash scoped variables for these types of messages. In fact, if you look at the Grails documentation about uploading files you will see it does just that.
def upload() {
def f = request.getFile('myFile')
if (f.empty) {
flash.message = 'file cannot be empty'
render(view: 'uploadForm')
return
}
f.transferTo(new File('/some/local/dir/myfile.txt'))
redirect(render: 'uploadForm')
}
Using the above example you could then include the following in your uploadForm GSP page.
${flash.message} to display this.

dont display div data not provided

I am working with mvc4 and displaying data from my model in to cshtml views.
When setting data in to the markup, I adding it in to div tags.
Is there a way in mvc that if the model property is not set, dont display the div?
Sample of my markup
<div class="myclass"> #Model.Text </div>
You can test for a value being set like so:
#if (!string.IsNullOrEmpty(Model.Text))
{
<div class="myclass"> #Model.Text </div>
}
Update: If you want to incorporate the logic for whether or not to render an element based on its value, you could create a Custom HTML Helper method.
How about wrapping it in a null check
#{
if (#Model.Text != null)
{
<div class="myclass"> #Model.Text </div>
}
}

Resources