-1

This is a continuation of This

I used setTimeout() to place cursor on the input fields on pressing the tab, without which the focus goes to a link outside the <div> for some reason I am not aware of. setTimeout() fixed that issue, but now:

On clicking on submit button the form does nothing but place cursor on the input fields for three or four times then proceeds with submitting.

Here is the submit button functions

$(“#submitbtn”).click(function(e) {
 console.log(“click”);
 e.preventDefault();
 var s = setTimeout(function() {
   removeTimeouts();
   startValidation();
   });
 e.stopPropagation();
 e.cancelBubble = true;
});

Here is hover function for Submit button

$(“#submitbtn”).mouseover(function(e) {
 console.log(“Hover”);
 removeTimeouts();
 $(“#submitbtn”).focus();
 e.preventDefault();
 e.stopPropagation();
 e.cancelBubble = true;
});

The function removeTimeouts() has all clearTimeout() for all setTimeout() through out the JavaScript file.

But somehow the click function is never works until third or fourth try. The hover function works on first mouse move though, it prints “Hover” on console, every time the mouse it moves over submit button.

Even after clearing all setTimeout() somehow the focus is moved to input fields instead of proceeding with the console.log() onclick.

Can someone help me understand the issue and help fix the form gets submitted on first click?

Update:

1) This is typed from mobile app, even after re-editing the quote appearing as “” It’s correct in my code just not here.

2) Focus and timeout event is to validate the input fields while moving out of the input field, like if the field is empty, the cursor won’t move to next input field. But just focus is not working, and tab just takes the cursor out of the input fields to a link below it, so time-out helps keeping the cursor the input field.

