Javascript based kalender
Tijd voor een javascriptje. Waar voor ik te vaak onnodig PHP zie. Soms loopt een website uit tot niets en blijf je zitten met een half werkende code. Zelf had ik in Januari een geweldig idee voor een meeting manager. Hellaas bleek de website toch iets in gewikkelder te zijn dan ik eerst dacht. En hij staat nu al 2 maanden op mijn "externe harde schrijf" te rusten. Maar ja wat er wel uit gekomen was een kleine oplossing waar veel webdesingers mee zitten te klooien en die deel ik even met jullie graag. Datums Iedereen kent die beruchte drie beruchte select boxen op een rijtje die een dag, maand en een jaar voor stellen. Waar de bezoeker een datum moet in vullen. Bijvoorbeeld een geboortje jaar. Nu vind ik het voor 1 datum niet zo erg. Maar bij 3 wordt het toch ongemakkelijk. Daarom heb ik besloten om een input veld (type = "text") te gebruiken waar de gebruiker gewoon een datum in kan vullen. Ook kan hij gebruik maken van een kalender die doormiddel van Javascript genereed wordt. Voor deze script is basis kennis van de WC3 DOM en javascript nodig. Hoewel het gebruik eenvoudig is dienen er 3 "config" waarden in te vullen. Deze versie is de eenvoudigste systeem. De script bevat aardig veel JS comments. Voorbeeld Browser ondersteuning Deze script werkt alleen on "moderne" browsers. (IE 5.0 en nieuwer, Safari, Firefox 1.0 en nieuwer en al zijn cloontjes en Opera 9.0. Opera 8.0 werkt waarschijnlijk wel maar niet getest. Door de gebruik van geavenceerde WC3 Dom scripts kan ik niet garanderen of het werkt onder IE 5.x op de Mac. Maar ja wie gebruikt dat nog? Installatie Download hier Unzip dit bestand en upload alle bestanden naar de webserver. Voeg nu in de html code de volgende codes toe. Wanneer je gebruik wilt maken van de "standaard" style sheet kan je deze style sheet ook gewoon toevoegen. Uiteraard kan je ook je eigen style sheet gebruiken met een andere opmaak zolang de class namen maar gelijk blijven. (Zie calendar.css) Maak nu een input veld aan waar de datum in moet te komen staan en geef deze een "id". Instellingen Om de kalender script in te stellen moet de volgende gegevens aanpassen Regel: 27 In dit voorbeeld gebruiken wij de huidige jaar + 5 jaar. Dit kan je zelf uiteraard aanpassen. Met het de jaren die jij wilt. Locatie van close cross moet je zelf even aangeven. In dit voorbeeld is het dit Nu volgen er een paar taal settings die je gewoon zo kunt laten of natuurlijk aanpassen. Nu komt het lastigste om deze script te activeren kan je kiezen uit mogelijkheden. Doormiddel van inline events en doormiddel van javascript. Doormiddel van inline event moet je gebruik maken van onclick="show_calendar_inline(this)" aan de element waar jij de onclick event wilt toevoegen en in regel 111 de volgende aanpassen Omdat ik zelf de onclick niet op de input element heb gedefineerd moet ik de id van de element vinden door een andere manier. Ik heb het gedaan door middel van de dom structuur 1 plaatsje naar voren schuiven. Omdat ik wou voorkomen dat ik voor alle input velden alles apart moest instellen. Jij kan als je gebruik wilt maken van 1 datum veld ook gewoon h = document.getElementById('idvandeveld'); gebruiken. Wanneer je de javascript methode wilt gebruiken moet je nog een anders javascriptje toevoegen namelijk die er voor zorgt dat de text doorloopt en automatisch de onclick events toevoegt. Zelf doe ik het volgens de volgende script. Dit script zorgt er voor dat op images met de class calendar een onclick target wordt gegeven Nu kan je doormiddel van 85 de juiste positie in de dom structuur op te geven. Ook hier kan je gewoon h = document.getElementById('idvandeveld') ; gebruiken wanneer je een datum veld hebt. Nu is het alleen nog de zaak om de return string op te geven in 313. Gebruik hier voor de juiste JS syntax. Dat is alles Gebruikte scripts van andere personen Functies findPosY en findPosX. Geschreven door PPK. (Find position)
[code]
/**
* @author Eris
* @version 0.2.0 (Beta)
* @date 09-01-2007
* @download http://www.schipbreukeling.nl/docs/scripts/kalender.html
* @license GPL http://www.schipbreukeling.nl/docs/license.html or license.txt
* Creates a layer with a calender where the user can select one date.
* Copyright (C) 2007 Eris
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* See readme.txt for more info.
*/
/*Config setting*/
//create a data object for the date now so we don't need to change it next year. (today.getFullYear() to get the current year) Offcourse you can set a "own" value
var today = new Date();
var start_year = today.getFullYear();
//end year
var end_year = today.getFullYear() + 5;
//location of the "close" cross
var delete_cross = '/images/scripts/calendar/delete.png';
//language settings.
var calendar = 'Calendar';
//month names
var month_names = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
//names of the days. 0 = sunday, 6 = saturday
//we don't care about "logic" values because the user will not see it. If they will see it he/she got enough knowlege about browsers and their quirks
var day_names = new Array('Sun','Mon','Tue','Wen','Thu','Fri','Sat');
//default config arrays please do not change!
//array with the days (0 = January 11 = December)
var days = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
//we don't take care about leap year. This will be done later
//W3C Dom support . Prevent browser errors.
if(document.getElementsByTagName && document.createElement){
var w3c = true;
}else{
var w3c = false;
}
/**
* function show_calendar(e)
* @param e
* @return nothing
* @id show_calendar
* Create a DHTML Layer. Add the basic elements and runs one time generate_table()
* Do not use this function when you want to use a inline onclick action!
*/
function show_calendar(e){
if(!w3c) return;
if (!e) var h = window.event.srcElement;
else var h = e.target;
if (h.nodeType == 3) // defeat Safari bug
h = h.parentNode;
//small short cut
var d = document;
if(!d.getElementById('calendar')){
//create a div element
var div = d.createElement('div');
//insert div inside the dom tree
d.body.appendChild(div);
div.id = 'calendar';
//before we forget we need to add a reminder. Otherwise the script will forget which input field should be field.
var hidden = d.createElement('input');
hidden.type = 'hidden';
hidden.id= 'id';
//behind this line you need to edit the location of the "input field"
//When you want to add a onclick on the field h.id is enough
//When you want to add a image (See example) you need to change it to:
//h.previousSibling.id; Find by testing and just general knowlege of the dom structure
hidden.value = h.previousSibling.id;
div.appendChild(hidden);
var mouseY = findPosY(h);
var mouseX = findPosX(h);
//placing block
mouseY = mouseY + 20;
div.style.top = mouseY +'px';
div.style.left = mouseX +'px';
//everything is ready continu to fill the div
finish_div();
}
}
/**
* function show_calendar_inline()
* @param {element)
* @return null
* @id show_calendar_inline()
* Description: the inline version of the show calendar
* Call it like onclick="show_calender_inline(this)"
*/
function show_calendar_inline(element){
if(!w3c) return;
//if the onclick is add to a other element the input we should move to there. Other whis use var h = element;
h = element.previousSibling;
//small short cut
var d = document;
if(!d.getElementById('calendar')){
//create a div element
var div = d.createElement('div');
//insert div inside the dom tree
d.body.appendChild(div);
div.id = 'calendar';
//before we forget we need to add a reminder. Otherwise the script will forget which input field should be field.
var hidden = d.createElement('input');
hidden.type = 'hidden';
hidden.id= 'id';
hidden.value = h.id;
div.appendChild(hidden);
var mouseY = findPosY(element);
var mouseX = findPosX(element);
//placing block
mouseY = mouseY + 20;
div.style.top = mouseY +'px';
div.style.left = mouseX +'px';
//every thing is ready now finish the div
finish_div();
}
}
/**
* function finish_div
* @param null
* @return null
* @id finish_div
* Description: Finish the div element
*/
function finish_div(){
if(!w3c) return;
var d = document;
var div = d.getElementById('calendar');
var title = div.appendChild(d.createElement('div'));
title.className = 'title';
title.innerHTML = '<div class="float_right"><img src="'+delete_cross+'" alt="Close" id="close"/></div>'+calendar;
d.getElementById('close').onclick = close_window;
//maak een date object
var now = new Date();
//create a selectbox with monts
var select1 = d.createElement('select');
select1.id = 'month';
for( i = 0; i < month_names.length; i++){
var option = d.createElement('option');
option.value = i;
option.appendChild(document.createTextNode(month_names[i]));
if(now.getMonth() == i){
option.selected = 'selected';
}
select1.appendChild(option);
}
//make now a select box for the curent year and the next year.)
var select2 = d.createElement('select');
select2.id = 'year';
for( i = start_year; i < (end_year + 1); i++){
var option = d.createElement('option');
if(now.getFullYear() == i){
option.selected = 'selected';
}
option.value = i;
option.appendChild(document.createTextNode(i));
select2.appendChild(option);
}
//add a onchange action
select1.onchange = generate_table;
select2.onchange = generate_table;
div.appendChild(select1);
div.appendChild(select2);
//now we generate a table. This is done by a second function so I don't have to copy past it twice.
generate_table();
}
/**
* function generate_table()
* @param null
* @return null
* @id generate_table
* Description: Generates a html table with all dates. Starting with the Sunday (Inside JS as 0 and end on Saturday as 6)
* date and year will fetched from the input fields earlier generated. By default Client side date / time. Or user set.
* output will become a HTML tabel maximum 7 cols and 6 rows ( Sunday, Monday, Tuesday, Wendsday, Thursday, Friday, Saturday)
* Rows Days of the week, (th)
*/
function generate_table(){
if(!w3c) return;
//look inside the div calendar if there exits a table. If true we trash it.
if(document.getElementById('table')){
//its exits trash it!
document.getElementById('calendar').removeChild(document.getElementById('table'));
}
var table = document.createElement('table');
var tbody = table.appendChild(document.createElement('tbody'));
if(!document.getElementById('calendar').appendChild(table)){
alert('Error');
}
table.id = 'table';
var month = document.getElementById('month');
var year = document.getElementById('year');
//now look for the values
var m = month.options[month.selectedIndex].value;
var y = year.options[year.selectedIndex].value;
//we just now generate a date
var dates = new Date();
dates.setYear(y);
dates.setMonth(m);
dates.setDate(1);
//traceback first day of the month
var firstDay = dates.getDay();
//create a tr with day names
var tr = document.createElement('tr');
for(i = 0; i < day_names.length;i++){
var th = document.createElement('th');
th.innerHTML = day_names[i];
tr.appendChild(th);
}
tbody.appendChild(tr);
//we got maybe a leap year lets check it.
//I don't care about the leap years each 100 years because its then no leap...
//(2100, 2200 and 2300) because this will happen 3 times every 400 year
// it will be a not a leap year. Script will show only 1 day wrong
if(dates.getFullYear() % 4 == 0){
//leap year
//februari
days[1] = 29;
}
//we now just loop trough the the var firstDay (string) till we have reached the first day. If so stop script
//create a element tr
var tr = document.createElement('tr');
for(i = 0; i < firstDay;i++){
var td = document.createElement('td');
//should be empty
td.innerHTML = '';
tr.appendChild(td);
}
//because the maxium value will be 6 we don't need to create a new row. Next for list we have to
var w = 0;
for(i = 1; i <= days[m];i++){
var td = document.createElement('td');
td.innerHTML = i;
//add a onclick event
td.onclick = close_return;
tr.appendChild(td);
if((i + firstDay) % 7 == 0){
//save tr in table
tbody.appendChild(tr);
//create a new tr
var tr = document.createElement('tr');
w = -1;
}
w++;
}
for(w;w % 7 > 0;w++ ){
var td = document.createElement('td');
//should be empty
td.innerHTML = '';
tr.appendChild(td);
}
table.appendChild(tr);
}
/**
* function close_return()
* @param null
* @return null
* @id close_return
* Description: Return the selected date back to the input field
*/
function close_return(e){
if(!w3c) return;
if (!e) var h = window.event.srcElement;
else var h = e.target;
if (h.nodeType == 3) // defeat Safari bug
h = h.parentNode;
var id = document.getElementById('id').value;
//create the date
var d = h.innerHTML;
if(d.length == 1){
d = '0' + d;
}
var month = document.getElementById('month');
var year = document.getElementById('year');
//now look for the values
//it seems to be that the month was a string instead of a int. Multiply m with 1 and add 1 . Then check to add a leading zero.
var m = month.options[month.selectedIndex].value * 1 + 1;
m = m.toString();
if(m.length == 1){
m = '0' + m;
}
var y = year.options[year.selectedIndex].value;
//d = day
//m = month
//y = year
var wanted_date = d + '-' + m + '-' + y;
document.getElementById(id).value = wanted_date;
close_window();
}
/**
* function close_window()
* @param null
* @return null
* @id close_close_window
* Description: Remove DHTML layer
*/
function close_window(){
if(!w3c) return;
document.body.removeChild(document.getElementById('calendar'));
}
/**
* function findPosX()
* @param {obj}
* @return {int}
* @id findPosX
* @author PPK
* Description: Find the X position of a element
*/
function findPosX(obj)
{
var curleft = 0;
if (obj.offsetParent)
{
while (obj.offsetParent)
{
curleft += obj.offsetLeft
obj = obj.offsetParent;
}
}
else if (obj.x)
curleft += obj.x;
return curleft;
}
/**
* function findPosY()
* @param {obj}
* @return {int}
* @id findPosY
* @author PPK
* Description: Find the Y position of a element
*/
function findPosY(obj)
{
var curtop = 0;
if (obj.offsetParent)
{
while (obj.offsetParent)
{
curtop += obj.offsetTop
obj = obj.offsetParent;
}
}
else if (obj.y)
curtop += obj.y;
return curtop;
}
[/code]
Reacties
0