The conflict between ng-model and ngModel causes a disruption in the form functionality

Embarking on the journey of Angular and life:

In front of me lies a petite email form.

This is functional:

    <form method="post" name="form" role="form" ng-controller="contactForm" ng-submit="form.$valid && sendMessage(input)" novalidate class="form-horizontal">
        <p ng-show="success"><b>Your message has been received</b></p>
        <p ng-show="error">Oops! Something went wrong, please try again.</p>

                <label for="name">Name:</label><br>
                <input type="text" id="name" name="name" ng-model="input.name" required><br>

                <label for="email">Email:</label><br>
                <input type="email" id="email" name="email" ng-model="input.email" required><br>

                <label for="messsage">Message:</label><br>
                <textarea id="messsage" name="message" ng-model="input.message" ngMaxlength='2000' required></textarea><br>

        <button type="submit" name="submit" ng-disabled="error" value="submit">Submit</button>
    </form>

This does not function as intended:

    <form method="post" name="form" role="form" ng-controller="contactForm" ng-submit="form.$valid && sendMessage(input)" novalidate class="form-horizontal">
        <p ng-show="success"><b>Your message has been received</b></p>
        <p ng-show="error">Oops! Something went wrong, please try again.</p>

                <label for="name">Name:</label><br>
                <input type="text" id="name" name="name" ngModel="input.name" required><br>

                <label for="email">Email:</label><br>
                <input type="email" id="email" name="email" ngModel="input.email" required><br>

                <label for="messsage">Message:</label><br>
                <textarea id="messsage" name="message" ngModel="input.message" ngMaxlength='2000' required></textarea><br>

        <button type="submit" name="submit" ng-disabled="error" value="submit">Submit</button>
    </form>

When 'ng-model' is used for the inputs and textarea, the email sends successfully, but the form loads initially in an invalid state. However, when 'ngModel' is used instead, the form loads cleanly but the email submission fails.

Here is the controller code:

  app.controller("contactForm", ['$scope', '$http', function($scope, $http) {
    $scope.success = false;
    $scope.error = false;

    $scope.sendMessage = function( input ) {
      $http({
          method: 'POST',
          url: 'processForm.php',
          data: input,
          headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
      })
      .success( function(data) {
        if ( data.success ) {
          $scope.success = true;
        $scope.input.name="";
        $scope.input.email="";
        $scope.input.message="";
        } else {
          $scope.error = true;
        }
      } );
    }

Check out the live version here: Note: The presence of a bothersome red background indicates an invalid state upon loading.

.ng-invalid{
    background-color:red;
}
  }]);

This serves as a visual cue to indicate the invalid loading status.

Answer №1

If you're noticing a bothersome red background on your form, it's likely because of a very general rule set by the .ng-invalid class being applied to the form as well. To address this issue, you'll need to make the styling more specific for the inputs and controls within the form.

For example:

input.ng-invalid, 
textarea.ng-invalid {
    background-color: red;
}

Alternatively, you can simply reset the rule for form.ng-invalid.


Additionally, the correct directive name is ng-model, not ngModel. Using the incorrect version will not have any effect other than adding a dummy attribute to the element. Angular uses camelCasing to differentiate directives in an HTML setting where case sensitivity is not a factor. In cases where ng-model is not specified and there is no novalidate attribute present, the browser's default HTML5 validation will take over, leading to inconsistencies. To prevent this native validation from occurring, you can utilize the HTML5 novalidate attribute on the form.

Answer №2

  • When it comes to programming with AngularJS, ng-model is used for writing the view (html part).
  • If you are creating a custom directive, ngModel is the way to go. It is typically placed in the "require:" parameter so that you can access variables like ngModel.$modelValue.

The ngModel.$modelValue will always contain the most up-to-date content typed by the user in real-time. This makes it useful for tasks such as validations.

Here's an example of the View code:

<!doctype html>
<html ng-app="plankton">
<head>
    <script src="/bower_components/angular/angular.min.js"></script>
    <script src="/scripts/emailing/emailing.directive.js"></script>
</head>
<body ng-controller="EmailingCtrl">
   <div> 
       <label>Enter Email: </label>
        <emailing id="person_email" ng-model="email_entered"></emailing>
   </div>      
</body>
</html>

Custom directive snippet:

(function() {
    'use strict';

angular.module('plankton', [])
       .directive('emailing', function emailing(){
        return {
            restrict: 'AE',
            replace: 'true',
            template: '<input type="text"></input>',
            controllerAs: 'vm',
            scope: {},
            require: "ngModel", 
            link: function(scope, elem, attrs, ngModel){
              console.log(ngModel); 
                scope.$watch(function(){  return ngModel.$modelValue;
                             }, function(modelValue){
                                 console.log(modelValue);//awesome! gets live data entered into the input text box 
                             });
            }, 
        }; 
       })
       .controller('EmailingCtrl', function($scope){
           var vm = this;

       });
})();

You can check out this example on Plunker here.

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 concealing the URL from the bottom left corner of the screen

