Validation works correctly during keyup events, but is ineffective during keypress events

When using the input box, there are certain validations in place:

1) The length input box should accept up to 3 integer values (no decimals).

2) The height input box should accept 3 integer numbers and decimals up to 2 places. Initially, everything works fine. However, after clicking the + button (next to the "Open New Row 1" option), new input fields appear but the validations do not work correctly. Even when using the same classes for the input boxes, the newly added boxes allow any number of digits and characters.

The keyup function is functional, but it does not work for the newly opened row when a key is pressed. How can I make it work on keypress in both cases? Validation works on keyup, but it fails on keypress.

var app = angular.module('Calc', []);
 var inputQuantity = [];
    $(function() {
      $(".form-control").each(function(i) {
        inputQuantity[i]=this.defaultValue;
         $(this).data("idx",i); // save this field's index to access later
      });
      $(".form-control").on("keyup", function (e) {
        var $field = $(this),
            val=this.value,
            $thisIndex=parseInt($field.data("idx"),10); 
        if (this.validity && this.validity.badInput || isNaN(val) || $field.is(":invalid") ) {
            this.value = inputQuantity[$thisIndex];
            return;
        } 
        if (val.length > Number($field.attr("maxlength"))) {
          val=val.slice(0, 5);
          $field.val(val);
        }
        inputQuantity[$thisIndex]=val;
      });      
    });
app.controller('Calc_Ctrl', function ($scope, $http) {
     $scope.choices = [{id : 'choice1', l2 : 0, b2 : 0}];
     $scope.areas = [{id : 'choice2', total : 0}];

     $scope.addNewChoice = function () {
          var newItemNo = $scope.choices.length + 1;
          $scope.choices.push({
               'id' : 'choice' + newItemNo, l2 : 0, b2 : 0
          });
     };
     $scope.removeChoice = function () {
          var lastItem = $scope.choices.length - 1;
          if (lastItem !== 0) {
               $scope.choices.splice(lastItem);
          }
     };
});
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="newscript.js"></script>

<body>
  <div ng-app="Calc" ng-controller="Calc_Ctrl">
               <div  data-ng-repeat="choice in choices" class="col-md-12 col-sm-12 col-xs-12 bottom-line no-gap">
                              <h6>Open New Row {{$index + 1}} 
                                   <button type="button" class="btn btn-default pull-right btn-right-gap  btn-red" aria-label="Left Align"  ng-click="addNewChoice()" style="margin-top: -5px;" id="plus_icon">
                                        <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
                                   </button>

                              </h6> 
                              <div class="row walls top-gap">

                                   <div class="form-group col-md-3 col-sm-3 col-xs-12">
                                        <label for="length">Length :</label>
                                        <input type="number" class="form-control text-red bold" id="length"  ng-model="choice.l2"  min="0" max="999" maxlength="6" step="0.00">
                                   </div>
                                   <div class="form-group col-md-3 col-sm-3 col-xs-12">
                                        <label for="height">Height :</label>
                                        <input type="number" class="form-control text-red bold" id="height"   ng-model="choice.b2"  min="0" max="999" maxlength="6" step="0.01">
                                   </div>
                                 
                                   <button type="button" class="btn btn-default pull-right btn-red" aria-label="Left Align"  ng-click="removeChoice()" id="minus_icon">
                                   </button>
                              </div>

                         </div>
  </div>
</body>

</html>

Answer №1

If we want to trigger the keyup event for all fields, we need to adjust the listener's definition. The selector .form-control should be included as a child selector within the on() function, with document as the main selector:

$(document).on("keyup",".form-control", function (e) {
// listener code
});

The behavior of the keypress event differs from the keyup event. Keypress is triggered for each key press, just before the value is updated in the field. On the other hand, the keyup event occurs after each key is released and the value is set in the field. Therefore, the same approach will not work for keypress.

