Напоминалка

Лучшая работа оператора та, которую незаметно.

Поиск по сайту

Поисковый запрос должен быть не менее 4-х символов.


Простой календарь событий (php, ajax, javascript)

Автор: rex751

Дата: 2013-03-17

Возникла необходимость вставить на сайт календарь новостей. Начал с поиска готовых решений в интернете. Те решения которые предлагались, показались громоздкими с кучей разных наворотов. Мне же нужен был простой календарь с возможностью выбора новости за какой-то день. Чем проще, тем лучше. После не продолжительного поиска (вполне возможно такие решение где-то есть), решил написать сам тем более в это время начал изучать ajax. И вот что получилось.

   Выкладываю этот код для того чтобы, во-первых - может кому-нибудь понадобится; и самое важное - для конструктивной критики. Вполне возможно код не совсем оптимальный, и что-то можно сделать проще и быстрее. Поэтому, если у кого-то есть идеи - предлагайте обязательно.

Макет календаря выполнен при помощи таблицы:

<body onload="cal()">
<div>
<table class='table_cal' cellspacing="0">
  <tr id='lenta' >
    <td colspan="3" id='title'>Архив новостей</td>
    <td id="prev" onclick="previos()"><a href="#"><</a></td>
    <td colspan="2" id='month_year' ><span id="monthID"></span>
   <span id="yr"></span></td>
    <td  id="nxt" onclick="next()"><span class='current_month'>></span>
   </td>
  </tr>
  <tr class='day_week' >
    <td>Пн</td>
    <td>Вт</td>
    <td>Ср</td>
    <td>Чт</td>
    <td>Пт</td>
    <td id="week_end">Сб</td>
    <td id="week_end">Вс</td>
  </tr>
  <tr class='days' >
    <td id="cell_11"></td>
    <td id="cell_12"></td>
    <td id="cell_13"></td>
    <td id="cell_14"></td>
    <td id="cell_15"></td>
    <td id='cell_16'></td>
    <td id='cell_10'></td>
  </tr>
  <tr class='days'  >
    <td id="cell_21"></td>
    <td id="cell_22"></td>
    <td id="cell_23"></td>
    <td id="cell_24"></td>
    <td id="cell_25"></td>
    <td id='cell_26'></td>
    <td id='cell_20'></td>
  </tr>
  <tr class='days' >
    <td id="cell_31" ></td>
    <td id="cell_32"></td>
    <td id="cell_33"></td>
    <td id="cell_34"></td>
    <td id="cell_35"></td>
    <td id='cell_36'></td>
    <td id='cell_30'></td>
  </tr>
  <tr class='days' >
    <td id="cell_41"></td>
    <td id="cell_42"></td>
    <td id="cell_43"></td>
    <td id="cell_44"></td>
    <td id="cell_45"></td>
    <td id='cell_46'></td>
    <td id='cell_40'></td>
  </tr>
  <tr class='days' >
    <td id="cell_51"></td>
    <td id="cell_52"></td>
    <td id="cell_53"></td>
    <td id="cell_54"></td>
    <td id="cell_55"></td>
    <td id='cell_56'></td>
    <td id='cell_50'></td>
  </tr>
  <tr class='days' >
    <td id="cell_61"></td>
    <td id="cell_62"></td>
    <td id="cell_63"></td>
    <td id="cell_64"></td>
    <td id="cell_65"></td>
  </tr>
</table>
</div>
</body>

Формирование AJAX запроса, отправка месяца и года на сервер и последующее заполнение календаря:

var n_month = new Array ("Январь", "Февраль", "Март",
    "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь",
    "Октябрь", "Ноябрь", "Декабрь");
var d = new Date();
var mth = d.getMonth();	
var yer = d.getFullYear();
var request = null;
//-----------------------------------------------------------------
function createRequest() {
     try {
       request = new XMLHttpRequest();
     } catch (trymicrosoft) {
       try {
         request = new ActiveXObject("Msxml2.XMLHTTP");
       } catch (othermicrosoft) {
         try {
           request = new ActiveXObject("Microsoft.XMLHTTP");
         } catch (failed) {
           request = null;
         }
       }
     }
     if (request == null)
       alert("Error creating request object!");
   }
   function getCal(year, month) {
     createRequest();
	 mes=month;
	 mes++;
	 data="?year="+year+"&month="+mes;
	 var url = "cal_req.php"+data;
     request.open("GET", url, true);
	 // при получении ответа от сервера запускаем функцию заполнения датами
	 request.onreadystatechange = function () {	fill_date(year, month);	} 
     request.send(null);
  }

