poteto / ember-changeset-validations Goto Github PK
View Code? Open in Web Editor NEWValidations for ember-changeset
Home Page: http://bit.ly/ember-changeset-demo
License: Other
Validations for ember-changeset
Home Page: http://bit.ly/ember-changeset-demo
License: Other
Also amend validators to take an option to opt-out of caching (e.g. async validators)
TODO:
1.2.10
// validations/text.js
import {
validateLength,
validateFormat,
} from 'ember-changeset-validations/validators';
export default {
text: {
validateFormat({regex: /^[a-z]*$/ }),
validateLength({max: 250, allowBlank: true})
}
};
type something, delete everything, will be isInvalid=true
and trigger the validateFormat-error
expecting to be valid, because 1st regex demands zero or more (*
) and 2nd allowBlank
is set.
a normal js match would indeed find a blank string:
var str = '';
var re = /^[a-z]*$/;
var found = str.match(re);
console.log(found);
// output: ["", index: 0, input: ""]
isInvalid
(removing the string-boundaries ^
and $
doesn't change anything but of course make the regex obsolete)
sorry I don't have time to set up a dummy link for this but I noticed it twice now...
ember-source: "2.13.3"
ember-changeset: "^1.3.0",
ember-changeset-validations: "^1.2.7",
export default {
url: [
validatePresence(true),
],
During one of our validations, we hit an external service that sometimes takes up to 2 seconds. Is there a property or event that I can hook into so I can show loading while until the async validator completes?
In my app, the propertyName for the input does not always map to the displayed label; this would be even more common in localised products.
For example:
<label for={{concat type "-" property}}>{{spanishProperty}}</label>
<input
class="u-full-width"
type={{type}}
id={{concat type "-" property}}
value={{get changeset property}}
oninput={{action (mut (get changeset property)) value="target.value"}}
onblur={{action validateProperty}}>
{{#if (get changeset.error property)}}
<small>
<ul>
{{#each (get (get changeset.error property) "validation") as |message|}}
<li>{{message}}</li>
{{/each}}
</ul>
</small>
{{/if}}
While it is possible to change the messages hash per language, the hardcoded {description}
just takes the propertyName and normalises it.
Would it be possible to allow the app/utils/messages.js
file to be overridden, in order to allow more complex names for the {description}
placeholder?
Hi there,
It seems like there is a bit of a clash happening with the default messages. The addon supports using a custom message map, but the way that the file is found iterates through all the modules (incl. addons) this results in the ember-validations/messages.js file being picked up and applied.
Looks like its happening here in the get-messages.js
util file.
I'm wondering if you know of any work around? I'm happy to submit a PR that might fix this as well, but any hints would be welcome 😃. I would like to remove ember-validations, but we have it used throughout our application and I'd rather slowly convert it our larger forms to ember-changesets over time.
Thanks!
1.2.4
https://ember-twiddle.com/cbe30296bfa00125a43447eb68f8b4a1
The default messages that come with ember-changeset-validations should be used.
The message, 'is invalid' is used instead because the get-messages function finds the ember-validations/messages.js
file and so can't match the type to a message template.
I want to put * on the required fields in a form if the Presence validator of those field attirbutes is present and set to true. For example, I've have a changeset
object and an attribute name say title
. How can I introspect the changeset
to see if title
has a presence validator and that presence validator has been set to true?
Hi, great addon.
I'm wondering, if there is a recommended way of changing validation messages at runtime?
I know it's possible to change it initially by defining a module that matches /validations\/messages$/gi
but it's only loaded once.
define(['foo/validations/messages'], () => {
return {default: {
...messages
}};
})
If a user changes its locale, it's impossible to update validation messages from what i can tell.
Are there any known workarounds for supporting this kind of use-case?
User should be able to provide their own messages
POJO that overrides https://github.com/DockYard/ember-changeset-validations/blob/master/addon/validators/messages.js
Will most likely involve an ember-cli hook step
I have a use case where I want to validate one field based on a value in another field (which, lets say, hasn't been changed).
Right now, using a custom validator, I can only see the validation arguments, field name, old value, new value, and change object. Is it possible to access the object underneath the changeset within a validation function?
The latest version of ember-changeset-validations
, 1.2.11, has a dependency on a beta version of ember-changeset
, 1.4.2-beta.1. This version seems to have bugs:
1.2.8
https://ember-twiddle.com/8687b828162c979dceef152ba69d1be8?openFiles=controllers.application.js%2C
Enter missing "t" in "Password" input field.
Password confirmation should be valid after both values are the same.
It's not revalidated until password confirmation field changes.
Currently,
email: /^[a-zA-Z0-9.!#$%&'*+/=?^_
{|}~-]+@a-zA-Z0-9?(?:.a-zA-Z0-9?)*$/`
This validation allows emails for emails with invalid format, for example: "y@y", this could cause problems for those who use the email validator to check emails but also use a database validator to store authentication credentials.
I'm not sure if the validation was intended this way. Another validator I have found to work is:
email: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
This might be more of a feature request than a bug (at least with the provided validators).
I have implemented a validator which checks for presence OR for the presence of other fields (so at least one of the fields must be "present" for the validator to pass). Currently there is no way to call validation for these other fields as the actual changeset
is not passed to the validator function (just the changes and the model).
The only "workaround" right now is to call validate on the main changeset validating all fields, but this means that before that happens, the isValid state is incorrect (and errors for said fields might be present on the changeset).
This is likely also an issue for the validator proposed in #189 / #191
I have a validation file which holds a complete set of validators for a particular template. The template conditionally renders certain fields. Even when those fields are not rendered the validators appear to be triggering an error on the changeset (since I am using validatePresence and nothing is being entered, since it is not rendered). Is there a way to skip a validator?
Don't need two CIs...
First off, great project! It has radically simplified/standardized our forms and validation handling.
Small issue with validateNumber
though. From playing around in my console (after struggling with false-positives in some tests):
> validate
function validateNumber() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
return function (key, value) {
var numValue = Number(value);
var…
undefined
is fine...
> validate({ })('someKey', undefined)
"Some key must be a number"
> validate({ allowBlank: false })('someKey', undefined)
"Some key must be a number"
... but null
...?
> validate({ })('someKey', null)
true
> validate({ allowBlank: false })('someKey', null)
true
https://github.com/DockYard/ember-changeset-validations/blob/master/addon/validators/number.js#L52 seems to be the issue.
> Number(undefined)
NaN
> Number(null)
0
Because JavaScript.
Will attempt a PR this weekend if possible.
Closed by #168.
validatePresence({ presence: true, on: 'email' })
2.1.0
This is probably me misunderstanding the behavior of the validator.
export default {
email: [
validatePresence(true),
validateFormat({ type: 'email' }),
],
password: [
validatePresence({ presence: true, on: 'email' }),
],
}
Empty password validates fine, but
Empty password stays valid, focused or not.
Once you type in a password and then remove it again then the validator fails (as expected).
The issue is, email validation accepts without the domain (like test@gmail).
I've added ember-changeset-validations to my Ember app today. I have some computed properties which observe model. They don't work anymore. What am I missing? How can I observe changeset properties?
This is now public API with #82
Fill all the fields correctly and press "save" button 2 times
all validations should be correct
passwordConfirmation validation is failing and giving error:
Password confirmation doesn't match password
After reading through the GH template that pops up when creating an issue ... I'm uncertain if this is a bug/ support like question / or documentation clarification (improvement?). Regardless, I have reproduced it with twiddle and captured a quick/easy to watch animated gif showing the breakdown.
I decided to use this ember addon because it has support for 1.13.13. When I actually implemented this (following the twiddle shown in the README) I discovered an issue worth mentioning.
https://ember-twiddle.com/b70553450d0c7e4e2329e02b7d082e11
With ember 2x and the 2x series template compiler it works as desired. Validations fall off as you type ahead. But with ember 1.13.13 and the older template compiler you are required to add the ember-get-helper because without it you get an error.
If you run the twiddle above you will see the following
This makes me think we have 1 of 2 issues
ember-changeset-validations
(a possible conflict with ember 1.13.13)I wanted to raise awareness mostly so we can update the twiddle/ call out that this implementation may not work for 1.13.13 or find and fix the bug with ember-changeset-validations
(or ember-get-helper
)
Update
It's worth noting that the actual validations do fall off from the changset itself - it seems to be a visual issue only. I'd guess we either don't notifyPropertyChange correctly or the ember-get-helper isn't picking that notify up as it should
Update 2
After I removed the ember-get-helper altogether (by doing the below) I still see this behavior making me think it's between ember 1.13.13/the template compiler? and ember-changeset-validations
{{#if changeset.error.firstName}}
<ul>
{{#each changeset.error.firstName.validation as |message|}}
<li><span>{{message}}</span></li>
{{/each}}
</ul>
{{/if}}
Update 3
Also found this in other related documentation and it's broken as well
{{#if changeset.error.firstName}}
<p>{{changeset.error.firstName.validation}}</p>
{{/if}}
From @brancusi
Hi,
Wondering how I can handle validators that return promises.
Trying to create a validator that checks if a name is available by calling some api/name_check service.
If you type anything in firstName you will notice [object Object] instead of a passing validation.
I noticed there was work done on handling validators that return promises, but I can't see how it actually works.
Thank you
Hi,
Thanks for creating a great ember addon.
Here is scenario:
I want to validate email field as a email and unique in DB (the uniqueEmail validator will make a request to server to check unique)
email: [
validateFormat({ type: "email" }),
uniqueEmail()
]
I think it would be nice if we check unique email just in case passed validateFormat only (for performance). Is there anyway to do it?
Thanks
The readme for validator number
contains the following:
propertyName: validateNumber({ gte: 10 }), // greater than or equal to 5
Comment there should say 10 instead of 5.
Edit: Scrap this
Line 101 references the Changeset Object but it is not there in the import list
https://github.com/DockYard/ember-changeset-validations/blame/master/README.md#L101
The validatePresenceOn
validator: validate presence if other field(s) are also there.
export default {
lastName: validatePresenceOn('firstName'),
password: validatePresenceOn([ 'email', 'ssn', 'address', ])
}
Alternatively, it could be an option for the validatePresence
validator:
export default {
lastName: validatePresence({ on: 'firstName' }),
password: validatePresence({ on: [ 'email', 'ssn', 'address', ] })
}
This is something I wrote as a custom validator, so if it's something you would like, I can put up a PR.
@rultor hello
The documentation currently shows that you can create a custom validator and which arguments are provided into the function, however, nowhere is it explained what each of these arguments actually IS. For example, I have a validator that is dependent on two values from the changeset
and I thought getting the property from the changes
argument would work but in some cases, I am getting undefined
. Whether or not this is a bug or just an issue in my code is irrelevant. The problem here is that there is no indication on what these args mean or how they should be used. key
, oldValue
and newValue
are easy enough, but what about changes
and content
?
In a legacy app, I've got some code that uses ember-validators, but I'm starting to add new functionality using ember-changeset-validators.
I discovered that just having ember-changset-validators installed in the same app breaks my old ember-validations code. Now when the old ember-validations code goes to look up the 'presence' validator, it somehow comes back with the validatesPresence
function from e-c-v. Then it can't call validator.create
, and the app screeches to a halt.
I know long term I want to get off of ember-validations, but for now I need to use both at once, e-v and e-c-v. One way to fix would be to update the names for 'validator:presence' etc to not clash with the names from e-v. Any other suggestions for fixing or working around?
export default function validatorName(options = {}) {
return (key, newValue, oldValue, changes) => {
return true;
};
}
Hey,
Thanks for the great library. I've noticed that you can return a promise from a custom validator leading me to believe I could write validators that query a remote backend. The most common use-case for this would be checking for other instances of a model with the same value (unique email for example).
It would be great to see a more verbose example this. I'm not sure what is the best way of getting access to the data store
as an injected dependency. From my understanding (based largely on this SO answer) you would need to declare the validator as an Object and register it with the container to be able to inject the store dynamically.
I may be overthinking this but would like to hear about some best practices when needing to interact with other models during validation.
Hi,
How to couple two validation files as one?
For example, I have two different cards in my page, for which I have two separate validation files.
I have them separately because, I can either create and submit (for which both the validation files need to be considered), else if I edit the already present details, I can edit a separate card & save.
Is there any way to achieve the above feature? Kindly guide.
Thanks in advance!
1.2.4
// test.js
import { validatePresence } from 'ember-changeset-validations/validators';
console.log(validatePresence);
npm install ember-changeset-validations
node test.js
I'd expect to see the validatePresence
function declaration outputted in the logs.
The module cannot be found:
Cannot find module 'ember-changeset-validations/validators'
Not sure if I'm missing something obvious here, but I tested this within an Ember app and had the same result. Wasn't sure if the problem was with my build process or something, so I thought I'd try the same thing in a single file (as above) and got the same result.
Tested with node 6.9.1
Starts with this commit in latest master
When using presence(true)
I expect the message to say {key} can't be blank
.
When using buildMessage('present')
I expect {key} can't be blank
.
When using buildMessage('blank')
I expect {key} must be blank
.
When using presence(true)
the message says{key} must be blank
.
On these lines the type
that is returned when the value is blank is blank
. In the new mapping blank
points to the correct message. However, the logic flips the type to present
which is the wrong message.
When using buildMessage('present')
I get {key} must be blank
.
When using buildMessage('blank')
I get {key} can't be blank
.
Latest Master starting at #126
From the Docs and existing behavior the buildMessage
function should have a signature like this:
buildMessage(key, type, value, context = {})
.
On this line the signature made a backwards incompatible change and now looks like this: buildMessage(key, result)
.
Is the next release intended to bump the major version? If not, any apps relying on buildMessage
will be broken.
Maybe if the underlying model is a DS.Model
, we can check and enforce type as a validator
Hello,
I know you won't answer questions, but I tought it would be good to share this. I stumbled upon an issue with validateFormat using regex when trying to check a boolean field. I suspect this simply cannot be used for boolean fields.
More info here:
Maybe this should be stated more clearly in the docs?
Thanks and keep up the good work!
Given the following Ember.Object:
Ember.Object.create({
title: 'Hello',
contactNumber: {
type: '07594378348',
number: ''
}
})
How do I define validations to validate the contactNumber.number field?
{
title: validatePresence(true),
contactNumber: ... ?
}
Running ember-changeset-validations 1.2.4 and ember 2.10 / ember data 2.10.
My validation file looks like this and I was getting back the default case "is invalid" error message instead of the expected standard message for 'present':
import { validatePresence } from 'ember-changeset-validations/validators';
export default {
amount: validatePresence({ presence: true })
};
I went into the buildMessage function and logged values until I noticed that the return in this line for the get of the type from the messages object was undefined:
return formatMessage(get(messages, type), assign({ description }, context));
I also noticed on further logging values that the "messages" object held all of its values in an object in a "defaults" property. As soon as I added defaults the message was displaying properly:
return formatMessage(get(messages.defaults, type), assign({ description }, context));
Even then, while the standard message content is there, the "description" doesn't seem to be added to the beginning of the message, but it seems like it should be based on what I'm seeing in the messages.js (i.e. the description variable is made a part of the message there). That said, this appends the description to the front of what's returned in the buildMessage:
return formatMessage(description + ' ' + get(messages.defaults, type), assign({ description }, context));
Hi @poteto & others,
I am trying to have more than one validated-form in the page, for the same model, taking a changeset.
Different fields will be applicable for each form. But certain fields in one form, is a computed property of another form (the computed property is given in the model itself, so when we save / get, field is computed and received).
Since they are different forms, and each form creates a new model, the model is not updating the other form. Is there any way in which this can be achieved?
Please find this Twiddle for a similar demo.
Many thanks in advance!
Hi!, i can't make a customValidator that check two fields in the changeset. The current changeset is hidden from validator for any reason, or simply i don't find a way go get it?
I think my usercase isn't very strange, i have to date and time fields that needs to be coherent between them.
Does it make sense to have a validator similar to ember-cp-validations' ds-error validator? The main goal (for me) would be to consolidate the sources of error messages, but perhaps this would over-complicate the functionality intended here.
Otherwise, the user needs to manually handle ember-data (server) errors if changeset.save rejects.
Given a changeset reacts to changes, the default state is always valid until a change is made on each property.
Is there a way to force a validation to run on the entire changeset on construction?
e.g.
let model = {};
let validations = Ember.Object.create({
myKey: validatePresence(true)
});
let changeset = new Changeset(model, lookupValidator(validations), validations);
console.log(changeset.get('isValid')); // true, but the changeset is invalid
changeset.validate();
console.log(changeset.get('isValid')); // false, as expected
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.