Step-by-step guide to building a personalized input field in AngularJS

I've been developing a custom input wrapper that includes error text handling, among other functionalities. However, I'm facing an issue where I can't reset the model values. Upon inspecting the scopes, I noticed that the outer scopes get updated on reset, but the inner scope of the directive does not update, and I'm uncertain about the cause.

Changing the ng-model watch in the directive from `scope.$watch(ngModel, function() {` to `scope.$watch('ngModel', function() {` enables the reset to work; however, the reset fails when the viewValue is invalid. Ideally, the reset should also work in this scenario.

Could I be making a grave mistake somewhere? The code below demonstrates the issue:

var app = angular.module('app', []);
app.directive('myInput', function() {
  return {
      restrict: "E",
      require: "ngModel",
      template: $('#myInput').html(),
      scope: {
        "ngModel": "=",
        "name": "@",
        "type": "@",
        "label": "@",
        "errorLabel": "@",
        "placeholder": "@"
      },
      link: function(scope, element, attributes, ngModel) {

        scope.$watch('ngModel', function() {
          scope.value = scope.ngModel;
          console.log('got value: ' + scope.value);
        });
        scope.$watch('value', function() {
          if(scope.value) {
            ngModel.$setViewValue(scope.value);
          }
        });
      }
  };
});

