Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 06.08.2016, 13:19
Интересующийся
Отправить личное сообщение для avalan4e Посмотреть профиль Найти все сообщения от avalan4e
 
Регистрация: 04.07.2016
Сообщений: 20

Как превратить велосипед в фотонный звездолёт
Приветствую, уважаемые коллеги. Поставил себе задачу: считывать данные формы, как только будут внесены изменения, затем обработать их на сервере и вернуть на страничку результат. Нагородил семнадцати колесный велосипед с треугольным парусом. Надел треуголку, а велосипед хоть и едет, но со скрежетом, и команда грозит поднять бунт и отправить меня прогуляться по рее на корм рыбам.
Если вкратце, то я считываю данные формы в режиме полёта (без сабмита и пр.), отправляю расчитывать на сервер, пишу в файл результат расчетов, читаю из файла полученный результат и вывожу его в необходимом блоке. Короче говоря, если бы я повстречал дьявола, то он бы попросил оставить автограф на сиськах.
Очень надеюсь, что существует более элегантное решение этой, как мне кажется, весьма тривиальной задачи. Надеюсь на вашу помощь.
var days = 3;
$('#days').change(function() {
  days = $(this).val();
})

var model;
$('#models [name="optradio"]').change(function() {
  model = $(this).val();

  var formData = new FormData();
  formData.append("type", type);
  formData.append("model", model);
  formData.append("days", days);
  // отослать
  var xhr = new XMLHttpRequest();
  xhr.open("POST", "interactive.php");
  xhr.send(formData);
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (xhttp.readyState == 4 && xhttp.status == 200) {
      $('#vote_status').text(xhttp.responseText);
    }
    else {
      $('#vote_status').text('');
      req();
    }
  };

  function req() {
    if (xhttp.readyState == 4 && xhttp.status == 200) {
      $('#vote_status').text(xhttp.responseText);
    }
    else {
      $('#vote_status').text('');
      req();
    }
  } 
    
  xhttp.open("GET", "INTERACTIVE_PRICE/INTERACTIVE_PRICE.txt", true);
  xhttp.send();
})

var type = "standart";
$('#types [name="optradio"]').change(function() {
  type = $(this).val();
})
Ответить с цитированием
  #2 (permalink)  
Старый 06.08.2016, 15:40
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от avalan4e
читаю из файла полученный результат и вывожу его в необходимом блоке
Зачем читать из файла, если интерпретатор все расчеты имеет?
Ответить с цитированием
  #3 (permalink)  
Старый 06.08.2016, 17:13
Интересующийся
Отправить личное сообщение для avalan4e Посмотреть профиль Найти все сообщения от avalan4e
 
Регистрация: 04.07.2016
Сообщений: 20

laimas, как их извлечь? Может в каких-то глобальных переменных хранятся?
Ответить с цитированием
  #4 (permalink)  
Старый 06.08.2016, 17:17
Интересующийся
Отправить личное сообщение для avalan4e Посмотреть профиль Найти все сообщения от avalan4e
 
Регистрация: 04.07.2016
Сообщений: 20

Rise, хех, да уж. Собирал по сусекам сети варианты решения своей задачи. Вот такой коктейль (или скорее борщ) получился. Предложите вариант получше? Или может почитать что-то для более целостной картины восприятия посоветуете?
Ответить с цитированием
  #5 (permalink)  
Старый 06.08.2016, 17:23
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от avalan4e
как их извлечь?
Встречный вопрос - и кто же здесь отправляю расчитывать на сервер, пишу в файл результат расчетов считает? А если посчитал и записал в файл, то то что он пишет в файл разве нельзя вернуть и клиенту?

А насчет "винегрета из JS и JQ", так в в jQuery готовых методов Ajax хоть отбавляй.
Ответить с цитированием
  #6 (permalink)  
Старый 06.08.2016, 18:14
Интересующийся
Отправить личное сообщение для avalan4e Посмотреть профиль Найти все сообщения от avalan4e
 
Регистрация: 04.07.2016
Сообщений: 20