3) Snippet - This does not replicate the issue as this is by far I can post the code sorry :(

(function ($) {
    // Behind the scenes method deals with browser
    // idiosyncrasies and such
    $.caretTo = function (el, index) {
        if (el.createTextRange) { 
            var range = el.createTextRange(); 
            range.move("character", index); 
            range.select(); 
        } else if (el.selectionStart != null) { 
            el.focus(); 
            el.setSelectionRange(index, index); 
        }
    };
    
    // Another behind the scenes that collects the
    // current caret position for an element
    
    // TODO: Get working with Opera
    $.caretPos = function (el) {
        if ("selection" in document) {
            var range = el.createTextRange();
            try {
                range.setEndPoint("EndToStart", document.selection.createRange());
            } catch (e) {
                // Catch IE failure here, return 0 like
                // other browsers
                return 0;
            }
            return range.text.length;
        } else if (el.selectionStart != null) {
            return el.selectionStart;
        }
    };

    // The following methods are queued under fx for more
    // flexibility when combining with $.fn.delay() and
    // jQuery effects.

    // Set caret to a particular index
    $.fn.caret = function (index, offset) {
        if (typeof(index) === "undefined") {
            return $.caretPos(this.get(0));
        }
        
        return this.queue(function (next) {
            if (isNaN(index)) {
                var i = $(this).val().indexOf(index);
                
                if (offset === true) {
                    i += index.length;
                } else if (typeof(offset) !== "undefined") {
                    i += offset;
                }
                
                $.caretTo(this, i);
            } else {
                $.caretTo(this, index);
            }
            
            next();
        });
    };

    // Set caret to beginning of an element
    $.fn.caretToStart = function () {
        return this.caret(0);
    };

    // Set caret to the end of an element
    $.fn.caretToEnd = function () {
        return this.queue(function (next) {
            $.caretTo(this, $(this).val().length);
            next();
        });
    };
}(jQuery));



var allTimeouts = [];
function placeCursor(id) {
  id.focus(function(e) {
    e.stopPropagation();
    //e.cancelBubble();
    id.caretToEnd();
  });
  id.focus();
}
function removeTimeouts(){
  for(var i = 0; i < allTimeouts.length; i++) {
    clearTimeout(allTimeouts[i]);
  }
}
function focusInNumber (id) {
  var thisID = id;
  var nextID = id + 1;
  var preID = id - 1;
  //$("#number" + thisID).prop("disabled", false);
  var s = setTimeout(function() {
    placeCursor($("#number" + thisID));
  });
  allTimeouts.push(s);
  if(preID != 0) {
    if($("#number" + preID).val().length <= 0) {
      var s = setTimeout(function() {
        placeCursor($("#number" + preID));
      });
      allTimeouts.push(s);
    }
  } 
}
function focusOutNumber (id) {
  var thisID = id;
  var nextID = id + 1;
  var preID = id - 1;
  var value = $("#number" + thisID).val();
  var regex = new RegExp(/^\d*$/);
  var regex1 = new RegExp(/^.*[\+\-\.].*/);
  var l = $("#number" + thisID).val().length;
  if(!value.match(regex)) {
    alert("Just enter numerical digits");
    var s = setTimeout(function() {
      placeCursor($("#number" + thisID));
    },5000);
    allTimeouts.push(s);
  } else {
    if (l<=0) {
      alert("This field cannot be empty");
      var s = setTimeout(function() {
        placeCursor($("#number" + thisID));
      },5000);
      allTimeouts.push(s);
    } else {
      if(value.match(regex)) {
        var s = setTimeout(function() {
          placeCursor($("#number" + nextID));
        }, 100);
        allTimeouts.push(s);
      }
    }
  }
}
$(document).ready(function(){
  $("#number1").focusin(function(){
    focusInNumber(1);
  });
  $("#number1").focusout(function(){
    focusOutNumber(1);
  });
  $("#number2").focusin(function(){
    focusInNumber(2);
  });
  $("#number2").focusout(function(){
    focusOutNumber(2);
  });
  $("#number3").focusin(function(){
    focusInNumber(3);
  });
  $("#number3").focusout(function(){
    focusOutNumber(3);
  });
  $("#number4").focusin(function(){
    focusInNumber(4);
  });
  $("#number4").focusout(function(){
    focusOutNumber(4);
  });
  $("#submitbtn").click(function(e) {
     console.log("click");
     e.preventDefault();
     var s = setTimeout(function() {
       removeTimeouts();
       alert("startValidation()");
     });
     e.stopPropagation();
     e.cancelBubble = true;
  });
  $("#submitbtn").mouseover(function(e) {
     console.log("Hover");
     removeTimeouts();
     $("#submitbtn").focus();
     e.preventDefault();
     e.stopPropagation();
     e.cancelBubble = true;
  });
});
.SubmitBtn {
  width: 100%;
  background-color: #cccccc;
}
.Submitbtn:hover {
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<input type="number" class="reqField" id="number1" placeholder="Enter Number only"></input>
<input type="number" class="reqField" id="number2" placeholder="Enter Number only"></input>
<input type="number" class="reqField" id="number3" placeholder="Enter Number only"></input>
<input type="number" class="reqField" id="number4" placeholder="Enter Number only"></input>

<div id="submitbtn" class="SubmitBtn">Submit</div>
Vikram Mohan
  • 39
  • 3
  • 15
  • 1
    Please click [edit](https://stackoverflow.com/posts/57107816/edit) then `[<>]` snippet editor and provide a [mcve] and use proper quotes – mplungjan Jul 19 '19 at 07:51
  • 2
    Also note that the `“` and `”` quotes are not valid in JS and will be giving you errors. – Rory McCrossan Jul 19 '19 at 07:53
  • why do you need the focus event and why do you need the timeout ? – madalinivascu Jul 19 '19 at 08:18
  • @RoryMcCrossan I typed this on mobile app, not sure why it took it as “” but on my original code it is appearing correct. – Vikram Mohan Jul 19 '19 at 08:56
  • @madalinivascu Focus and timeout event s is to validate the input fields while typing and on focus-out. Only with timeout the focus works. – Vikram Mohan Jul 19 '19 at 08:58
  • @mplungjan I have updated the snippet, but the issue did not occur on it. This is the best I can think of to post the code that are non-sensitive. This code is exactly the same along with more validation on char typed, symbol typed, decimal point typed, space typed and such, on each input fields and there are eighty such input fields. – Vikram Mohan Jul 19 '19 at 11:08
  • @mplungjan: Ah, Come on, there wont be any alert, instead there are error text that are displayed on the screen below the text box. Like I said this is the least I can publish hiding the sensitive data. The alerts and console.log() are just here on the snippet. Will not be on the actual code. I can not replicate the issue of click function not working on first three tries, unless I post the actual code, which would get me fired lol! – Vikram Mohan Jul 19 '19 at 11:50
  • Ok, I see. Well good luck finding it then :/ – mplungjan Jul 19 '19 at 11:52

1 Answers1

0

After breaking my head and console.log on all the statement to figure out the flow of code, I was able to find that on $("#submitbtn").click() there is some .focusout() is called.

As these .focusout() were necessary for on the go validation on the <input> fields, i tried to add $.(":focus").blur() and it worked along with adding a return false; on placeCursor() function.

The $.(":focus").blur() removes focus from any currently focused element. And this is a live saver for our logic of code.

So the code looks like

$("#submitbtn").mouseover(function(e) {
 console.log("Hover");
 $.(":focus").blur();
 removeTimeouts();
 $("#submitbtn").focus();
 e.preventDefault();
 e.stopPropagation();
 e.cancelBubble = true;
});

....

function placeCursor(id) {
  id.focus(function(e) {
  e.stopPropagation();
  //e.cancelBubble();
  id.caretToEnd();
 });
 id.focus();
 return false;
}

Hope this helps someone someday. Thank you!

Vikram Mohan
  • 39
  • 3
  • 15