林柏年 林柏年 - 1 month ago 12
HTML Question

Contenteditable field onchange event add date

HTML:

<p id="bon_date" class="inline" style="color:#0000ff;" contenteditable="true" onchange="add7day()"> enter date </p>


javascript:

function add7day() {
var str = document.getElementById(#bon_date).value;
var startdate = str.split("/");
var month = parseInt(stardate[0], 10);
var day = parseInt(stardate[1], 10);
var o_month = parseInt(stardate[0], 10);
var o_day = parseInt(stardate[1], 10);
if (month == 1 | month == 3 | month == 5 | month == 7 | month == 8 | month == 10 | month == 12) {
if ((day + 7) > 31) {
month = month + 1;
day = day + 7 - 31;
} else {
day = day + 7;
}
document.getElementById(#bon_date).innerHTML = o_month + "/" + o_day + "~" + month + "/" + day;

} else {
if ((day + 7) > 30) {
month = month + 1;
day = day + 7 - 30;
} else {
day = day + 7;
}

document.getElementById(#bon_date).innerHTML = o_month + "/" + o_day + "~" + month + "/" + day;

}


I can get the string from input type field but I can`t get it from contenteditable field.

and when it runs to
var month = parseInt(stardate[0],10);
I get errors like:


stardate[0] is not define..


I want input a date by manual and gets the date after 7 days.

Any ideas?

Answer

Okay, where to begin.

I'm not going to question the use of a contenteditable element instead of an input type="text" or input type="date" element, I'm just going to fix your JavaScript.

Elements with contenteditable are not converted to input elements or textareas, so they do not have a value property, but they do have a textContent because they're otherwise normal HTML nodes which can have text nodes.

Elements with contenteditable also do not emit an onchange or change event when their text content is edited. You could listen for the input event, but that would break your code, because your function would constantly amend the element's contents every time the user pressed a key—making it practically unusable.

The next best thing to the onchange event is the onblur/blur event, so we'll use that. This means when the user focuses off the event, i.e. clicks outside it (or presses the tab key etc) the function will fire.


stardate[0] comes back as undefined because you didn't define a variable called stardate, you defined startdate. Similarly, none of the code works at all without getting the bon_date element, which in this case would be done by fixing your code so document.getElementById() is given a parameter 'bon_date' (not '#bon_date', because document.getElementById does not use CSS selectors).

// Store the element in a variable so we don't have to keep writing this crap out.
var bd = document.getElementById('bon_date');

// Listen for the blur event by adding an event listener in JavaScript.
// You could also use an 'onblur=' attribute on the element in question.
bd.addEventListener('blur', add7day, false);

function add7day() {
  // Get the element's text content.
  var str = bd.textContent;

  // You could just say startdate = bd.textContent.split("/") and leave out out the str variable.
  var startdate = str.split("/");
   
  var month = parseInt(startdate[0], 10);
  var day = parseInt(startdate[1], 10);
  var o_month = parseInt(startdate[0], 10);
  var o_day = parseInt(startdate[1], 10);
   
  if (month == 1 | month == 3 | month == 5 | month == 7 | month == 8 | month == 10 | month == 12) {
    if ((day + 7) > 31) {
      month = month + 1;
      day = day + 7 - 31;
    } else {
      day = day + 7;
    }

    // no need to use innerHTML, just amend the textContent again
    bd.textContent = o_month + "/" + o_day + "~" + month + "/" + day;

  } else {
    if ((day + 7) > 30) {
      month = month + 1;
      day = day + 7 - 30;
    } else {
      day = day + 7;
    }

   bd.textContent = o_month + "/" + o_day + "~" + month + "/" + day;

  }
}
<p id="bon_date" class="inline" style="color:#0000ff;" contenteditable="true"> Enter date (MM/DD) </p>

That gets your code working. Sort of. You should think about validating user input to make sure it's a valid date (not the 1000th day of a 50th month) etc. Moment.js is a very handy JavaScript library to use when dealing with dates and times.