Rise,
Ради неё весь сыр-бор. Был вариант на jquery без привлечения внешних скриптов, который работал хорошо и быстро, но с одним недостатком -- view page source обнажает всю кухню.
Ответить с цитированием
  #7 (permalink)  
Старый 06.08.2016, 18:46
Интересующийся
Отправить личное сообщение для avalan4e Посмотреть профиль Найти все сообщения от avalan4e
 
Регистрация: 04.07.2016
Сообщений: 20

Rise, собственно вот оно:
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">


<h2>Выберите класс автомобиля</h2>
<form id="auto-class">
  <div class="checkbox">
    <label><input id="auto-class-econom" type="checkbox" value="econom-value" name="econom-checkbox">Эконом-класс</label>
  </div>
  <div class="checkbox auto-class-vip">
    <label><input id="auto-class-vip" type="checkbox" value="">Представительский класс (VIP)</label>
  </div>
</form>

<h2>Выберите тип аренды</h2>
<form name="chk" id="types">
  <div class="radio">
    <label><input id="standart" type="radio" name="optradio" value="standart" checked>Стандарт</label>
  </div>
  <div class="radio">
    <label><input id="wedding" type="radio" name="optradio" value="wedding">Автомобиль на свадьбу</label>
  </div>
</form>

<?
  $pricelist = array();
  $handle = @fopen("pricelist.txt", "r");
  if ($handle) {
      while (($buffer = fgets($handle, 4096)) !== false) {
        list($id, $auto, $price, $class) = explode(":", $buffer);
        $pricelist[$id] = array('class' => $class, 'price' => $price, 'auto' => $auto);
      }
      echo '<form name="tt" id="models">';
      foreach ($pricelist as $id => $value) {
        echo '<div class="radio '.$value["class"].' hidden">'.'
              <label><input type="radio" name="optradio" value="'.$id.'">';
              echo $value["auto"];
              echo " - ";
              echo $value["price"];
              echo " - ";
              echo $value["class"];
              echo '</label>
            </div>    
        ';
      }
      echo '</form>';
      if (!feof($handle)) {
          echo "Error: unexpected fgets() fail\n";
      }
      fclose($handle);
  }
?>
<input id="days" type="number" name="days" min="3" value="3"><br>
<button id="test-button"></button>

<div id="vote_status"></div>

Да, и по большому счету мне не столько нужна секретность формулы расчета, сколько относительная безопасность от внесения изменений в процессе выполнения. В вопросах безопасности я, конечно, полный профан, но что-то мне подсказывает, если оставить всю кухню на виду, то жди беды.
Ответить с цитированием
  #8 (permalink)  
Старый 07.08.2016, 00:37
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от avalan4e
не столько нужна секретность формулы расчета, сколько относительная безопасность от внесения изменений в процессе выполнения
Клиент может считать у себя в браузере, в тетрадке в клеточку, хоть на доске мелом, и это не несет опасности если серверу все эти расчеты побоку. А у нормального сервера так и должно быть - клиентский скрипт, это сервис, серверный скрипт, это контроль.

Есть менеджер и машины для прогулок описанные в базе (не файлах), и серверный скрипт.

Клиент выбрал машину А - получает в свой клиентский калькулятор цену проката за один час. Выбирает 3 часа покататься - клиентский калькулятор просчитал стоимость катания. Клиент удовлетворен и жмет Заказать - серверу приходят данные: фейс клиента, идентификатор выбранной машины и время проката. А чего там насчитал клиентский калькулятор серверу глубоко "все равно", этого ему не надо.

Полученные данные пишутся в базу (не файл) в таблицу заказов также под своим идентификатором. Из базы данных по идентификатору выбранной машины получаем цену проката за час, умножаем на выбранное время и эти расчеты шлем заказчику на почту/телефон/пейджер/etc и менеджеру почту/телефон/админку сообщение о новом заказе.

Менеджер оторванная от макияжа присланным сообщением заходит в админку, видит новый заказ, который опять таки рассчитывается - по ID машины узнаем ее цену, множим на 3, что и отображается менеджеру как Итого.

