Многим пользователям интернета очень нравится, когда можно применить какой-то фильтр на странице, или подгрузить данные из базы данных без перезагрузки страницы. В данном посте я расскажу, как такое можно сделать с помощью JavaScript и AJAX.
Чтобы не сильно мудрить, я взял за пример случай, когда нужно получить новости определенных категорий на указанную дату. Идея такая: мы отмечаем чекбоксы нужных категорий, указываем дату и нажимаем кнопку «Показать новости»; после этого появляется картинка загрузки и данные загружаются в нужный блок страницы.
Представим ситуацию, когда у нас есть две таблицы (категории и новости) такой структуры:
Одно условие, что у новости может быть только одна категория (связь 1 ко ∞), в противном случае – тут уже совсем другая связь. Представим, что в наших таблицах содержатся такие данные:
Как выше указывалось, наши категории будут checkbox-ами, значит, их вывод сделаем примерно таким:
Кроме этого у нас указывается дата для получения новостей, и нужна сама кнопка «Показать новости». Во время получения новостей я буду отображать некий индикатор загрузки, для примера я взял такую картинку:
Зачем это надо?! Ну если, например, у вас очень медленный хостинг, или слишком сложный запрос, который долго отрабатывается, тогда надо как-то сообщить пользователю что что-то делается. Чтобы он не нажал кнопку, увидел, что ничего не срабатывает и не ушел со страницы.
Конечно же, наш результат надо куда-то выводить, так что добавим еще и результирующий блок. Будет это, примерно, такой код:
Дата: (yyyy-mm-dd)
Для подгрузки результата в блок нужен такой JavaScript-код (действия в комментариях):
Чтобы не сильно мудрить, я взял за пример случай, когда нужно получить новости определенных категорий на указанную дату. Идея такая: мы отмечаем чекбоксы нужных категорий, указываем дату и нажимаем кнопку «Показать новости»; после этого появляется картинка загрузки и данные загружаются в нужный блок страницы.
Представим ситуацию, когда у нас есть две таблицы (категории и новости) такой структуры:
Одно условие, что у новости может быть только одна категория (связь 1 ко ∞), в противном случае – тут уже совсем другая связь. Представим, что в наших таблицах содержатся такие данные:
categories | |
5 | Спорт |
8 | Музыка |
9 | Кино |
11 | IT |
news | ||||
3 | Название новости 1 | Текст новости 1 | 2012-11-03 | 5 |
4 | Название новости 2 | Текст новости 2 | 2012-11-03 | 9 |
6 | Название новости 3 | Текст новости 3 | 2012-11-03 | 11 |
7 | Название новости 4 | Текст новости 4 | 2012-11-04 | 5 |
8 | Название новости 5 | Текст новости 5 | 2012-11-04 | 11 |
10 | Название новости 6 | Текст новости 6 | 2012-11-05 | 8 |
11 | Название новости 7 | Текст новости 7 | 2012-11-05 | 11 |
Как выше указывалось, наши категории будут checkbox-ами, значит, их вывод сделаем примерно таким:
<?php
$result = mysql_query("SELECT * FROM categories ORDER BY name;")
or die("Invalid query: " . mysql_error());
echo "<fieldset><legend>Категории</legend>";
while ($row = mysql_fetch_array($result)) {
echo "<input name='news_cat' type='checkbox' value='".$row["id"]."' />".$row["name"]."<br/>";
}
echo "</fieldset>";
?>
Не трудно заметить, что значениями value наших чекбоксов являются идентификаторы категорий.
Кроме этого у нас указывается дата для получения новостей, и нужна сама кнопка «Показать новости». Во время получения новостей я буду отображать некий индикатор загрузки, для примера я взял такую картинку:
Зачем это надо?! Ну если, например, у вас очень медленный хостинг, или слишком сложный запрос, который долго отрабатывается, тогда надо как-то сообщить пользователю что что-то делается. Чтобы он не нажал кнопку, увидел, что ничего не срабатывает и не ушел со страницы.
Конечно же, наш результат надо куда-то выводить, так что добавим еще и результирующий блок. Будет это, примерно, такой код:
...
Дата: <input name="newsdate" type="text" size="10" /> <span style="font-size:12px;">(yyyy-mm-dd)</span><br /><br />
<?php
$result = mysql_query("SELECT * FROM categories ORDER BY name;")
or die("Invalid query: " . mysql_error());
echo "<fieldset><legend>Категории</legend>";
while ($row = mysql_fetch_array($result)) {
echo "<input name='news_cat' type='checkbox' value='".$row["id"]."' />".$row["name"]."<br/>";
}
echo "</fieldset>";
?>
<br/>
<input name="getnews" type="button" value="Показать новости" onclick="getnews()" />
<div id="download_img" style="display:none;"><img src="loading.gif" alt="" width="100" height="100" /></div>
<div id="result_div"></div>
...
Если разместить данный код, то должна получится, примерно, такая картина:Дата: (yyyy-mm-dd)
Для подгрузки результата в блок нужен такой JavaScript-код (действия в комментариях):
function getnews() {
dateformat = /[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])$/;
newsdate = $('input[name="newsdate"]').val();
// Проверяем формат введенной даты
if (!dateformat.test(newsdate)) {
alert("Неверный формат даты!");
return false;
}
// Проверяем отмечен ли хоть один чекбокс
if ($('input[name="news_cat"]').is(':checked')==false) {
alert("Ни одна категория не выбрана!");
return false;
}
//Показываем картинку загрузки
$('div#download_img').css('display', 'block');
tagsArray = new Array();
//Формируем массив из изначений value чекбоксов
$('input[name="news_cat"]:checked').each(function() {tagsArray.push(this.value);});
//Отправляем ajax-запрос к файлу newsfilter.php, в нем передаем дату и массив категорий
$.ajax({
type:"POST",
url:"newsfilter.php",
data: {"newsdate":newsdate, "categories[]":tagsArray},
cache: false,
success: function(responce){
//Загружаем результат в блок с id=result_div и прячем картинку загрузки
$('div#result_div').html(responce);
$('div#download_img').css('display', 'none');
}
})
}
Ну и, чтобы все это дело заработало, надо создать файл newsfilter.php, который будет формировать список новостей. Различные проверки на передаваемые параметры не пишу, а также не пишу подключение к БД (думаю, несложно будет доработать код под себя), напишу только простенькую защиту от SQL-инъекций и основной функционал данного файла. Выводимую информацию также доработаете сами: всякие там стили, картинки и т.д. Я же выведу результат по-простому:
...
<?php
$newsdate = preg_replace("/[^0-9\-]/i", "", $_POST["newsdate"]);
$categories = preg_replace("/[^0-9,]/i", "", implode(",", $_POST["categories"]));
$queryText = "SELECT
news.title AS title,
news.news_text AS news_text,
categories.name AS categ
FROM
news
LEFT JOIN
categories
ON
news.category = categories.id
WHERE
news.category IN (".$categories.")
AND
news.news_date = '".$newsdate."'
ORDER BY
categories.name";
$result = mysql_query($queryText);
if (mysql_num_rows($result)>0) {
$resultText ="";
while ($row = mysql_fetch_array($result)) {
$resultText .= "<h3>".$row["title"]."</h3>";
$resultText .= "<span style='font-style:italic;'>Категория: </span>".$row["categ"]."<br/>";
$resultText .= "<p>".$row["news_text"]."</p>";
}
echo $resultText;
} else {
echo "Нет новостей по указанным критериям!";
}
?>
Вот так можно реализовать получение данных из БД без перезагрузки страницы. Извините, что демо не могу предоставить, но, думаю, трудностей возникнуть не должно. Между тегами <head> не забудьте подключить библиотеку jQuery, чтобы работал JavaScript:
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js'></script>
newsfilter.php
ОтветитьУдалитьВОТ ПРАВИЛЬНЫЙ ВАРИАНТ ТВОЙ КОТ НЕ РАБОТАЕТ
$newsdate = preg_replace("/[^0-9\-]/i", "", $_POST["newsdate"]);
$categories = preg_replace("/[^0-9\-]/i", "", $_POST["categories"]);
$string = join(',', $categories);
$result = mysql_query ("SELECT title,news_text, news_date FROM news WHERE category IN($string) AND news_date ='$newsdate'" );
$row = mysql_fetch_array ($result);
if($row == false)
{echo "Не чего не нашлось";}
do{
echo "
$row[news_text]
";
}
while($row = mysql_fetch_array ($result));
Ну не знаю, спорить не буду... Свой код я тестировал на локале в денвере, Ваш же, по-моему, отличается только использованием join (у меня implode) и конструкцией цикла... что, как на меня, не должно ничего менять...
УдалитьПосмотрим, может еще кто оставит комментарий, что данный код не работает. Пока Вы первый, кто об этом написал
Супер, спасибо большое, получилось.
ОтветитьУдалитьПравда я сделал не чекбоксами, а выпадающим списком, но это не суть.
А не подскажете, как сделать еще чекбокс, который выдавал бы новости из любой категории, т.е. value должен включать в себя id всех категорий.
...новости из любой категории...
УдалитьСлучайной категории, или со всех категорий вместе взятых?
Не обязательно впихивать в value все id категорий. Можно сделать его равным true или false (либо 1 и 0), и передавать его в файл newsfilter.php
УдалитьА там уже проверять... Если, например, значение 1, то убирать из запроса условие
news.category IN (".$categories.")
Таким образом, будут выбраны все категории.
Ну и в нагрузку)))
УдалитьЕсли все таки надо впихивать в value id всех категорий, то делаем value равным 1, 2, 3, 5 и т.д. (через запятую). А в js превращаем строку в массив идентификаторов, например так:
categories=$('input[name="all_cat"]').value.split(',');
Ну и дальше передавать массив так же в файл newsfilter.php
спасибо, попробую
УдалитьТы жив еще?
ОтветитьУдалитьЭтот комментарий был удален автором.
Удалитьадениум Без определения сорта ,
ОтветитьУдалитьВзрослые адениумы и саженцы