What is the best way to utilize the $('input').on('change', function() method within AngularJS?

I am working on creating a registration form page using AngularJS and I need to display the percentage completed. The form consists of over 50 fields, so I am looking for a simple way to implement this functionality.

Below is a snippet of the code I have written. I am not sure if this is the most efficient way to write it.

HTML Code

 <script src="angular/angular.js"></script>
 <html ng-app="myapp" ng-controller='profileController'>
 <form>
   First name: <input type="text" name="firstname" ng-model="nameValue" ng-click="percentageCount()"/><br>
   Last name: <input type="text" name="lastname" ng-model="lnameValue" ng-click="percentageCount()"/>
   Age: <input type="text" name="age" ng-model="ageValue" ng-click="percentageCount()" />
   Gender: <input type="text" name="gender" ng-model="genderValue" ng-click="percentageCount()"/>
   City:  <select name="txt_country" class="drop-down-box" id="country" ng-click="percentageCount()" ng-model="countryValue">
                        <option value="" selected="selected">Select Country</option>
                        <option value="United States">United States</option>
                        <option value="United Kingdom">United Kingdom</option>
                        <option value="Afghanistan">Afghanistan</option>
                        <option value="Albania">Albania</option>                    
                      </select>

</form>
<p>{{count}}% completed</p>
</html>

Script

<script>

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

myapp.controller('profileController', function ($scope,$http) 
{
    $scope.count = 0;
    $scope.percentageCount = function()
    {
        $scope.count = 0;

        if($scope.nameValue != null)
          $scope.count = $scope.count + 20;
        if($scope.lnameValue != null)
          $scope.count = $scope.count + 20;  
        if($scope.ageValue != null)
          $scope.count = $scope.count + 20;
        if($scope.genderValue != null)
          $scope.count = $scope.count + 20;   
        if($scope.countryValue != null)
          $scope.count = $scope.count + 20;       

    }

});

</script>

As you can see, there are many 'if' conditions in the script.

In JQuery, we could achieve this using:

$('input').on('change', function() 

I would like to know how to optimize this code in AngularJS for better efficiency.

Thank you for your help!

Answer №1

Finding a more efficient way to update the count without constantly recalculating and storing it in the scope can be achieved by binding the count directly to a function call within the template:

<p>{{ percentageCount() }}% completed</p>

myapp.controller('profileController', function ($scope,$http) {
    $scope.percentageCount = function() {
        var count = 0;

        if ($scope.nameValue != null)
          count += 20;
        if ($scope.lnameValue != null)
          count += 20;
        if($scope.ageValue != null)
          count += 20;
        if($scope.genderValue != null)
          count += 20; 
        if($scope.countryValue != null)
          count += 20;     

        return count;
    }
});

Angular will automatically update the page with the new value each time something triggers an event that changes the scope, as long as the result of the function has changed. This approach works well since the function is simple and fast.

If the calculation for each property follows a consistent rule (100 divided by the number of properties), you could optimize the function as shown below:

var props = ['nameValue', 'lnameValue', 'ageValue', 'genderValue', 'countryValue'];

$scope.percentageCount = function() {
        var count = 0;
        angular.forEach(props, function(prop) {
            if ($scope[prop]) {
                count += (100 / props.length);
            }
        });
        return count;
    }
});

Answer №2

Angular offers a variety of directives for fundamental DOM manipulation. When transitioning from the JQuery environment to AngularJS, it is advisable to always seek out an appropriate directive and avoid using JQuery altogether.

In this scenario, utilizing ng-change can achieve similar functionality as $('input').change()

Answer №3

Instead of binding event handlers to the inputs, monitor changes in the model. Keep an eye on all the model properties simultaneously so that your handler is only triggered once for a group of changes.

var attributes = ['nameValue', 'lnameValue', 'ageValue', 'genderValue', 'countryValue'];

$scope.$watchGroup(attributes, updateValues);

function updateValues() {
    var counter = 0;

    attributes.forEach(function(attribute) {
        if ($scope[attribute] != null) {
            counter += 20;
        }
    });

    $scope.counter = counter;
}

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

Tips for adjusting the current window location in Selenium without having to close the window

I am currently working with seleniumIDE My goal is to have a Test Case navigate to a different location depending on a condition (please note that I am using JavaScript for this purpose, and cannot use the if-then plugin at the moment). I have tried using ...

Encountering a console error: Prop type validation failed for the `Rating` component with the message that the prop `value` is required but is currently `undefined`

I am encountering a proptype error which is causing an issue with the URL display on my Chrome browser. Instead of showing a proper address, I am seeing the URL as undefined like this: http://localhost:3000/order/undefined Instead of undefined, I should h ...

Working with JSON data and extracting specific information within the grades

