0

I have this code that generates a calendar. I want the dates to be links. So for example, if a date is Today, the link will be https://example.com/dates/2020-09-18. This will be dynamic for any date. If date year selected is 2016-10-20, the link for the date becomes https://example.com/dates/2016-10-20 etc.

The code is

function generate_year_range(start, end) {
  var years = "";
  for (var year = start; year <= end; year++) {
    years += "<option value='" + year + "'>" + year + "</option>";
  }
  return years;
}

var today = new Date();
var currentMonth = today.getMonth();
var currentYear = today.getFullYear();
var selectYear = document.getElementById("year");
var selectMonth = document.getElementById("month");


var createYear = generate_year_range(2016, 2021);
/** or
 * createYear = generate_year_range( 1970, currentYear );
 */

document.getElementById("year").innerHTML = createYear;

var calendar = document.getElementById("calendar");
var lang = calendar.getAttribute('data-lang');

var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

var dayHeader = "<tr>";
for (day in days) {
  dayHeader += "<th data-days='" + days[day] + "'>" + days[day] + "</th>";
}
dayHeader += "</tr>";

document.getElementById("thead-month").innerHTML = dayHeader;


monthAndYear = document.getElementById("monthAndYear");
showCalendar(currentMonth, currentYear);



function next() {
  currentYear = (currentMonth === 11) ? currentYear + 1 : currentYear;
  currentMonth = (currentMonth + 1) % 12;
  showCalendar(currentMonth, currentYear);
}

function previous() {
  currentYear = (currentMonth === 0) ? currentYear - 1 : currentYear;
  currentMonth = (currentMonth === 0) ? 11 : currentMonth - 1;
  showCalendar(currentMonth, currentYear);
}

function jump() {
  currentYear = parseInt(selectYear.value);
  currentMonth = parseInt(selectMonth.value);
  showCalendar(currentMonth, currentYear);
}

function showCalendar(month, year) {

  var firstDay = (new Date(year, month)).getDay();

  tbl = document.getElementById("calendar-body");


  tbl.innerHTML = "";


  monthAndYear.innerHTML = months[month] + " " + year;
  selectYear.value = year;
  selectMonth.value = month;

  // creating all cells
  var date = 1;
  for (var i = 0; i < 6; i++) {
    var row = document.createElement("tr");

    for (var j = 0; j < 7; j++) {
      if (i === 0 && j < firstDay) {
        cell = document.createElement("td");
        cellText = document.createTextNode("");
        cell.appendChild(cellText);
        row.appendChild(cell);
      } else if (date > daysInMonth(month, year)) {
        break;
      } else {
        cell = document.createElement("td");
        cell.setAttribute("data-date", date);
        cell.setAttribute("data-month", month + 1);
        cell.setAttribute("data-year", year);
        cell.setAttribute("data-month_name", months[month]);
        cell.className = "date-picker";
        cell.innerHTML = "<span>" + date + "</span>";

        if (date === today.getDate() && year === today.getFullYear() && month === today.getMonth()) {
          cell.className = "date-picker selected";
        }
        row.appendChild(cell);
        date++;
      }


    }

    tbl.appendChild(row);
  }

}

function daysInMonth(iMonth, iYear) {
  return 32 - new Date(iYear, iMonth, 32).getDate();
}
html {
  font-family: sans-serif;
  font-size: 15px;
  line-height: 1.4;
  color: #444;
}

body {
  margin: 0;
  background: #504f4f;
  font-size: 1em;
}

.wrapper {
  margin: 15px auto;
  max-width: 1100px;
}

.container-calendar {
  background: #ffffff;
  padding: 15px;
  max-width: 475px;
  margin: 0 auto;
  overflow: auto;
}

.button-container-calendar button {
  cursor: pointer;
  display: inline-block;
  zoom: 1;
  background: #00a2b7;
  color: #fff;
  border: 1px solid #0aa2b5;
  border-radius: 4px;
  padding: 5px 10px;
}

