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

Guide on effectively sending a secondary parameter in an ajax request

Struggling to implement a year/make/model multi-select feature, I have managed to get the scripts working. However, what appears to be missing is the ability to pass both a year and make variable together in order to fetch the final model results. Below a ...

Adjusting the settimeout delay time during its execution

Is there a way to adjust the setTimeout delay time while it is already running? I tried using debounceTime() as an alternative, but I would like to modify the existing delay time instead of creating a new one. In the code snippet provided, the delay is se ...

Issue with JSON or Jquery: Uncaught error message: Cannot access property 'error' as it is null

I am attempting to initiate an ajax call using the jQuery code provided below. However, when I try this in Chrome, I encounter an error that says 'uncaught typeerror cannot read property 'error' of null'. This prevents the preloader fr ...

Using the class for jQuery validation as opposed to the name attribute

I am looking to implement form validation using the jquery validate plugin, but I am facing an issue with using the 'name' attribute in the html since it is also used by the server application. Specifically, I want to restrict the number of check ...

What is a global variable used for in JavaScript?

Here is the code snippet that I am currently working on: $(".link").each(function() { group += 1; text += 1; var links = []; links[group] = []; links[group][text] = $(this).val(); } ...

An error occurred while trying to update with Webpack Dev Server: [HMR] Update failed due to an issue fetching the update manifest,

I encountered an issue in the browser console while attempting to live reload / HMR on Webpack. The error arises after saving a file following a change. [HMR] Update failed: Error: Failed to fetch update manifest Internal Server Error Could the failure b ...

Exploring the world of Node.js and the power of 64-bit var

Currently, I am developing a Node.js application that communicates via TCP with a C++ server. The server utilizes a binary protocol similar to Protocol Buffers but not identical. One of the data types returned by the server is an unsigned 64-bit integer ( ...

Tips on altering a predetermined input text value using JavaScript

I have a question about using JavaScript. I am currently developing a tax calculation system. function calculateTax(){ var invoiceValue = document.getElementById("invoicevalue"); var ppn = document.getElementById("ppn"); var pph = document.get ...

Sending a 2-dimensional array from JavaScript to the server using AJAX

My JavaScript code involves working with a 2D array. var erg = new Array(); for (var i in val) { erg[i] = new Array(); for (var j in val[i]()) { erg[i][j] = val[i]()[j](); } } However, I encountered an issue where only the 1D array ...

Node.js - Hitting maximum call stack size limit despite using process.nextTick()

I am currently developing a module for creating "chainable" validation in Express.js: const validatePost = (req, res, next) => { validator.validate(req.body) .expect('name.first') .present('This parameter is required') ...

Is it possible to retrieve the current CSS value set by a media query using JavaScript?

Currently working on a website project that involves accessing and manipulating the display property of a menu. The goal is to toggle the menu open or closed based on its current state. In my setup, the initial state of the menu is defined as closed using ...

repeated firing of keydown event in ReactJS

Having an issue with adding an event listener and checking if it's level 1. When I press the space key once, it seems to fire more than 50 times. Any assistance would be greatly appreciated. document.addEventListener("keyup", function(e) { if(l ...

Troubleshooting: MongoDB/mongoose post save hook does not execute

My current setup involves the following model/schema: const InvitationSchema = new Schema({ inviter: {type: mongoose.Schema.Types.ObjectId, ref: 'Account', required: true}, organisation: {type: mongoose.Schema.Types.ObjectId, ref: 'Orga ...

Every Dynamic Post automatically defaults to the initial object

I am currently developing an app that retrieves feeds from a Wordpress site and displays individual posts in a jQuery mobile list format. Here is the JavaScript code I am using: $(document).ready(function () { var url = 'http://howtodeployit.com/ ...

The server has sent cookies headers, however, the browser did not store the cookies

I need assistance in understanding why browsers such as Chrome are not setting cookies, even though the Set-Cookie header is present in the Response Headers: Access-Control-Allow-Origin: * Connection: keep-alive Content-Length: 345 Content-Type: applicati ...

Tips for modifying the value of a JSON object using Javascript or Jquery

I am looking to retrieve the value of a specific key, potentially accessing nested values as well. For example, changing the value of "key1" to "value100" or "key11" to "value111. { "key1": "value1", "key2": "value2", ...

What is the reason behind the non-linear execution sequence of JS functions when controlling an sqlite3 database?

In my Node.js application, I have a SQLite3 controller function like this: exports.findUser=function findUser(user){ var temp ; var db = new sqlite3.Database('kitchen.db'); var stmt_user_find = "SELECT * FROM user WHERE un = ?"; db.all(stmt_user ...

Update the displayed image on the webpage based on information retrieved from the database

Can someone help me figure out how to change the clickable icon on getseats.php from available to unavailable when a seat's status is 0? I'm struggling with this and any advice would be appreciated. Here's the code I have: <?php $noerro ...

Utilizing the v-for directive to loop through JSON data with unique IDs and linking them to Input components in PrimeVue

In my database, I have a collection of products with a column named attributes that stores property/value pairs in JSON format. Each product can have unique attributes. For instance, one product's attributes could be: #product1 attributes { color: & ...

The issue of React Js's inline style malfunctioning when using a loop condition

Having some trouble with setting different backgrounds for items in a loop in React JS. I attempted to use inline styles to make it dynamic, but no luck so far. Any tips or solutions? { main.map((item, index) => ( <a key={index} href=&apo ...