var app = angular.module('Calc', []);
 var inputQuantity = [];
    $(function() {
      $(".form-control").each(function (i) {
            inputQuantity[i] = this.defaultValue;
            $(this).data("idx", i); // save this field's index for later access
        });
        $(document).on("keypress", ".form-control", function (e) {
            if (e.charCode!=0){
            var $field = $(this),
            val = this.value + '' + String.fromCharCode(e.charCode), pattern;
            if (this.step == 0.00)
                pattern = /[^0-9]/
            else
                pattern = /[^0-9.]/
            if (val > parseInt(this.max, 10) || pattern.test(val) || (val.match(/\./) && (val.match(/\./g).length > 1 || val.replace(/\d+./, '').length > 2))) {
                e.preventDefault();
            }
           }
        });
        $(document).on("keyup",".form-control", function (e) {
            var $field = $(this),
                val=this.value,
                $thisIndex=parseInt($field.data("idx"),10); 
            if (parseInt(val,10) > parseInt(this.max, 10) ) {
                this.value = inputQuantity[$thisIndex];
                return;
            } 
            if (val.length > Number($field.attr("maxlength"))) {
                val=val.slice(0, 5);
                $field.val(val);
            }
            inputQuantity[$thisIndex]=val;
        });      
    });
app.controller('Calc_Ctrl', function ($scope, $http) {
     $scope.choices = [{id : 'choice1', l2 : 0, b2 : 0}];
     $scope.areas = [{id : 'choice2', total : 0}];

     $scope.addNewChoice = function () {
          var newItemNo = $scope.choices.length + 1;
          $scope.choices.push({
               'id' : 'choice' + newItemNo, l2 : 0, b2 : 0
          });
     };
     $scope.removeChoice = function () {
          var lastItem = $scope.choices.length - 1;
          if (lastItem !== 0) {
               $scope.choices.splice(lastItem);
          }
     };
});
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="newscript.js"></script>

<body>
  <div ng-app="Calc" ng-controller="Calc_Ctrl">
               <div  data-ng-repeat="choice in choices" class="col-md-12 col-sm-12 col-xs-12 bottom-line no-gap">
                              <h6>Open New Row {{$index + 1}} 
                                   <button type="button" class="btn btn-default pull-right btn-right-gap  btn-red" aria-label="Left Align"  ng-click="addNewChoice()" style="margin-top: -5px;" id="plus_icon">
                                        <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
                                   </button>

                              </h6> 
                              <div class="row walls top-gap">

                                   <div class="form-group col-md-3 col-sm-3 col-xs-12">
                                        <label for="length">Length :</label>
                                        <input type="text" class="form-control text-red bold" id="length"  ng-model="choice.l2" min="0" max="999" maxlength="6" step="0.00">
                                   </div>
                                   <div class="form-group col-md-3 col-sm-3 col-xs-12">
                                        <label for="height">Height :</label>
                                        <input type="text" class="form-control text-red bold" id="height"   ng-model="choice.b2" min="0" max="999" maxlength="6" step="0.01">
                                   </div>
                                 
                                   <button type="button" class="btn btn-default pull-right btn-red" aria-label="Left Align" ng-click="removeChoice()" id="minus_icon">
                                   </button>
                              </div>

                         </div>
  </div>
</body>

</html>

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

how to use AngularJS filter and ng-options to format specific options as bold in a select dropdown

I am currently utilizing AngularJS ng-options to populate specific select elements. I am interested in bolding and disabling certain options. Despite trying to achieve this using the filter along with ng-options, I have been unsuccessful so far. While I ca ...

Adding a proptype for a setState method in React components

