Skip to content

Обработка форм

AlexGyver edited this page Oct 2, 2022 · 8 revisions

В библиотеке есть механизм веб-форм: набор компонентов, объединённых в "блок" с кнопкой отправки. При нажатии на кнопку библиотека получает текущие значения сразу со всех компонентов. Удобно в сценариях, когда нужно поменять сразу несколько настроек и после отправки например дать команду на запись в EEPROM.

Форма

  • Форма имеет своё уникальное имя, должно начинаться с /
  • Внутри формы может быть сколько угодно элементов, но только одна кнопка SUBMIT
  • При нажатии на SUBMIT esp получает имя формы и значения всех элементов внутри неё
  • При нажатии на SUBMIT страница перезагрузится, поэтому значения компонентов страницы нужно хранить в переменных и передавать при следующей сборке страницы

Пример с двумя формами, первая может передать текст из окна ввода, вторая - только факт нажатия кнопки:

форма_1
    ввод текста
    кнопка submit
форма_1

форма_2
    кнопка submit
форма_2

В конструкторе GyverPortal это будет выглядеть так:

void build() {
  GP.BUILD_BEGIN();            // запустить конструктор
  GP.THEME(GP_LIGHT);          // применить тему

  GP.FORM_BEGIN("/login");     // начать форму, передать имя
  GP.TEXT("txt", "Login", ""); // ввод текста, подсказка Login, текста нет
  GP.BREAK();                  // перенос строки
  GP.SUBMIT("Submit");         // кнопка Submit
  GP.FORM_END();               // завершить форму

  GP.FORM_BEGIN("/exit");      // начать форму, передать имя
  GP.SUBMIT("Exit");           // кнопка Exit
  GP.FORM_END();               // завершить форму

  GP.BUILD_END();              // завершить построение
}

Результат работы конструктора:
demo

Общий сигнал

  • Обработка происходит в подключенной функции-обработчике действия
  • При отправке любой формы функция form() вернёт true
  • Дальнейшую обработку действий рекомендуется поместить в условие, чтобы микроконтроллер не занимался лишней работой

Поиск формы

Для определения отправленной формы нужно передать в form() её имя:

void action() {
  if (portal.form()) {
    Serial.print("Submit form: ");
    if (portal.form("/login")) Serial.println("Login");
    if (portal.form("/exit")) Serial.println("Exit");
  }
}

При помощи formName() можно узнать имя отправленной формы

Парсинг значений

Данные со всех компонентов формы приходят в одном запросе и должны быть обработаны внутри условия

if (portal.form(имя)) {
}

Вручную

В библиотеке предусмотрены парсеры для всех компонентов и типов данных:

String getString(имя); // получить String строку с компонента
int getInt(имя);       // получить число с компонента
float getFloat(имя);   // получить float с компонента
bool getBool(имя);     // получить состояние чекбокса
GPdate getDate(имя);   // получить дату с компонента
GPtime getTime(имя);   // получить время с компонента
GPcolor getColor(имя); // получить цвет с компонента

Зная состав формы, можно переписать данные в переменные:

String str;

void action() {
  if (portal.form("/login")) {
    str = portal.getString("txt");
  }
}

Не рекомендуется использовать этот способ, т.к. если компонента нет в форме - get-функция вернёт 0 (или пустой текст).

Автоматически

Есть более удобный вариант для передачи значений в переменные, вот такой набор парсеров:

bool copyStr(имя, char* t);           // переписать в char массив
bool copyStr(имя, char* t, int len);  // + размер массива
bool copyString(имя, String& t);
bool copyInt(имя, int& t);
bool copyFloat(имя, float& t);
bool copyBool(имя, bool& t);
bool copyDate(имя, GPdate& t);
bool copyTime(имя, GPtime& t);
bool copyColor(имя, GPcolor& t);

Данные парсерсы переписывают приходящее значение в указанную переменную и возвращают true при этом событии:

String str;

void action() {
  if (portal.form("/login")) {
    portal.copyString("txt", str);
  }
}

См. пример actionForm

Парсер copyStr

Данный парсер переписывает данные в виде текста в массив char. Размер массива должен быть на 1 больше максимальной длины текста, который там хранится (для \0 символа). В copyStr можно передать реальный размер массива. Если текст будет слишком большим - он не запишется в массив, что позволит избежать критической ошибки и зависания программы.

char str[10];

void action() {
  if (portal.form("/login")) {
    portal.copyStr("txt", str, 10);
  }
}
Clone this wiki locally