28.02.2016, 07:05
|
Интересующийся
|
|
Регистрация: 24.08.2015
Сообщений: 15
|
|
Jquery + PHP + Smarty
Приветствую, имеется форма:
<select id="country" name="country">
<option>Выберите страну...</option>
{foreach $row_country as $country}
<option value="{$country.country_id}">{$country.name}</option>
{/foreach}
</select>
<select id="region" name="region" disabled>
<option>Выберите регион...</option>
{foreach $row_region as $region}
<option value="{$id.region_id}">{$region.region}</option>
{/foreach}
</select>
Jquery функция:
$('#country').change( function() {
var country = $('#country').val();
$.ajax({
type: "POST",
url: "index.php?option=registration",
data: country,
success: function(data) {
$("#region").removeAttr('disabled');
$("#results").html(country);
alert(country);
}
});
});
И PHP обработчик:
class Registration extends Core {
public function getContent() {
global $mysqli;
global $smarty;
$res = $mysqli->query("SELECT * FROM countries ORDER BY name");
if ($res->num_rows > 0) {
for ($i=0; $i<$res->num_rows; $i++) {
$row_country[] = $mysqli->assoc($res);
}
$smarty->assign("row_country", $row_country);
$smarty->assign("country", $_POST['country']);
}
$res_region = $mysqli->query("SELECT * FROM cities WHERE country_id=".$_POST['country']." ORDER BY region");
if ($res_region->num_rows > 0) {
for ($j=0; $j<$res_region->num_rows; $j++) {
$row_region[] = $mysqli->assoc($res_region);
}
$smarty->assign("row_region", $row_region);
}
}
}
Получается что при выборе первого селекта, переменная country должна подставиться во второй SQL запрос и вывести второй список в зависимости от выбранного селекта.
Проблема в том, что в блоке с id="results" - значение переменной country выводит правильно, а в PHP класс ее засунуть не получается, подскажите как можно решить проблему?
|
|
28.02.2016, 07:38
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Сообщение от middlee
|
подскажите как можно решить проблему?
|
С ответа на вопрос - если это связанные списки, то почему шаблонизатору, а значит и клиенту отдается сразу два списка?
|
|
28.02.2016, 08:11
|
Интересующийся
|
|
Регистрация: 24.08.2015
Сообщений: 15
|
|
Понимаю к чему вы клоните, но придумать как подсунуть второй, а потом и третий список именно классом(PHP)+Smarty не получается
Может подскажите как можно сделать? Хотя-бы в теории
Последний раз редактировалось middlee, 28.02.2016 в 08:15.
|
|
28.02.2016, 08:43
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Сообщение от middlee
|
в ООП не силен
|
А он в данном случае нужен? Зачем писать класс, публичная функция которой не принимает параметров, обрабатывая конкретный один - значение $_POST['country'], а хотите еще и тертий, и...? Каким же образом $_POST догадается сам подставить нужный ключ?
Более того, у вас mysqli, но вы не только не используете его подготовленные запросы, но и сами не беспокоитесь о безопасности, подставляя в запрос как есть - $_POST['country'].
В данном классе совсем и не нужен запрос к таблице countries, так как список этих значений уже должен быть у клиента.
Не понимаете ООП, напишите проще, свой легкий скрипт, который будет обрабатывать запросы, при этом, если сервер отдает готовый html-списков, то Smarty не нужен, куда проще сразу:
if ($res->num_rows) {
$s = '<select name="'.$key.'">';
while($row = $mysqli->assoc($res)) $s .= '<option value="'.$row['field_name'].'">'.htmlspecialchars($row['field_name']).'</option>';
echo $s .= '</select>';
}
Если же все таки Smart, то
if ($res->num_rows) {
$row = [];
while($row[] = $mysqli->assoc($res));
$smarty->assign("row_region", $row);
}
Но ответ сервера на Ajax запрос, а значит не $smarty->assign(), а перехват в переменную, которую затем возвращать клиенту.
Не $row_region, а $row и $res, а не $res_region потому, что функция должна получать параметр: ключ => значение, где ключ определяет список на клиенте породивший запрос, а значит и таблицу, к которой нужно обратиться. В противном случае придется на каждый список писать отдельные функции. А что на сервере, что на клиенте должен быть один метод обработки запросов.
Как поступать на клиенте при возврате очередного списка от сервера, во многом будет зависеть от html представления этих списков, их окружения.
Разберетесь с работой на базе простого скрипта, а далее дай бог может и сообразите как это должно существовать как класс.
Последний раз редактировалось laimas, 28.02.2016 в 08:59.
|
|
29.02.2016, 16:32
|
Интересующийся
|
|
Регистрация: 24.08.2015
Сообщений: 15
|
|
Решил проблему, не так как хотелось конечно, но на первое время сойдет, выкладываю решению, может кому-то пригодится:
<select id="country" name="country">
<option>Выберите страну...</option>
{foreach $row_country as $country}
<option {if $country.country_id == $smarty.get.country} selected {/if} value="{$country.country_id}">{$country.name}</option>
{/foreach}
</select>
<select id="region" name="region">
<option>Выберите регион...</option>
{foreach $row_region as $region}
<option {if $region.region_id == $smarty.get.region} selected {/if} value="{$region.region_id}">{$region.name}</option>
{/foreach}
</select>
<select id="city" name="city">
<option>Выберите город...</option>
{foreach $row_city as $city}
<option value="{$city.id}">{$city.name}</option>
{/foreach}
</select>
$('#country').change( function() {
var country = $('#country').val();
$.ajax({
type: "GET",
url: "index.php?option=registration&country="+country,
data: country,
success: function(data) {
document.location.href = "index.php?option=registration&country="+country;
}
});
});
$('#region').change( function() {
var region = $('#region').val();
var country = $('#country').val();
$.ajax({
type: "GET",
url: "index.php?option=registration&country="+country+"®ion="+region,
data: region,
success: function(data) {
document.location.href = "index.php?option=registration&country="+country+"®ion="+region;
}
});
});
class Registration extends Core {
public function getContent() {
global $mysqli;
global $smarty;
$res = $mysqli->query("SELECT * FROM country ORDER BY name");
if ($res->num_rows > 0) {
for ($i=0; $i<$res->num_rows; $i++) {
$row_country[] = $mysqli->assoc($res);
}
$smarty->assign("row_country", $row_country);
$smarty->assign("country", $_POST['country']);
}
$res_region = $mysqli->query("SELECT * FROM region WHERE country_id=".$_GET['country']." ORDER BY name");
if ($res_region->num_rows > 0) {
for ($j=0; $j<$res_region->num_rows; $j++) {
$row_region[] = $mysqli->assoc($res_region);
}
$smarty->assign("row_region", $row_region);
}
$res_city = $mysqli->query("SELECT * FROM city WHERE region_id=".$_GET['region']." ORDER BY name");
if ($res_city->num_rows > 0) {
for ($j=0; $j<$res_city->num_rows; $j++) {
$row_city[] = $mysqli->assoc($res_city);
}
$smarty->assign("row_city", $row_city);
}
}
}
laimas держи +, помог
Последний раз редактировалось middlee, 29.02.2016 в 16:35.
|
|
29.02.2016, 18:43
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Это не решение, это называется "подогнать под ответ" и вряд ли кто-то таким захочет воспользоваться.
Во-первых WHERE country_id=".$_GET['country'].", это явная дыра в безопасности, уж коли не используете с этой целью сам mysqli, то тогда уж
' ... WHERE country_id=".(int)$_GET['country']."
' ... WHERE region_id=".(int)$_GET['region']."
Так обрабатывать строки ресурса:
for ($j=0; $j<$res_region->num_rows; $j++) {
$row_region[] = $mysqli->assoc($res_region);
}
это слишком. )
Во-вторых должно быть не $_GET['country'] и $_GET['region'], а public function getContent(argument), в качестве которого и выступает полученное POST значение, и на клиенте хватит одного метода .ajax() для обслуживания этих списков.
Вы просто поторопились.
Последний раз редактировалось laimas, 29.02.2016 в 18:53.
|
|
29.02.2016, 22:20
|
Интересующийся
|
|
Регистрация: 24.08.2015
Сообщений: 15
|
|
Дырки в безопасности это уже совсем другой вопрос, с этим все нормально.
А чем плох цикл for? В вашем примере выше "тот же х.., только в другой руке" (извините за выражение). По-моему разницы нет, тут кто как привык, так и делает.
Последний раз редактировалось middlee, 29.02.2016 в 22:24.
|
|
01.03.2016, 01:51
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Сообщение от middlee
|
А чем плох цикл for?
|
Ничем, да и поворотливей цикла while будет, но вы ведь делаете лишние неоправданные операции. Ну а что кроме 0 или больше 0 может вернуть запрос, кроме неудачи запроса (думаю у вас ошибки обрабатываются, и при ее наличии далее не будет исполнения)? А 0, есть !1, любовь писать обязательно if ($res_city->num_rows > 0) умиляет. )
Цикл for, это не обязательно for ( expr1; expr2; expr3 ), каждое из этих выражений вообще может быть пустым, а для получения строк ресурса в массив достаточно лишь одного:
$arr = [];
for (; $arr[] = $mysqli->assoc($res); )
А привлекать Smaprty для возврата простого списка клиенту, это вообще моветон. Будь списков больше, так лучше вообще JSON, и Smarty тут не приделах.
У вас лишнее в методах как на сервере, так и на клиенте, ибо вы решаете, что делать серверу не посредством как это принято "совокупностью параметров", а в лоб - пришло А, есть функция А, пришло Б, есть функция Б, и т.д..
|
|
02.03.2016, 21:50
|
Интересующийся
|
|
Регистрация: 24.08.2015
Сообщений: 15
|
|
Возникла еще одна проблемка, новую тему не создаю, под эту вполне подходит, есть вот такая конструкция:
$('#auth_form').submit( function(e){
e.preventDefault();
var m_method=$(this).attr('method');
var m_action=$(this).attr('action');
var m_data=$(this).serialize();
$.ajax({
type: m_method,
url: m_action,
data: m_data,
success: function(){
document.location.href="index.php";
},
error: function() {
alert("Ошибка");
}
});
});
В PHP скрипте идет обычная выборка, как сделать чтобы если эта выборка не сработала, то есть $res->num_rows = 0, срабатывал параметр error в JQuery скрипте, а не success?
Последний раз редактировалось middlee, 02.03.2016 в 22:11.
|
|
03.03.2016, 06:05
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Конечно извиняюсь ибо звучит грубо, но вы первый вопрос решили через задницу и в данном случае хотите такого же решения.
Метод error служит для обработки именно ошибок, как то отсутствия соединения с сервером, некорректные данные возвращенные сервером, к примеру без определения этого метода и формата JSON, будь он некорректен, то будет тишина.
Какое отношение имеет к ошибке отсутствие записей в базе? Это не ошибка, это информация, которую нужно сообщить пользователю, и если эту ситуацию не анализирует сервер и не возвращает готовое сообщение, то это должен анализировать клиент и в методе success, а не error.
|
|
|
|