I'm facing a dilemma with this line of code: <a class="btn btn-block btn-lg" ng-class='login.anchorClass' ng-href="{{login.idp_authnrequest_url}}"><img src="{{login.file_name}}"/>{{login.name}}</ ...

Positioning Bootstrap 4 Dropdown Menus

I am currently utilizing Bootstrap 4 and I am facing a situation where I need to create a website header containing dropdown categories. Here is how it appears in normal view: https://i.sstatic.net/N90KR.png And here is how it looks when hovering/clickin ...

Modifying the position of an image in Flask

I am trying to center an image on my webpage and have attempted the following code: <image height="300px" width="300px" src="{{url_for('static',filename = 'img/Rasd.jpeg')}}" > Visit this webpage fo ...

Guide on implementing a looping settimeout function on a sliding page to dynamically load an HTML template within the Framework 7 framework

My current setup involves using Framework7 (framework7.io). The code below functions correctly on the main view page, utilizing a looping settimeout to refresh signups.html every second: <script type=“text/javascript” src=“code.jquery.com/jquery- ...

What are the steps to increase the size of the search bar?

I have been working on this code, but I am struggling to align the search bar properly within the navigation bar. Can someone please guide me on how to achieve this? I apologize for my lack of coding expertise, as I am new to Information Technology and s ...

Display user's name in navigation bar using asp.net mvc

When working on an ASP.NET MVC project, I wanted to include a short message for the user, such as 'Hello, username!' In the navigation bar, specifically when the user is signed in, I encountered some display issues with the standard bootstrap la ...

Unable to update angular $scope using ng-click

I am attempting to modify a directive controller's $scope using ng-click. There is a simple button in my code: <button ng-click="showEnterKeyField = !showEnterKeyField">btn {{showEnterKeyField}}</button> This code functions as expected, ...

Fetching JSON data cross-domain with the help of JavaScript or JQuery

I am currently attempting to retrieve JSON data from this specific url. However, I am encountering difficulties in making it function as intended. The goal is to seamlessly integrate the school's lunch menu utilizing NutriSlice. We are leveraging Ris ...

How can we save individual words from a sentence in PHP without using the explode function?

I have created a PHP tag script for my website, but I feel like the code is too long. Is there a way to simplify and shorten it? <?php include("admin/apps/site-settings.php"); // establish database connection $albumq = mysql_query("select * fro ...

Centering an icon in tandem with Typography text using Material UI

Is there a way to align an icon with the text so that they are on the same level? Currently, it seems like the icon is slightly above the text. I've tried using padding-top: 5px and margin-top: 5px, but those solutions didn't work as expected. ...

How to ensure that HTML5 range input retains its value after multiple page reloads

How can I ensure that an HTML5 slider (input range) tag resets its position whenever the page is reloaded? Currently, it remains at the last dragged position upon reloading the page. ...

The container size is not being recognized by the Pseudo Element with 100% width

I am currently using a pseudo element (before) to add a border on top of a container within a two column layout. My goal is to have the border only appear on one specific container. Since I have set the width of the pseudo element to 100%, shouldn't ...

The PUT rest service does not function in AngularJS version 1.0.8

I am facing an issue with my AngularJS application that has a CRUD Rest service. While the Create, Read, and Delete methods are functioning properly, the PUT method is not working. I have searched on Stackoverflow and found similar problems with accepted s ...

Troubleshooting problem with Laravel and Vue integration

I have experience working on a Laravel and Vue.js project. Here is the code snippet for the Laravel view: @extends('layouts/app') @section('content') <div id="app"> </div> @endsection And here is the ...

What causes my Angular form to be labeled as dirty even after setting a control to pristine manually?

I have recently developed a new directive: app.directive("customDate", ['$filter', function ($filter) { return { restrict: 'A', require: '?ngModel', link: function (scope, element, attributes, cont ...

Tips for altering CSS using the `:hover` pseudo-class

CSS Style for Navbar .navbar li { color: #B7B7B7; font-family: 'Montserrat', sans-serif; font-size: 14px; min-width: 70px; padding: 22px 16px 18px; } .navbar #menumain ul { width: 120%; } .navbar ul ul { display: none; } <div ...

Styling based on a custom data attribute in CSS

Imagine having a snippet of code in your HTML file that looks like this: <div data-v="20px"> <p>this text repeats itself over and over again</p> </div> The width of the <div> should match the value of data-v, as seen bel ...

AnguLotly - Keep your #div hidden from me

Just starting to dabble in AngularJS and I'm trying to connect it with Plotly. My goal is to pull JSON data for the X and Y axes in Plotly charts. Everything seems to be working smoothly until I hit the Plotly line. It's having trouble locating m ...

Caption image on hover

Is it possible to make an image overlap text on a horizontal menu bar when hovering with the mouse? I am designing a horror website and would like a bloody handprint to appear over the links in the menu bar when they are hovered over. I know this can be do ...

What is the method for resetting the counter back to 1 whenever the labels are updated?

I am currently working on a breathing exercise code that involves counting in the following manner: 8-second inhale 8 second "hold inhale" 12-second "exhale" 8-second "hold exhale" Everything is functioning correctly except for the counter, which con ...