.table-calendar {
  border-collapse: collapse;
  width: 100%;
}

.table-calendar td,
.table-calendar th {
  padding: 5px;
  border: 1px solid #e2e2e2;
  text-align: center;
  vertical-align: top;
}

.date-picker.selected {
  font-weight: bold;
  outline: 1px dashed #00BCD4;
}

.date-picker.selected span {
  border-bottom: 2px solid currentColor;
}


/* sunday */

.date-picker:nth-child(1) {
  color: red;
}


/* friday */

.date-picker:nth-child(6) {
  color: green;
}

#monthAndYear {
  text-align: center;
  margin-top: 0;
}

.button-container-calendar {
  position: relative;
  margin-bottom: 1em;
  overflow: hidden;
  clear: both;
}

#previous {
  float: left;
}

#next {
  float: right;
}

.footer-container-calendar {
  margin-top: 1em;
  border-top: 1px solid #dadada;
  padding: 10px 0;
}

.footer-container-calendar select {
  cursor: pointer;
  display: inline-block;
  zoom: 1;
  background: #ffffff;
  color: #585858;
  border: 1px solid #bfc5c5;
  border-radius: 3px;
  padding: 5px 1em;
}
<!DOCTYPE>
<html>

<head>
  <link rel="stylesheet" type="text/css" href="calendar.css">
</head>

<body>
  <div class="wrapper">
    <div class="container-calendar">
      <h3 id="monthAndYear"></h3>
      <div class="button-container-calendar">
        <button id="previous" onclick="previous()">&#8249;</button>
        <button id="next" onclick="next()">&#8250;</button>
      </div>

      <table class="table-calendar" id="calendar" data-lang="en">
        <thead id="thead-month"></thead>
        <tbody id="calendar-body"></tbody>
      </table>

      <div class="footer-container-calendar">
        <label for="month">Jump To: </label>
        <select id="month" onchange="jump()">
          <option value=0>Jan</option>
          <option value=1>Feb</option>
          <option value=2>Mar</option>
          <option value=3>Apr</option>
          <option value=4>May</option>
          <option value=5>Jun</option>
          <option value=6>Jul</option>
          <option value=7>Aug</option>
          <option value=8>Sep</option>
          <option value=9>Oct</option>
          <option value=10>Nov</option>
          <option value=11>Dec</option>
        </select>
        <select id="year" onchange="jump()"></select>
      </div>
    </div>
  </div>
  <script src="calendar.js" type="text/javascript"></script>
</body>

</html>

8
  • 1
    What exactly is wrong with the code you posted? You told us your goal and showed code, but I don't know what exact issue you are facing. Commented Sep 18, 2020 at 11:12
  • What have you tried? Where is the problem? Commented Sep 18, 2020 at 11:13
  • I don't know Javascript at all, forgive me so I was not able to create links for the dates. That is what I'm hopeful of doing. Commented Sep 18, 2020 at 11:18
  • Does this answer your question? How do I create a link using javascript? Commented Sep 18, 2020 at 11:19
  • Where will the link appear after date the is selected ? Its very unclear whats the end goal here. Commented Sep 18, 2020 at 11:21

1 Answer 1

1
function links () {
    document.querySelectorAll('td.date-picker > span').forEach(element => {
    //get all days from calendar as element
    
      var year = element.parentElement.getAttribute('data-year');
    //extract year data attribute from parent element div
    
      var month = element.parentElement.getAttribute('data-month');
    //extract month data attribute from parent element div
    
      var day =  element.textContent;
    //save day value
    
      if (month.length === 1) {
        month = "0" + month;
      }
    // if month is one digit add 0 to it
    
        if (day.length === 1) {
        day = "0" + day;
      }
    // if day is one digit add 0 to it
    
      element.innerHTML = '<a href="https://example.com/dates/' + year + '-' + month + '-' + day + '">' + element.textContent + '</a> '
    //replace element with link data
    })
}
links()

