4

I'm pretty new to HTML, CSS and jQuery - and while my HTML and CSS are OK, my jQuery is not too good - and I think I'm trying to achieve something quite complicated.

As you can see in the code I have a calendar built, and I want people to be able to navigate around it using their arrow keys and press enter to highlight a square. The best example of what I want is this http://jsfiddle.net/BNrBX/ but it VERY confusing! As the html has noting but the container div, and I'm not good enough at understanding jQuery to really get what has been written.

Here is the HTML code for the calendar:

<div class="calander">

<div class="date"><div class="calandertext">&#60;</div></div>
<div class="month" id="month2"><div class="calandertext">April</div></div>
<div class="date"><div class="calandertext">&#62;</div></div>

<div class="day"><div class="calandertext">M</div></div>
<div class="day"><div class="calandertext">T</div></div>
<div class="day"><div class="calandertext">W</div></div>
<div class="day"><div class="calandertext">T</div></div>
<div class="day"><div class="calandertext">F</div></div>
<div class="day"><div class="calandertext">S</div></div>
<div class="day"><div class="calandertext">S</div></div>

<div class="date"><div class="calandertext"></div></div>
<div class="date"><div class="calandertext">1</div></div>
<div class="date"><div class="calandertext">2</div></div>
<div class="date"><div class="calandertext">3</div></div>
<div class="date"><div class="calandertext">4</div></div>
<div class="date"><div class="calandertext">5</div></div>
<div class="date"><div class="calandertext">6</div></div>

<div class="date"><div class="calandertext">7</div></div>
<div class="date"><div class="calandertext">8</div></div>
<div class="date"><div class="calandertext">9</div></div>
<div class="date"><div class="calandertext">10</div></div>
<div class="date"><div class="calandertext">11</div></div>
<div class="date"><div class="calandertext">12</div></div>
<div class="date"><div class="calandertext">13</div></div>

<div class="date"><div class="calandertext">14</div></div>
<div class="date"><div class="calandertext">15</div></div>
<div class="date"><div class="calandertext">16</div></div>
<div class="date"><div class="calandertext">17</div></div>
<div class="date"><div class="calandertext">18</div></div>
<div class="date"><div class="calandertext">19</div></div>
<div class="date"><div class="calandertext">20</div></div>

<div class="date"><div class="calandertext">21</div></div>
<div class="date"><div class="calandertext">22</div></div>
<div class="date"><div class="calandertext">23</div></div>
<div class="date"><div class="calandertext">24</div></div>
<div class="date"><div class="calandertext">25</div></div>
<div class="date"><div class="calandertext">26</div></div>
<div class="date"><div class="calandertext">27</div></div>

<div class="date"><div class="calandertext">28</div></div>
<div class="date"><div class="calandertext">29</div></div>
<div class="date"><div class="calandertext">30</div></div>
<div class="date"><div class="calandertext"></div></div>
<div class="date"><div class="calandertext"></div></div>
<div class="date"><div class="calandertext"></div></div>
<div class="date"><div class="calandertext"></div></div>

</div>

And heres the CSS:

.calander {
font-size: 0;
    width: 70%
}

.month {
position: relative;
height: 80px;
background-color: #FFE06B;
width: 71.4265%;
display: inline-block;
}

.day {
position: relative;
height: 50px;
background-color: #4DC3F0;
display: inline-block;
width: 14.2853%;
}

.date {
position: relative;
height: 80px;
background-color: #FFE06B;
display: inline-block;
width: 14.2853%;
-webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;
   box-sizing: border-box;
}

.calandertext {
position: absolute;
bottom: 0;
left: 0;
right: 0;
top: 50%;
text-align: center;
line-height: 0;
font-size: 40px;
}

I've put both together in a jsfiddle: http://jsfiddle.net/9SVez/

Any help - or a pointer of where to go - would be simply fantastic.

Thanks! Josh

Iswanto San
  • 18,263
  • 13
  • 58
  • 79
JoshuaESummers
  • 493
  • 2
  • 7
  • 24

3 Answers3

2

