Issue
I am new to js and I am trying to loop through elements by class name and make a change to the element's textcontent using javascript. The following is what I have so far, but this does not work.
<script type="text/javascript">
function dformat(i) {
var hasDate = document.getElementsByClassName("dformat")[i].textContent.trim().includes("/");
if(hasDate === false) {
window.setTimeout(dformat, 100); /* this checks the flag every 100 milliseconds*/
} else {
dateString = document.getElementsByClassName("dformat")[i].textContent.trim();
const options = { year: 'numeric', month: 'short', day: 'numeric' };
let dateArr = dateString.split("/");
var sMonth = dateArr[0];
var sDay = dateArr[1];
var sYear = dateArr[2];
let newDateString = sYear + "/" + sMonth + "/" + sDay
let newDate = new Date(newDateString);
document.getElementsByClassName("dformat")[i].textContent=newDate.toLocaleDateString('en-us', options);
}
}
var ditems = document.getElementsByClassName("dformat");
for (var i = 0; i < ditems.length; i++) {
dformat(i);
}
</script>
The following is an example of one of the elements
<span class="dformat">26/06/1992</span>
The expected output would be to have changed text on each of the elements with class dformat
Update: I tried the same function with getelementbyid on a single element (i.e without a for loop) and got the expected result. I have trouble doing the same on a set of elements by classname instead of a single element by id.
Solution
There's nothing wrong with your for loop, the problem is with your Date
objection construction. Date
s cannot be created with the YYYY/MM/DD format. (See warning section here) What you instead need to do is pass the year, month, and day as parameters to the constructor.
let newDate = new Date(sYear, sMonth, sDay);
Some other notes...
You don't need to use document.getElementsByClassName
to find the elements each time. You can simply pass the element directly to the function.
function dformat(e) {
dateString = e.textContent.trim();
if (!dateString.includes('/')) {
window.setTimeout(dformat, 100, e);
return;
}
const options = { year: 'numeric', month: 'short', day: 'numeric' };
let dateArr = dateString.split("/");
var sMonth = dateArr[0];
var sDay = dateArr[1];
var sYear = dateArr[2];
let newDate = new Date(sYear, sMonth, sDay);
e.textContent=newDate.toLocaleDateString('en-us', options);
}
var ditems = document.getElementsByClassName("dformat");
for (var i = 0; i < ditems.length; i++) {
dformat(ditems[i]);
}
Here's a code snippet showing this in action.
function dformat(e) {
dateString = e.textContent.trim();
if (!dateString.includes('/')) {
window.setTimeout(dformat, 100, e);
return;
}
const options = { year: 'numeric', month: 'short', day: 'numeric' };
let dateArr = dateString.split("/");
var sMonth = dateArr[0];
var sDay = dateArr[1];
var sYear = dateArr[2];
let newDate = new Date(sYear, sMonth, sDay);
e.textContent=newDate.toLocaleDateString('en-us', options);
}
var ditems = document.getElementsByClassName("dformat");
for (var i = 0; i < ditems.length; i++) {
dformat(ditems[i]);
}
<span class="dformat">26/06/1992</span>
<br>
<span class="dformat">27/06/1992</span>
<br>
<span class="dformat">28/06/1992</span>
<br>
<span class="dformat">29/06/1992</span>
Secondly, if you use setTimeout
, you will need to pass the element to the function. As you have it, the function will be called with no arguments, so it would break if it ever found something without a /
. You can see how I did it above to fix that.
I'm a little suspicious of using setTimeout
in this way. This only allows the spans to be formatted once, if you really want continuous monitoring then you you will need to constantly setTimeout
outside the function definition in the main script. Or if you just need to wait for the document to be ready, you should place your scripts after your HTML content and that will not be a problem. (See here). I won't speculate further since that isn't the purpose of this question, but I wanted to let you know that something seems wrong there.
Answered By - TechnoSam
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.