//---------------Функция заполнения календаря датами----------------------------------
function fill_date(year, month){
	// если пришел ответ (readyState == 4) от сервера заполняем календарь 
if (request.readyState == 4) {
var arr1 = eval("(" + request.responseText + ")"); //преобразуем полученный ответ из json в асс. массив
var dayCount = new Date(year, month + 1, 0).getDate(); //считаем количество дней в месяце
	//получаем день недели для первого числа месяца
	month++;
	var dateStr = month+"/1/"+year; 
	var d = new Date(dateStr);  
	var d_week = d.getDay();
	n_str = 1;
	y=1;
//очистка ячеек в первой строке
if(d_week==0) d_w=7; else d_w=d_week;
	while (y < d_w){
		document.getElementById("cell_"+"1" + y).style.visibility="hidden";
		myid = document.getElementById( "cell_"+"1" + y);
		myid.innerHTML = ""; y++;
	}
//Заполнение датами		
for (x=1; x <= dayCount; x++){
	st_str =n_str + "";
	//отображаем ранее скрытые ячейки 
	// меняем цвет выходных
	document.getElementById("cell_"+st_str + d_week).style.visibility="visible"; 
	if (d_week == 6 || d_week == 0) {document.getElementById("cell_"+st_str + d_week).style.background="#B4D9EE";} 
	myid = document.getElementById("cell_"+ st_str + d_week);
	//полученные из базы даты новостей, дополняем ссылкой на скрипт извлечения новости из архива
	if (arr1[x])
			{
			res="<a href='arhiv.php?id="+arr1[x]+"'><div id='link'>"+x+"</div></a>";
			myid.innerHTML = res;
			}
		else {  
			res=x;
			myid.innerHTML = res;
		}
	if (d_week == 0) n_str++;
	if (d_week == 6) d_week = 0;
	else d_week++;
}
//Очистка последних ячеек
	z=1;
	while (z <= 10){
		st_str =n_str + "";
		document.getElementById("cell_"+st_str + d_week).style.visibility="hidden"; // скрываем не задействованные ячейки
		myid = document.getElementById("cell_"+st_str + d_week);
		myid.innerHTML = "";
		if (d_week == 0) n_str++;
		if (d_week == 6) d_week = 0;
		else d_week++; 
		z++;
	}
}	
}
//---------------------------Вызов текущего месяца
function cal()
{	 
	myid = document.getElementById("monthID");
	myid.innerHTML = n_month[mth];
	myid = document.getElementById("yr");
	myid.innerHTML = yer;
	getCal(d.getFullYear(), d.getMonth());
}
//--------------------------Функция вызова предыдущего месяца
function previos(){
	n_mon = document.getElementById("monthID").innerHTML;
	n_yr = document.getElementById("yr").innerHTML;
	if ( n_mon == "Январь" )  // если январь то год минус 1 и следующий месяц под индексом "11"(декабрь)
		{  	n_yr = n_yr - 1;
			key = 11; 
	}
	else {                     // находим индекс месяца из массива имён n_month
			for(find in n_month){
  				if(n_month[find]==n_mon) {
    			key = find; 
				key = key -1; // и сдвигаем на предыдущий месяц
  				}
 			}
		}
		end_mth = key;
	//обратное включение перехода на следующий месяц
	if (n_yr !== yer && n_month[end_mth] !== n_month[mth] ){
		myid3 = document.getElementById("nxt");
		myid3.innerHTML = "<a href='#'>></a>";
	}
	// заполнение календаря предыдущим месяцем
	myid = document.getElementById("monthID");
	myid.innerHTML = n_month[key];
	myid = document.getElementById("yr");
	myid.innerHTML = n_yr;
	getCal(n_yr, key);
}
//---------------------------------------Функция вызова следующего месяца
function next(){
	n_mon = document.getElementById("monthID").innerHTML;
	n_yr = document.getElementById("yr").innerHTML;
	
	
	if ( n_mon == "Декабрь" ) //если декабрь , тогда год плюс 1 и идекс месяца 0
		{  	++n_yr;
			key = 0; 
			
		}
	else {                       // находим индекс месяца из массива имён n_month
			for(find in n_month){
  				if(n_month[find]==n_mon) {
    				 ++find;    // и сдвигаем на следующий месяц
					key=find;
  				}
 			}
	}
	end_mth = key-1;
	// Проверка и запрет вызова будущего месяца и выключение 
	// перехода на следующий месяц при первичном заполнении календаря
	if (n_yr == yer && n_month[end_mth] == n_month[mth] ){
		myid3 = document.getElementById("nxt");
		myid3.innerHTML = "<span class='current_month'>></span>";
	}
	else{
		//выключения перехода на следующий месяц при переходе календаря на текущий месяц
		if (n_yr == yer && n_month[key] == n_month[mth] ){
		myid3 = document.getElementById("nxt");
		myid3.innerHTML = "<span class='current_month'>></span>";
		}
		//заполнение календаря следующим месяцем
		myid = document.getElementById("monthID");
		myid.innerHTML = n_month[key];
		myid = document.getElementById("yr");
		myid.innerHTML = n_yr;
		getCal(n_yr, key);
	}
}

