hueitan / angular-validation

[INACTIVE] Client Side Validation for AngularJS 1. (You should use version > 2 :boom:)
http://hueitan.github.io/angular-validation/
703 stars 176 forks source link

reset method #185

Open enesaltinok opened 8 years ago

enesaltinok commented 8 years ago

Hi,

Calling reset(form) method clears form field values. But I need the keep values. Is there any way keeping the values and clearing the error messages?

hueitan commented 8 years ago

@enesaltinok Thanks for raising up this question.

In general,

The HTMLFormElement.reset() method restores a form element's default values.

After the reset, we should keep the orignal values, if default value is not given, make the field empty.


But in the case, input with the attribute value="something", the reset method doesn't keep the original values.

again, thanks for reporting this.

hueitan commented 8 years ago

@Nazanin1369 @lvarayut see this.

http://stackoverflow.com/questions/10610282/angularjs-value-attribute-on-an-input-text-box-is-ignored-when-there-is-a-ng-m

seems given the default value in angularjs using native form value is not that easy.


Considering, should we use the attribute value for input in AngularJS?

hung-doan commented 8 years ago
  1. Current validation-reset must be named validation-clear because we clear the form, not reset it(restore to the original value).
  2. In my opinion, do not touch value input. Because It's already handled by AngularJs, just leave it alone.

Even if We can handle input attribute. It's almost impossible go get origin data when value attr and ng-model point to the same instance! . Because everything is async, We might don't know value is origin data or new inputted data

hueitan commented 8 years ago

I can't agree with you more.

But I prefer to stick with the reset not clear although we have the different behavior to the native Form.

Because people use reset more than clear in the Form term. In this situation, using AngularJS already breaks the original Form native behaviour, so we can't or hardly to make it back to the normal case.

I suggest, we should think more about, what is reset in AngularJS.

Or we should support - how to set the default value in angular-validation.

hung-doan commented 8 years ago

I prefer reset because It has the same behavior as native form (https://www.w3.org/wiki/HTML/Elements/input/reset) But I agree to stick with the reset because It will break current API if we change reset to clear.

I think the API would be :

<input ng-model="username" o-value ="username" />

We have to catch username value before it changed by user. => Define a watch on o-value

var watchDestructor = $scope.$watch($attrs.oValue,function(newVal, oldVal){ 
     if(typeof oldVal === 'undefined' && oldVal !== newVal)
     {
        //Update `defaultValue ` here
       document.querySelector('input[o-value="'+$attrs.oValue+'"]').defaultValue = newVal;
       watchDestructor();
     }
   });

Then, We just use inputElement.defaultValue to get origin data.

hueitan commented 8 years ago

@hungdoan2 This is a good idea :beers: what about the attribute name be original-value?

hung-doan commented 8 years ago

It's a good one. I often use "o-" prefix(stand for option) to define that: "this is an data attribute, not a directive". So, with me both original-value and o-value is fine.

j-langlois commented 8 years ago

hello friends, I haven't been here a while but if it might help anybody, I modified a bit of code to enable clearing the error messages. I've done this on 1.3.2 some time ago, hope I'm not forgetting anything

/**
 * clears the validation status for the specific form
 * @param form
 */
this.clear = function(form) {
  if (form === undefined) {
    console.error('This is not a regular Form name scope');
    return;
  }

  if (form.validationId) {
    $scope.$broadcast(form.$name + 'clear-' + form.validationId);
  } else if (form.constructor === Array) {
    for (var k in form) {
      $scope.$broadcast(form[k].$name + 'clear-' + form[k].validationId);
    }
  } else {
    for (var i in form) {
      if (i[0] !== '$' && form[i].hasOwnProperty('$dirty')) {
        $scope.$broadcast(i + 'clear-' + form[i].validationId);
      }
    }
  }
};
/**
 * Clears the validation for specific form
 */
scope.$on(ctrl.$name + 'clear-' + uid, function() {
  /**
   * clear scope.$watch here
   * clear the $watch method to prevent
   * $watch again while clearing the form
   */
  watch();

  $timeout(function() {
    ctrl.$setPristine();
    ctrl.$setValidity(ctrl.$name, undefined);
    ctrl.$render();
    if ($validationProvider.clearCallback) $validationProvider.clearCallback(element);
  });
});

In your controller:

var $validationProvider = $injector.get('$validation');
angular.extend($validationProvider, {
    // adapt to your success/error implementation
    clearCallback: function(element) {
        $(element).parents('.form-group:first').removeClass('has-success').removeClass('has-error');
        $(element).siblings('i.form-control-feedback').remove();
    }
});

And then when needed, call

$validationProvider.clear(form);
stefanmonkey commented 7 years ago

I just found a way to define o-value just use ng-model-options="{ getterSetter: true }"

like document write https://docs.angularjs.org/api/ng/directive/ngModel

JS:

$ctrl_1.form_scope = {
        checkValid: $validationProvider.checkValid,
        submit: function (form) {
            $validationProvider.validate(form)
                .success($ctrl_1.success(form))
                .error($ctrl_1.error);
        },
        reset: function (form) {
            $validationProvider.reset(form);
        },
        disable: function () {
            $ctrl_1.form_scope.disabled = true;
        },
        enable: function () {
            $ctrl_1.form_scope.disabled = false;
        },

        // default value
        hostname: function (newHostname) {
            // Note that newName can be undefined for two reasons:
            // 1. Because it is called as a getter and thus called with no arguments
            // 2. Because the property should actually be set to undefined. This happens e.g. if the
            //    input is invalid
            return arguments.length ? (serverInfo.hostname = newHostname) : serverInfo.hostname;
        },
        product_category: function (newProductCategory) {
            return arguments.length ? (serverInfo.product_category = newProductCategory) : serverInfo.product_category;
        }
    };

HTML:

<input type="text" class="form-control" name="hostname" placeholder="3" ng-model="$ctrl_1.form_scope.hostname" ng-model-options="{ getterSetter: true }" maxlength="30"
 ng-value="$ctrl_1.serverInfo.hostname" validator="required"/>