Javaish
Javaish

Reputation: 179

Weird Javascript behaviour when working with date

Basically i try to take the value of data attributes when clicked the values are 7,14,30 and i try insert them into some javascript date code but it dont show the correct date? if i put in the values myself it will alert the correct dates but when i use a javascript variable which holds one of the data attributes i will get dates far away from the real date?

Sample site here

HTML

<form class="annonceForm" action="index.php?page=opretAuction" method="POST">
    <input type="text" name="" placeholder="Produkt">

    <div id="auctionExpireWrapper" class="auctionExpireWrapper">
        <span data-auctionExpire="7" class="auctionExpire">7 dage</span>
        <span data-auctionExpire="14" class="auctionExpire">14 dage</span>
        <span data-auctionExpire="30" class="auctionExpire">30 dage</span>
    </div>
    <input id="auctionStartDateInput" type="hidden">
    <input id="auctionEndDateInput" type="hidden">

    <textarea placeholder="Beskrivelse"></textarea>
           <!-- HIDDEN INPUT FELTER -->
           <input type="hidden" name="CSRFToken" value="<?php echo $_SESSION['CSRFToken']; ?>">
    <input type="hidden" name="OpretAuctionAuctioneer" value="<?php echo $_SESSION['username']; ?>"> 
</form>

Javascript

document.getElementById("auctionExpireWrapper").addEventListener("click", function (e) {
var expireDate = e.target.getAttribute("data-auctionExpire");
alert(expireDate);
var today = new Date();

When i use the expireDate variable it mess up the date, if i insert etc 14 manually without the variable everything works fine?

today.setDate(today.getDate() + expireDate);
var dd = today.getDate();
var mm = today.getMonth() + 1; //January is 0!
var yyyy = today.getFullYear();

if (dd < 10) {
    dd = '0' + dd
}
if (mm < 10) {
    mm = '0' + mm
}

today = yyyy + '-' + mm + '-' + dd;
alert(today);
});

Could anyone explain to me why it behaves like this?

Upvotes: 0

Views: 44

Answers (1)

KarelG
KarelG

Reputation: 5244

Posting an answer instead of further comments. OP has asked the following question in the comments:

What is the difference between dataset.auctionExpire? and why is the e lower case?

Because it's defined by this way. If you check the HTMLElement.dataset documentation, you will find

The name of a custom data attribute in HTML begins with data-. It must contain only letters, numbers and the following characters: dash (-), dot (.), colon (:), underscore (_) -- but NOT any ASCII capital letters (A to Z).

However, in your HTML, you can define your data- attribute with uppercase like you did here:

<span data-auctionExpire="7"

But internally, it will be stored as auctionexpire. Each similar named attribute that follows doesn't get added. Here below is a small example where I have added multiple data-attributes. The only difference is that some characters are in uppercase:

document.getElementById('forTest').addEventListener('click', function() {
   console.log('this.dataset.auctionexp: ' +  this.dataset.auctionexp);
   console.log('this.dataset.auctionExp: ' +  this.dataset.auctionExp);
   console.log('this.dataset.auCTionexp: ' +  this.dataset.auCTionexp);
   console.log('this.dataset.AUCTIONEXP: ' +  this.dataset.AUCTIONEXP);
});
<span id="forTest" data-auctionExp="one uppercase" data-auCTionexp="CT as upper" data-AUCTIONEXP="FULL UPPER">clickme</span>

In order to fix your problem, I have replaced the second line. But that's not the only problem. The type of the value that you retrieve from .dataset.auctionexpire is of type string. When you're doing

today.setDate(today.getDate() + expireDate)

you're adding an integer with a string value

  today.getDate() // = 13, type Number (time of this post)
  expireDate      // =  7, type String(clicked on "7 tage")
+ ----------------------
  // result: 137

So you were setting the new day part with 137 days instead of 20 (13+7). To fix it, simply cast the string to number by using new Number() like I did here below.

document.getElementById("auctionExpireWrapper").addEventListener("click", function(e) {
  var expireDate = e.target.dataset.auctionexpire;
  // expireDate is a string, not number. You have to cast it
  expireDate = new Number(expireDate);
  // should be correct now.
  
  console.log('expireDate: ' + expireDate);
  
  var today = new Date();
  today.setDate(today.getDate() + expireDate);
  
  var dd = today.getDate();
  var mm = today.getMonth() + 1; //January is 0!
  var yyyy = today.getFullYear();

  if (dd < 10) {
    dd = '0' + dd
  }
  if (mm < 10) {
    mm = '0' + mm
  }

  today = yyyy + '-' + mm + '-' + dd;
  console.log('today: ' + today);
});
<form class="annonceForm" action="index.php?page=opretAuction" method="POST">
  <input type="text" name="" placeholder="Produkt">

  <div id="auctionExpireWrapper" class="auctionExpireWrapper">
    <span data-auctionExpire="7" class="auctionExpire">7 dage</span>
    <span data-auctionExpire="14" class="auctionExpire">14 dage</span>
    <span data-auctionExpire="30" class="auctionExpire">30 dage</span>
  </div>
  <input id="auctionStartDateInput" type="hidden">
  <input id="auctionEndDateInput" type="hidden">

  <textarea placeholder="Beskrivelse"></textarea>
  <!-- HIDDEN INPUT FELTER -->
  <input type="hidden" name="CSRFToken" value="<?php echo $_SESSION['CSRFToken']; ?>">
  <input type="hidden" name="OpretAuctionAuctioneer" value="<?php echo $_SESSION['username']; ?>">
</form>

Upvotes: 1

Related Questions