1

I have this function, that gives the user the correct amount of buttons depending on the month. So if the user loads the page, Februari will show up, and 28 buttons aswell. If the user changes to March, there will be 31 buttons. The user is able to click on the button, and the corresponding button will be added to the mySql database. So if the user chooses Februari, and the button 3, the value in the database will say 2018-02-03. The problem is, and what I need help with, is if the user changes the month on the page, it does not change the value in the database. The month value in the database is always the current month of the year. Tried different solutions but nothing works. The value of the month is in a h2 with the id "displayingMonth".

Function:

  function drawTable(daysInMonth) {
          var cellsToDraw = daysInMonth;
          var table = document.getElementById("table");
          var dateObj = new Date();
            var month = dateObj.getMonth()+1;
            var day = dateObj.getDate();
            var year = dateObj.getFullYear();
            newdate = year + "-" + month;
            table.innerHTML = "";
          for (r = 0; r < (daysInMonth / 7); r++) {
            var newRow = document.createElement("tr");
            table.appendChild(newRow);
            for (c = 0; c < 31 && cellsToDraw > 0; c++) {
            v = c +1;
            //var newCell = document.createElement("td");
              var newCell = document.createElement("input");
              newCell.setAttribute("type", "radio");
              newCell.setAttribute("name", "day");
              newCell.setAttribute("value", newdate + "-" + v);
              newRow.appendChild(newCell);
              newCell.innerHTML = 
              cellsToDraw--;
            }
          }
        }

to get the month displayed:

function daysInMonth(month, year) {
     var days;
     switch (month) {
       case 1: 
       var leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
       days = leapYear ? 29 : 28;
       break;
       case 3:
       case 5:
       case 8:
       case 10:
       days = 30;
       break;
       default:
       days = 31;
      }
      return days;
    }

To get the month:

 window.onload = function() {
    var month = new Date();
    var index = month.getMonth();
    var months = ["Januari", "Februari", "March", "April", "May", "June", "July", "Augusti", "September", "October", "November", "December"];
    document.getElementById("todayField").innerHTML = months[month.getMonth()];
    // Draws a table for the current month
    drawTable(daysInMonth(index, 2018));
    }

to get the next month

   function next() {
        var months = ["Januari", "Februari", "March", "April", "May", "June", "July", "Augusti", "September", "October", "November", "December"];
        var weeks = ["Sunday", "Monday", "Tuseday", "Wednesday", "Thursday", "Friday", "Saturday"];
        var nextMonth = index + 1 > 11 ? 0 : index + 1;
        index = nextMonth;
        document.getElementById("displayingMonth").innerHTML = months[nextMonth];
        drawTable(daysInMonth(index, 2018));
      }

HTML

  <input id="newCell"type="hidden"name="day" value="">

All help is appriciated!

