diff --git a/src/AutoConnectAux.cpp b/src/AutoConnectAux.cpp index 9fb16a0..5b16f83 100644 --- a/src/AutoConnectAux.cpp +++ b/src/AutoConnectAux.cpp @@ -145,7 +145,11 @@ bool AutoConnectAux::release(const String& name) { bool AutoConnectAux::setElementValue(const String& name, const String value) { AutoConnectElement* elm = getElement(name); if (elm) { - if (elm->typeOf() != AC_Select) { + if (elm->typeOf() == AC_Select) { + AutoConnectSelect* elmSelect = reinterpret_cast(elm); + elmSelect->select(value); + } + else { if (elm->typeOf() == AC_Checkbox) { if (value == "checked") { AutoConnectCheckbox* elmCheckbox = reinterpret_cast(elm); @@ -160,8 +164,6 @@ bool AutoConnectAux::setElementValue(const String& name, const String value) { elm->value = value; return true; } - else - AC_DBG("Element<%s> value type mismatch\n", name.c_str()); } return false; } diff --git a/src/AutoConnectElementBasis.h b/src/AutoConnectElementBasis.h index 04f4bd8..a7f92e5 100644 --- a/src/AutoConnectElementBasis.h +++ b/src/AutoConnectElementBasis.h @@ -195,7 +195,7 @@ class AutoConnectRadioBasis : virtual public AutoConnectElementBasis { */ class AutoConnectSelectBasis : virtual public AutoConnectElementBasis { public: - explicit AutoConnectSelectBasis(const char* name = "", std::vector const& options = {}, const char* label = "") : AutoConnectElementBasis(name, ""), label(String(label)), _options(options) { + explicit AutoConnectSelectBasis(const char* name = "", std::vector const& options = {}, const char* label = "", const uint8_t selected = 0) : AutoConnectElementBasis(name, ""), label(String(label)), selected(selected), _options(options) { _type = AC_Select; } virtual ~AutoConnectSelectBasis() {} @@ -204,9 +204,12 @@ class AutoConnectSelectBasis : virtual public AutoConnectElementBasis { void add(const String& option) { _options.push_back(String(option)); } size_t size(void) const { return _options.size(); } 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); + const String& value(void) const; String label; /**< A label for a subsequent input box */ + uint8_t selected; /**< Index of checked value (1-based) */ protected: std::vector _options; /**< List options array */ diff --git a/src/AutoConnectElementBasisImpl.h b/src/AutoConnectElementBasisImpl.h index 56a5ca9..4caf555 100644 --- a/src/AutoConnectElementBasisImpl.h +++ b/src/AutoConnectElementBasisImpl.h @@ -181,23 +181,21 @@ void AutoConnectRadioBasis::empty(const size_t reserve) { const String AutoConnectRadioBasis::toHTML(void) const { String html = String(""); - if (enable) { - if (label.length()) { - html = label; - if (order == AC_Vertical) - html += String(F("
")); - } - uint8_t n = 0; - for (const String value : _values) { - n++; - String id = name + "_" + String(n); - html += String(F("")); - if (order == AC_Vertical) - html += String(F("
")); - } + if (label.length()) { + html = label; + if (order == AC_Vertical) + html += String(F("
")); + } + uint8_t n = 0; + for (const String value : _values) { + n++; + String id = name + "_" + String(n); + html += String(F("")); + if (order == AC_Vertical) + html += String(F("
")); } return html; } @@ -205,7 +203,7 @@ const String AutoConnectRadioBasis::toHTML(void) const { /** * 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(); return checked ? _values.at(checked - 1) : _nullString; } @@ -223,6 +221,19 @@ void AutoConnectSelectBasis::empty(const size_t 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 "); - for (const String option : _options) - html += String(F("")); - html += String(F("")); + if (label.length()) + html = String(F("")); + html += String(F("")); 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 element. This element is used * for form submission. An 'onclick' attribute calls fixed JavaScript diff --git a/src/AutoConnectElementJson.h b/src/AutoConnectElementJson.h index 3f382e5..ed42401 100644 --- a/src/AutoConnectElementJson.h +++ b/src/AutoConnectElementJson.h @@ -24,6 +24,7 @@ #define AUTOCONNECT_JSON_KEY_OPTION "option" #define AUTOCONNECT_JSON_KEY_PATTERN "pattern" #define AUTOCONNECT_JSON_KEY_PLACEHOLDER "placeholder" +#define AUTOCONNECT_JSON_KEY_SELECTED "selected" #define AUTOCONNECT_JSON_KEY_STORE "store" #define AUTOCONNECT_JSON_KEY_STYLE "style" #define AUTOCONNECT_JSON_KEY_TITLE "title" @@ -237,10 +238,11 @@ class AutoConnectRadioJson : public AutoConnectElementJson, public AutoConnectRa */ class AutoConnectSelectJson : public AutoConnectElementJson, public AutoConnectSelectBasis { public: - explicit AutoConnectSelectJson(const char* name = "", std::vector const& options = {}, const char* label = "") { + explicit AutoConnectSelectJson(const char* name = "", std::vector const& options = {}, const char* label = "", const uint8_t selected = 0) { AutoConnectSelectBasis::name = String(name); AutoConnectSelectBasis::_options = options; AutoConnectSelectBasis::label = String(label); + AutoConnectSelectBasis::selected = selected; } ~AutoConnectSelectJson() {} size_t getObjectSize(void) const override; diff --git a/src/AutoConnectElementJsonImpl.h b/src/AutoConnectElementJsonImpl.h index 5df0e64..fd03913 100644 --- a/src/AutoConnectElementJsonImpl.h +++ b/src/AutoConnectElementJsonImpl.h @@ -320,7 +320,8 @@ void AutoConnectRadioJson::serialize(JsonObject& json) { json[F(AUTOCONNECT_JSON_KEY_ARRANGE)] = String(F(AUTOCONNECT_JSON_VALUE_VERTICAL)); 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. */ 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(); for (String _option : _options) size += _option.length(); @@ -345,14 +346,15 @@ bool AutoConnectSelectJson::loadMember(const JsonObject& json) { String type = json[F(AUTOCONNECT_JSON_KEY_TYPE)].as(); if (type.equalsIgnoreCase(F(AUTOCONNECT_JSON_TYPE_ACSELECT))) { _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(); - } if (json.containsKey(F(AUTOCONNECT_JSON_KEY_OPTION))) { empty(); ArduinoJsonArray optionArray = json[AUTOCONNECT_JSON_KEY_OPTION]; for (auto value : optionArray) add(value.as()); + if (json.containsKey(F(AUTOCONNECT_JSON_KEY_SELECTED))) + selected = static_cast(json[F(AUTOCONNECT_JSON_KEY_SELECTED)].as()); return true; } } @@ -370,6 +372,8 @@ void AutoConnectSelectJson::serialize(JsonObject& json) { for (String o : _options) options.add(o); json[F(AUTOCONNECT_JSON_KEY_LABEL)] = label; + if (selected > 0) + json[F(AUTOCONNECT_JSON_KEY_SELECTED)] = selected; } /**