Od jakiegoś czasu bawię się wzorcem projektowym MVC i JQuery. Niedawno pojawił się problem, którego nie umiem sam rozwiązać.
Aplikacja, którą piszę, ma pomóc użytkownikowi w zarządzaniu czasem. Stworzyłem w niej dwie struktury: cel i zadanie. Zadanie to krokowa czynność, którą należy wykonać, by osiągnąć dany cel.
Zatem mamy zależność: jeden cel - wiele zadań.
Problem pojawił się w jednej z formatek. Docelowe działanie ma być takie, że kiedy użytkownik wybiera jeden combobox z listą celów (pobranych z bazy danych), pojawia się ukryty dotąd drugi combobox, który wyświetla listę zadań w ramach uprzednio wybranego celu. Obecnie wygląda to tak, że kiedy wybieram combobox z listą celów, combobox z listą zadań pojawia się i znika, a w konsoli przeglądarki mam komunikat:
"Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to
the end user's experience.". Na forach przeczytałem, że problem można rozwiązać poprzez dodanie do AJAX-a "async: false", jednak i to nie pomogło.
Tyle tytułem wstępu, teraz czas na kod.
index.php:
Kod
<!DOCTYPE html>
<html lang="pl-PL">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script type="text/javascript" src="js/jquery-2.1.3.min.js"></script>
<script type="text/javascript" src="js/moj_skrypt.js"></script>
<script type="text/javascript" src="js/moj_skrypt2.js"></script>
<link rel="stylesheet" href="css/styles.css" type="text/css" />
</head>
<body>
<?php
include('include.php');
if($_GET['akcja']=='PobierzDate')
{
$data_od=$_POST['data_od'];
$next_data = HourController::pobierzNastepneDaty($date);
echo $next_data;
}
if($_GET['akcja']=='TydzienStworz')
{
$controller=new WeekController();
}
if($_GET['akcja']=='ZadanieWyswietlZadanie')
{
$nazwa_celu=$_POST['nazwa_celu'];
}
if($_GET['akcja']=='PobierzZadania')
{
try
{
$nazwa_celu=$_POST['nazwa_celu'];
$db = new PDO('mysql:host=localhost;dbname=harmonogram', 'root', '') or die();
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$text_query = "SELECT `nazwa_zadania` from `zadanie` where `id_celu` in
(select `id_celu` from `cel` where `nazwa_celu`='Zrobic prawo jazdy');";
$stmt = $db->query($text_query);
$result = $stmt->fetchAll();
foreach($result as $row)
{
$zadanie=$row['nazwa_zadania'];
}
$stmt->closeCursor();
}
catch(PDOException $e)
{
echo "Polaczenie nie moglo zostac utworzone: ".$e->getMessage();
}
}
else
{
new HourController();
}
?>
</body>
</html>
<html lang="pl-PL">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script type="text/javascript" src="js/jquery-2.1.3.min.js"></script>
<script type="text/javascript" src="js/moj_skrypt.js"></script>
<script type="text/javascript" src="js/moj_skrypt2.js"></script>
<link rel="stylesheet" href="css/styles.css" type="text/css" />
</head>
<body>
<?php
include('include.php');
if($_GET['akcja']=='PobierzDate')
{
$data_od=$_POST['data_od'];
$next_data = HourController::pobierzNastepneDaty($date);
echo $next_data;
}
if($_GET['akcja']=='TydzienStworz')
{
$controller=new WeekController();
}
if($_GET['akcja']=='ZadanieWyswietlZadanie')
{
$nazwa_celu=$_POST['nazwa_celu'];
}
if($_GET['akcja']=='PobierzZadania')
{
try
{
$nazwa_celu=$_POST['nazwa_celu'];
$db = new PDO('mysql:host=localhost;dbname=harmonogram', 'root', '') or die();
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$text_query = "SELECT `nazwa_zadania` from `zadanie` where `id_celu` in
(select `id_celu` from `cel` where `nazwa_celu`='Zrobic prawo jazdy');";
$stmt = $db->query($text_query);
$result = $stmt->fetchAll();
foreach($result as $row)
{
$zadanie=$row['nazwa_zadania'];
}
$stmt->closeCursor();
}
catch(PDOException $e)
{
echo "Polaczenie nie moglo zostac utworzone: ".$e->getMessage();
}
}
else
{
new HourController();
}
?>
</body>
</html>
Kiedy wywoływana jest akcja "TydzienStworz", uruchamiam konstruktor kontrolera WeekKontroler, który z kolei inicjalizuje potrzebne dane i wywołuje widok, z którym mam problem: WeekTaskAddView.
WeekTaskAddView.php:
Kod
<?php
class WeekTaskAddView
{
private $naglowek;
private $data_od;
private $data_do;
private $lista_celow;
private $lista_celow_liczba_wierszy;
public function __construct($naglowek, $data_od, $data_do, $lista_celow)
{
$this->naglowek = $naglowek;
$this->data_od=$data_od;
$this->data_do=$data_do;
$this->lista_celow=$lista_celow;
$this->lista_celow_liczba_wierszy=count($this->lista_celow);
$this->wyswietlStrone();
}
private function wyswietlStrone()
{
echo '<!DOCTYPE html>';
echo '<html lang="pl-PL">';
echo '<head>';
echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>';
echo '<script src="js/jquery-2.1.3.min.js"></script>';
echo '</head>';
echo '<body>';
echo '<h1>'.$this->naglowek.'</h1>';
echo '<form method="POST" action="index.php?akcja=TydzienDodaj">';
echo "<div id='zadania'>";
echo "</div>";
for ($i=0; $i<7; $i++)
{
$data_kalendarzowa = date("d-m-Y", strtotime("$this->data_od+$i day"));
echo "<div id='dzien'><br>".$data_kalendarzowa."</div>";
echo "<table border=1><tr><td><select name='godzina' id='godzina'
class='godzina'>";
$j=0;
$k=0;
do
{
$k=0;
if($k==0)
{
if(($j<10)&($k==0))
{
echo "<option>0$j:0$k</option>";
}
}
$k+=15;
do
{
if(($j<10)&($k>0))
{
echo "<option>0$j:$k</option>";
}
if(($j>=10)&($k>0))
{
echo "<option>$j:$k</option>";
}
$k+=15;
}
while ($k<60);
$j++;
}
while ($j<24);
echo "</select></td></tr>";
echo "<tr><td>Nazwa celu</td><td><select name='cele' id='cele'
class='cele'>";
for ($m=0; $m<$this->lista_celow_liczba_wierszy; $m++)
{
echo "<option>".$this->lista_celow[$m]['nazwa_celu']."</option>";
}
echo "</select></td>";
echo "<td>Nazwa zadania:</td></tr>";
echo "<tr><td><div id='zadania' name='zadania'
class='zadania'></div></td>";
echo "</tr></table>";
}
echo '</div>';
//$dzien_tyg_ang = date("l",strtotime($data_od));
echo "</form>";
echo '</body>';
echo '</html>';
}
}
?>
class WeekTaskAddView
{
private $naglowek;
private $data_od;
private $data_do;
private $lista_celow;
private $lista_celow_liczba_wierszy;
public function __construct($naglowek, $data_od, $data_do, $lista_celow)
{
$this->naglowek = $naglowek;
$this->data_od=$data_od;
$this->data_do=$data_do;
$this->lista_celow=$lista_celow;
$this->lista_celow_liczba_wierszy=count($this->lista_celow);
$this->wyswietlStrone();
}
private function wyswietlStrone()
{
echo '<!DOCTYPE html>';
echo '<html lang="pl-PL">';
echo '<head>';
echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>';
echo '<script src="js/jquery-2.1.3.min.js"></script>';
echo '</head>';
echo '<body>';
echo '<h1>'.$this->naglowek.'</h1>';
echo '<form method="POST" action="index.php?akcja=TydzienDodaj">';
echo "<div id='zadania'>";
echo "</div>";
for ($i=0; $i<7; $i++)
{
$data_kalendarzowa = date("d-m-Y", strtotime("$this->data_od+$i day"));
echo "<div id='dzien'><br>".$data_kalendarzowa."</div>";
echo "<table border=1><tr><td><select name='godzina' id='godzina'
class='godzina'>";
$j=0;
$k=0;
do
{
$k=0;
if($k==0)
{
if(($j<10)&($k==0))
{
echo "<option>0$j:0$k</option>";
}
}
$k+=15;
do
{
if(($j<10)&($k>0))
{
echo "<option>0$j:$k</option>";
}
if(($j>=10)&($k>0))
{
echo "<option>$j:$k</option>";
}
$k+=15;
}
while ($k<60);
$j++;
}
while ($j<24);
echo "</select></td></tr>";
echo "<tr><td>Nazwa celu</td><td><select name='cele' id='cele'
class='cele'>";
for ($m=0; $m<$this->lista_celow_liczba_wierszy; $m++)
{
echo "<option>".$this->lista_celow[$m]['nazwa_celu']."</option>";
}
echo "</select></td>";
echo "<td>Nazwa zadania:</td></tr>";
echo "<tr><td><div id='zadania' name='zadania'
class='zadania'></div></td>";
echo "</tr></table>";
}
echo '</div>';
//$dzien_tyg_ang = date("l",strtotime($data_od));
echo "</form>";
echo '</body>';
echo '</html>';
}
}
?>
Formatka zawiera m.in. pola z listą dni i godzin zaplanowanych na dane zadanie. Pole z zadaniami jest opakowane w diva o nazwie i identyfikatorze "zadania".
Skrypt, który obsługuje zdarzenie wybrania comboboxa z listą celów jest następujący:
moj_skrypt2.js:
Kod
$(document).ready(function(){
$('.zadania').hide();
$('.cele').change(function()
{
var cel=$(this).val();
$.ajax({
type: 'POST',
async: false,
url: "index.php?akcja=PobierzZadania",
data: {'nazwa_celu': cel},
success: function(response) {
$('.zadania').show();
$('.zadania').html('<select name="zadania2" id="zadania2"><option>'+response+'</option></select>');
},
})
})
$('#godzina').change(function()
{
})
});
$('.zadania').hide();
$('.cele').change(function()
{
var cel=$(this).val();
$.ajax({
type: 'POST',
async: false,
url: "index.php?akcja=PobierzZadania",
data: {'nazwa_celu': cel},
success: function(response) {
$('.zadania').show();
$('.zadania').html('<select name="zadania2" id="zadania2"><option>'+response+'</option></select>');
},
})
})
$('#godzina').change(function()
{
})
});
Skrypt ma za zadanie utworzenie nowego comboboxa i pobranie listy zadań poprzez wywołanie akcji "PobierzZadania". Problem w tym, że kiedy wybieram jakiś cel, combobox z listą zadań pojawia się na chwilę i znika. Problem weryfikowałem pod przeglądarką Google chrome.
Proszę o jakieś sugestie i/lub KONSTRUKTYWNE uwagi.
Pozdrawiam
Mikołaj