Issue
I'm trying to create some sort of calendar app. When you click on a blank box it shows a form to create an event. You use "ANTERIOR" or "SIGUIENTE" to navigate the calendar.
The form appears correctly when you click on a box until you click either "ANTERIOR" or "SIGUIENTE", and then it stops working.
Here's the complete code:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="css/calendar.css">
<title></title>
</head>
<body>
<div id="calendar">
</div>
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<script src="js/calendar.js"></script>
</body>
</html>
calendar.js
// function to add days to date
Date.prototype.addDays=function(d){return new Date(this.valueOf()+864E5*d);};
Date.prototype.subtractDays=function(d){return new Date(this.valueOf()-864E5*d);};
// set initial variables
var longDays = ["Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"];
var shortDays = ["Lun", "Mar", "Mie", "Jue", "Vie", "Sab"];
var months = ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'];
var time = ['8<br>am', '9<br>am', '10<br>am', '11<br>am', '12<br>pm', '1<br>pm', '2<br>pm', '3<br>pm', '4<br>pm', '5<br>pm']
var weekStart = new Date();
weekStart = weekStart.subtractDays(weekStart.getDay() - 1);
var nav = '<div class="nav">\
<button id="prev-week" class="nav-prev-btn"><< Anterior</button>\
<button id="next-week" class="nav-next-btn">Siguiente >></button>\
</div>';
function formatDate(date) {
var month = date.getMonth();
var date = date.getDate();
return date.toString() + '/' + months[month];
}
function showCalendar(startDate) {
var days = shortDays;
if ($(window).width() > 640) {
days = longDays;
}
var cal = document.createElement('div');
cal.setAttribute('id', 'calendar-wrapper');
var timeDiv = document.createElement('div');
timeDiv.setAttribute('id', 'hours');
timeDiv.className = "column time";
var corner = document.createElement('div');
corner.className = "box corner";
timeDiv.appendChild(corner);
for (i=0; i<10; i++) {
var box = document.createElement('div');
box.className = 'box';
$(box).append("<p>" + time[i] + "</p>");
timeDiv.appendChild(box);
}
$(cal).append(timeDiv);
var tempDate = startDate;
for (i=0; i<6; i++) {
var dayContainer = document.createElement('div');
dayContainer.className = "column day";
var dayBox = document.createElement('div');
dayBox.className = "box";
var text = days[i] + "<br>" + formatDate(tempDate);
$(dayBox).append(text);
dayContainer.appendChild(dayBox);
for (j=8; j<18; j++) {
var box = document.createElement('div');
box.className = "box available";
box.setAttribute('data-year', tempDate.getFullYear());
box.setAttribute('data-month', tempDate.getMonth());
box.setAttribute('data-date', tempDate.getDate());
box.setAttribute('data-hour', j);
dayContainer.appendChild(box);
}
$(cal).append(dayContainer);
tempDate = tempDate.addDays(1);
}
$('#calendar').append(cal);
}
function nextWeek() {
$('#calendar-wrapper').remove();
weekStart = weekStart.addDays(7);
showCalendar(weekStart);
}
function prevWeek() {
$('#calendar-wrapper').remove();
weekStart = weekStart.subtractDays(7);
showCalendar(weekStart);
}
function showAddEvent(data) {
$('.new-event').remove();
var date = data['date'] + '/' + (parseInt(data['month']) + 1) + '/' + data['year'];
var time = data['hour'] + ':00';
var form = '<form action="#" method="POST">\
<label for="date">Fecha: <input type="text" name="date" value="' + date + '">\
<label for="time">Hora: <input type="text" name="time" value="' + time + '">\
<label for="comments">Observaciones: <textarea name="comments"></textarea>\
<input class="submit-btn" type="submit" value="Enviar">\
<button class="cancel-btn">Cancelar</button>\
</form>';
formWrapper = document.createElement('div');
formWrapper.className = 'new-event';
$(formWrapper).append(form);
$('body').append(formWrapper);
}
$(document).ready(function() {
$("#calendar").append(nav);
// initiate the calendar
showCalendar(weekStart);
// previous week button handler
$("#prev-week").click(function() {
prevWeek();
});
// Next week button handler
$("#next-week").click(function() {
nextWeek();
});
$('.available').click(function() {
var data = $(event.target).data();
showAddEvent(data);
});
});
Solution
When you click on #prev-week
Or #next-week
you actually call functions that remove parts of your existing HTML that are #calender-wrapper
then create a new calendar wrapper that's contain elements with .availabe
classes.
jQuery .click
event binding method called a direct binding methoud that only works with the exesting elements on your document when you removed #calender-wrapper
jQuery considers .availabe
elements as new objects even they have the same class with the same name.
Alternatively, use delegated events to attach event handlers. like...
$( document ).on( "event-name", ".dynamic-element-selector", function() {
##code;
});
Look I don't fully understand thing completely, and why this happens but it's true.
Event handlers are bound only to the currently selected elements; they must exist at the time your code makes the call to .on(). To ensure the elements are present and can be selected, place scripts after the elements in the HTML markup or perform event binding inside a document ready handler. Alternatively, use delegated events to attach event handlers.
Source - jQuery .on() documentation
Update:
Please replace this part of your script from:
$(document).ready(function() {
$("#calendar").append(nav);
// initiate the calendar
showCalendar(weekStart);
// previous week button handler
$("#prev-week").click(function() {
prevWeek();
});
// Next week button handler
$("#next-week").click(function() {
nextWeek();
});
$('.available').click(function() {
var data = $(event.target).data();
showAddEvent(data);
});
});
To:
$(document).ready(function() {
$("#calendar").append(nav);
// initiate the calendar
showCalendar(weekStart);
// previous week button handler
$("#prev-week").click(function() {
prevWeek();
});
// Next week button handler
$("#next-week").click(function() {
nextWeek();
});
$(document).on('click', '.available', function() {
var data = $(this).data();
showAddEvent(data);
});
});
Answered By - Moataz Zaitoun
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.