0

I hope someone can help me, I'm afraid I'm very new to javascript and so apologies if this problem has a a very simple solution. However, I have spent a lot of time trying to fix this myself, but no success.

The purpose of the code is to determine how many days there are in the month and to dynamically create a button relating to each of those days. Overlaying this 'calendar' is a div with a close button which will contain question details, the close button closes this div to reveal the 'calendar' underneath.

I have a number of issues; firstly, the buttons do not appear to be acting like buttons- the cursor doesn't change to a pointer on mouse over and the pseudo classes for hover, active etc. aren't recognised. Secondly, although the buttons appear to have the 'click' listener attached in chrome element inspector they do not execute the 'showQuestion' function.

The code is as follows:

The CSS

 .day {
    width: 15%;
    max-width: 120px;
    min-width: 60px;
    height: 15%;
    max-height: 120px;
    min-height: 60px;
    padding: 10px;
    border: 1px solid #aaaaaa;
    margin: 5px;
    color: white;
    background-color:#000088;
    display:block;
    cursor:pointer;
}



  .day:hover, .day:active{
        background:#00ddff;
    }



 .day:focus{
        border 1px solid #000000;
    }



    .day.today{
        background-color: Red;
    }

    .centred{
        display: -webkit-box;   /* OLD - iOS 6-, Safari 3.1-6 */
        display: -moz-box;      /* OLD - Firefox 19- (buggy but mostly works) */
        display: -ms-flexbox;   /* TWEENER - IE 10 */
        display: -webkit-flex;  /* NEW - Chrome */
        display: flex; 
        align-self: center;
        justify-content: ltr;
        flex-wrap: wrap;
    }

    #container {
        position: fixed;
        margin-top: 25%;
        margin-left: 10%;
        overflow: hidden;
        width: 80%;
        height: auto;
        background-color: yellow; 
        z-index: 1000;
    }



    #questionContainer{
        position:fixed;
        margin-top: 5%;
        margin-left: 5%;
        width: 90%;
        height: 90%;
        display:block;
        background-color: green;
        z-index:3000;
    }



     #closeButton{
        background: blue;
        text-decoration: : none;
        padding: 5px 5px 5px 25px;
        border:none;
        color:white;
        cursor:pointer;

    }



 .show {
        -o-transition: opacity .5s;
        -moz-transition: opacity .5s;
        -webkit-transition: opacity .5s;
        transition: opacity .5s;
        opacity:1;
        filter:alpha(opacity=100); /*IE transparency*/
    }



 #closeButton:hover, #closeButton:active{
        background:#ffffff;
    }

    #closeButton:focus{
        border 1px solid #000000;
    }




 .hide {  
        -o-transition: opacity .5s;
        -moz-transition: opacity .5s;
        -webkit-transition: opacity .5s;
        transition: opacity .5s;
        opacity: 0; 
        filter:alpha(opacity=0); /*IE transparency*/
    }

The HTML

<body>

<div id="container" class="centred">
</div>

<div id = "questionContainer" class="centred">
    <button id = "closeButton" class = "show" onClick="hideQuestion()">Close</button>
</div>

</body>

Javascript

 var qtnContainer = document.getElementById("questionContainer");

    function hideQuestion(){
        qtnContainer.className = "hide";
    }

     function showQuestion(){
        qtnContainer.className = "show";
    }

    Date.prototype.daysInThisMonth=function() {
        return new Date(this.getFullYear(),this.getMonth()+1,0).getDate();
    };

    var days = new Date().daysInThisMonth();
    var today = new Date().getDate();

    //alert("days in month = "+ days);
    //alert("day of the month = "+ today);

    for (var i = 0; i < days; i++){
        var dayBtn = document.createElement("button");
        dayBtn.innerHTML = "Day "+(i+1);
        document.getElementById("container").appendChild(dayBtn); 
        if(dayBtn !== null){
            dayBtn.id = "day"+(i+1);
            dayBtn.className = "day";
            dayBtn.addEventListener("click",showQuestion, false);
        }

    } 

    alert("day"+today);

    if(dayBtn.id = "day"+today){
    document.querySelector("#day"+today).className += " today";
    }  

While I appreciate any help I receive please do not supply me with any jQuery solutions, I want to build the functionality in pure javascript to increase my understanding of the language.

Thanks in advance for any help!

3 Answers3

1

So, you've got a couple of small issues with the code, but past those, it's actually all working.

First off, assuming this is your entire javascript file, you're attempting to run code looking for elements on the page, when the page hasn't fully loaded yet. So what you need to do, is only start executing this code when the body has loaded. Simple to do, just change your body tag to look something like this:

<body onload="now_do_stuff()">

And then wrap the JS that is currently not inside of a function, in this new function. So something like:

function now_do_stuff() {

    qtnContainer = document.getElementById("questionContainer");

    for (var i = 0; i < days; i++){
        var dayBtn = document.createElement("button");
        dayBtn.innerHTML = "Day "+(i+1);
        document.getElementById("container").appendChild(dayBtn); 
        if(dayBtn !== null){
            dayBtn.id = "day"+(i+1);
            dayBtn.className = "day";
            dayBtn.addEventListener("click",showQuestion, false);
        }

    } 

    alert("day"+today);

    if(dayBtn.id = "day"+today) {
        document.querySelector("#day"+today).className += " today";
    }
}

And then it will work!

Note that I've moved the very first line (where you declare qtnContainer) into this function too, and removed that 'var'. The reason for this is that it will make it a global variable, that the other functions (i.e. hideQuestion and showQuestion) then have access to.

David Downes
  • 1,145
  • 10
  • 24
  • Thanks very much for your help, both yours and spassvogel's answers combined means that it is now working. However, it wasn't working for me in Chrome without the 'pointer-events' CSS. I thought it might've been something to do with the creation of the elements, but hope the null 'if' statement covered that. Adding an action to the body will, I'm sure be a very useful hint for mein the future. Thanks again for prompt response as well. – user3331939 Feb 20 '14 at 11:26
0

You should delegate the click event.

So instead of: dayBtn.addEventListener("click",showQuestion, false);

It should be: document.getElementById("day"+(i+1)).addEventListener("click",showQuestion, false);

Something like this I think. (not sure since I use mainly jQuery)

drip
  • 12,378
  • 2
  • 30
  • 49
  • Thanks for your advice, I'm sure you're right, but the listener is working 'as is' at the moment and if it ain't broke I'm not going to try to fix it! I'll keep your suggestion in mind though when it breaks in the future... – user3331939 Feb 20 '14 at 11:32
0

Well, the event was wired up properly, but your questionContainer was still blocking any interaction with the mouse. Use pointer-events: none to fix this.

Like this:

 .hide {  
        -o-transition: opacity .5s;
        -moz-transition: opacity .5s;
        -webkit-transition: opacity .5s;
        transition: opacity .5s;
        opacity: 0; 
        filter:alpha(opacity=0); /*IE transparency*/
        pointer-events:none;
    }

See it working: http://jsfiddle.net/t9zvS/1/

Possibly you'll have some problems in IE. Research this SO topic: Pass mouse events through absolutely-positioned element

Community
  • 1
  • 1
spassvogel
  • 3,479
  • 2
  • 18
  • 23
  • Great, thanks very much for your help and your prompt response, I'll look into the IE issues as advised. I'd never even heard of 'pointer-events'! – user3331939 Feb 20 '14 at 11:30