user485399
user485399

Reputation: 65

Text box Date mask

I want to display a text box on my webpage which has a Date input mask. For example: When the user visits the page; the text box should be prefilled with dd/mm/yyyy in light grey color. He should overwrite the same using some valid date like 20/12/1990.

How to accomplish this task (JQuery, JavaScript)? Any inputs would be helpful!!

Upvotes: 0

Views: 7703

Answers (3)

Soth
Soth

Reputation: 3045

I was looking for code like this while back. There are a lot of mask plugins but if you want to roll your own this is a good start.

This allows arrow key usage, highlight and delete, overwrite the date just by typing.

let input = document.getElementById("input");
input.addEventListener("keydown", date_mask);
input.addEventListener("focus", on_focus);
let old_date = "01/01/2022";
input.value = old_date;

function date_mask(e) {
  if (e.key.match(/Arrow/g)) return; //ignore Arrow keys
  let new_date = e.target.value;
  new_date = str_splice(new_date,e.target.selectionStart, e.target.selectionEnd, ""); //if we highlighted we are overwriting;
  let caret = e.target.selectionStart; //get current caret position
  if (e.key.match(/^\w$/g)) {
    //only trigger on a single character -
    //this prevents it from looking weird as slashes are inserted in an empty input box
    e.preventDefault();
    new_date = str_splice(new_date, caret, caret, e.key);
    caret++;
  }
  let mask_result = mask(caret, new_date, old_date, "dd/dd/dddd");
  e.target.value = mask_result.date;
  old_date = mask_result.date;
  e.target.setSelectionRange(mask_result.caret, mask_result.caret); //set new caret position
}

function mask(caret, new_date, old_date, mask) {
  //CARET CONTROL and WRITE OVER
  let diff = new_date.length - old_date.length;
  //Caret control
  if (diff == 1) {
    //we have added a number
    if (!new_date.charAt(caret).match(/\d/g)) caret++; //if its not a digit we move the caret forward
    new_date = new_date.slice(0, caret) + new_date.slice(caret + 1); //write over the date
  } else {
    //we have deleted
    if (!new_date.charAt(caret - 1).match(/\d/g)) {
      //if its not a digit behind us we move the carat backwards
      caret = caret - 1 < 0 ? 0 : caret - 1;
    }
  }

  //MASKING
  new_date = new_date.replace(/[^\d\n]/g, ""); //remove everything but the digits
  let parsed = mask.split("").reduce(
    (acc, obj, i) => {
      if (i < new_date.length + acc.ctr) {
        //we dont want to add extra slashes if the number isnt big enough
        if (obj == "d") {
          //replace all d's with digits
          acc = {
            date: (acc.date += new_date.charAt(i - acc.ctr)), //we remove any slashes using the slash counter
            ctr: acc.ctr
          };
        } else {
          //its part of the mask (a slash)
          acc = { date: (acc.date += obj), ctr: acc.ctr + 1 }; //increment the slash counter
        }
      }
      return acc;
    },
    { date: "", ctr: 0 }
  );

  return { date: parsed.date, caret: caret };
}

function on_focus(e) {
    setTimeout(function () { //we have to set a timeout otherwise it won't work
      e.target.setSelectionRange(0, 0);
    }, 0);
};

function str_splice(str, start, end, replace) {
  let del_num = end - start;
  str = str.split("");
  str.splice(start, end - start, replace);
  return str.join("");
}
<input id="input"></input>

Upvotes: 0

Gabe
Gabe

Reputation: 50523

How about this jQuery plugin...then apply mask

Upvotes: 1

dsomnus
dsomnus

Reputation: 1410

http://digitalbush.com/projects/masked-input-plugin/ should help.

Upvotes: 2

Related Questions