Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reset observable form fields Knockout

On my MVC project I have a View with 3 forms and one KO ViewModel.

On each form I have a reset button to clear its own fields.

I can't use input type="reset" because it doesn't update the observable values.

I can't either reset the View Model because that will reset all the observables of the View Model and I only need to reset the ones that are on the form that triggered the reset.

I can write 3 functions, one for each form and manually deleting each form fields like this:

this.onForm1Reset = function () {
    this.field1('');
    this.field2('');
    //etc..
}

this.onForm2Reset = function () {
    this.field3('');
    this.field4('');
    //etc..
}

this.onForm3Reset = function () {
    this.field5('');
    this.field6('');
    //etc..
}

But I'm looking for a more global and a shorter solution.

I made a lot of researches online but couldn't find a good solution for that.

Any help would be very much appreciated.

like image 427
user3378165 Avatar asked Feb 26 '26 17:02

user3378165


2 Answers

If you can group the forms' fields, you can use a with binding on each form to provide a different context to the form members, so the reset function (as a click handler) attached to a reset button will only be looking at the observables for its own form.

If you can't group the fields, a (less-preferred) possibility would be to run through the bound elements of the form containing the reset button, reset their values, and fire the change events for them. The commented-out code in my snippet would do that.

vm = {
    fieldset1: {
      field0: ko.observable(),
      field1: ko.observable()
    },
    fieldset2: {
      field2: ko.observable(),
      field3: ko.observable()
    },
    fieldset3: {
      field4: ko.observable(),
      field5: ko.observable()
    },
    reset: function(data) {
      for (var key in data) {
        if (data.hasOwnProperty(key)) {
          data[key]('');
        }
      }
    };

    ko.applyBindings(vm);

    /*
    $('body').on('click', '[type="reset"]', function() {
      $(this.parentNode).find('[data-bind*="value:"]').each((index, item) => {
        $(item).val('').change();
      });
    });
    */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<form data-bind="with: fieldset1">
  <input data-bind="value:field0" />
  <input data-bind="value:field1" />
  <input type="reset" data-bind="click: $parent.reset" />
</form>

<form data-bind="with: fieldset2">
  <input data-bind="value:field2" />
  <input data-bind="value:field3" />
  <input type="reset" data-bind="click: $parent.reset" />
</form>

<form data-bind="with: fieldset3">
  <input data-bind="value:field4" />
  <input data-bind="value:field5" />
  <input type="reset" data-bind="click: $parent.reset" />
</form>
like image 113
Roy J Avatar answered Mar 01 '26 07:03

Roy J


A more practical solution would be to contain your view-model in an observable, and re-create the model upon resetting:

function MyViewModel()
{
    this.field1 = ko.observable();
    this.field2 = ko.observable();

    // etc...
}

var model = {
    data: ko.observable(new MyViewModel()),
    reset: function() {
        model.data(new MyViewModel());
    }
};

ko.applyBindings(model);

And in your HTML:

<body data-bind="with: data">
    ...
    <button data-bind="click: $root.reset">Reset</button>
</body>

See Fiddle

Update (as per your comment):

Since you don't want to replace the entire view-model but only reset certain fields, I assume you'll have to introduce a reset() method to your model:

function MyViewModel()
{
    this.field1 = ko.observable();
    this.field2 = ko.observable();

    this.reset = function() {
        this.field1('');
        this.field2('');
    }.bind(this);
}

ko.applyBindings(new MyViewModel());

And in your HTML:

<button data-bind="click: reset">Reset</button>
like image 38
haim770 Avatar answered Mar 01 '26 06:03

haim770



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!