Skip to content
Merged
Prev Previous commit
Next Next commit
Only clean model if the form's condition is no longer satisfied. This…
… prevents the form from wiping itself when a $destroy event occurs that is not connected to the condition logic (such as if the FormController contains an element that wraps the form with an ng-if).
  • Loading branch information
jbsaff committed May 1, 2015
commit 45683370a06204e39c73ee19229d8ced1c845394
77 changes: 41 additions & 36 deletions src/directives/schema-validate.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
angular.module('schemaForm').directive('schemaValidate', ['sfValidator', 'sfSelect', 'sfUnselect',
function(sfValidator, sfSelect, sfUnselect) {
angular.module('schemaForm').directive('schemaValidate', ['sfValidator', 'sfSelect', 'sfUnselect', '$parse',
function(sfValidator, sfSelect, sfUnselect, $parse) {

return {
restrict: 'A',
Expand Down Expand Up @@ -128,48 +128,53 @@ angular.module('schemaForm').directive('schemaValidate', ['sfValidator', 'sfSele
// Default behavior can be supplied as a globalOption, and behavior can be overridden in the form definition.
scope.$on('$destroy', function() {
var form = getForm();
var conditionResult = $parse(form.condition);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was looking through the code and testing some, and I'm not quite sure why we need to check on the condition here? Shouldn't we always just follow the destroy strategy if we get a destroy event? I'm thinking that condition might not be the only thing that can remove a form element from the form, any other add on might use a ng-if somewhere and since any field not in the DOM won't get any validation done on it anyways It's probably best to remove it from the model.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had left it in as a way to help show where I was coming from with my solution, because I wasn't 100% confident that the service I put in would be correct (I'd still label myself an apprentice with Javascript). Assuming that the flag will handle for the case where the destroy is coming from outside of the form, then I agree that destroys initiated within the form should just follow the destroyStrategy. It'll be more consistent (and still configurable) and easier to explain.

console.log(conditionResult(scope));

// Either set in form definition, or as part of globalOptions.
var destroyStrategy =
!form.hasOwnProperty('destroyStrategy') ? DEFAULT_DESTROY_STRATEGY : form.destroyStrategy;
var schemaType = getSchemaType();
if (form.hasOwnProperty('condition') && !conditionResult(scope)) { // If condition is defined and not satisfied.

if (destroyStrategy && destroyStrategy !== 'retain' ) {
// Don't recognize the strategy, so give a warning.
console.warn('%s has defined unrecognized destroyStrategy: \'%s\'. Used default instead.',
attrs.name, destroyStrategy);
destroyStrategy = DEFAULT_DESTROY_STRATEGY;
}
else if (schemaType !== 'string' && destroyStrategy === '') {
// Only 'string' type fields can have an empty string value as a valid option.
console.warn('%s attempted to use empty string destroyStrategy on non-string form type. ' +
'Used default instead.', attrs.name);
destroyStrategy = DEFAULT_DESTROY_STRATEGY;
}
// Either set in form definition, or as part of globalOptions.
var destroyStrategy =
!form.hasOwnProperty('destroyStrategy') ? DEFAULT_DESTROY_STRATEGY : form.destroyStrategy;
var schemaType = getSchemaType();

if (destroyStrategy === 'retain') {
return; // Valid option to avoid destroying data in the model.
}

destroyUsingStrategy(destroyStrategy);
if (destroyStrategy && destroyStrategy !== 'retain') {
// Don't recognize the strategy, so give a warning.
console.warn('%s has defined unrecognized destroyStrategy: \'%s\'. Used default instead.',
attrs.name, destroyStrategy);
destroyStrategy = DEFAULT_DESTROY_STRATEGY;
}
else if (schemaType !== 'string' && destroyStrategy === '') {
// Only 'string' type fields can have an empty string value as a valid option.
console.warn('%s attempted to use empty string destroyStrategy on non-string form type. ' +
'Used default instead.', attrs.name);
destroyStrategy = DEFAULT_DESTROY_STRATEGY;
}

function destroyUsingStrategy(strategy) {
var strategyIsDefined = (strategy === null || strategy === '' || strategy === undefined);
if (!strategyIsDefined){
strategy = DEFAULT_DESTROY_STRATEGY;
if (destroyStrategy === 'retain') {
return; // Valid option to avoid destroying data in the model.
}
sfUnselect(scope.form.key, scope.model, strategy);
}

function getSchemaType() {
var sType;
if (form.schema) {
sType = form.schema.type;
destroyUsingStrategy(destroyStrategy);

function destroyUsingStrategy(strategy) {
var strategyIsDefined = (strategy === null || strategy === '' || strategy === undefined);
if (!strategyIsDefined) {
strategy = DEFAULT_DESTROY_STRATEGY;
}
sfUnselect(scope.form.key, scope.model, strategy);
}
else {
sType = null;

function getSchemaType() {
var sType;
if (form.schema) {
sType = form.schema.type;
}
else {
sType = null;
}
return sType;
}
return sType;
}
});

Expand Down