Ensuring data is saved on multiple forms using ui-router in AngularJS

Implementation Details:

I'm currently utilizing ui-router to load a form page in a ui-view div. I found an excellent example by Andres Ekdahi. My question is, how can I perform a $dirty check on multiple forms using the same directive?

Form 1

 <form name="myForm" ng-controller="Controller" confirm-on-exit>

Form 2

<form name="iForm" ng-controller="Controller" confirm-on-exit ng-model="myModel">

app.js (directive)

myApp.directive('confirmOnExit', function() {
        return {
            link: function($scope, elem, attrs) {
                // Condition when the back button is pressed 
                window.onbeforeunload = function(){
                    if ($scope.myForm.$dirty) {
                        return "The formI is dirty, do you want to stay on the page?";
                    }
                }
                // Conditional statement when a user tries to load another form (via icons)
                $scope.$on('$stateChangeStart', function(event, next, current) {
                    if ($scope.myForm.$dirty) {
                        if(!confirm("MyForm. Do you want to continue?")) {
                            event.preventDefault();
                        }
                    }

                    if ($scope.iForm.$dirty) {
                        if(!confirm("iForm. Do you want to continue?")) {
                            event.preventDefault();
                        }
                    }
                });
            }
        };
    });

Error:

Upon initial page load, the $dirty value is false. After filling out the form details and clicking on the third icon (file), I encountered an error regarding the second form's dirty check if ($scope.iForm.$dirty), along with an issue relating to $dirty in the alert.

angular.js:12520 TypeError: Cannot read property '$dirty' of undefined

and

<form name="iForm" ng-controller="Controller" confirm-on-exit="" ng-model="myModel" class="ng-pristine ng-untouched ng-valid ng-scope">

Demo: Plunker

Answer โ„–1

Discover a more straightforward approach.

All you need to do is specify that your directive must be placed on a form element and then access the form controller within the link function:

myApp.directive('confirmOnExit', function() {
        return {
            require: 'form',
            link: function($scope, elem, attrs, formController) {
                // determine what happens when the back button is pressed 
                window.onbeforeunload = function(){
                    if (formController.$dirty) {
                        return "The form '" + formController.$name + "' has unsaved changes. Do you wish to leave this page?";
                    }
                }
                // handle situation where user tries to navigate away from current form (e.g. via icons)
                $scope.$on('$stateChangeStart', function(event, next, current) {
                    if (formController.$dirty) {
                        if(!confirm(formController.$name + ". Do you want to continue ?")) {
                            event.preventDefault();
                        }
                    }
                });
            }
        };
    });

Answer โ„–2

Streamline your directive by extracting it from the name attribute of the form, allowing for a single condition within the directive and making it easily reusable in multiple locations.

<form name="myForm" ng-controller="Controller" confirm-on-exit>

Code

var form = $scope[attrs.name]; //Retrieves the form name from the name attribute and searches for it within the scope
if (form.$dirty) { //Ensures that the form object exists before proceeding to the next check
    if(!confirm("myForm. Do you want to continue ?")) {
        event.preventDefault();
    }
}

View Demo

Answer โ„–3

Make sure to always check for the existence of the form before checking if it is dirty. Here's an example:

if ($scope.myForm && $scope.myForm.$dirty) {
    if(!confirm("myForm. Do you want to continue ?")) {
        event.preventDefault();
    }
}

if ($scope.iForm && $scope.iForm.$dirty) {
    if(!confirm("iform. Do you want to continue ?")) {
        event.preventDefault();
    }
}

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

Why isn't PHP's rawurlencode the same as JavaScript's escape function?

When I use urlencode or rawurlencode in PHP to encode the simple character ยง (paragraph), the result is "%C2%A7". However, using escape in JavaScript only produces "%A7". This creates encoding issues when transferring data between a PHP server and a JavaS ...

The ng-change directive is used on a dropdown to modify the styling of another HTML element

