How to reset a form in AngularJS using either HTML or a built-in directive

Within a standard modal popup in Bootstrap, I have implemented a form consisting of input fields, a submit button, a cancel button, and a close-icon. When selecting the name from an Object data-list using ng-repeat, the popup containing the form will display.

The following scenarios are present:

  • Validation can be performed on the input fields by entering valid data and then clicking Submit. No problems encountered
  • If one chooses to click Cancel or the close icon without entering any value in the input fields, there are no issues.

  • Entering invalid data into the input fields and clicking Submit has been handled appropriately. No concerns

  • If invalid data is entered and then Cancel or the close icon is clicked, this presents an issue.

The final scenario highlights the existing issue:

In the case where the first element from ng-repeat is clicked, the form loads within the popup. If the user closes the modal when the form contains errors, upon reopening, the form does not reset. This project uses 'controller as' instead of $scope, so $scope.formName.$setPristine() cannot be utilized from the controller directly.

A common way to reset the form would usually involve using the $scope in the controller but I am seeking an alternative method utilizing HTML and directives like ng-init.

EDIT 1:

As requested, I have included the code snippet along with a demonstration link: [https://jsfiddle.net/shashank2691/0k496jyd/](https://jsfiddle.net/shashank2691/0k496jyd/)

Note: In the demo example, upon clicking Submit in the popup, errors are displayed for invalid input fields.

Expected:

Upon closing and reopening the popup after initially opening it (with invalid form data), errors should not be displayed unless the fields are still invalid and the Submit button is pressed.

Actual:

When reopening the popup for the second time, errors beneath the invalid input fields are displayed once more.

HTML:

<div ng-app="app" ng-controller="test as ctrl">
  <h4 class="lead" align="center">
Popup Display
</h4>
  <div class="row">
    <div ng-repeat="item in ctrl.dataList" class="col-xs-6 form-group" align="center">
      <div class="img-thumbnail pointer" ng-click="ctrl.openPopup(item)" data-toggle="modal" data-target="#testPopup" data-backdrop="static">
        <span>{{item.name}}</span>
      </div>
    </div>
  </div>


  <div id="testPopup" role="dialog" class="popup-modal-section modal fade">
    <div class="modal-dialog">
      <div class="modal-content">
        <div class="modal-body">
          <form name="inputForm.form" novalidate ng-submit="ctrl.saveData(inputForm.form.$valid, ctrl.selected);">
            <h3 class="lead" align="center">
Profile Details:
</h3>
            <div class="form-group">
              <div>
                <label>Name</label>
              </div>
              <div>
                <input type="text" class="form-control" ng-model="ctrl.selected.name" name="name" ng-required="true" />
                <span class="error" ng-show="(inputForm.form.name.$error.required || inputForm.form.name.$invalid)">Name is required</span>
              </div>
            </div>

            <div class="form-group">
              <div>
                <label>City</label>
              </div>
              <div>
                <input type="text" class="form-control" ng-model="ctrl.selected.city" name="city" ng-required="true" />
                <span class="error" ng-show="(inputForm.form.city.$touched &&  inputForm.form.city.$error.required) || (inputForm.form.$submitted &&     inputForm.form.city.$error.required)">City is required</span>
              </div>
            </div>

            <div align="right">
              <button class="btn btn-primary" type="submit">
                Submit
              </button>
              <button class="btn btn-default" data-dismiss="modal">
                Close
              </button>
            </div>
          </form>
        </div>
      </div>
    </div>
  </div>
</div>

JS:

var app = angular.module('app', []);

app.controller('test', function() {
  var vm = this;
  vm.dataList = [{
    "id": "0",
    "name": "Pankaj M."
  }, {
    "id": "1",
    "name": "Rakesh G."
  }, {
    "id": "2",
    "name": "Piyush C."
  }, {
    "id": "3",
    "name": "Danny K."
  }];

  vm.openPopup = function(data) {
    vm.selected = angular.copy(data);
  };

  vm.saveData = function(isValid, data) {
    console.log('Form Valid ', isValid);
  };
});

CSS:

.pointer {
  cursor: pointer;
}

.error {
  color: red;
}

Demonstration available at: [https://jsfiddle.net/shashank2691/0k496jyd/](https://jsfiddle.net/shashank2691/0k496jyd/)

Answer №1

One issue arises when utilizing the Twitter Bootstrap modal since it utilizes the same HTML template for all modal instances, which may not be desirable.

An optimal solution would involve eliminating Twitter Bootstrap (along with jQuery) as they are unnecessary. Instead, a specialized Angular directive such as the UI Bootstrap $modal service would be recommended.

This approach results in a more angular-centric design rather than relying heavily on jQuery.

Controller:

var app = angular.module('app', ['ui.bootstrap']);

app.controller('test', function($uibModal) {
  var vm = this;
  vm.dataList = [{
    "id": "0",
    "name": "Pankaj M."
  }, {
    "id": "1",
    "name": "Rakesh G."
  }, {
    "id": "2",
    "name": "Piyush C."
  }, {
    "id": "3",
    "name": "Danny K."
  }];

  vm.openPopup = function(data) {
    $uibModal.open({
      bindToController: true,
      controllerAs: 'ctrl',
      templateUrl: 'profile.html',
      resolve: {
        user: angular.copy(data)
      },
      controller: function(user) {
        this.selected = user;
      }
    }).result
    .then(function(updated) {
      vm.saveData(data, updated);
    })
  };

  vm.saveData = function(data, updated) {
    angular.extend(data, updated);
    console.log('Form Valid', data);
  };
});

Modal HTML:

<div class="modal-body">
  <form name="inputForm.form" novalidate="" ng-submit="inputForm.form.$valid && $close(ctrl.selected)">
    <h3 class="lead text-center">Profile Details:</h3>
    <div class="form-group">
      <div>
        <label>Name</label>
      </div>
      <div>
        <input type="text" class="form-control" ng-model="ctrl.selected.name" name="name" ng-required="true" />
        <span class="error" ng-show="(inputForm.form.name.$error.required || inputForm.form.name.$invalid)">Name is required</span>
      </div>
    </div>
    <div class="form-group">
      <div>
        <label>City</label>
      </div>
      <div>
        <input type="text" class="form-control" ng-model="ctrl.selected.city" name="city" ng-required="true" />
        <span class="error" ng-show="(inputForm.form.city.$touched &&  inputForm.form.city.$error.required) || (inputForm.form.$submitted && inputForm.form.city.$error.required)">City is required</span>
      </div>
    </div>
    <div align="right">
      <button class="btn btn-primary" type="submit">Submit</button>
      <button class="btn btn-default" type="button" ng-click="$dismiss()">Close</button>
    </div>
  </form>
</div>

Demo: http://plnkr.co/edit/NuOWdDHzDiN2hszB5u4P?p=info

Answer №2

Based on your explanation, it seems like there may be a scope issue with the form. One way to resolve this is by passing the form into the submit or close function and then calling pristine within that function. Here's an example:

$scope.submit=function(form){
  form.$setPristine();
}

Alternatively, you can avoid this issue by creating an object in your controller and assigning the form as a property of that object. Like so:

$scope.formObject={};

In your HTML, use dot notation for the form name like this:

<form name="formObject.test_form">
 ...
</form>

If possible, it would be helpful if you could provide your code for further assistance.

Answer №3

There are multiple ways to achieve this:

  1. You can create a reset method for your form model and trigger it when your modal is closed:

function TestCtrl($scope) {
  $scope.initModel = function() {
    $scope.fields = {
      "something": "INITIAL VALUE"
    };
  };
  
  $scope.initModel();
}
angular
  .module('test', [])
  .controller('TestCtrl', ['$scope', TestCtrl])
;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<section ng-app="test">
  <article ng-controller="TestCtrl">
    <form name="test" ng-submit="onSubmit($event, test)">
      <input ng-model="fields.something" type="text" />
    </form>
  </article>
</section>

  1. Another approach is to create a specific application state for the form, allowing you to call a $location change and re-instantiate each bound controller (an example would get too complex here, but feel free to ask for more details if needed).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering a TypeError when attempting to read the property 'name' of undefined while submitting a form in node.js

I'm currently working on a node Js project and I'm encountering an issue while saving form values to a mongoDB database. I've been troubleshooting but can't seem to pinpoint the cause of this error. The error is occurring at the router. ...

Displaying random divs and subsequently animating them downwards using JavaScript

I am in the process of creating a random appearing div that then falls down. Here is the code I have so far: $(document).ready(function(){ $('#test').animate({top: 80 + '%'},900); }); <div id="test" style="background:#98bf21;heigh ...

The function service.foo is not recognized in Angular

My service function is not being recognized by my component import { Injectable } from '@angular/core'; import { ToastController } from '@ionic/angular'; @Injectable({ providedIn: 'root' }) export class LocationService { ...

An error was encountered stating "TypeError: Unable to call function on undefined object while attempting to utilize a JSON object

My current setup involves using D3js with MongoDB and AngularJS to showcase my data. Everything works smoothly until I decide to give my JSON array a name. Suddenly, Angular starts throwing errors at me and I'm left confused as to why. Here is the or ...

Maximizing values entered into form fields

Looking for a way to extract the highest number from a set of input fields in an HTML form using JavaScript? Take this example: <input id="temp_<strong>0</strong>__Amount" name="temp[<strong>0</strong>].Amount" type="text" valu ...

Is there a chance of a race condition occurring during file uploads when processed individually through AJAX with PHP?

I have created a form for uploading multiple files. <form id="myuploadform" enctype="multipart/form-data"> <input id="uploadedFiles" name="uploadedFiles" type="file" class="form-control&qu ...

Dynamic scrolling text for overflowing text display

Here's a scenario I'm facing: Let's say I have three div tags, each 100 pixels wide: <--- DIV WIDTH ---> Text in div 1 Text in div two, it overflows Text in div three <--- DIV WIDTH ---> Currently, I've set the following C ...

Having difficulty accessing a JSON imported object beyond the FOR loop

I am facing an issue when trying to reference my imported JSON data. The problem arises when I attempt to access the data outside of a FOR loop, resulting in the error message "Uncaught TypeError: Cannot read property 'Tname' of undefined" The f ...

Using AngularJS location.path for unique custom URLs

Control Code: $scope.$on('$locationChangeStart', function () { var path = $location.path(); var adminPath = '/admin/' ; if(path.match(adminPath)) { $scope.adminContainer= function() { return true; }; }); HTML <div clas ...

Add a new item to an array in Angular 2 when a click event occurs

I'm trying to add a new list item (which comes from an API) when a button is pressed, but I'm not sure how to do it. Can anyone provide some guidance? Here's the code: <ul> <li *ngFor="let joke of jokes">{{joke.value}}</li> ...

Is the integer value included in the linear progression?

I have a unique setup where each time the user clicks a 'Done' button, 20 is added to a base number, x (..-40,-20,0,20,40,60..). This updated value of x is then saved in a database and displayed in real-time using Ajax. However, I am facing a ch ...

A mysterious JavaScript snippet that automatically scrolls down when the webpage is loaded

Recently, I encountered an issue with a mysterious JavaScript script that automatically scrolls down when entering the page (I suspect it's JavaScript). I've tried to investigate using Firebug, examining the code, deleting scripts, and even remov ...

node.js: The Yahoo weather jQuery plugin fails to display any data

After successfully implementing node.js with jQuery and the plugin from , I now aim to utilize the weather data for a different purpose rather than directly inserting it into the HTML. However, I am encountering difficulties in accessing or displaying the ...

Stop options from being hidden in a select dropdown using HTML

Can I keep the options visible when a user selects an item in the 'select' dropdown? I want to add more options to the 'select' when the user clicks on the 'op2' item, without closing the list of options. <select> <o ...

Array updating using the foreach method in Angular

Hey everyone, I've encountered an error that seems to be related to scope and I could use some advice. I'm currently looping through an array and trying to push the results to another array. However, when I attempt to push the results to public m ...

Disposing of memory in THREE JS when switching between routes in VUE

Currently, I am delving into the world of VUE JS and working on a basic SPA that navigates through different pages. In my spare time, I have developed several THREE JS demos which unfortunately tend to slow down and eventually halt when switching between ...

Sundays and last days are excluding React-big-calendar and dayjs longer events from being displayed

I've encountered a bug in my calendar view implementation. Long events are not displaying on Sundays or the ending day. Please refer to this image for reference: https://i.stack.imgur.com/V0iis.png Event details: Start time: Mon Aug 07 2023 15:44:00 ...

Converting the length attribute of a table to a string does not yield any

After grappling with this bug for some time now, I've come up empty-handed in my search for a solution online. Expected Outcome: Upon pressing the create row button, I anticipate a new row being added at the bottom of the table. This row should cons ...

Providing the module with the URL

How can I retrieve the URL within a module? module.exports = function(app, Reviews, Anon, User, url){ var url = url; console.log("url", url)// url is undefined how to get url function postHandler(req, res){ } app.post("/individual/"+ u ...

Is the validity of the expression !args.value || args.value.length true?

After analyzing this segment of code, I noticed an interesting expression: !args.value || args.value.length For instance, consider the following scenario: let v = {}; console.log(!v.value); //outputs true console.log(v.value); //outputs undefined con ...