-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First draft of validation binding for chip #9
base: master
Are you sure you want to change the base?
Changes from 1 commit
d491e42
cdca70a
40b8cf5
cf40e48
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
# ## validate-* | ||
chip.binding 'validate-*', (element,attr,controller) -> | ||
controller.parent.hasValidation = true | ||
controller.parent.validation = {} | ||
type = attr.camel | ||
# Initially tested for a validation object with typeof, but that felt too | ||
# rigid, so I simplfied it a bit. | ||
if attr.value.indexOf(':') < 1 | ||
# Loading options as an object passed from the controller | ||
options = controller.eval attr.value | ||
else | ||
# Attempt to parse options directly from validation attribute | ||
# We will probably need to spend more time working out the best format here | ||
# since passing an object string in the attribute isn't going to work. | ||
# | ||
# Currently using the following 'shortcode' for validation options: | ||
# option:value -e 'This is an optional message' | ||
# | ||
# Seperate options with | character (do not love this). | ||
options = {} | ||
optsArry = attr.value.split '|' | ||
for opt in optsArry | ||
optArry = opt.split ':' | ||
optionKey = optArry[0].trim() | ||
optionValMsg = optArry[1].split '-e' | ||
options[optionKey] = {} | ||
options[optionKey].value = optionValMsg[0].trim() | ||
options[optionKey].errorMessage = optionValMsg[1]?.trim() | ||
|
||
# maybe store custom validations to check validation type against | ||
# customValidations = {} | ||
|
||
# Some preset validations | ||
# Focusing less on the actual validations themselves and more on a way to | ||
# evaluate preset and custom validations since every app has different needs. | ||
# | ||
# When defining a validation rule, use the following: | ||
# {x} = field value, {y} = validation option value | ||
validations = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be great, maybe in a second pass, to have this at a more global level and add validations via There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup, that was the idea here. I left that there as a reminder, but would want it to be something set globally in your app config. |
||
all: | ||
required: | ||
evaluation: '{x} != ""' | ||
errorMessage: 'This is a required field.' | ||
text: | ||
minLength: | ||
evaluation: '{x}.length >= {y}' | ||
errorMessage: 'This field must be at least {y} characters long.' | ||
maxLength: | ||
evaluation: '{x}.length <= {y}' | ||
errorMessage: 'This field must be at most {y} characters long.' | ||
# numerical: | ||
# default: '{x}.match(/0-9/)' | ||
minValue: | ||
evaluation: '{x} >= {y}' | ||
errorMessage: 'This value must be greater than {y}.' | ||
maxValue: | ||
evaluation: '{x} <= {y}' | ||
errorMessage: 'This value must be less than {y}.' | ||
email: | ||
default: | ||
evaluation: '{y}.match(/@/)' | ||
errorMessage: 'Please enter a valid email address.' | ||
|
||
element.on 'change', -> | ||
value = element.val() | ||
validResponse = validateField(value,type,options) | ||
if validResponse.valid | ||
# Do some happy, positive things | ||
console.log 'Hey Slugger, you did it right!' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove the debugging code before merge. |
||
element.removeClass('chip_validation_invalid') | ||
element.addClass('chip_validation_valid') | ||
else | ||
# Scorch the earth with shameful red error messages | ||
console.log 'Nope, not even close. Here\'s where you went wrong, Sparky:' | ||
console.error validResponse.errorMsgs | ||
element.removeClass('chip_validation_valid') | ||
element.addClass('chip_validation_invalid') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps we can add an
|
||
controller.validation.valid = validResponse.valid | ||
controller.validation.errorMsgs = validResponse.errorMsgs | ||
|
||
validateField = (value,type,options) -> | ||
response = { | ||
valid:true | ||
message:'' | ||
errorMsgs:[] | ||
} | ||
|
||
validateVal = (validation) -> | ||
if validation.value? | ||
return validation.value | ||
else | ||
return validation | ||
|
||
validateMsg = (validation) -> | ||
if validation.message? | ||
return validation.message | ||
else | ||
return null | ||
|
||
isValid = true | ||
errorMsgs = [] | ||
for optionName, optionValue of options | ||
validation = validations[type][optionName] || validations.all[optionName] | ||
if validation? | ||
rule = validation.evaluation.replace('{x}','"' + value + '"') | ||
.replace('{y}',optionValue.value) | ||
if eval rule | ||
isValid = true; | ||
else | ||
isValid = false | ||
if validation.errorMessage | ||
errorMsgs.push validation.errorMessage.replace '{y}', | ||
optionValue.value | ||
else | ||
validation.errorMessage 'Input for this field is invalid.' | ||
else | ||
'validation missing' | ||
response.valid = true; | ||
console.warn 'Validation method: ' + optionName + ' not found!' | ||
response.valid = isValid | ||
response.errorMsgs = errorMsgs | ||
return response |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won't work for forms that have portions inside of partials, perhaps several deep, or forms that have repeating sections which create controllers for that section.
We'll need to have a binding at the form level that will create the validation object on that controller. Here we can throw an error if the validation object doesn't exist indicating that it must be created using
bind-validate
or whatever we call the aggregating binding.