I am new to AngularJS but I have searched extensively and could not find a working answer to this question, maybe its just not possible the way I have it in mind.
What I would like is to be able to combine error conditions so that I can use more generic error messages in the ng-messages module. This saves us a lot of time maintaining texts as our application is multi-lingual. In my example it would be great to combine minlength, maxlength, and pattern and have it reference 1 generic message. The only way I have gotten it to work is for a separate ng-message for each type and then reuse the error text which seems redundant to me. Hopefully it's something short I am missing like not understanding when/how to use , or ||.
<form id="myFormId" name="myForm" novalidate>
<input name="sText" ng-model="someText"
type="text"
required
ng-minlength="8" minlength="8"
ng-maxlength="8" maxlength="8"
ng-pattern="/^[a-zA-Z0-9]{8,8}$/" pattern="/^[a-zA-Z0-9]{8,8}$/">
<div ng-messages="myForm.sText.$error" role="alert">
Error message:
<div ng-message="required">Required text missing</div>
<div ng-message="minlength || maxlength || pattern">Not right length or bad pattern - Why does this not work? I have also tried using comma , instead of || </div>
<div ng-message="minlength">Too short - this does work but does not change even if this is removed</div>
</div>
</form>
I have created this simple Plunk to illustrate what I am trying to do:
EDIT 1
I do realize I could use a single regex pattern expression but the above validations is strictly to reproduce the issue and show an example. I have other validations I would like to combine that could not be expressed with a single pattern.
ng-messages will show error message inside ng-messages directive element, but that has limitation that you could only display single error ng-message inside the ng-messages div.
So if you wanted to show multiple ng-message inside ng-messages directive you need to add ng-messages-multiple attribute on ng-messages directive element.
Docs Link
Markup
<div ng-messages="myForm.sText.$error" role="alert" ng-messages-multiple>
Error message:
<div ng-message="required">
Required text missing
</div>
<div ng-message="minlength, maxlength, pattern">
Not right length or bad pattern - Why does this not work? I have also tried using comma , instead of ||(OR)
</div>
<div ng-message="minlength">
Too short - this does work but does not change even if this is removed
</div>
</div>
Working Plunkr
Update
After angular document updation I came to know that ng-messages doesn't support to show multiple ng-message error inside ng-messages, for solving this problem we should have ng-messages-multiple attribute on ng-messages element.
From Docs
By default, ngMessages will only display one error at a time. However, if you wish to display all messages then the ng-messages-multiple attribute flag can be used on the element containing the ngMessages directive to make this happen.
Markup
<div ng-messages="myForm.sText.$error" role="alert" ng-messages-multiple>
Error message:
<div ng-message="required">
Required text missing
</div>
<div ng-message="minlength, maxlength, pattern">
Not right length or bad pattern - Why does this not work? I have also tried using comma , instead of ||(OR)
</div>
<div ng-message="minlength">
Too short - this does work but does not change even if this is removed
</div>
</div>
Working Plunkr
In Angular 1.4 you can specify multiple errors for a ng-message:
<div ng-message="minlength, maxlength">
Your email must be between 5 and 100 characters long
</div>
See documentation
Inorder to make your ng-message more generic you can keep all your error messages at one place and use it when required. You could do this using ng-message-include.
Have a look at : Reusing and Overriding Error Messages
http://www.yearofmoo.com/2014/05/how-to-use-ngmessages-in-angularjs.html#reusing-and-overriding-error-messages.
I think you will like to implement this.
Related
I'm trying to write a small directive that will append the validation tags and ngMessages dynamically to the input. But I'm having trouble appending the ng-message attribute to the div.
The idea is to have this,
<div validator validations="{json_data containing error messages}">
<input name='fieldName'>
</div>
Turned in to the following according to the provided JSON.
<div validator>
<input required="required"></input>
<div ng-message="fieldName" ng-if="fieldName.$dirty>
<p ng-message="required"> scope.message </p>
</div>
</div>
I've currently managed to get the ng-required appeneded using the answer to this answer. But I can't seem to append the ng-message tag using the same technique. What should be done differently to solve this issue?
The final directive should be able to generate something like this Fiddle
The current version can be found in the Fiddle here the example works as expected until 'scope' is added. But as soon as 'scope' is added, the example stops working.
Update
I've realized that this only occurse when you add a local scope. This error doesn't occure when using the global scope and accessing the variable using scope.$eval(attrs.message)
I have an ng-repeat for a list of attributes and want to show error messages for each input. For a pattern error I also want to show the specific regex it has to match.
Can I access an input's pattern somehow? I know I could add an attribute containing the regex but I would like to know if there is an angular way somehow.
(This is an oversimplified example, the regexes can be different for different attributes)
<form name="form">
<div data-ng-repeat="(attributeName, attributeMetaData) in configuration.metaData">
<input data-ng-model="configuration[attributeName]" type="text" name="{{attributeName}}" data-ng-pattern="/^[0-9][0-9]:[0-9][0-9]$/">
<span data-ng-show="form[attributeName].$error.pattern && form[attributeName].$dirty">
Please check your input format [pattern should go here]
</span>
</div>
</form>
jsFiddle: http://jsfiddle.net/lisapfisterer/ndu2g0ev/
Based on your restriction that the model cannot be changed, I guess your best bet is to have a separate model containing just regexes
This was taken from a e-mail thread between me and the author. I've moved it from e-mail to SO hoping that it may benefit others. ElasticUI can be found here
My Original Question(s)
I see that search is eui-enabled by querystring.length. We would like to the search and sorting triggered by buttons, rather than the
watch functionality.
It's a bit confusing when the search returns no results. Instead of a no results found message it simply returns the deafualt (all)
results. Is it possible to make the results empty by default, rather
than return all?
Author's Answer
1+2 - this is both possible. In AngularJS, keep in mind what "model"
variable you use and connect to your UI / Directives, something along
the following lines would make sense
<div eui-query="ejs.MatchQuery('textField', querystring)" eui-enabled="querystring.length"> <input type="text" ng-model="querystring_live" />
<input type="button" ng-click="querystring=querystring_live" /> </div>
<div ng-if="!querystring.length"> No query specified </div>
Notice what happens on a click. You could also wrap an ng-if clause
around you're results to only display results when a query has been
specified.
When I include this snippet, the ng-if condition doesn't take (the "No query specified" stays at all times) and after submitting the search, results are blank, even if it's query I'm sure should return results.
Being new to angular, an obvious mistake may go over my head. Is there anything obvious that is missing?
Edit
Found the issue: Forgot to fill in the field with which to run the query against: eui-query="ejs.MatchQuery('post_title', querystring)" ('post_title' being the ES field)
Although it seems like you may have found the answer I think there's still a bug in the "author answer" (me) you posted above. Seems like I fell for the dot-problem in Angular. This should work better:
<div ng-init="qs_model={live:'', after_click:''}">
Debug: {{qs_model | json}}
<h3>Search</h3>
<div eui-query="ejs.MatchQuery('tweet.text', qs_model.after_click)" eui-enabled="qs_model.after_click.length">
<input type="text" ng-model="qs_model.live" />
<input type="button" ng-click="qs_model.after_click=qs_model.live" />
</div>
<div ng-if="!qs_model.after_click.length">No query specified </div>
</div>
It's cleaner to define qs_model in a controller as opposed to ng-init I demoed above.
Also note that even if eui-query is disabled (no querystring specified), ElasticUI will at this moment still do a MatchAll query behind the scenes (you can choose to hide the results using ng-if).
Are there solutions to manage entered email-contacts in HTML forms as removable blocks with [x] buttons, similar to Gmail?
Instead of generic text input with comma-separated e-mails I want to have more advanced field with autocomplete (not a question here) and autoreplace for entered e-mails where each e-mail becomes a block with quick remove [x] button.
Of course, it's not very complicated to write the solution manually, but I'm sure this has been solved before.
Quick example of what I'm looking for: http://jsfiddle.net/JNVgq/4/
<div class="wrap">
<input class="shadow" value="test#email.com, other#email.com" />
<div class="email"> test#email.com × </div>
<div class="email"> other#email.com × </div>
<input class="current" value="second#e" />
</div>
Found myself unable to google this stuff with no exact and clear keywords.
Here we go: Chosen jQuery Plugin
You can modify the code to use a text box instead of list box to accomplish what you are looking for. See the multiple select example.
EDIT:
Tag-it mentioned anpsmn by looks exactly what you are looking for.
Another option that I used for this (which includes the autocomplete part either from static list or server-side endpoint) is jquery-tokeninput
I have a jQuery selector that is running way too slow on my unfortunately large page:
$("#section").find(":visible:input").filter(":first").focus();
Is there a quicker way to select the first visible input without having to find ALL the visible inputs and then filtering THAT selection for the first? I want something like :visible:input:first but that doesn't seem to work.
[Edit]
Here's the basic idea of what #section looks like:
<div id="section">
<div>
Some text <input type="text">
</div>
<div>
etc. etc. <input type="text">
</div>
</div>
$(":input:visible:first", "#section").focus();
If you first filter for the type of control you avoid checking the :visible on all the #section's elements.
It seems like you need only to catch the first input type="text" visible.
This should be a bit faster.
$("input[type='text']:visible:first", "#section").focus();
How about adding class="default_field" to the default field for each page, then using $('.default_field').focus();?
How easy this is to do depends on your server-side technology of course, but the advantages are that it takes the processing burden off of the client (which is extra important for IE6), and it also gives you the flexibility to choose a default input other than the very first one on pages where it's appropriate.