1

I have written a simple javascript function that takes the input of a date textfield and convert it to dd-mm-yyyy format.

function dateConvert(dateValue) {
 if(dateValue == null) {
   var grDate = null;
 }
 else {
  var n = dateValue.search("/"); 
    if( n >= 0) {
    var res = dateValue.split("/");
    var day = res[0];
     if( day.length == 1 ) {
      day = "0"+day;     
     }
    var month = res[1];
     if( month.length == 1 ) {
      month = "0"+month;     
     }
    var year = res[2];
    var grDate = day+"-"+month+"-"+year;
    /*alert(grDate);*/
    }
   else {
    var grDate = dateValue; 
   }
 }

document.getElementById("mydate").value = grDate;
}
<input type="text" name="mydate" id="mydate" onblur="dateConvert(this.value)" />

Is there a way to make function "global" and use it to every textfield that calls the function without having to write it e.g. 3 times if I want to use it in 3 different date textfields?

Dominik
  • 6,078
  • 8
  • 37
  • 61
sak69GR
  • 33
  • 6
  • Add an event listener to `input` with a certain data attribute or class ... – Dominik Feb 28 '21 at 20:17
  • [How to addEventListener to multiple elements in a single line](https://stackoverflow.com/questions/40956717/how-to-addeventlistener-to-multiple-elements-in-a-single-line) and [How to add an event listener to multiple elements in JavaScript](https://flaviocopes.com/how-to-add-event-listener-multiple-elements-javascript/) – Alon Adler Feb 28 '21 at 20:30
  • That is 100% what cusomized built-in elements are perfect for, check my answer below. – connexo Mar 01 '21 at 11:33

2 Answers2

1

Thanks for the replay to Dominik. Make my mind spin I didn't use event listener but querySelectorAll Here is the correct version. It works fine

function myFunction() {
var x = document.querySelectorAll(".mydate");
var i;
for (i = 0; i < x.length; i++) {    

var dateValue = x[i].value; 
 if(dateValue == null) {
     var grDate = null;
 }
 else {
    var n = dateValue.search("/"); 
      if( n >= 0) {
        var res = dateValue.split("/");
        var day = res[0];
         if( day.length == 1 ) {
            day = "0"+day;   
         }
        var month = res[1];
         if( month.length == 1 ) {
            month = "0"+month;   
         }
        var year = res[2];
        var grDate = day+"-"+month+"-"+year;
        /*alert(grDate);*/
      }
     else {
        var grDate = dateValue; 
     }
 }
x[i].value = grDate;        
}
}

for inputs

<p><input type="text" name="field1" class="mydate" onblur="myFunction()" /></p>
<p><input type="text" name="field2" class="mydate" onblur="myFunction()" /></p>
<p><input type="text" name="field3" class="mydate" onblur="myFunction()" /></p>
sak69GR
  • 33
  • 6
0

Excellent question - because this is the perfect example where a custom element solves the problem.

It's really easy:

customElements.define('my-date', class extends HTMLInputElement {
  constructor() {
    super();
    this.dateConvert = this.dateConvert.bind(this);
    this.addEventListener('blur', this.dateConvert);
  }

  dateConvert() {
    if (this.value) {
      let n, res, day, month, year;
      n = this.value.search("/");
      if (n >= 0) {
        res = this.value.split("/");
        day = res[0];
        if (day.length == 1) {
          day = "0" + day;
        }
        month = res[1];
        if (month.length == 1) {
          month = "0" + month;
        }
        year = res[2];
        this.value = `${day}-${month}-${year}`;
      } 
    }
  }
}, { extends: 'input' });
<input is="my-date" />

Now you can even add new date inputs dynamically and they come with your behaviour automatically. No fuddling around in the DOM, just an element that does exactly what you need any time it's in the HTML anywhere.

Please note that unfortunately Safari does not support customizing built-in elements, so you either will have to resort to a polyfill (check https://github.com/webcomponents/polyfills/tree/master/packages/custom-elements or https://github.com/ungap/custom-elements#readme) for that, or use an autonomous custom elements like this:

customElements.define('my-date', class extends HTMLElement {
  constructor() {
    super();
    this.input = document.createElement('input');
    this.appendChild(this.input);
    this.dateConvert = this.dateConvert.bind(this);
    this.input.addEventListener('blur', this.dateConvert);
  }

  dateConvert() {
    if (this.value) {
      let n, res, day, month, year;
      n = this.value.search("/");
      if (n >= 0) {
        res = this.value.split("/");
        day = res[0];
        if (day.length == 1) {
          day = "0" + day;
        }
        month = res[1];
        if (month.length == 1) {
          month = "0" + month;
        }
        year = res[2];
        this.value = `${day}-${month}-${year}`;
      } 
    }
  }
  
  get value() {
    return this.input.value;
  }
  
  set value(val) {
    this.input.value = val;
  }
});
<my-date></my-date>

Just as a sidenote, you might want to consider using the built-in API for dateTime conversion/formatting:

https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat

connexo
  • 53,704
  • 14
  • 91
  • 128
  • Thanks a lot for the replay connexo. That was a great answer. Above everything you made me search and learn. – sak69GR Mar 02 '21 at 20:22