Обратите внимание! Запрос на вывод события (см. выше строка 69) осуществляется по идентификатору в таблице(то есть, одно событие в день)!
Если же есть несколько событий в день, то строку запроса надо соответсвующим образом изменить:

res="<a href='arhiv.php?dates="+year+"-"+month+"-"+x+"'>
                 <div id='link'>"+x+"</div>
        </a>";

Обработчик на сервере( выборка из таблицы архива новостей - идентификатора и даты новости):

if (isset($_GET['year'])) {$year =$_GET['year']; 
if ($year == '') { unset($year);}}
if (isset($_GET['month'])) {$month =$_GET['month']; 
if ($month == '') { unset($month);}}
$conn = @mysql_connect("localhost", "user", "password");
if (!$conn)
  die("Error connecting to MySQL: " . mysql_error());

if (!mysql_select_db("BD_NAME", $conn))
  die("Error selecting Head First database: " . mysql_error());
//выбор полей id, dates по необходимому месяцу соответсвующего года
$select = 'SELECT id,DAY(dates)';
$from   = '  FROM arhiv';
$where  = '  WHERE YEAR(dates)='.$year.' AND MONTH(dates)='.$month;
$data = array();

$queryResult = @mysql_query($select . $from . $where);
while($row=mysql_fetch_array($queryResult))
	{  
		$data[$row['DAY(dates)']]=$row['id'];
	}
// преобрзование массива в данные json
$resalt = json_encode($data);
echo $resalt;

mysql_close($conn);

Примечание: без обработчика на сервере, календарь датами заполняться не будет.


Пример можно посмотреть здесь

Архив с файлами скачать здесь

Как вариант можно добавить к ссылке атрибут title с названием новости(события), если есть соответсвующее поле в таблице. Для этого в файле обработчика на сервере(call_req.php) добавим выбор из базы поля title и соответсвенно изменим формирование данных.(Актуально, если только одно событие в день).

$select = 'SELECT id,title,DAY(dates)';
.
.
.
.
while($row=mysql_fetch_array($queryResult))
	{  
$data[$row['DAY(dates)']]=$row['id']."' title='".$row['title']."'";
	}

В результате при наведении на дату в календаре у нас будет появляться название новости(события)

Измененный пример можно посмотреть здесь

 

Здесь расположен календарь событий с использованием jquery datepicker

Просмотров: 41519

Вход

Регистрация

Забыли пароль?

Погода

У нас есть изюминка
изюминка

статистика

©2009-2017 TOEFilm.ru Творческое объеденение "Эпсилон-MIX". Все права защищены.

©2009-2010 TOEFilm.ru Творческое объеденение "Эпсилон-Фильм". Все права защищены.