I need the icon to the left of the input in my HTML form to change based on whether the user selects male or female. However, I am facing an issue where when switching from nothing to female, the icon does not update immediately (even though the ng-change ...

Creating a hover effect for displaying image masks

My website features a profile page displaying the user's photo. I am attempting to create a functionality where when the user hovers over their photo, a transparent mask with text appears allowing them to update their profile picture via a modal. How ...

How come I am able to send back several elements in react without the need to enclose them in a fragment

This piece of code is functioning properly in React, displaying all the names on the page. However, I am questioning why it is returning multiple elements as a React component. Shouldn't they be wrapped in a single fragment? function App() { const n ...

Tips for accessing nested array data using jQuery DataTables

Here is the JSON data I am working with: { "00100": { "claim_id": "21", "reference_no": "00100", "distributor_name": "Standard Match", "group_name": "A", "month": "Jun2017", "grand_total": "268.532", "details": [ { ...

What steps can be taken to address the issue of two components loading simultaneously?

While implementing page transitions with react-router-dom and react-spring's useTransitions, I encountered some bugs despite the transition animation working well. I believe CSS might help resolve these issues, but I am unsure about the exact approach ...

Is the connection and callback order incorrect in Node.js and MQTT?

As I explore using the mqtt package for nodejs, I keep coming across code samples like the one below: const mqtt = require('mqtt') const client = mqtt.connect('mqtt://test.mosquitto.org') client.on('connect', function () { ...

What is the best way to combine two JavaScript functions into a single function, especially when the selector and function to be invoked may differ?

In the provided snippet, I am using the following function callers: // del if ( maxDelivery > 0 ) { if ( maxDelivery === 1 ){ delAdressFunc( dels ); } else { for ( i = 0; i < maxDelivery; i += 1 ){ delAdressFunc( ...

Testing Restful API Endpoints and Code Coverage with Node.js using Mocha

My time in Istanbul has been delightful, and I've been dabbling in different Node.js coverage libraries. However, I'm facing a challenge. Most of my unit tests involve making HTTP calls to my API, like this: it('should update the custom ...

Access data from previous request and transmit it to another request in a Node.js environment

I am facing a situation where I need to extract the parsed json response from a variable in a POST request, store it in a new variable, and then pass that variable in the headers for a subsequent GET request. However, my current approach is not yielding th ...

Only switch a radio button when the Ajax call results in success

Within an HTML form, I am working with a group of Radio buttons that trigger an Ajax call when the onchange() event is fired. This Ajax call communicates with the server to process the value sent by the call. The response can either be a string of "succes ...

Achieving Style= Background-Img URL Extraction with Cheerio

I am attempting to retrieve the URL of the background image. The background image is located within an a href tag. The a href tag contains the following style: style="background-img:url("")" I am using cheerio (a Node.js module simila ...

The children prop in React Typescript is specified in the props type, but for some reason it is not being

I am currently developing a component library using a combination of React, TypeScript, Styled Components, and Rollup. One of the components I have created is a Button component, defined using a type interface. After rolling up the library and importing th ...

Enhancing the Security of Spring Rest Services: A Guide to Implementing Spring Security with AngularJS

I currently have a setup with a Spring MVC Server Backend hosting Rest-Services and an AngularJS WebFrontend. I'm looking to enhance the security of my spring mvc rest services, but I want to implement it using Java config. However, I am unsure about ...

Prevent popup content from refreshing: Tips for creating a dynamic user experience

Currently, I am working on a website that is similar to Facebook. One of the features I am implementing is the ability for users to like posts or photos and see who has liked them. However, I am facing an issue with the popup that shows the list of people ...

Refreshing a page in Next.js causes query parameters to disappear

I am facing an issue with routing between two components and passing data from the first to the second without sending the parameter in the URL. The problem arises when I refresh the page and the query params are lost. <p className={styles.jobname}& ...

Tips for enabling autocomplete in ASPX using the original page request exclusively

Currently, our team is working on a project involving an ASPX (.NET 2.0) page with a select list that contains over 200 elements. We are in need of autocomplete functionality to transform this select list into a user-friendly text box with auto-suggestion ...

Error: The property '...' is not found in the ReactElement<any, any> type, but it is required in the type '{...}'

As a beginner in TypeScript, I am currently working on rendering a page by fetching data from getStaticProps. The code snippet I am using for this purpose is: import React, {FormEvent, useState} from "react"; import { InferGetStaticPropsType } fr ...

Is it possible to create dynamic tabs using Bootstrap on .aspx pages?

I am facing an issue with my code. I have written a JavaScript function that enables moving to the next tab when clicking on tabs, but I also want to move to the next tab when clicking on a specific button. The script works as expected, except for one prob ...

Unable to generate dynamic HTML through AJAX request

I made an Ajax API call and received the response in JSON format. I need to create dynamic HTML to display each value in HTML elements. I tried getting the response from the API but couldn't generate the HTML. Can someone assist me with this? Also, I ...