patternjavascriptModerate
Custom JavaScript validation using the factory / module patterns
Viewed 0 times
thejavascriptfactorymodulevalidationpatternscustomusing
Problem
I am in the process of diving a bit deeper into JavaScript development and am looking at some common language patterns (module, and factory in particular). In this code, my aim is to create a re-usable framework for creating custom field validators in JS that can be easily extended. In addition, I want the code that does the validation to NOT have a big conditional logic block that needs to be maintained (for example:
The Factory allows new types of validators to be added to its registration at any point, provided they have a common prototype. The particular type of validator can then be instantiated by the factory by passing the name that was registered with that type.
I have segmented the code into separate files as I intend to be able to drop this into projects I'm working on, add any custom validation needed for the application, and move on.
The general flow of the UI is this:
For this project, I opted to use knockout.js as a MVVM framework for binding to the UI and making the form responsive.
The Code
I have the following HTML form (in its entirety):
```
JavaScript Validator
var model = new FormViewModel();
$(function() {
ko.applyBindings(model);
});
Form Status:
Validation Testing
First Name:
Last Name:
if(required) {} elseif(regex) {} elseif(numeric){}, etc....).The Factory allows new types of validators to be added to its registration at any point, provided they have a common prototype. The particular type of validator can then be instantiated by the factory by passing the name that was registered with that type.
I have segmented the code into separate files as I intend to be able to drop this into projects I'm working on, add any custom validation needed for the application, and move on.
The general flow of the UI is this:
- When the page first loads, the fields are empty. Because of this, (and the required validation), I have an initial state that prevents the page from showing errors on load.
- The KnockoutJS binding on the form fields triggers the field validation after each keystroke.
- If at any point the form is invalid, the field will be highlighted and a "validation summary" will be shown at the top, indicating the state of the form.
- Any validation errors will cause the form to be unable to submit
For this project, I opted to use knockout.js as a MVVM framework for binding to the UI and making the form responsive.
The Code
I have the following HTML form (in its entirety):
```
JavaScript Validator
var model = new FormViewModel();
$(function() {
ko.applyBindings(model);
});
Form Status:
Validation Testing
First Name:
Last Name:
Solution
This review is mostly about improving the implementation.
I don't know JavaScript enough to answer your big questions.
Try to catch @konijn or @flambino in the 2nd monitor chat room.
Naming
The first most noticeable thing to me is the naming of variables.
I think the convention is to use
and
JSHint
If you paste your code to http://jshint.com/,
it points out a couple of interesting issues, most notably:
Simplification
Although I'm against clever tricks that try to make the code super-compact,
I would shorten the code in a couple of places in a not yet too clever way.
Instead of this:
I would use a ternary operator:
Instead of this:
Why not simply:
Instead of this:
This is much better:
Instead of this:
This is better:
Coding style
The
I would also remove the unnecessary parentheses from around expressions like these:
I don't know JavaScript enough to answer your big questions.
Try to catch @konijn or @flambino in the 2nd monitor chat room.
Naming
The first most noticeable thing to me is the naming of variables.
I think the convention is to use
PascalCase for classes,and
camelCase for variables.JSHint
If you paste your code to http://jshint.com/,
it points out a couple of interesting issues, most notably:
- You have
CreateInstancetwice in the same object: the second will overwrite the first
- Parentheses
()missing when invokingValidProtoinvar protoInstance = new ValidProto;, and by the wayprotoInstanceseems to be unused
- A couple of other minor issues, do see it for yourself and correct all if possible
Simplification
Although I'm against clever tricks that try to make the code super-compact,
I would shorten the code in a couple of places in a not yet too clever way.
Instead of this:
if (self.IsValid()) {
return "";
} else {
return self.ValidationMessageFormat().replace("{0}", self.DisplayName());
} // end if/elseI would use a ternary operator:
return self.IsValid() ? "" : self.ValidationMessageFormat().replace("{0}", self.DisplayName());Instead of this:
var request = new types[type](args);
return request;Why not simply:
return new types[type](args);Instead of this:
if(!isNullOrWhiteSpace(data)) {
self.IsValid(true);
} else {
self.IsValid(false);
} // end if/elseThis is much better:
self.IsValid(!isNullOrWhiteSpace(data));Instead of this:
var oldClass = "";
if(newClass == "invalid") {
oldClass = "valid";
} else {
oldClass = "invalid";
} // end if/elseThis is better:
var oldClass = newClass == "invalid" ? "valid" : newClass;Coding style
The
// end if/else and such are indeed pretty annoying, as @JaDogg said, just noise in the code.I would also remove the unnecessary parentheses from around expressions like these:
return (val == null || val == undefined);
return (isNullOrUndefined(val) || val == "" || val.trim() == "");Code Snippets
if (self.IsValid()) {
return "";
} else {
return self.ValidationMessageFormat().replace("{0}", self.DisplayName());
} // end if/elsereturn self.IsValid() ? "" : self.ValidationMessageFormat().replace("{0}", self.DisplayName());var request = new types[type](args);
return request;return new types[type](args);if(!isNullOrWhiteSpace(data)) {
self.IsValid(true);
} else {
self.IsValid(false);
} // end if/elseContext
StackExchange Code Review Q#67458, answer score: 11
Revisions (0)
No revisions yet.