app.controller('user', ['$scope', function($scope) {
  $scope.currentUser = {
    email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="15657067667a7b55667c61703b767a78">[email protected]</a>"
  };
  $scope.resetUser = function() {
    console.log('resetting user');
    console.log($scope.user);
    $scope.user = angular.copy($scope.currentUser);
    console.log($scope.user);
  };
  $scope.submitUser = function(user) {
    console.log('submitting user');
    console.log(user);
  };
  $scope.resetUser();
}]);
.error {
  color: red;
}
.my-input {
  border: 5px solid transparent;
}
.ng-invalid.my-input {
  border: 5px solid red;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular.min.js"></script>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script type="text/html" id="myInput">
    <ng-form name="thisForm">
      <label
        ng-class="{error: thisForm.$invalid}"
        for="{{name}}"
        ng-bind="thisForm.$valid ? label : errorLabel"></label></br>
      <input
        class="my-input"
        name="{{name}}"
        type="{{type}}"
        placeholder="{{placeholder}}"
        ng-model="value"></input>
    </ng-form>
  </script>
  
</head>
<body ng-app="app">
  <div ng-controller="user">
    <ng-form name="userForm">
      <my-input
        type="email"
        ng-model="user.email"
        error-label="Enter a valid Email"
        label="Email"
        placeholder="Enter an Email"
        name="Email"></my-input>
      </br>
      <button ng-click="resetUser()">Reset</button>
      <button ng-click="submitUser(user)" ng-disabled="userForm.$invalid">Submit</button>
    </ng-form>
  </div>
  
</body>
</html>

Answer №1

If you're still facing the problem of your watcher not triggering when the input is invalid (fails the Angular email test), it could be because Angular doesn't update your model if the input doesn't pass validation. You can refer to this link for more information.

Alternatively, I suggest using Angular's ngMessages directive to display error messages for an input field. It seems like you may be reinventing something that Angular already offers as a built-in feature.

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

Redirect to the login page if the base URL is accessed when the state changes with `$rootScope.$on($stateChangeStart

I am currently utilizing angular ui-router, along with angular-cookies for authentication in my ionic mobile application. Here are the defined states: .config(function ($stateProvider, $urlRouterProvider) { $stateProvider .state('login&apos ...

Steer clear of including optional dependencies when using Yarn for package installations

Within my yarn.lock file, there is a single reference to momentjs: pikaday@^1.6.0: version "1.6.1" resolved "https://registry.yarnpkg.com/pikaday/-/pikaday-1.6.1.tgz#b91bcb9b8539cedd8dd6d08e4e7465e12095671b0" optionalDependencies: moment "2.x" ...

Mastering intricate data structures using React.js

I am working on creating a table for orders using React+Redux. The data I need is stored in props and it has a structured format similar to this: [{ //stored in props(redux state) "id": 37, //order 1 "content": { "items": { " ...

What are the characteristics of json and jquery that set them apart in this particular case?

I have utilized Kendo UI to create some charts. These charts are populated with data from a WCF service I developed in ASP.NET. Despite being the creator of both the chart and the service, I am still unsure which code pertains to JSON and which belongs to ...

Reset the form upon submission in AngularJS

Hey, I'm looking to reset the form values after a successful submission. How can I achieve this? <div ng-controller="employeelistController as listControl"> <div class="container form-group" ng-controller="addEmployee as addemp"> ...

Confusion Arises When Joomla Buttons Clash

I am facing an issue with two modules on my website, each containing a button code. The code for the buttons is as follows: First Button <div onclick="parent.location='first-link'" data-mce-onclick=""><button class="button">First Bu ...

JavaScript glitch preventing fancybox functionality in Firefox browser

I'm experiencing an issue with FancyBox not working on Firefox while using js no conflict on this specific site Upon inspecting with Firebug, I encountered the following error: Error Line: 99 A similar error is also being thrown by Safari: Typ ...

Combining two sequential API requests in a cascading manner

I am attempting to verify endpoint availability by chaining two API requests and passing the token generated from the first request into the authorization header of the second request. Despite successfully generating the token, the second API is unable to ...

Retrieve each individual element from an array sequentially using jQuery

I am looking to retrieve elements from an array one at a time and only display each element after completing a certain action with the previous one. Here’s an example: var elems = ['Apple','Orange','Banana'], i = 0; ...

Show a JS file variable in an HTML document using a Pug file

Two types of files are in question here. The first one is a pug file: doctype html html head meta(charset='utf-8') meta(name='viewport', content='width=device-width, initial-scale=1, shrink-to-fit=no') link(href=& ...

Store the filter value in a variable inside a directive

Can I use filters in directives as well as controllers? Imagine injecting the filter into a directive like this... app.directive('ngDirective', ['$compile','$filter', function ($compile, $filter) { 'use ...

Resizing objects within a section to conform to the section's dimensions is not possible in CSS/HTML

I'm facing some challenges with responsiveness on my landing page. Utilizing the scrollify jQuery library, users can skip between different sections of the landing page on click or scroll. However, when switching to landscape orientation on mobile d ...

Is there a more productive approach to creating numerous React components?

I am currently working on a page where I need to render 8 components. The only thing that differs between each component is the values that are being iterated... <Item classModifier="step" image={Step1} heading={Copy.one.heading} /> <Item ...

If the variable $scope.val equals 3, execute a loop three times utilizing ng-repeat

In my application, there is a specific scenario where I need to run a loop (using ng-repeat) a certain number of times based on a parameter. For example: $scope.rating = 3; In this case, the loop will run (using ng-repeat) three ...

Retrieve array values using the forEach() method

I need to retrieve the name value from an array stored in another Object. exports.send = function(req,res){ req.body.items.forEach(function(item){console.log(item.name)}) } Output: Product 3 Product 2 However, I am struggling to extract these values ...

Maximizing jQuery DataTables performance with single column filtering options and a vast amount of data rows

My current project involves a table with unique column select drop-downs provided by an amazing jQuery plug-in. The performance is excellent with about 1000 rows. However, the client just informed me that the data could increase to 40000 rows within a mont ...

Efficient Local Database with Javascript

When storing a substantial amount of data, such as a big hashmap in JavaScript, what would be the optimal format for quick retrieval while also supporting Unicode? Would XML or JSON be better suited for this purpose? ...

Distinguish between RegisterClientScriptBlock and RegisterStartupScript with the response.write("script") method

Could you please provide an explanation and the unique advantages of using RegisterClientScriptBlock, RegisterStartupScript, and response.write("script"); individually? I have gathered some information such as: The RegisterClientScriptBlock() method inje ...

Developing a React Native app using Expo and Firebase? Learn how to prevent Firebase details from

I have encountered a problem with my code while working on the user edit profile page in my react native app. The issue I am facing is related to displaying the previously inputted firebase details from the collection in the text input fields when the user ...

"Utilizing AJAX function within the success handler of another AJAX

I recently developed an AJAX website that fetches PHP pages from a specific folder named /pages within my index.php file. Within one of my pages, painting.php, there is a link that leads to another page called painting-slider.php. Now, I am wondering how ...