Here is a JSON data structure that contains information about a student named Alice and her grades in various courses: { "student": [{ "cert_id": "59826ffeaa6-b986fc04d9de", "batch_id": "b3d68a-402a-b205-6888934d9", "name": "Alice", "pro ...

Automatic session destruction in Laravel 5.1 when using AngularJS is a seamless process

Session in laravel 5.1 automatically ending My server side is Laravel and client side uses AngularJS. Even though I'm storing session data in root scope and window Storage for the front end, my application sometimes experiences random session destru ...

Discover the power of AngularJS dashboard templates

What is the best way to utilize free AngularJS Dashboard Templates that are available online? I have come across a variety of free angular dashboard templates. While they seem appealing, I am struggling to find detailed instructions on how to implement t ...

NodeJS parseStream, setting boundaries for chunk extraction from a stream

Struggling with parsing Node's filesystem. Below is the code snippet in question: var fs = require('fs'), xml2js = require('xml2js'); var parser = new xml2js.Parser(); var stream = fs.createReadStream('xml/bigXML.xml&ap ...

Angular: The issue with lazy-loading a decorator and how to solve it

How to Register a Decorator Synchronously angular .module('myApp') .decorator('$controller', MyDecorator); angular .module('myApp') .controller('MyCtrl', MyCtrl); Registering a Decorator Asynchronously $t ...

The function .classList.remove() is effective when applied to one element, but fails to work on a different element

I am facing an issue where only one element is getting affected when trying to remove classes from multiple elements if certain email input requirements are met. Can someone help me understand why this is happening? Here is the code snippet: const emailI ...

Eliminate elements from an array within a promise

I am facing an issue with the currentBillCyclePath parameter in the following function. I need to use this parameter to filter out certain elements after executing the query. However, inside the while loop, the value of currentBillCyclePath is undefined. ...

Can the site be shown in the background?

I have a unique idea for a games website that I want to share. It's a bit difficult to explain, so please bear with me as I try to convey my vision! The inspiration for this project comes from a website called . Have you seen it before? The concept i ...

React Typescript: Unable to set component as element

Currently, I am working on mapping my JSX component (Functional Component) inside an object for dynamic rendering. Here's what I have devised up to this point: Interface for Object interface Mappings { EC2: { component: React.FC<{}>; ...

Struggling to retrieve JSON data from the MercadoLibre API while consistently encountering the CORS error?

I have been attempting to access a mercadolibre API that provides JSON data I need to utilize. However, whenever I make an AJAX GET request, I keep receiving the same error: "Response to preflight request doesn't pass access control check: It does n ...

The dropdown hack on ui.bootstrap.typeahead is compromised when multiple input fields are used in AngularJS

I attempted to enhance ui.bootstrap.typeahead with a hack that adds a dropdown functionality. I discovered the hack on this site. The modification allows the dropdown to appear when clicking inside the input field. Although it functioned appropriately with ...

Struggling to implement nested routes with react-router-dom version 5.2.0?

I'm currently working on implementing nested routing in React using react-router-dom 5.2.0. For a better understanding of the project, you can access the CodeSandbox link here: https://codesandbox.io/s/nested-routes-8c7wq?file=/src/App.js Let's ...

Receive regular updates every week for an entire month using Javascript

How can I calculate the number of check-ins per week in a month using Javascript? I have been unable to find relevant code for this task. Specifically, I am interested in determining the total count of user check-ins on a weekly basis. For example, if a u ...

Encountering a glitch while attempting to render with the select tag in React.js

I have developed two functions that generate JSX content and created a logic to display each function based on the user's choice: const Register = () =>{ const [value, setMyValue] = useState() function Zeff(){ return( <div> <h1& ...

Issue encountered: Object is not functioning properly with Node.js AuthenticationExplanation: A TypeError occurred

As a newcomer to Stack Overflow, I am doing my best to ask this question clearly. I am currently following a tutorial step by step ( http://scotch.io/tutorials/javascript/easy-node-authentication-setup-and-local ) but I encountered an issue after the thir ...

Personalized JavaScript Arrays

Seeking assistance to format data received from an API. Can anyone provide guidance? fields: [ { name: "A", values: { data: [1, 2, 3, 4, 5] } }, { name: "B", values: { data: [6 ...

What is the process for converting a URL or HTML document to a PDF using the html2pdf JavaScript library?

I am working on creating a button that utilizes the html2pdf library to convert an HTML page into a PDF. Instead of selecting an element with query selector or getElementById, I would like to pass a URL because the page I want to convert is not the same as ...

Exploring nested arrays of objects and applying value constraints

Is there a way to iterate through an array and display only 5 items at once, with the option to call a function on click that will add another 20 items? I have an object structured like this: let someObject = [ { data: [ { id: 123, ...