I am currently developing a reusable component for a project. This particular component includes user and setUser as props, much like the example provided below. const UserComponent = ({ user, setUser }) => { const calcHandler = useCallback(() =& ...

Efficiently sorting items by category name in PHP with Ajax

Currently, I am working on a functionality that involves two dropdown lists. The first one, located at the top, is for selecting a category of meals. Each option in this dropdown has an associated id_cat value. <option value="1">Pâtis ...

I am unable to fire a simple jQuery event when pressing a key until the next key is pressed

I am currently working on a project for a friend, where I have implemented a hidden text field. When the user starts typing in this field, the text is displayed in a div element to create an effect of typing directly onto the screen instead of an input fie ...

There seems to be a problem with the sorting functionality on the table in React JS,

My React table is functioning well with all columns except for the country name column. I double-checked the API and everything seems to be in order, but I'm stuck on how to troubleshoot this issue. const Table = () => { const[country, setCount ...

Is there a way to keep Angular from automatically re-sorting my list when I make edits to it?

I have designed a small application with Angular for managing Todolists. Each list contains multiple todos, where each todo has attributes such as name, value1, and value2. To automatically sort each list using Angular, I utilized ng-repeat="todo in selec ...

Programming the tab pages within Chrome

By using JavaScript, I successfully opened a new tab at www.blogger.com from the Main.html page. <script> window.open("https://www.blogger.com"); </script> I am now on the blogger page. My goal is to automatically scroll to the end of the bl ...

Retrieve the data of elements that have been clicked using jQuery

I am struggling with a particular issue and would appreciate some assistance. Recently, I've been working on developing buttons that, when clicked, add data to a form for submission. An example of the code structure is as follows: <div> < ...

Manipulating the DOM with Javascript and jQuery: Adding a new element and retrieving its reference

I am encountering an issue with a Web App that relies on JavaScript and jQuery. Essentially, the website includes a button that triggers a JavaScript function when clicked. Within this function, there are two other functions named Foo and Bar. Foo generate ...

What is the best way to send a prop to my home route following a redirect?

I am working with react-router-dom and I want to pass :id to my first route (/) when redirecting. This is important so that I can access :id in my Interface component and maintain consistent URL structure for my single-page application. Is it feasible to a ...

Failure to execute the success function

My current issue involves making an AJAX call to retrieve a record from the database. Despite console logs showing that the record is successfully returned, the success function fails to execute. function ajaxForParent() { var search = document.getEle ...

Developing an interactive bar graph using D3.js and AngularJS

I have a dataset that needs to be visualized on a bar chart, with the data dynamically updating according to the selected dates. The bar chart should display data for a week comprising of 7 days. There is a date pagination feature on the page which allows ...

how to change the color of a specific item in a list created using v-for

I'm a beginner when it comes to vueJs and I'm attempting to toggle the class "active" on a single element once it has been clicked. Currently, my code toggles all elements with the class material_icons. How can I modify it to toggle only the elem ...

Ways to extend the timeout duration for Vercel Serverless functions

I've encountered an issue with my API endpoint on a NextJS project where it exceeds the 60-second time limit to execute. Despite being on a pro Vercel plan, I have been unable to extend the timeout limit successfully. Within the endpoint itself, I at ...

Is my Magento journey on the correct course?

I am wanting to include or require a file in DATA.php within magento. Below is the code snippet I have: public function formatPrice($price) { require_once(Mage::getBaseDir('app').'\design\frontend\neighborhood ...

Show User Input as a dynamic tool-tip in Highcharts

Is it possible to gather 12 user inputs through multiple text areas in a popup dialog box, and then use these inputs as tooltips for various points on a graph like the one shown in this demo: http://www.highcharts.com/demo/line-labels? I haven't found ...

How do I retrieve a nested object element based on the value of a specific field in Mongoose?

Below is the teamModelSchema schema that I am working with. var teamMemberModelSchema = new mongoose.Schema({ "email": { "type": String, "required": true, "min": 5, "max": 20 }, "name": { "type": String ...

Caution: It is important for every child in a list to have a distinctive "key" prop value. How can a shared key be used for multiple items?

When I click on a header from my list, an image should appear. However, I'm encountering an error that needs to be resolved. I've been struggling to find a solution for adding unique keys to multiple elements in order to eliminate the error. Des ...

Ways to retrieve a specific value in an array of objects

When working with the p5 javascript library, there is a convenient built-in function called {key} that captures the key you press. For instance, using text(${key},200,200) will display the key pressed at position 200, 200 on the canvas. If I were to stor ...

The scroll-to-top arrow remains concealed when the height of the html and body elements is set to 100

I recently added a scroll-to-top arrow using Jquery, and it's functioning flawlessly. However, I encountered an issue when I set body and html to a height of 100%, as it mysteriously disappears. View this fiddle for reference The HTML structure is a ...