WORKING EXAMPLE:

function generate_year_range(start, end) {
  var years = "";
  for (var year = start; year <= end; year++) {
    years += "<option value='" + year + "'>" + year + "</option>";
  }
  return years;
}

var today = new Date();
var currentMonth = today.getMonth();
var currentYear = today.getFullYear();
var selectYear = document.getElementById("year");
var selectMonth = document.getElementById("month");


var createYear = generate_year_range(2016, 2021);
/** or
 * createYear = generate_year_range( 1970, currentYear );
 */

document.getElementById("year").innerHTML = createYear;

var calendar = document.getElementById("calendar");
var lang = calendar.getAttribute('data-lang');

var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

var dayHeader = "<tr>";
for (day in days) {
  dayHeader += "<th data-days='" + days[day] + "'>" + days[day] + "</th>";
}
dayHeader += "</tr>";

document.getElementById("thead-month").innerHTML = dayHeader;


monthAndYear = document.getElementById("monthAndYear");
showCalendar(currentMonth, currentYear);



function next() {
  currentYear = (currentMonth === 11) ? currentYear + 1 : currentYear;
  currentMonth = (currentMonth + 1) % 12;
  showCalendar(currentMonth, currentYear);
  links () 
}

function previous() {
  currentYear = (currentMonth === 0) ? currentYear - 1 : currentYear;
  currentMonth = (currentMonth === 0) ? 11 : currentMonth - 1;
  showCalendar(currentMonth, currentYear);
  links () 
}

function jump() {
  currentYear = parseInt(selectYear.value);
  currentMonth = parseInt(selectMonth.value);
  showCalendar(currentMonth, currentYear);
  links () 
}

function showCalendar(month, year) {

  var firstDay = (new Date(year, month)).getDay();

  tbl = document.getElementById("calendar-body");


  tbl.innerHTML = "";


  monthAndYear.innerHTML = months[month] + " " + year;
  selectYear.value = year;
  selectMonth.value = month;

  // creating all cells
  var date = 1;
  for (var i = 0; i < 6; i++) {
    var row = document.createElement("tr");

    for (var j = 0; j < 7; j++) {
      if (i === 0 && j < firstDay) {
        cell = document.createElement("td");
        cellText = document.createTextNode("");
        cell.appendChild(cellText);
        row.appendChild(cell);
      } else if (date > daysInMonth(month, year)) {
        break;
      } else {
        cell = document.createElement("td");
        cell.setAttribute("data-date", date);
        cell.setAttribute("data-month", month + 1);
        cell.setAttribute("data-year", year);
        cell.setAttribute("data-month_name", months[month]);
        cell.className = "date-picker";
        cell.innerHTML = "<span>" + date + "</span>";

        if (date === today.getDate() && year === today.getFullYear() && month === today.getMonth()) {
          cell.className = "date-picker selected";
        }
        row.appendChild(cell);
        date++;
      }


    }

    tbl.appendChild(row);
  }

}

function daysInMonth(iMonth, iYear) {
  return 32 - new Date(iYear, iMonth, 32).getDate();
}

function links () {
document.querySelectorAll('td.date-picker > span').forEach(element => {
  var year = element.parentElement.getAttribute('data-year');
  var month = element.parentElement.getAttribute('data-month');
  var day =  element.textContent;
  if (month.length === 1) {
    month = "0" + month;
  }
    if (day.length === 1) {
    day = "0" + day;
  }
  element.innerHTML = '<a href="https://example.com/dates/' + year + '-' + month + '-' + day + '">' + element.textContent + '</a> '
})
}

links ()
html {
  font-family: sans-serif;
  font-size: 15px;
  line-height: 1.4;
  color: #444;
}

body {
  margin: 0;
  background: #504f4f;
  font-size: 1em;
}

