angular-validation icon indicating copy to clipboard operation
angular-validation copied to clipboard

reset method

Open enesaltinok opened this issue 9 years ago • 9 comments

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?

enesaltinok avatar Jan 06 '16 09:01 enesaltinok

@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 avatar Jan 06 '16 09:01 hueitan

@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?

hueitan avatar Jan 06 '16 09:01 hueitan

  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

hung-doan avatar Jan 11 '16 04:01 hung-doan

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.

hueitan avatar Jan 11 '16 04:01 hueitan

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.

hung-doan avatar Jan 11 '16 06:01 hung-doan

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

hueitan avatar Jan 11 '16 06:01 hueitan

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.

hung-doan avatar Jan 14 '16 07:01 hung-doan

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);

j-langlois avatar May 28 '16 14:05 j-langlois

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"/>

stefanmonkey avatar Jun 30 '17 10:06 stefanmonkey