Нужно передать значение переменной при нажатии button
Здравствуйте. Помогите передать значение переменной "txtName" и $buttonName = true на страницу при нажатии кнопки "buttonName" без перезагрузки страницы.
if ($_POST['buttonName']) { echo $_POST['txtName']; } } echo ' <input id="txtId" name="txtName" type="text" value=""> <input id="buttonId" name="buttonName" type="button" onClick="" value="Добавить">'; |
Ajax поможет, XMLHttpRequest или один из методов jQuery, если используется.
if ($_POST['buttonName']) { echo $_POST['txtName']; } А без кнопки buttonName, что не прокатит? if ($_POST['txtName']) { echo $_POST['txtName']; } |
Это добавление товаров в корзину. Поэтому нажатие кнопки "добавить" обязательно должно быть. Я не очень владею ajax, поэтому и прошу помощи. Немного осваиваю js, но знаний не хватает на некоторые моменты связанные с отправкой переменных через формы не подгружая страницы.
|
Laimas, а Вы не могли бы подробнее с кодом показать как осуществить передачу переменной нажатием кнопки?
|
Ну если корзина и добавление товара, то 'txtName', это не то что нужно, нужен идентификатор товара.
Вы используете в этом проекте jQuery или нет? |
Да использую. Нужна любая реализация задуманного. Js мне хоть как-то знаком, с jquery все сложнее :)
|
Ну на jQuery как раз сложностей нет, все намного проще. Выберите упрощенные его методы Ajax .get() или .post(), их вполне хватит. Попробуйте хотя бы по примерам что-то написать, а далее с конкретными проблемами можно и на форум.
|
Хотелось бы на примере увидеть. Сейчас пытаюсь изучить ajax, но не все моменты понятны. Нужен пример.
|
Так примеры есть и по ссылке. Ну если не понятно как их задействовать конкретно к кнопке и полю ввода, то можно поступить например так - поля input, это поля вне формы, если не подразумевается добавление N-товаров с одной страницы, то есть запрос на добавление, это добавление только одного товара. Пусть все товары на странице отображаются в списке, и элемент UL имеет id "products", в нем, а не по всей странице и нужно искать кнопки инициализирующие запрос сервера:
<ul id="products"> <li><input type="number" name="pid[100]" value="1" min="1"> <button></button></li> <li><input type="number" name="pid[212]" value="1" min="1"> <button></button></li> </ul> Поле выбора количества товара лучше сделать типа number - в Opera, Chrome, в последнем FF такое поле будет иметь кнопки. Старые браузеры будут "понимать" такое поле как text. Имя поля, это ключ содержащий идентификатор товара, в примере равен pid. На сервере идентификатор можно получить так: (int)key($_POST['pid']). Кнопки добавления по умолчанию, это что-то кругленькое, с иконкой корзины к примеру, а по нажатию кнопке добавляется класс "send", при котором изображение кнопки изменятся на gif-анимацию, крутилку указывающую что идет обмен с сервером. На время запроса сервера нужно блокировать запросы на добавление товара, а по окончании снимать блокировку. Это можно сделать с помощью двух методов jQuery - ajaxStart и ajaxStop, которые можно привязать к любою объекту. В итоге получится, что-то такое: <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <script> function toBasket(o) { $.post('url', o.attr('name')+'='+o.val(), function(d) { //d содержит ответ сервера //удаляем анимацию у кнопки o.next().removeClass('send'); }) } $(function() { var add = $('#products').find('button'); add.click(function() { //добавляем анимацию кнопке и передаем количество товара серверу toBasket($(this).addClass('send').prev()) }).on({ ajaxStart: function() { //блокируем отправку add.prop('disabled', 1) }, ajaxStop: function() { //разрешаем отправку add.prop('disabled', 0) } }); }); </script> PS. Подправил, совершенно из головы вылетел идентификатор товара ) |
Цитата:
1. Добавил скрипт между тегами <head> </head> 2. Кнопки вывел за форму (form) и добавил стиль к кнопкам .send, прописав его в css. Ничего не получилось. :( Изначально стиль прописывается у кнопки, и при нажатии тоже срабатывает. Но id товара не передается. Как было 0, так и осталось. Прописал строку «Номер: (int)key($_POST['pid'])» прямо под списком с кнопками. Я явно что-то не учел :) |
<? session_start(); //база товаров $products = [ 23 => ['price'=>120, 'name'=>'Товар 1'], 245 => ['price'=>230, 'name'=>'Товар 2'], 39 => ['price'=>150, 'name'=>'Товар 3'], 109 => ['price'=>380, 'name'=>'Товар 4'] ]; //запрос на добавление товара if($_POST) { if($pid = (int)key(current($_POST)) AND $val = (int)$_POST['pid'][$pid]) { //что нам шлют? //sleep(1); //убрать комментарий для проверки корректности действий на клиенте под локальным сервером //проверяем есть ли такой товар в базе и, если требуется, то и наличе его на складе if(array_key_exists($pid, $products)) { //добавляем товар в корзину $_SESSION['basket'][$pid] = [$val, $products[$pid]['price'], [$products[$pid]['name']]]; //получаем и возвращаем всего в корзине exit(json_encode(totalBasket())); } else exit(json_encode(['msg'=>'Нет в наличии'])); } else exit; } function totalBasket() { $cart = &$_SESSION['basket']; return [array_sum(array_map('current', $cart)), array_sum(array_map('array_product', $cart))]; } ?> <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <style> #short-basket { width: 700px; height: 50px; line-height: 50px; padding-left: 10px; background: #eee; margin: 0 auto; } #products { list-style: none; padding: 0; width: 700px; margin: 20px auto; } #products li { display: inline-block; width: 300px; vertical-align: top; margin: 0 30px 50px 0; } #products li input { width: 60px; } button { padding: 2px 10px 2px 20px; border: 0; border-radius: 2px; background: #ddd url(data:image/gif;base64,R0lGODlhCgAKAIAAAAD/AAAAACH5BAAAAAAALAAAAAAKAAoAAAIIhI+py+0PYysAOw==) no-repeat 5px 50%; cursor: pointer; } .send { background-image: url(data:image/gif;base64,R0lGODlhCgAKAIAAAP8AAAAAACH5BAAAAAAALAAAAAAKAAoAAAIIhI+py+0PYysAOw==); } </style> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <script> var add; function toBasket(o) { $.post(location, o.attr('name')+'='+o.val(), function(d) { if(d.msg) { alert(d.msg) //нет в наличии } else { //отображаем состояние корзины $('#short-basket').find('b') .eq(0) .text(d[0]) //товаров .end() .eq(1) .text(d[1]+'.00'); //на сумму } //удаляем анимацию у кнопки o.next().removeClass('send'); //снимаем блокировку add.prop('disabled', 0) }, 'json') } $(function() { add = $('#products').find('button'); add.click(function() { //блокируем отправку add.prop('disabled', 1) toBasket($(this).addClass('send').prev()) }); }); </script> </head> <body> <div id="short-basket">В корзине: товаров <b>0</b>, на сумму <b>0.00</b> руб.</div> <ul id="products"> <? foreach($products as $k=>$v) $ul .= '<li><h4>'.$v['name'].'</h4><p>Цена: '.$v['price'].'.00 руб.</p><input type="number" name="pid['.$k.']" value="1" min="1"> <button>В корзину</button></li>'; echo $ul; ?> </ul> </body> </html> Кнопки вывел за форму Нет, имеется ввиду, что форма в данном случае не нужна, используются одни элементы INPUT, главное чтобы INPUT и BUTTON были обязательно соседними элементами братьями. Если же со страницы можно добавлять в корзину сразу несколько товаров, то в этом случае удобнее было бы использовать форму, ее событие onsubmit. При этом кнопка "В корзину" будет одна, а серверу будет отправляться массив N-товаров. Прописал строку «Номер: (int)key($_POST['pid'])» Это моя ошибка, таким образом можно и не получить, нужно как в примере выше. Сохраните его как .php под любым именем - адрес запроса указан как текущий посредством location, поэтому имя скрипта роли не играет. Корзина на сессии, а так как время ее жизни является глобальной установкой, нельзя под каждого юзверя установить, то чтобы продлевать ее, можно периодически, например через 10 мин., опрашивать сервер асинхронным запросом без ответа. В этом случае использовать методы ajaxStart и ajaxStop нельзя, так как запросы для сессии и добавления товаров асинхронные, поэтому блокировка и снятие блокировки кнопок перенесено в инициализацию и финиш запроса добавления товаров соответственно. Структура корзины следующая: array( ID_товара => array( количество_товара, цена_товара, array(наименование_товара) ) ) В этом случае легко просчитать общее количество товаров в корзине и их общую сумму стандартными функциями РНР. Именование товара, а возможно и другие какие либо его параметры дополнительные, помещаются в корзину для того, чтобы не "дергать" постоянно базу при обращении к корзине. Все эти доп. параметры должны быть помещены в массив, иначе использовать функцию array_product() для получения произведения количества на цену будет нельзя. Заполненный же массив будет возвращать для этой функции 1, что не будет влиять на результат умножения. Пример написан под РНР не ниже 5.4. |
Вложений: 1
Цитата:
На скрине видно, что я добавил в 4 input число 10, результат корзина выдала совершенно неожиданный. :) |
Вы думаете это ошибка и непонятный алгоритм? :)
Нет тут ошибки и непонятно. Если к примеру добавить первого товара 2 шт., а второго 3 шт., то общее количество будет равно 5 на сумму 930. Посмотрим что у нас в массиве корзины: <pre> print_r($_SESSION['basket']); </pre> и получаем: Код:
Array Измените части кода на следующие (думаю понятно будет что и где): //запрос на добавление товара if($_POST) { if($pid = (int)key(current($_POST)) AND $val = (int)$_POST['pid'][$pid]) { //что нам шлют? sleep(1); //убрать комментарий для проверки корректности действий на клиенте под локальным сервером //проверяем есть ли такой товар в базе и, если требуется, то и наличе его на складе if(array_key_exists($pid, $products)) { //добваляем товар в корзину $_SESSION['basket'][$pid] = ['count'=>$val, 'price'=>$products[$pid]['price'], 'prop'=>['name'=>$products[$pid]['name']]]; //получаем и возвращаем всего в корзине exit(json_encode(totalBasket())); } else exit(json_encode(['msg'=>'Нет в наличии'])); } else exit; } function totalBasket() { return $_SESSION['basket'] ? [array_sum(array_map('current', $_SESSION['basket'])), array_sum(array_map('array_product', $_SESSION['basket']))] : [0, 0]; } $tot = totalBasket(); //.... <div id="short-basket">В корзине: товаров <b><?=$tot[0]?></b>, на сумму <b><?=$tot[1]?>.00</b> руб.</div> //........ foreach($products as $k=>$v) $ul .= '<li><h4>'.$v['name'].'</h4><p>Цена: '.$v['price'].'.00 руб.</p>'. ($_SESSION['basket'] && array_key_exists($k, $_SESSION['basket']) ? '<p>В корзине '.$_SESSION['basket'][$k]['count'].' шт.</p>' : '<input type="number" name="pid['.$k.']" value="1" min="1"> <button>В корзину</button></li>'); Добавьте в корзину каких либо два товара, после чего обновите странице по F5. О чем либо это говорит? |
Вложений: 1
Цитата:
1. Для чего нужен sleep (1)? 2. Как сделать кнопку reset корзины, она там не будет лишней. 3. При обновлении страницы корзина показывает количество 0, сумма 0. Хотя в array корзины товары есть в каком-то количестве. Как это исправить? Я еще не попробовал Ваш новый код. Возможно он это и исправляет, сейчас займусь им :) Цитата:
|
1. Для чего нужен sleep (1)?
Для того чтобы проверить работу кнопок (анимация, блокировка) на локальном сервере. Ведь на нем все будет работать влет, и глазом моргнуть не успеете. А sleep (1) это пауза в одну секунду перед выполнением скрипта, а значит и ответа сервера, чтобы удостовериться, а потом убрать это. На реальном же сервере у вас в любом случае будут задержки. 2. Как сделать кнопку reset корзины, она там не будет лишней. Либо поместить ul (это в примере, у вас может быть и что-то иное) в форму и использовать ее стандартную кнопку reset, либо любую кнопку, и обработчик ее на jQuery, например: <button id="reset">Сбросить</button> //в стилях кнопок button:not([id=reset]) { //... //либо можно оформить под кнопку reset любой иной элемент, и не трогать стили кнопок //код $('#reset').click(function() { $('#products').find('input').val(1); }) При использовании формы и input type=reset, в случае, если потребуется работать с элементами input, не забывайте об этой кнопке. 3. При обновлении страницы корзина показывает количество 0, сумма 0. Хотя в array корзины товары есть в каком-то количестве. Как это исправить? Я еще не попробовал Ваш новый код. Возможно он это и исправляет, сейчас займусь им Займитесь, именно исправления это и учитывают. если такой товар не добавлен в таблицу базы от данного пользователя (который привязан к сессии по id), тогда мы создаем товар для него и ставим туда количество полученное из input, а если товар уже есть в корзине этого пользователя, тогда суммируем его. Вот тут действительно интересно. Мой пример в первой его инкарнации, это не только добавление, но и редактирование корзины со страницы товаров. Я ведь не зря вопросы задавал. То есть, после того как товар добавился в корзину, можно добавить сообщение у товара "В корзине", а текст кнопки сменить с "В корзину" на "Изменить". А в вашем случае "а если товар уже есть в корзине этого пользователя, тогда суммируем его" при каждом добавлении товара надо и сообщать, и сбрасывать значение поля ввода в единицу, иначе это будет не добавление, а бардак :) Но это уже политика магазина, как вам надо так и делайте, я могу по этому поводу иметь свое мнение, которое не обязательно должно быть истиной. |
Сброс ресет не работает на jquery.
Если я правильно понимаю этот код, то первая строка запускает функцию при нажатии на кнопку reset, а функция обращается к id = products, где ищет все input и устанавливает для них параметр val в 1. $('#reset').click(function() { $('#products').find('input').val(1); }) Вот этот val = 1 должен сбрасывать удалять товары из корзины полностью, т.е. проставить количество всех товаров в 0. Я попробовал просто удалить сессию и все сбрасывается, но это команда php, а как без перезагрузки реализовать? :) можно конечно через форму указать тип кнопки и так чистить, у меня так и чистится на данный момент корзина, но интересует именно переделка корзины с отсутствием перезагрузки страниц. Я еще вечером попробую разобраться в вашем коде, пока не все понятно, учусь еще на ваших примерах :) |
Естественно, что этот код устанавливает значения по умолчанию (1) в полях ввода, а сервер не запрашивается при этом, и естественно корзина не удаляется. Это как пример реализации "очистить форму, которой нет". А добавлять запрос к серверу я не стал по двум соображениям (добавление в корзину асинхронное, это важно):
1) Представим, что я ваш покупатель, и на странице А купил три бублика, на странице Б 5 кило конфет к бубликам, на странице В пакетик чая, а потом подумал, да ну его нафик, съем и так, всухомятку. Жму на кнопку reset, предполагая, что таким образом удаляю чай из корзины. Представляете мой ужас, когда я вернувшись на страницу А, пойму что сегодня останусь голодным? Дело хозяйское, но по моему эта кнопка для корзины, это вред. Корзина в примере, это не корзина как таковая, это ее краткое представление. Вы когда в магазине реальном покупаете что-то, ведь в уме считаете наличие суммы в кармане и хватит ли ее на покупки? Вот для этого и служит краткое представление корзины в интернет магазине. Сама же корзина, ее полное представление, в котором можно удалять товар/товары, изменять их количество, или вообще очистить корзину, вызывается отдельно. Это можно реализовать также асинхронным запросом, то есть, к примеру, кнопка/ссылка в кратком представлении раскрывает панель полного представления корзины - редактируйте на здоровье. 2) Корзина, это всего лишь часть задачи - приобретения товара в магазине. А задача, это от выбора товара до оформления заказа. И эту задачу надо решать комплексно, так чтобы сервер и клиент не каждый сам по себе, а единое. Это идея, интерфейс обслуживающий эту идею, удобное представление данных, чтобы сценарии этого интерфейса были оптимальны. А вот взять к примеру мой пример по добавлению товара, а потом притулить к нему кнопку "Сбросить", нагрузив сервер этой задачей как отдельным запросом, так не пойдет. |
Часовой пояс GMT +3, время: 05:06. |