Merge pull request #66 from Hieromon/master

Supports saving and loading of the selected option with the AutoConnectSelect
pull/69/head^2
Hieromon Ikasamo 6 years ago committed by GitHub
commit 5dab5f65de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      src/AutoConnectAux.cpp
  2. 5
      src/AutoConnectElementBasis.h
  3. 72
      src/AutoConnectElementBasisImpl.h
  4. 4
      src/AutoConnectElementJson.h
  5. 12
      src/AutoConnectElementJsonImpl.h

@ -145,7 +145,11 @@ bool AutoConnectAux::release(const String& name) {
bool AutoConnectAux::setElementValue(const String& name, const String value) { bool AutoConnectAux::setElementValue(const String& name, const String value) {
AutoConnectElement* elm = getElement(name); AutoConnectElement* elm = getElement(name);
if (elm) { if (elm) {
if (elm->typeOf() != AC_Select) { if (elm->typeOf() == AC_Select) {
AutoConnectSelect* elmSelect = reinterpret_cast<AutoConnectSelect*>(elm);
elmSelect->select(value);
}
else {
if (elm->typeOf() == AC_Checkbox) { if (elm->typeOf() == AC_Checkbox) {
if (value == "checked") { if (value == "checked") {
AutoConnectCheckbox* elmCheckbox = reinterpret_cast<AutoConnectCheckbox*>(elm); AutoConnectCheckbox* elmCheckbox = reinterpret_cast<AutoConnectCheckbox*>(elm);
@ -160,8 +164,6 @@ bool AutoConnectAux::setElementValue(const String& name, const String value) {
elm->value = value; elm->value = value;
return true; return true;
} }
else
AC_DBG("Element<%s> value type mismatch\n", name.c_str());
} }
return false; return false;
} }

@ -195,7 +195,7 @@ class AutoConnectRadioBasis : virtual public AutoConnectElementBasis {
*/ */
class AutoConnectSelectBasis : virtual public AutoConnectElementBasis { class AutoConnectSelectBasis : virtual public AutoConnectElementBasis {
public: public:
explicit AutoConnectSelectBasis(const char* name = "", std::vector<String> const& options = {}, const char* label = "") : AutoConnectElementBasis(name, ""), label(String(label)), _options(options) { explicit AutoConnectSelectBasis(const char* name = "", std::vector<String> const& options = {}, const char* label = "", const uint8_t selected = 0) : AutoConnectElementBasis(name, ""), label(String(label)), selected(selected), _options(options) {
_type = AC_Select; _type = AC_Select;
} }
virtual ~AutoConnectSelectBasis() {} virtual ~AutoConnectSelectBasis() {}
@ -204,9 +204,12 @@ class AutoConnectSelectBasis : virtual public AutoConnectElementBasis {
void add(const String& option) { _options.push_back(String(option)); } void add(const String& option) { _options.push_back(String(option)); }
size_t size(void) const { return _options.size(); } size_t size(void) const { return _options.size(); }
const String& at(const std::size_t n) const { return _options.at(n); } const String& at(const std::size_t n) const { return _options.at(n); }
void select(const String& value);
void empty(const size_t reserve = 0); void empty(const size_t reserve = 0);
const String& value(void) const;
String label; /**< A label for a subsequent input box */ String label; /**< A label for a subsequent input box */
uint8_t selected; /**< Index of checked value (1-based) */
protected: protected:
std::vector<String> _options; /**< List options array */ std::vector<String> _options; /**< List options array */

@ -181,23 +181,21 @@ void AutoConnectRadioBasis::empty(const size_t reserve) {
const String AutoConnectRadioBasis::toHTML(void) const { const String AutoConnectRadioBasis::toHTML(void) const {
String html = String(""); String html = String("");
if (enable) { if (label.length()) {
if (label.length()) { html = label;
html = label; if (order == AC_Vertical)
if (order == AC_Vertical) html += String(F("<br>"));
html += String(F("<br>")); }
} uint8_t n = 0;
uint8_t n = 0; for (const String value : _values) {
for (const String value : _values) { n++;
n++; String id = name + "_" + String(n);
String id = name + "_" + String(n); html += String(F("<input type=\"radio\" name=\"")) + name + String(F("\" id=\"")) + id + String(F("\" value=\"")) + value + String("\"");
html += String(F("<input type=\"radio\" name=\"")) + name + String(F("\" id=\"")) + id + String(F("\" value=\"")) + value + String("\""); if (n == checked)
if (n == checked - 1) html += String(F(" checked"));
html += String(F(" checked")); html += String(F("><label for=\"")) + id + String("\">") + value + String(F("</label>"));
html += String(F("><label for=\"")) + id + String("\">") + value + String(F("</label>")); if (order == AC_Vertical)
if (order == AC_Vertical) html += String(F("<br>"));
html += String(F("<br>"));
}
} }
return html; return html;
} }
@ -205,7 +203,7 @@ const String AutoConnectRadioBasis::toHTML(void) const {
/** /**
* Returns current selected value in the radio same group * Returns current selected value in the radio same group
*/ */
const String& AutoConnectRadioBasis::value() const { const String& AutoConnectRadioBasis::value(void) const {
static const String _nullString = String(); static const String _nullString = String();
return checked ? _values.at(checked - 1) : _nullString; return checked ? _values.at(checked - 1) : _nullString;
} }
@ -223,6 +221,19 @@ void AutoConnectSelectBasis::empty(const size_t reserve) {
_options.reserve(reserve); _options.reserve(reserve);
} }
/**
* Indicate an entry with the specified value in the value's collection.
* @param value The value to indicates in the collection.
*/
void AutoConnectSelectBasis::select(const String& value) {
for (std::size_t n = 0; n < _options.size(); n++) {
if (at(n).equalsIgnoreCase(value)) {
selected = n + 1;
break;
}
}
}
/** /**
* Generate an HTML <select> element with an <option> element. * Generate an HTML <select> element with an <option> element.
* The attribute value of the <option> element is given to the * The attribute value of the <option> element is given to the
@ -234,17 +245,28 @@ void AutoConnectSelectBasis::empty(const size_t reserve) {
const String AutoConnectSelectBasis::toHTML(void) const { const String AutoConnectSelectBasis::toHTML(void) const {
String html = String(""); String html = String("");
if (enable) { if (label.length())
if (label.length()) html = String(F("<label for=\"")) + name + String("\">") + label + String(F("</label>"));
html = String(F("<label for=\"")) + name + String("\">") + label + String(F("</label>")); html += String(F("<select name=\"")) + name + String(F("\" id=\"")) + name + String("\">");
html += String(F("<select name=\"")) + name + String(F("\" id=\"")) + name + String("\">"); uint8_t n = 1;
for (const String option : _options) for (const String option : _options) {
html += String(F("<option value=\"")) + option + "\">" + option + String(F("</option>")); html += String(F("<option value=\"")) + option + "\"";
html += String(F("</select>")); if (n++ == selected)
html += String(F(" selected"));
html += ">" + option + String(F("</option>"));
} }
html += String(F("</select>"));
return html; return html;
} }
/**
* Returns current selected value in the radio same group
*/
const String& AutoConnectSelectBasis::value(void) const {
static const String _nullString = String();
return selected ? _options.at(selected - 1) : _nullString;
}
/** /**
* Generate an HTML <input type=button> element. This element is used * Generate an HTML <input type=button> element. This element is used
* for form submission. An 'onclick' attribute calls fixed JavaScript * for form submission. An 'onclick' attribute calls fixed JavaScript

@ -24,6 +24,7 @@
#define AUTOCONNECT_JSON_KEY_OPTION "option" #define AUTOCONNECT_JSON_KEY_OPTION "option"
#define AUTOCONNECT_JSON_KEY_PATTERN "pattern" #define AUTOCONNECT_JSON_KEY_PATTERN "pattern"
#define AUTOCONNECT_JSON_KEY_PLACEHOLDER "placeholder" #define AUTOCONNECT_JSON_KEY_PLACEHOLDER "placeholder"
#define AUTOCONNECT_JSON_KEY_SELECTED "selected"
#define AUTOCONNECT_JSON_KEY_STORE "store" #define AUTOCONNECT_JSON_KEY_STORE "store"
#define AUTOCONNECT_JSON_KEY_STYLE "style" #define AUTOCONNECT_JSON_KEY_STYLE "style"
#define AUTOCONNECT_JSON_KEY_TITLE "title" #define AUTOCONNECT_JSON_KEY_TITLE "title"
@ -237,10 +238,11 @@ class AutoConnectRadioJson : public AutoConnectElementJson, public AutoConnectRa
*/ */
class AutoConnectSelectJson : public AutoConnectElementJson, public AutoConnectSelectBasis { class AutoConnectSelectJson : public AutoConnectElementJson, public AutoConnectSelectBasis {
public: public:
explicit AutoConnectSelectJson(const char* name = "", std::vector<String> const& options = {}, const char* label = "") { explicit AutoConnectSelectJson(const char* name = "", std::vector<String> const& options = {}, const char* label = "", const uint8_t selected = 0) {
AutoConnectSelectBasis::name = String(name); AutoConnectSelectBasis::name = String(name);
AutoConnectSelectBasis::_options = options; AutoConnectSelectBasis::_options = options;
AutoConnectSelectBasis::label = String(label); AutoConnectSelectBasis::label = String(label);
AutoConnectSelectBasis::selected = selected;
} }
~AutoConnectSelectJson() {} ~AutoConnectSelectJson() {}
size_t getObjectSize(void) const override; size_t getObjectSize(void) const override;

@ -320,7 +320,8 @@ void AutoConnectRadioJson::serialize(JsonObject& json) {
json[F(AUTOCONNECT_JSON_KEY_ARRANGE)] = String(F(AUTOCONNECT_JSON_VALUE_VERTICAL)); json[F(AUTOCONNECT_JSON_KEY_ARRANGE)] = String(F(AUTOCONNECT_JSON_VALUE_VERTICAL));
break; break;
} }
json[F(AUTOCONNECT_JSON_KEY_CHECKED)] = checked; if (checked > 0)
json[F(AUTOCONNECT_JSON_KEY_CHECKED)] = checked;
} }
/** /**
@ -328,7 +329,7 @@ void AutoConnectRadioJson::serialize(JsonObject& json) {
* @return An object size for JsonBuffer. * @return An object size for JsonBuffer.
*/ */
size_t AutoConnectSelectJson::getObjectSize() const { size_t AutoConnectSelectJson::getObjectSize() const {
size_t size = AutoConnectElementJson::getObjectSize() + JSON_OBJECT_SIZE(3) + _options.size() * JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(1); size_t size = AutoConnectElementJson::getObjectSize() + JSON_OBJECT_SIZE(4) + _options.size() * JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(1);
size += sizeof(AUTOCONNECT_JSON_KEY_LABEL) + label.length(); size += sizeof(AUTOCONNECT_JSON_KEY_LABEL) + label.length();
for (String _option : _options) for (String _option : _options)
size += _option.length(); size += _option.length();
@ -345,14 +346,15 @@ bool AutoConnectSelectJson::loadMember(const JsonObject& json) {
String type = json[F(AUTOCONNECT_JSON_KEY_TYPE)].as<String>(); String type = json[F(AUTOCONNECT_JSON_KEY_TYPE)].as<String>();
if (type.equalsIgnoreCase(F(AUTOCONNECT_JSON_TYPE_ACSELECT))) { if (type.equalsIgnoreCase(F(AUTOCONNECT_JSON_TYPE_ACSELECT))) {
_setMember(json); _setMember(json);
if (json.containsKey(F(AUTOCONNECT_JSON_KEY_LABEL))) { if (json.containsKey(F(AUTOCONNECT_JSON_KEY_LABEL)))
label = json[F(AUTOCONNECT_JSON_KEY_LABEL)].as<String>(); label = json[F(AUTOCONNECT_JSON_KEY_LABEL)].as<String>();
}
if (json.containsKey(F(AUTOCONNECT_JSON_KEY_OPTION))) { if (json.containsKey(F(AUTOCONNECT_JSON_KEY_OPTION))) {
empty(); empty();
ArduinoJsonArray optionArray = json[AUTOCONNECT_JSON_KEY_OPTION]; ArduinoJsonArray optionArray = json[AUTOCONNECT_JSON_KEY_OPTION];
for (auto value : optionArray) for (auto value : optionArray)
add(value.as<String>()); add(value.as<String>());
if (json.containsKey(F(AUTOCONNECT_JSON_KEY_SELECTED)))
selected = static_cast<uint8_t>(json[F(AUTOCONNECT_JSON_KEY_SELECTED)].as<int>());
return true; return true;
} }
} }
@ -370,6 +372,8 @@ void AutoConnectSelectJson::serialize(JsonObject& json) {
for (String o : _options) for (String o : _options)
options.add(o); options.add(o);
json[F(AUTOCONNECT_JSON_KEY_LABEL)] = label; json[F(AUTOCONNECT_JSON_KEY_LABEL)] = label;
if (selected > 0)
json[F(AUTOCONNECT_JSON_KEY_SELECTED)] = selected;
} }
/** /**

Loading…
Cancel
Save