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
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 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.
I'm trying to set a text_field and text area on a webpage that doesn't have an id any longer. I'm guessing the site is trying to avoid automation. The input and textarea tags are inside of a form. Here are the input and textarea tags and what is contained.
<input class="uniform-input ng-pristine ng-invalid ng-invalid-required ng-valid-maxlength" type="text" data-invalid-chars="" data-max-length="50" required="" placeholder="Subject" data-float-label="true" data-ng-model="message.Subject"></input>
<textarea class="uniform-input ng-pristine ng-invalid ng-invalid-required ng-valid-maxlength" data-invalid-chars="" data-max-length="4000" required="" placeholder="Enter your message here" data-ng-keypress="view.error = false" data-float-label="true" data-ng-model="message.Body"></textarea>
Also there is a button that I need to click after submitting the text with this button tag:
<button data-ng-if="!paymentInfo" type="button" class="button button-grey ng-scope" data-ng-click="ctrl.sendMessage()" data-ng-disabled="view.waiting" data-ng-class="{ 'button-disabled': view.waiting }">Send Now</button>
How do I click it when it has no name?
Any help as to how to set this with Watir would be very appreciated. If Watir is unable to do it is there a possible JS workaround that I could use? Please let me know if any further information is needed to help.
Using ruby gem watir
require 'watir-webdriver'
$browser = Watir::Browser.new
$browser.goto "yourwebsite.com"
$x = 0
def test
print "#{$x}"
begin
$browser.text_fields[$x].set "#{$x}"
rescue StandardError => e
puts " no text field found, try again.\n\n"
end
$x += 1
end
Keep changing the value of X to see what text fields you are manipulating. I suppose you could make a loop but you might get an error. Keep calling test until you find what you're looking for.
The elements do look like they have some descriptive attributes. The text fields have a data-ng-model that describes the field. As well, the button has a text that is likely unique.
Therefore, I would do:
browser.text_field(:data_ng_model => 'message.Subject').set('subject text')
browser.textarea(:data_ng_model => 'message.Body').set('body text')
browser.button(:text => 'Send Now').click
I think this approach is more expressive in terms of what your code is doing. As well, it can be more robust as it is not susceptible to fields being re-ordered or other fields being added/removed.
I have been identifying those ng-data objects via xpath, mainly when there is not a more specific way to identify them. Justin is right about an approach that is robust; find a way taht does not need to be refactored down the road. Here is what I would have:
browser.text_field(xpath: '//input[#data-ng-model="message.Subject"]').set("Hello")
browser.button(:text => 'Send Now').click
I prefer not using a lot of xpath, except for when it guarantees me a unique way to find an object on a page.
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