.wrapper {
  margin: 15px auto;
  max-width: 1100px;
}

.container-calendar {
  background: #ffffff;
  padding: 15px;
  max-width: 475px;
  margin: 0 auto;
  overflow: auto;
}

.button-container-calendar button {
  cursor: pointer;
  display: inline-block;
  zoom: 1;
  background: #00a2b7;
  color: #fff;
  border: 1px solid #0aa2b5;
  border-radius: 4px;
  padding: 5px 10px;
}

.table-calendar {
  border-collapse: collapse;
  width: 100%;
}

.table-calendar td,
.table-calendar th {
  padding: 5px;
  border: 1px solid #e2e2e2;
  text-align: center;
  vertical-align: top;
}

.date-picker.selected {
  font-weight: bold;
  outline: 1px dashed #00BCD4;
}

.date-picker.selected span {
  border-bottom: 2px solid currentColor;
}


/* sunday */

.date-picker:nth-child(1) {
  color: red;
}


/* friday */

.date-picker:nth-child(6) {
  color: green;
}

#monthAndYear {
  text-align: center;
  margin-top: 0;
}

.button-container-calendar {
  position: relative;
  margin-bottom: 1em;
  overflow: hidden;
  clear: both;
}

#previous {
  float: left;
}

#next {
  float: right;
}

.footer-container-calendar {
  margin-top: 1em;
  border-top: 1px solid #dadada;
  padding: 10px 0;
}

.footer-container-calendar select {
  cursor: pointer;
  display: inline-block;
  zoom: 1;
  background: #ffffff;
  color: #585858;
  border: 1px solid #bfc5c5;
  border-radius: 3px;
  padding: 5px 1em;
}
<!DOCTYPE>
<html>

<head>
  <link rel="stylesheet" type="text/css" href="calendar.css">
</head>

<body>
  <div class="wrapper">
    <div class="container-calendar">
      <h3 id="monthAndYear"></h3>
      <div class="button-container-calendar">
        <button id="previous" onclick="previous()">&#8249;</button>
        <button id="next" onclick="next()">&#8250;</button>
      </div>

      <table class="table-calendar" id="calendar" data-lang="en">
        <thead id="thead-month"></thead>
        <tbody id="calendar-body"></tbody>
      </table>

      <div class="footer-container-calendar">
        <label for="month">Jump To: </label>
        <select id="month" onchange="jump()">
          <option value=0>Jan</option>
          <option value=1>Feb</option>
          <option value=2>Mar</option>
          <option value=3>Apr</option>
          <option value=4>May</option>
          <option value=5>Jun</option>
          <option value=6>Jul</option>
          <option value=7>Aug</option>
          <option value=8>Sep</option>
          <option value=9>Oct</option>
          <option value=10>Nov</option>
          <option value=11>Dec</option>
        </select>
        <select id="year" onchange="jump()"></select>
      </div>
    </div>
  </div>
  <script src="calendar.js" type="text/javascript"></script>
</body>

</html>

EDIT:

To apply this on calendar navigation wrap this in function

links ()

and call it on page load as well as your navigating function, i added links () at end to initiate it:

function next() {
function previous() {
function jump() {
Sign up to request clarification or add additional context in comments.

14 Comments

Your code works like I want but it's missing other months, dates.
@maryongubo Please study the code for future reference, people here like to see some attempt at desired effect. But I know how is it when you get stuck and do not even know where to start, plus you are new here. Keep in mind this website is not free writing service, its bug fix mostly. So please try to learn how this code i wrote works. If you have any questions feel free to ask. Cheers and welcome to SO
Added the code in WordPress but links disappear when I navigate. I copied the whole code here because it already works like I want. I don't know what could be different in WordPress.
@maryongubo Did you check your console.log for errors?
@maryongubo Also I hope you copied whole code from fiddle including functions next() , previous() and jump() , because that is where I added links () at end to react to navigating calendar.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.