not showing the error message in signup page - handlebars.js

! {{#if errors}}{{#each errors}}{{#if #index is equal To 0}}<div class="error" id="name-Error">{{msg}}</div>{{/if}}{{#if #index is equal To 1}}<div class="error" id="email-Error">{{msg}}</div>{{/if}}{{#if #index is equal To 2}}<div class="error" id= " mobile-Error ">{{msg}}</div>{{/if}}{{#if #index is equal To 3}}<div class="error" id="password-Error">{{msg}}</div>{{/if}}{{/each}}{{/if}} !
Error: #if requires exactly one argument

Related

angularJS change form input border color on error

This is my first time using bootstrap and angularJS and I have created a login form . If my username does not have the correct length I display an error under the input . However I also want to change the input border color to red if I have an error displayed and I do not know how to do it . If I can do this for a single input I can use it everywhere
My code for a username input :
<form name= "logForm">
<div class="form-group">
<label for="username">Username:</label>
<input type="username" class="form-control" id="uname" placeholder="Enter username" name="uname"
ng-minlength= "10" ng-maxlength = "15" ng-model = "uname" required/>
<span style= "color: #4CAF50" ng-show = "logForm.uname.$valid">Valid</span>
<span style= "color:red" ng-show= "logForm.uname.$touched && logForm.uname.$error.minlength">
Min length is 10
</span>
<span style= "color:red" ng-show= "logForm.uname.$touched && logForm.uname.$error.maxlength">
Max length is 15
</span>
</div>
</form>
So I need to find a way that whenever the error shows up my input border is red and when I have valid input the border must be green .
This can be done using ng-class or ng-style:
solution using ng-style:
<input type="username"
class="form-control"
ng-style="!(!(uname.length < 10) && !(uname.length > 15)) && {"border" : "1px solid red"} "
id="uname"
placeholder="Enter username"
name="uname"
ng-minlength="10"
ng-maxlength="15"
ng-model="uname"
required
/>
You can add class to element using ng-class. More information about this directive is available under documentation: https://docs.angularjs.org/api/ng/directive/ngClass
In your case you want to add some class to form when error is visible. All you have to do is add something like ng-class="{ 'is-invalid': logForm.uname.$touched && logForm.uname.$error.minlength }" into your input. (Please note that class is-invalid is official bootstrap input error class, but can be vary in different versions: https://getbootstrap.com/docs/4.0/components/forms)
<input type="username"
ng-class="{ 'is-invalid': logForm.uname.$touched && logForm.uname.$error.minlength }"
class="form-control"
id="uname"
placeholder="Enter username"
name="uname"
ng-minlength="10"
ng-maxlength="15"
ng-model="uname"
required
/>
If you just want to add some style instead of class, you can use ng-style directive:
https://docs.angularjs.org/api/ng/directive/ngStyle

Make field required based on another value (state required if country is USA)

I want to have simple form validation on the STATES dropdown if and only if the country value is equal to USA or CANADA.
My validation works so far but its not dependent on the selection of USA or CANADA. Basically right now it will force you to select a state even if you select a country other than USA or CANADA.
<div class="row">
<div class="form-group" ng-class="{ 'has-error' : participantForm.country.$invalid && (!participantForm.country.$pristine || isSubmitted) }">
<div class="col-sm-6 key">Country<span class="req">*</span>:</div>
<div class="col-sm-6 val">
<select ng-model="participant.country" name="country" class="form-control" required ng-options="country.Key as country.Value for country in countries">
<option value="">SELECT</option>
</select>
<p ng-show="participantForm.country.$error.required && (!participantForm.country.$pristine || isSubmitted)" class="help-block">Select a country.</p>
</div>
</div>
<div class="row">
<div class="form-group" ng-class="{ 'has-error' : participantForm.state.$invalid && (!participantForm.state.$pristine || isSubmitted) }">
<div class="col-sm-6 key">US State or Canadian Province:</div>
<div class="col-sm-6 val">
<select ng-model="participant.state" name="state" class="form-control" required ng-options="state.Key as state.Value for state in states">
<option value="">SELECT</option>
</select>
<p ng-show="participantForm.state.$error.required && (!participantForm.state.$pristine || isSubmitted)" class="help-block">Your state is required for USA or Canada.</p>
</div>
</div>
If you give a value to the name property of the wrapping form element, AngularJS should automatically put an object on $scope by that name. For example, if you have the following:
<form name="participantForm">
<input name="state" />
</form>
$scope.participantForm will be an angular supplied object that allows you to access info about the form on the page. In addition to that, if there is a name property on a form input element, there will also be an angular supplied object that is a property of the form: $scope.participantForm["state"]
You actually use that in your view logic right now.
You should remove the "required" attribute on the select input element for the state/province so that it stops always requiring an input.
Instead, you should have a function that fires whenever the value of the state/province input changes, checks the value of the country field, and then manually sets the validity of the state/province field appropriately. The function may look like this:
$scope.validateStateField = function() {
var isValid = true;
var country = $scope.participant.country;
if (country === "USA" || country === "Canada") {
var state = $scope.participant.state;
isValid = state != null && state !== '';
}
$scope.participantForm["state"].$setValidity("required", isValid);
}
If you ensure that this function runs when the state field changes and when the user tries to submit the form, then you'll not only change the validity of the input appropriately but you'll also have a correct value to check before you proceed with submission logic:
if ($scope.participantForm.$valid) {
// Proceed because everything checks out
}
I believe there are also ways to create custom validators that are more native to Angular, but this is how I tend to manually approach dependent validation.

How to concatenate and pass down a Handlebars variable into a partial

This is our Handlebars partial we've called input-field. We're trying to dynamically create name and email fields based on the number of participants selected on the previous page.
<div class="form-group {{errors.fullName.class}}" id="fullName">
<label for="full-name">Your full name</label>
<p class="message-error">{{errors.fullName.message}}</p>
<input type="text" class="form-control" name="fullName" value="{{values.fullName}}">
</div>
We have some functions which create and display error messages if any of those form fields are unfilled. Instead of {{errors.fullName.class}}, we need it to be {{errors.fullName{{this}}.class}}.
We've found that Handlebars doesn't allow you to refer to another handlebars variable inside a handlebars statement this way.
It's all within an each loop:
{{#each otherOccupiers}}
{{> input-field}}
{{/each}}
Does anyone have an idea about how to achieve this effect, maybe by writing a handlebars helper function or some other way to perform this concatenation.
I'm assuming the data object you are passing to handlebars looks something like this:
{
otherOccupiers: ["A", "B"],
errors: {
fullName: {
class: "error-class",
message: "error-message"
}
}
}
However if you change the structure of your data object to look something like this:
{
errors: {
otherOccupiers: [
"A" : {
fullName: {
class: "error-class",
message: "error-message"
}
}
"B" : {
fullName: {
class: "error-class",
message: "error-message"
}
}
]
}
}
Then you can do an each loop like this:
{{#each errors.otherOccupiers}}
<div class="form-group {{this.fullName.class}}" id="fullName">
<label for="full-name">Your full name</label>
<p class="message-error">{{this.fullName.message}}</p>
<input type="text" class="form-control" name="fullName">
</div>
{{/each}}

Go 'up' scope in meteor blaze?

How can I use a variable in a scope up from the current scope in Blaze?
For example:
<template name="userLayoutEditCreate">
{{#each findUser id}}
<h3>I am a single user (edit/create)</h3>
<h3>{{id}}</h3>
<form action="/" method="post">
<fieldset>
<!-- Primary instruments multi-select -->
<div class="form-group">
<label class="control-label" for="playerPrimaryInstrument">Primary instruments</label>
<div class="controls text-left">
<select id="playerPrimaryInstrument" name="playerPrimaryInstrument">
{{#each instruments}}
<option value="{{name}}" {{#if equals primary_instrument name}} selected="selected" {{/if}}>{{name}}</option>
{{/each}}
</select>
</div>
</div>
</fieldset>
</form>
{{/each}}
</template>
The if statement does not run within the each block. But it does run outside of the each block (I have defined the helper).
The error I get looks like this.
Reactive HTML attributes must either have a constant name or consist of a single {{helper}} providing a dictionary of names and values. A template tag of type BLOCKOPEN is not allowed here.
==== EDIT ====
Even using the '../' scope definition didn't work in this case. What DID work was putting the expression inside the value of the selected attribute. I'm not sure why that is, please let me know if you have any idea?
The solution:
{{#each instruments}}
<option value="{{name}}" selected="{{#if equals name ../primary_instrument}} selected {{/if}}">{{name}}</option>
{{/each}}
Try this:
{{#if equals ../primary_instrument name}}
{{/if}}

Handlebars #each within #if issue

I have an #if condition that I have tested is false, but it enters anyway. Here is the Handlebar script :
{{#each this.properties}}
<span class="values">
{{#if is-object-property}}
{{#each values}}
<span class="value" style="color:blue;">{{this}}</span>
{{/each}}
{{else}}
{{#each values}}
<span class="value">{{this}}</span>
{{/each}}
{{/if}}
</span>
{{/each}}
The thing is that all I have displayed is blue while my object looks like that:
properties: Array[3]
0: Object
code: "pays"
reliability: 100
values: Array[1]
1: Object
code: "pnb"
reliability: 100
values: Array[1]
2: Object
code: "source"
is-object-property: "true"
reliability: 100
values: Array[2]
And as you can see, except for the object 2, the objects 0 and 1 should have an undefined result for is-object-property. They do have that result, that's why I don't understand why I have all in blue.
I assumed it entered the condition, but as it is written on the handlebars website : "You can use the if helper to conditionally render a block. If its argument returns false, undefined, null, "" or [] (a "falsy" value), Handlebars will not render the block."
(see "The if block helper" at http://handlebarsjs.com/)
This solved the problem :
<span class="values">
{{#each values}}
{{#if ../is-object-property}}
<span class="value" style="color:blue;">{{this}}</span>
{{else}}
<span class="value">{{this}}</span>
{{/if}}
{{/each}}
</span>

Resources