Вариант 2. Ваша фирма/контора/артель/etc из 1 кг железа производит 20 кг золота. Клиент хочет получить у вас 50 кг, при этом он имеет возможность только отправлять запрос, без сервиса, так как формула получения золота "делим 1 кг железа на 5, возводим в квадрат части и складываем их вместе" является большим се6кретом, держится исключительно на сервере и своем, и защищенном от любых атак и взломов, что при таком способе добычи желтого металла может и возможно организовать.

А машины, время, это не есть секрет и проблемы надуманные, у вас просто не верно поставлены взаимоотношения клеиент-сервер, да и хранение выбрано не лучшее.

Последний раз редактировалось laimas, 07.08.2016 в 00:40.
Ответить с цитированием
  #9 (permalink)  
Старый 07.08.2016, 13:01
Интересующийся
Отправить личное сообщение для avalan4e Посмотреть профиль Найти все сообщения от avalan4e
 
Регистрация: 04.07.2016
Сообщений: 20

Rise,
По сути, только расчет. Количество машин не ограничено. Но могу предположить, что автопарк всё же может насчитывать до 20-50 автомобилей. С учетом всех замечаний передал следующим образом:
var days = 3;
$('#days').change(function() {
  days = $(this).val();
  $('#vote_status').text(countPrice(type_val, model_val, days));
})

var model_val = -1;
var model;
$('#models [name="optradio"]').change(function() {
  model = $(this).attr("id");
  model_val = $(this).val();
  $('#vote_status').text(countPrice(type_val, model_val, days));
})

var type_val = 1;
var type = "standart";
$('#types [name="optradio"]').change(function() {
  type = $(this).attr("id");
  type_val = $(this).val();
  $('#vote_status').text(countPrice(type_val, model_val, days));
})

function countPrice(t,m,d) {
  if (m > 0 && d > 2 && t > 0) return t * m * d;
  else if (d < 3) return "Выберите количество часов не меньше 3-х";
  else return "Error: обратитесь к тех. поддержке";
}

Не пробовал предложенный вами вариант т. к. придется менять разметку. Но он гораздо практичнее, так что, устранив остальные проблемы, отредактирую разметку и воспользуюсь им.
Пока что все работает хорошо. Только происходит существенная задержка при прокликивании в скоростном режиме нескольких часов аренды кряду. Если увеличивать/уменьшать количество на стрелках клавиатуры или забивать числа в поле вручную, то никакой задержки. Тестировал на подобных сайтах эту фишку, и у них все работает гладко в этом отношении. В чем может быть проблема?
Ответить с цитированием
  #10 (permalink)  
Старый 07.08.2016, 13:28
Интересующийся
Отправить личное сообщение для avalan4e Посмотреть профиль Найти все сообщения от avalan4e
 
Регистрация: 04.07.2016
Сообщений: 20

laimas,
Предположим, что база заказов не нужна. Как Вы оцениваете вариант, если на серверной части создать массив прайслиста и использовать полученные из $_POST идентификаторы для доступа к соответствующему элементу? Массив в любом случае не грозит разрастись до астрономических размеров, так что это не грозит потерей производительности.
По поводу второго варианта. Как все таки реализовать его без прославления сатаны написанием кода, подобного тому, что я представил в старте темы? Может есть на примете что-то стоящее покурить на эту тему? Если так, то я с удовольствием принимаюсь разжигать уголек для трубки.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Открытие div блока при первом визите на сайт Nushaba Общие вопросы Javascript 28 20.12.2013 21:24
Решение проблемы кодировок для AJAX и PHP без iconv (cp1251 в AJAX) Serge Ageyev AJAX и COMET 10 24.04.2013 20:48
Как организовать RichEdit arma Элементы интерфейса 2 18.02.2010 14:57
О наследовании событий, или как корректно его отменить. JCShen Events/DOM/Window 8 09.02.2010 00:00
Как правильно послать XML в POST запросе LowCoder AJAX и COMET 10 15.07.2009 23:20