Regular Expression for name should NOT contain "www." and name should NOT be numbers only in angularjs - regex

Can you please tell me the Regular Expression for name should NOT contain "www." and name should NOT be numbers only in angularjs using ng-pattern. Here I want to show two different error messages like:
name should NOT be numbers only
name should NOT contain "www.
Based on the input it will show any one of those messages.
I tried like this /^((?!www.).)*$/, it is working for name should NOT contain "www." not for another means "name should NOT be numbers only". If I'm adding | (OR) condition it is showing both messages.

There is no good way to show two different error messages with ngPattern. The cleanest solution would probably be custom directives for validation. You could also try using the uiValidate directive from AngularUI, which lets you call a custom validation function.
Untested uiValidate example:
<input name="name" type="text" ui-validate="{www:'validateNotWww($value)', numbers:'validateNotNumbers($value)'}"/>
<span ng-show="form.name.$error.www">Name should NOT contain "www."</span>
<span ng-show="form.name.$error.numbers">Name should NOT be numbers only.</span>
validateNotWww and validateNotNumbers would be functions defined on your $scope.

Related

Input validation with pattern Angular 2

I'm currently writing a simple form in ionic 2 (Angular 2). I was wondering how I'd add a simple regular expression pattern to the validation:
I basically have this:
<form>
<ion-input stacked-label>
<ion-label>{{label.msisdn}}</ion-label>
<input type="text"
[(ngModel)]="msisdn"
ngControl="msisdnForm"
required
maxlength="10"
minlength="10"
pattern="06([0-9]{8})"
#msisdnForm="ngForm"
>
</ion-input>
<button [disabled]="!msisdnForm.valid" block (click)="requestActivationCode()">
{{label.requestActivationCode}}
</button>
</form>
The maxlength, minlength & required are being picked up (the button is disabled if conditions not met). Now I want to limit the input to numeric and prefix it with 06 (Dutch phone number with minimum amount of numbers).
The pattern is however not picked up in the validation. Can I do it this way, or do I need a code approach?
Add the pattern to a variable
var pattern=/06([0-9]{8})/;
and bind the attribute to it
<input type="text"
[(ngModel)]="msisdn"
ngControl="msisdnForm"
required
maxlength="10"
minlength="10"
[pattern]="pattern"
#msisdnForm="ngForm"
>
Seems this PR https://github.com/angular/angular/pull/6623/files needs to land first.
There is still an open issue https://github.com/angular/angular/issues/7595
This prevents pattern being bound to. The pattern needs to be statically added to the DOM (without binding) to work.
I put more details (Angular 2.0.8 - 3 March 2016):
https://github.com/angular/angular/commit/38cb526
Example from repo:
<input [ngControl]="fullName" pattern="[a-zA-Z ]*">
I tested it, and it worked :) - here is my code:
<form (ngSubmit)="onSubmit(room)" #roomForm='ngForm' >
...
<input
id='room-capacity'
type="text"
class="form-control"
[(ngModel)]='room.capacity'
ngControl="capacity"
required
pattern="[0-9]+"
#capacity='ngForm'>
UPDATE September 2017
I just wanna to say that currently when I have more experience, I usally use following 'cheap' approach to data validation:
Validation is ONLY on server side (not in angular at all!) and if something is wrong then server (Restful API) return some error code e.g HTTP 400 and following json object in response body (which in angular I put to err variable ):
this.err = {
"capacity" : "too_small"
"filed_name" : "error_name",
"field2_name" : "other_error_name",
...
}
(if server return validation error in different format then you can usually easily map it to above structure)
In html template i use separate tag (div/span/small etc.)
<input [(ngModel)]='room.capacity' ...>
<small *ngIf="err.capacity" ...>{{ translate(err.capacity) }}</small>
As you see, when there is some error in 'capacity' then tag with error translation (to user language) will be visible. This approach have following advantages:
it is very simple
in angular we not double validation code which is (and must be) in server (in case of regexp validation this can either prevent or complicate ReDoS attacks)
we have full control on way the error will be shown to user (here as egzample in <small> tag)
because in server response we return error_name (instead of direct error message), we can easily change error message (or translate it) by modify only frontend-angular code (or files with translations). So in that case we not need to touch backend/server code.
Of course sometimes (if this is needed - eg. retypePassword field which is never send to server) I make exceptions of above approach and make some validation in angular (but use similar "this.err" mechanism to show errors (so I not use pattern attribute directly in input tag but rather I make regexp validation in some component method after user raise proper event like input-change or save) .

An advanced Find and Replace with RegEx in Sublime Text

I have a directory full of Classic ASP legacy code, and almost all files have something similar to this:
<input type="hidden" name="driverPayment" value="<% =driverPayment %>">
Then later in the code, some JavaScript is running, and doing the following:
var x = document.getElementById('driverPayment')
This works fine in IE, but of course doesn't work anywhere else because there is no ID attribute defined.
The fix is to go through the 1770 files and manually add an ID attribute that matches the name property on the input. So make it like so:
<input type="hidden" name="driverPayment" id="driverPayment" value="<% =driverPayment %>">
Is there a way I can automate this process by using the logic below:
Get input element with a name attribute
If input has id attribute, move to next input
Else add an ID attribute to the input, and give it a name matching the value of the name attribute
I'd like to do this for the 1770 Classic ASP files I have. I am using Sublime Text.
You can use regex to match. My regex isn't great but the following should work. Happy for others to improve on it. I used some regex from this question.
Right Click project folder
Choose "Find in folder" option
Find and replace options appear at bottom of screen. Select the regex option (far left).
Enter
<(?:input)\s+(?=[^>]*\bname\s*=)(?![^>]*\bid\s*=)[^>]*>?(name="driverPayment")
in Find field
Enter
id="driverPayment" name="driverPayment"
in Replace field
Click Replace

How do I use a custom Tooltip Text for Invalid Input Pattern instead of "You must use this format: [blank]"

When the input does not match the pattern specified by the pattern attribute, Firefox simply says, "Please match the requested format", which is okay; however, when this validation fails Internet Explorer 10 displays "You must use this format:" in a tooltip with nothing else. This may be simple, but searching has not yielded me a clue as to how to supply text to the tooltip telling it the pattern that should be used.
Example below for a one to four digit number:
<input id="institution_threshold_days" type="text" placeholder="0-9999" pattern="^[0-9]{1,4}$" />
Try using the title attribute to describe what you want it to say:
<input id="institution_threshold_days" type="text" placeholder="0-9999" pattern="^[0-9]{1,4}$" title="Please enter a number less than 10000." />
Should work for all major browsers...
From Microsoft
the content of the title attribute is both shown as tooltip text for
the field and appended to the generic pattern mismatch error message.
From Mozilla
Use the title attribute to describe the pattern to help the
user.
And although I cannot find official documentation, it appears to work in Chrome as well.

issues with ngPattern directive

I've this code:
<form name="test">
<input type="text" ng-model="code" name="code" ng-pattern="/^code_[0-9]+$/"/>
<div ng-show="test.code.$dirty && test.code.$invalid">
Error:
<span ng-show="test.code.$error.pattern">Pattern fail.</span>
</div>
</form>
I have 2 issues with this code:
Strings like " code_232 ", "code_232 " " code_232" pass the validation. I'm not expert with regex, so this could be an issue simply related to the regex i wrote: /^code_[0-9]+$/
If i start writing "code_23892" (a correct string), i get the error
message while i'm still writing (test.code.$error.pattern = true). Is there a built-in way to avoid this? So my desidered behaviour is:
If i write "cod", and the input has still focus: no error
If i write "cod" and the input loses focus: error.
If i write "a", "ca", "coa" etc.: error, cause the pattern is already violated.
Is this already possible, or i've write a custome validation directive to achieve this?
Thanks in advance.
The reason that whitespace doesn't trigger a failed validation is because ng-model automatically trims the value. If you don't want that, you can add ng-trim="false" to your <input />. Note that ng-trim is a quite new attribute, so you might have to update your Angular version.
About your second question; I don't think you can avoid the validation to run during the time you type, but you could change your code to only display the error when the input looses focus. I don't think that something like ng-blur and ng-focus exists, but it should be pretty simple to implement them.

How can I display extra details in the autosuggest, but only ID in the input field?

I'm using a ColdFusion autosuggest for my UserID field. When a user starts to type in a UserID, a list of user ids and the user names associated with it pop up (populated by a cfc function). Sample code:
<cfinput name="userID" type="text" value="#userID#" autoSuggest="cfc:Utilities.suggestUser({cfautosuggestvalue})" matchcontains="true" />
The suggestions are listed in the format "User Name <userID>". So if the user would start typing 123, a sample suggestion that would pop up would be "Harvey Mann <1234>".
The problem is that if the user chooses that suggestion, I don't want to insert the whole suggested text into the input field - I just want to insert the user id ("1234" in this case). I would also like to be able to insert the user name ("Harvey Mann") into an adjacent field/area if possible. Is there any way to accomplish this?
Since you are using CF's built-in implementation of autosuggest, you are stuck with only having access to one returned value. Thus if the value consists of mutliple 'parts' and you want to insert different 'parts' of the value into different columns, you will have to parse the value and extract appropriate parts from the string. In your example case you could treat the value as a list delimited by <. In this case you can get the name 'part' with
trim(listfirst(form.userID, "<"))
and the id 'part' with
replace(listlast(form.userID, "<"), ">", "")
Alternatively, you can always use jQuery UI Autocomplete implementation - you'll have to write your own javascript for it, but it gives you far more control than the built-in cf's implementation. Check jQuery UI docs for more info: http://jqueryui.com/demos/autocomplete/
UPDATE:
On second thought, if you just want to display selected value's 'name' part in another area on the same page, you may be able to do it using just CF's built-in autosuggest and a bit of javascript. Try adding this code to the HEAD section of your page:
<cfajaxproxy bind="javaScript:showName({userID})">
<script type="text/javascript">
showName = function(strUserId) {
document.getElementById("someID").innerHTML = strUserId.split('<')[0];
}
</script>