Alison
  • 147
  • 9
  • 1
    Are you trying to build your own date picker? If you wish to save a lot of time... you could have a look into [jQuery UI DatePicker](https://jqueryui.com/datepicker/)... then all you have to focus on, is the ajax and php to update/retrieve from database. – IncredibleHat Feb 09 '18 at 16:50
  • @IncredibleHat thanks for the tip! I know I can use it, but I dont really like the way it looks and that is why I want to do my own. I have a easy connection to the database, so that is not the issue, the issue is only with the month – Alison Feb 09 '18 at 16:52
  • @IncredibleHat me aswell! but I added some more code, that might help? – Alison Feb 09 '18 at 16:57
  • @IncredibleHat the php takes the value from the html input, I dont think the issue is with the php, since I can add value in to the database. No I dont use any ajax calls – Alison Feb 09 '18 at 17:01
  • I would personally start at the submit portion of the PHP code. Try giving it input that you would expect from the form and see if you're still having the same issue. Then move along, testing each element as you go. I like starting at the source. You said you think the php code is fine. Maybe post it here and we can see where the issue might be, as if it is always using the current year and month, I might expect this to be in the php code. Or the way it is formatting the date maybe. Either way, including that piece will help with troubleshooting. – adprocas Feb 09 '18 at 17:05

1 Answers1

2

Alright, some slight adjustments here. This is highly specific to your code, so bear with the changes. The issue lies with the use of var dateObj = new Date(); and then pulling the month from it to add to each 'day' radio input a user chooses.

Each input is using the 'current date' for that, and thus pulls the wrong month for what its passing.

Instead, you'll need to push the selected month date into the drawTable function, so it can build properly from that. And example of such would be:

function drawTable(daysInMonth,selectedMonth) {
    ...
    // selectedMonth has the proper index for the Date() function
    // setting 2018 here, because your code isnt inc years yet
    var dateObj = new Date(2018, selectedMonth, 1, 0, 0, 0, 0);
    ...
}

window.onload = function() {
    ...
    drawTable(daysInMonth(index, 2018), month.getMonth());
}

function next() {
    // you may want to deal with looping to the next year here too
    ...
    drawTable(daysInMonth(index, 2018), nextMonth);// nextMonth holds proper index
}

I think I should note that this passes the "month index", because new Date() takes a month index of 0 - 11. So passing it straight from a .getMonth() is the most compatible (no need to add +1 or -1 to them).


Here is also full chunk of your code with many changes applied to reduce some complexity and allow for years to roll as next month loops. There are a lot of changes in here, but mainly, it relies a lot more on the Date() object. No need for the daysInMonth() function you have.

// set as global
var showDate = new Date();
var months = ["Januari", "Februari", "March", "April", "May", "June", 
              "July", "Augusti", "September", "October", "November", "December"];
var weeks = ["Sunday","Monday","Tuseday","Wednesday","Thursday","Friday","Saturday"];

function drawTable(forDate) {
    var daysInMonth = new Date(forDate.getFullYear(),forDate.getMonth()+1,0).getDate();
    // ^^^ magic way to get number of days!
    var cellsToDraw = daysInMonth;
    // for a zero-padded non-index YYYY-MM prefix value:
    var newdate = forDate.getFullYear() +"-"+ ("0"+ (forDate.getMonth() + 1)).slice(-2);
    var table = document.getElementById("table");
    table.innerHTML = "";
    for (var r = 0; r < (daysInMonth / 7); r++) {
        var newRow = document.createElement("tr");
        table.appendChild(newRow);
        for (var c = 0; c < 31 && cellsToDraw > 0; c++) {
            // for a zero-padded day to tack onto newdate
            var day = ("0" + (c + 1)).slice(-2);
            var newCell = document.createElement("input");
            newCell.setAttribute("type", "radio");
            newCell.setAttribute("name", "day");
            newCell.setAttribute("value", newdate + "-" + day);// makes YYYY-MM-DD
            newRow.appendChild(newCell);
            newCell.innerHTML = '';
            cellsToDraw--;
        }
    }
}

window.onload = function() {
    document.getElementById("todayField").innerHTML = months[showDate.getMonth()];
    drawTable( showDate );
};

function next() {
    if (showDate.getMonth() == 11) {
        showDate.setMonth( 0 );
        showDate.setFullYear( showDate.getFullYear()+1 );
    } else {
        showDate.setMonth( showDate.getMonth()+1 );
    }
    document.getElementById("displayingMonth").innerHTML = months[showDate.getMonth()];
    drawTable( showDate );
}

function prev() {
    if (showDate.getMonth() === 0) {
        showDate.setMonth( 11 );
        showDate.setFullYear( showDate.getFullYear()-1 );
    } else {
        showDate.setMonth( showDate.getMonth()-1 );
    }
    document.getElementById("displayingMonth").innerHTML = months[showDate.getMonth()];
    drawTable( showDate );
}
IncredibleHat
  • 4,006
  • 4
  • 13
  • 27
  • Thanks for the example! But I dont really think that I fully understand what I am supposed to do. Should I create a new function called selectedMonth? – Alison Feb 09 '18 at 17:33
  • No. Add `selectedMonth` as a second parameter to your current function. Then in the other actions that call `drawTable` ... you include the month index. If its next, it includes the next month index, if its first load, its going to be the current month index. All the `...` means all that other code you currently have is unchanged... just changing the lines I have shown here. – IncredibleHat Feb 09 '18 at 17:37
  • I added a big hunk of 'new' code you could try out as well. Has a lot of changes to it, elimination of complexity. – IncredibleHat Feb 09 '18 at 18:06
  • Happy coding @Alison ! You got a monster project going there :) – IncredibleHat Feb 09 '18 at 18:31
  • 1
    But is there a way for me to show what year it is next to the month? I tried document.getElementById("displayingMonth").innerHTML = months[showDate.getMonth() + date.getFullYear()]; but it did not work in the window.onload = function() – Alison Feb 09 '18 at 18:34
  • That would be doing 'math' since both of those return ints. You would need to put the `+ showDate.getFullYear()` OUTSIDE of the end brace `]`... `document.getElementById("displayingMonth").innerHTML = months[showDate.getMonth()] +' '+ showDate.getFullYear();` – IncredibleHat Feb 09 '18 at 18:54
  • But, I just noticed that the date comes in to the database as 2018-2-2, instead of 2018-02-02. Why does it do that? Is is due to some date settings? – Alison Feb 09 '18 at 19:12
  • That would be since the Date() returns ints (02 really isnt an int). If your database needs them to be purely zero-padded (?) you may have to break the incoming POST var into parts, and pad each day and month accordingly. Kind of beyond this question though, its not as easy to do in javascript as it is in php (https://stackoverflow.com/questions/10073699/pad-a-number-with-leading-zeros-in-javascript) – IncredibleHat Feb 09 '18 at 19:16
  • Well, since I have another function that search for the date as YY-MM-DD I will need to have it in the right format, otherwise my other function will not work – Alison Feb 09 '18 at 19:30
  • YY ? Hehe... didn't the y2k scare force you to stick with YYYY ? ;) I understand. If pulling the value from the database is not YY-MM-DD, you can format it to do so (look at sql DATE_FORMAT syntax if the field is a datetime field). If its a varchar field, then just use PHP, and drop it into something like this `date('y-m-d',strtotime( $thedatestring ));` – IncredibleHat Feb 09 '18 at 19:35
  • Will use YYYY ;) . No so im not using datetime, just a simple varchar, but the other function is via a datePicker, which searches for YYYY-MM-DD, thats why I need it in that format – Alison Feb 09 '18 at 19:43
  • If you need two digit month and day in javascript side (to use/set in the input value), this can help: https://stackoverflow.com/a/6040556/2960971 (I applied this to the big alternative code example in my answer above) – IncredibleHat Feb 09 '18 at 19:54
  • Alright! I will need to look in to the link that you wrote! :) – Alison Feb 09 '18 at 20:18
  • I was thinking, is it possible to add a placeholder to the buttons? I mean that the first button says "1", the second says "2", and so on? Like a placeholder – Alison Feb 10 '18 at 16:03
  • Yes, you'll have to append more in the js when adding the `input` to that table. I'd suggest wrapping the input and text in a `label` element, so that it behaves as one clickable item. – IncredibleHat Feb 10 '18 at 16:31
  • Hmm.. not sure if I really understand what you mean unfortunately.. :( – Alison Feb 10 '18 at 16:32
  • Well its a bit too complex to cover in comments, and we've kind of gone out of the scope of this original question ;) hehe. It may be a good new question about how to append more things to the DOM with JS. How to wrap a radio input with a label and text dynamically with js. – IncredibleHat Feb 10 '18 at 16:36
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/164892/discussion-between-alison-and-incrediblehat). – Alison Feb 10 '18 at 16:55