It doesn't need to be as difficult as the example you're working off. That example is ridiculously verbose and isn't particularly very well designed.

In my example below I've hooked up the arrow events, the main part about what makes my code simple is the calendarMap variable. It's an array that holds all the divs in their x,y positions, this allows us to make moving around the map as simple as moving around the x,y values.

jsFiddle

var position = { x: 0, y: 0 };
var calendarMap = [];

$(document).ready(function () {
    $('.row').each(function () {
        calendarMap.push([]);
        $('.day, .date', this).each(function () {
            calendarMap[calendarMap.length - 1].push($(this));
        });
    });
    highlightCell();
});

$(window).on('keydown', function (e) {
    if (e.keyCode === 37) // left
        moveLeft();
    else if (e.keyCode === 38) // up
        moveUp();
    else if (e.keyCode === 39) // right
        moveRight();
    else if (e.keyCode === 40) // down
        moveDown();
    highlightCell();
});

function moveLeft() {
    position.x--;
    if (position.x < 0)
        position.x = 0;
}

function moveUp() {
    position.y--;
    if (position.y < 0)
        position.y = 0;
}

function moveRight() {
    position.x++;
    if (position.x >= calendarMap[0].length)
        position.x = calendarMap[0].length - 1;
}

function moveDown() {
    position.y++;
    if (position.y >= calendarMap.length)
        position.y = calendarMap.length - 1;
}

function highlightCell() {
    $('.day, .date').removeClass('selected');
    calendarMap[position.y][position.x].addClass('selected');
}

I've left getting the mouse events working and the top row as an exercise for you. For the mouse you want to handle mouseover, figure out which item in calendarMap is being hovered, set position and call highlightCell(). For the top row you probably want to add some custom attributes or something because it's a row with only 3 cells.

Daniel Imms
  • 47,944
  • 19
  • 150
  • 166
  • Your answer works great. And i'm trying to use your solution for other tasks but the difficulty am facing is that when contents of the main div is overflown, contents of the div does not scroll to the exact position of the current active position. here's an updated jsFiddle of your answer http://jsfiddle.net/g9HMf/2/ – user1862764 Dec 16 '13 at 03:56
1
var $date = $('.day.date').not(':has(:empty)'),
    o = {
       38: -7,
       40: 7,
       37: 'prev',
       39: 'next'
    };

$(document).on('keyup', function (e) {
    var dir = o[e.which],
        $active = $('.active').removeClass('active'),
        i = $date.index($active);

    // Enter Key
    if (e.which === 13) {
        $('.selected').removeClass('selected');
        $active.addClass('selected');
        return;
    }

    // Select the target element
    if (!$active.length) {
        $date.first().addClass('active');
        return;
    } else {
        if (dir === 'next' || dir === 'prev') {
            $active[dir]().addClass('active');
        } else {
            $date.eq(dir + i).addClass('active');
        }
    }
});

http://jsfiddle.net/eqrNT/

Ram
  • 143,282
  • 16
  • 168
  • 197
  • your answer seems difficult for him to understand – user1862764 Oct 20 '13 at 07:17
  • 1
    @user1862764 Actually it's just code and it was downvoted. You are right, it seems to be difficult to understand as reader should examine the code but I think it's self-explanatory for a _programmer_. Thanks for removing the downvote. – Ram Oct 20 '13 at 21:50
0

I edited your code for left and right arrow: http://jsfiddle.net/9SVez/2/ It is not the "best" js, but it should give you a tip:)

var currentDay=0;
function doSelect(){
    $('#firstDay').nextAll().css({backgroundColor: '#FFE06B'});
   $('#firstDay').nextAll().slice(currentDay,currentDay+1).css({backgroundColor: 'blue'});

}
$(function () {
    $(document).keydown(function(e){
        if (e.keyCode == 37) { 
           //alert( "left pressed" );
            currentDay--;
        }

        if (e.keyCode == 39) { 
           //alert( "right pressed" );
            currentDay++;
        }
        doSelect();
        return false;
    });
   doSelect();

});
Piotr Stapp
  • 19,392
  • 11
  • 68
  • 116