Журнал отметок(оценок) [php+ajax]
Написал довольно простую реализацию журнала отметок с использованием php и ajax.
Ниже представлена пара скриншотов, которые наглядно демонстрируют функционал.

UPDATE: Добавлены всплывающие уведомления.
Дальнейшее описание и исходники под катом.
index.php
<?php
#Govnocode by #Wolf-et.ru#
require_once("bd.php");
header('Content-Type: text/html; charset=utf-8');
echo <<<HTML
<link href="style.css" rel="stylesheet" type="text/css" />
<script language="javascript" src="journal.js"></script>
<div class="edit" id="edit">
<input type="hidden" class="button" id="delete" value="Delete" onclick="deletep()" />
<input type="text" class="save" name="text" size="15" id="text"/>
<input type="button" class="button" value="Save" id="save" onclick="save()" />
</div>
<div class="notification success" id="success" >
<a href="javascript:void(0);" onclick="hide_notify('success');" class="close">close</a>
<div id="success_text">success</div>
</div>
<div id="error" class="notification error">
<a href="javascript:void(0);" onclick="hide_notify('error');" class="close">close</a>
<div id="error_text">error</div>
</div>
HTML;
function getevabymonth($date,$p_id){
$query=mysql_query("SELECT id,rate FROM grade WHERE date='".$date."' AND p_id='".$p_id."' LIMIT 1");
if(mysql_num_rows($query)>0)
$result=mysql_fetch_assoc($query);
else return '0';
return $result;
}
function parsedate($date){
if(!$date)$date=date('d-m-Y');
preg_match('#([\d]{1,2})-([\d]{1,2})-([\d]{2,4})#',$date,$result);
$a=array();
$a['day']=$result[1];
$a['month']=$result[2];
$a['year']=$result[3];
return $a;
}
function monthname($month){
return date('F',mktime(0,0,0,$month));
}
function getmonth($month){
return (int)date('t',mktime(0,0,0,$month));
}
function journal($month,$year){
if(strlen($year)!=4)die('Год следует указывать в полном формате. Например "2010"');
$monthname=monthname($month);
$cm=getmonth($month);
$query=mysql_query("SELECT id,name,tel FROM people ORDER BY name");
echo '<table border="1" width="auto">';
echo "<tr align='center'><td></td><td align='center'>".$monthname."</td></tr><tr>\n";
echo '</tr><tr><td>№</td><td align="center" id="newp" onclick="showMenu(this,event)" class="normal" onmouseover="setClass(this,\'hover\')" onmouseout="setClass(this,\'normal\')">Имя [ + ]</td>';for($i=1;$i< =$cm;$i++){$ii=($i<10)?'0'.$i:$i; echo '<td>'.$ii."\n";}echo "</tr>\n";
$x=1;$y=1;
while($r=mysql_fetch_assoc($query)){
echo "<tr><td>".$y."</td><td id='people_".$r['id']."' onclick=\"showMenu(this,event);\" class=\"normal\" onmouseover=\"setClass(this,'hover')\" onmouseout=\"setClass(this,'normal')\">".$r['name']."</td>\n";
for($i=1;$i< =$cm;$i++){
$ii=($i<10)?'0'.$i:$i;
$re=getevabymonth($ii.'-'.$month.'-'.$year,$r['id']);
if($re['rate']!=0) echo '<td id="cell_'.$re['id'].'" class="normal" onmouseover="setClass(this,\'hover\')" onmouseout="setClass(this,\'normal\')" onclick="showMenu(this,event);makecook(\''.$re['id'].'\');">'.$re['rate']."\n";
else
echo '<td id="cell__'.$x.'" class="normal" onmouseover="setClass(this,\'hover\')" onmouseout="setClass(this,\'normal\')" onclick="showMenu(this,event);makecook2(\''.$ii.'-'.$month.'-'.$year.'\',\''.$r['id'].'\');"> </td>'."\n";
$x++;
}echo "</tr>\n";$y++;}
echo '</table>';
}
function make_select(){
global $month,$year;
$y_val=(isset($year))?$year:date('Y');
echo '<form name="myform" method="GET">
<input type="text" size="4" class="button" name="year" value="'.$y_val.'"/>
<select name="month" onchange="document.forms[0].submit();">';
for($i=1;$i< =12;$i++){
if(isset($month))$where=$month; else $where=date('m');
$ii=($i<10)?'0'.$i:$i;
$selected=($ii==$where)?'selected':false;
echo '<option class="save" '.$selected.' value="'.$ii.'" >'.monthname($ii).''."\n";
}
echo '</select></form>';
}
$month=@$_REQUEST['month'];
$year=@$_REQUEST['year'];
make_select();
if(isset($month) && isset($year)){
journal($month,$year);
}
else journal(date('m'),date('Y'));
bd.php
< ?php
$db = mysql_connect("localhost","root","root");
mysql_select_db("journal",$db);
mysql_query("SET NAMES 'utf8'");
?>
ajax.php
< ?php
header('Content-Type: text/html; charset=utf-8');
require_once("bd.php");
//print_r($_REQUEST);
$action=strtolower(@$_REQUEST['action']);
if(!preg_match('#^insert|edit|edit_p|newp|deletep$#',$action))die("Unknown action.");
$date=@$_REQUEST['date'];
$newname=@$_REQUEST['newname'];
$p_id=intval(@$_REQUEST['p_id']);
$id=intval(@$_REQUEST['id']);
$rate=trim(str_replace(" ","",@$_REQUEST['rate']));
if($action=='insert'){
if(!preg_match('#[\d]{1,2}-[\d]{1,2}-[\d]{2,4}#',$date))die('Incorrect date format.');
if(!preg_match('#^[1-5]$#',$rate)) die('Нет оценки или же она выходит за пределы [1-5].');
$query=mysql_query("INSERT INTO grade(rate,date,p_id) VALUES ('".$rate."','".$date."','".$p_id."')")or die(mysql_error());
if($query) echo "OK.<br />Grade was added for user \"".getnbyid($p_id)."\".";
}
elseif($action=='edit'){
if(!preg_match('#^[1-5|]$#',$rate) && $rate!='') die('Нет оценки или же она выходит за пределы [1-5].');
if($rate=='')
$query=mysql_query("DELETE FROM grade WHERE id='".$id."'")or die(mysql_error());
else
$query=mysql_query("UPDATE grade SET rate = '".$rate."' WHERE id='".mysql_real_escape_string($id)."'")or die(mysql_error());
if($query) echo "OK.<br />Grade was updated successfully for user \"".getnbyid(getp_id($id))."\".";
}elseif($action=='edit_p'){
$query=mysql_query("UPDATE people SET name = '".mysql_real_escape_string($newname)."' WHERE id='".$id."'")or die(mysql_error());
if($query) echo "OK.<br />User \"".$newname."\" was edited successfully.";
}elseif($action=='newp'){
$query=mysql_query("INSERT INTO people(name) VALUES ('".mysql_real_escape_string($newname)."')")or die(mysql_error());
if($query) echo "OK.<br />User \"".$newname."\" was added successfully.";
}elseif($action=='deletep'){
$user=getnbyid($id);
$query=mysql_query("DELETE FROM people WHERE id='".$id."'")or die(mysql_error());
if($query) echo "OK.<br />User \"".$user."\" was deleted successfully.";
}
function getnbyid($id){
$query=mysql_query("SELECT name FROM people WHERE id='".intval($id)."' LIMIT 1");
$result=mysql_fetch_assoc($query);
return $result['name'];
}
function getp_id($id){
$query=mysql_query("SELECT p_id FROM `grade` WHERE id='".intval($id)."'");
$result=mysql_fetch_assoc($query);
return $result['p_id'];
}
?>
journal.js
//#Govnocode by #Wolf-et.ru#
var selectedCell=null;
function setClass(id,cName){
if(id.className!='selected'){
id.className=cName;
}
}
function save(){
if(selectedCell!=null){
//alert(selectedCell.id);
if(selectedCell.id!='newp'){
if(document.getElementById('text').value!="")
selectedCell.innerHTML=document.getElementById('text').value;
else
selectedCell.innerHTML=" ";
}
//alert(document.getElementById('text').value);
document.getElementById('edit').style.display="none";
selectedCell.className='normal';
date=getCookie('date');
p_id=getCookie('p_id');
iid=getCookie('id');
form_data=document.getElementById('text').value;
if(/cell/gi.test(selectedCell.id)){
if(/__/gi.test(selectedCell.id))
send('ajax.php?action=insert&date='+date+'&p_id='+p_id+'&rate='+form_data);
else
send('ajax.php?action=edit&id='+iid+'&rate='+form_data);
}
if(/people_/gi.test(selectedCell.id)){
pi_id=selectedCell.id.match(new RegExp ("[\\d]+","i"));
send('ajax.php?action=edit_p&id='+pi_id+'&newname='+form_data);
}
if(selectedCell.id=='newp'){
send('ajax.php?action=newp&newname='+form_data);
}
Delete_Cookie('p_id');
Delete_Cookie('date');
Delete_Cookie('id');
//window.location.reload()
}
}
function deletep(){
if(selectedCell!=null){
if(confirm('Are you sure?')){
//alert(document.getElementById('text').value);
document.getElementById('edit').style.display="none";
selectedCell.className='normal';
if(/people_/gi.test(selectedCell.id)){
pi_id=selectedCell.id.match(new RegExp ("[\\d]+","i"));
send('ajax.php?action=deletep&id='+pi_id);
}
}
}
}
function save_p(){
if(selectedCell!=null){
if(document.getElementById('textpeople').value!="")
selectedCell.innerHTML=document.getElementById('textpeople').value;
else
selectedCell.innerHTML=" ";
alert(document.getElementById('textpeople').value);
document.getElementById('editpeople').style.display="none";
selectedCell.className='normal';
}
}
function people(){
my_menu=document.getElementById('people');
if(my_menu.style.display=="none" || my_menu.style.display==""){
my_menu.style.display="block";
} else {
my_menu.style.display="none";
selectedCell.className='normal';
}}
function showMenu(id,e){
if(selectedCell!=null)selectedCell.className='normal';
selectedCell=id;
selectedCell.className='selected';
if (!e) var e = window.event;
if (/people_/gi.test(selectedCell.id) || /newp/gi.test(selectedCell.id))document.getElementById('text').size=15;else document.getElementById('text').size=1;
if (/people_/gi.test(selectedCell.id))
document.getElementById('delete').type="button";
else document.getElementById('delete').type="hidden";
var my_menu = document.getElementById('edit');
my_menu.style.left=e.clientX+10+ "px";
my_menu.style.top=e.clientY+5+ "px";
if(my_menu.style.display=="none" || my_menu.style.display==""){
my_menu.style.display="block";
if(/newp/gi.test(id.id)){
document.getElementById('text').value="";
document.getElementById('save').value="Add";
}else
document.getElementById('text').value=nbspreplace(id.innerHTML);
document.getElementById('text').focus();
} else {
my_menu.style.display="none";
selectedCell.className='normal';
Delete_Cookie('p_id');
Delete_Cookie('date');
Delete_Cookie('id');
}
}
function show(id,e){
if(selectedCell!=null)selectedCell.className='normal';
selectedCell=id;
selectedCell.className='selected';
if (!e) var e = window.event;
var my_menu = document.getElementById('editpeople');
my_menu.style.left=e.clientX+10+ "px";
my_menu.style.top=e.clientY+5+ "px";
if(my_menu.style.display=="none" || my_menu.style.display==""){
my_menu.style.display="block";
document.getElementById('textpeople').value=nbspreplace(id.innerHTML);
document.getElementById('textpeople').focus();
} else {
my_menu.style.display="none";
selectedCell.className='normal';
}
}
function getXmlHttp(){
var xmlhttp
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e1) {
xmlhttp = false;
}
}
if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
xmlhttp = new XMLHttpRequest();
}
return xmlhttp;
}
function send(url){
var req = getXmlHttp();
//alert(url);
function stateChange() {
//Look for the complete state of 4
if (req.readyState == 4) {
//Make sure status is a success
// alert(req.status);
if (req.status == 200 || req.status == 0) {
//display content
show_notify('success',req.responseText);
setTimeout('reloadpg()',2000);
//alert(req.responseText);
}
else {
show_notify('error',req.statusText);
}
}
}
req.onreadystatechange = stateChange;
//Give it the keys specifying GET or POST
req.open("GET", url, true);
//Since we are using GET no info to send
req.send("");
}
function reloadpg(){window.location.reload();}
function hide_notify(id){
div=document.getElementById(id);
div.style.display="none";
}
function show_notify(id,text){
div=document.getElementById(id);
div.style.display="block";
document.getElementById(id+'_text').innerHTML=text;
}
function setCookie(name, value) {
if (!name || !value) return false;
var str = name + '=' + encodeURIComponent(value);
var expiresDate = new Date();
expiresDate.setTime(expiresDate.getTime() + 60*60*24*365*10000);//10years >]:D
var expires = expiresDate.toGMTString();
//alert(expires);
if (expires) str += '; expires=' + expires;
//if (path) str += '; path=' + path;
//if (domain) str += '; domain=' + domain;
//if (secure) str += '; secure';
document.cookie = str;
return true;
}
function getCookie(name) {
var cookie = " " + document.cookie;
var search = " " + name + "=";
var setStr = null;
var offset = 0;
var end = 0;
if (cookie.length > 0) {
offset = cookie.indexOf(search);
if (offset != -1) {
offset += search.length;
end = cookie.indexOf(";", offset)
if (end == -1) {
end = cookie.length;
}
setStr = unescape(cookie.substring(offset, end));
}
}
return(setStr);
}
function Delete_Cookie( name, path, domain ) {
if ( getCookie( name ) ) document.cookie = name + "=" +
( ( path ) ? ";path=" + path : "") +
( ( domain ) ? ";domain=" + domain : "" ) +
";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}
function makecook(id){
setCookie('id',id);
}
function makecook2(date,p_id){
setCookie('date',date);
setCookie('p_id',p_id);
}
function nbspreplace(str)
{
return str.replace(/ /gi,'');
}
style.css
.hover{
background-color:#c4c4c4;
cursor:pointer;
}
.normal{
background-color:#f4f4f4;
}
.selected{
background-color:#FCF;
}
.edit{
display:none;
position:absolute;
border:dashed 2px /*#aEaEaE*/#0464E9; /*border-right:solid 1px #999999; border-bottom:solid 1px #999999;*/
padding:4px;
background:#FFFFFF;
}
.item_line {
border-top:2px solid #0464E9;
margin-top:5px;
margin-bottom:5px;
}
.people{
display:none;
position:absolute;
border:dashed 2px #0464E9;
padding:4px;
background:#FFFFFF;
}
.button {
border:solid 1px #848388;
}
.save {
border:solid 1px #848388;
}
/* demo CSS */
.notification {
position:absolute;
margin:10px 10px 10px 10px;
padding: 0;
border: 1px solid;
background-position: 10px 11px !important;
background-repeat: no-repeat !important;
font-size: 13px;
width: 350px;
right: 0;
font-style:normal;
padding: 10px 10px 10px 36px;
line-height: 1.5em;
}
.notification.success {
display:none;
background: #d5ffce url(tick_circle.png);
border-color: #9adf8f;
color: #556652;}
.notification.error {
display:none;
background: #ffcece url(cross_circle.png);
border-color: #df8f8f;
color: #665252;}
.notification .close {
position:absolute;
right:5px;
top:5px;
width:7px;
height:7px;
display:block;
text-indent:-30000px;
background: url(cross_grey_small.png) no-repeat 0 0;
}
grade.sql
-- -- Структура таблицы `grade` -- CREATE TABLE IF NOT EXISTS `grade` ( `id` int(11) NOT NULL AUTO_INCREMENT, `rate` varchar(11) NOT NULL, `date` varchar(11) NOT NULL, `p_id` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=54 ; -- -- Дамп данных таблицы `grade` -- INSERT INTO `grade` (`id`, `rate`, `date`, `p_id`) VALUES (4, '5', '18-08-2010', 2), (19, '4', '19-08-2010', 3), (20, '1', '21-08-2010', 3), (21, '4', '16-08-2010', 2), (22, '2', '28-08-2010', 3), (23, '5', '29-08-2010', 3), (24, '5', '20-08-2010', 4), (25, '1', '01-08-2010', 1), (47, '2', '14-08-2010', 5), (29, '1', '13-08-2010', 3), (31, '5', '07-01-2010', 1), (32, '4', '03-08-2010', 3), (33, '1', '06-08-2010', 2), (34, '1', '05-08-2010', 3), (35, '5', '09-08-2010', 3), (37, '2', '15-08-2010', 3), (39, '5', '31-08-2010', 3), (49, '2', '31-08-2010', 1), (48, '1', '31-08-2010', 5), (42, '2', '26-08-2010', 3), (50, '3', '31-08-2010', 2), (46, '3', '24-08-2010', 3), (52, '2', '31-08-2010', 4), (53, '2', '21-08-2010', 4);
grade.sql
-- -- Структура таблицы `people` -- CREATE TABLE IF NOT EXISTS `people` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `tel` varchar(255) NOT NULL, `something` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ; -- -- Дамп данных таблицы `people` -- INSERT INTO `people` (`id`, `name`, `tel`, `something`) VALUES (2, 'Петров', '222-222', 'something'), (3, 'Сидоров', '333-333', 'something'), (4, 'Сидоренко', '444-444', 'something'), (6, 'Краснов', '', '');

Я только изучаю php, и меня заинтересовал этот пример, но при попытке запустить журнал у себя пришел к выводу, что тут ошибка где то тут:
$query=mysql_query("SELECT id,rate FROM grade WHERE date='".$date."' AND p_id='".$p_id."' LIMIT 1");
и выплывает она тут:
function parsedate($date){
if(!$date)$date=date('d-m-Y');
preg_match('#([\d]{1,2})-([\d]{1,2})-([\d]{2,4})#',$date,$result);
$a=array();
$a['day']=$result[1];
$a['month']=$result[2];
$a['year']=$result[3];
return $a;
}
Какая ошибка?
Нет, прошу прощения. это наверное моя ошибка, так и не смог его поставить. А хотел посмотреть как он работает