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. 38
      src/AutoConnectElementBasisImpl.h
  4. 4
      src/AutoConnectElementJson.h
  5. 10
      src/AutoConnectElementJsonImpl.h

@ -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<AutoConnectSelect*>(elm);
elmSelect->select(value);
}
else {
if (elm->typeOf() == AC_Checkbox) {
if (value == "checked") {
AutoConnectCheckbox* elmCheckbox = reinterpret_cast<AutoConnectCheckbox*>(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;
}

@ -195,7 +195,7 @@ class AutoConnectRadioBasis : virtual public AutoConnectElementBasis {
*/
class AutoConnectSelectBasis : virtual public AutoConnectElementBasis {
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;
}
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<String> _options; /**< List options array */

@ -181,7 +181,6 @@ 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)
@ -192,20 +191,19 @@ const String AutoConnectRadioBasis::toHTML(void) const {
n++;
String id = name + "_" + String(n);
html += String(F("<input type=\"radio\" name=\"")) + name + String(F("\" id=\"")) + id + String(F("\" value=\"")) + value + String("\"");
if (n == checked - 1)
if (n == checked)
html += String(F(" checked"));
html += String(F("><label for=\"")) + id + String("\">") + value + String(F("</label>"));
if (order == AC_Vertical)
html += String(F("<br>"));
}
}
return html;
}
/**
* 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 <select> element with an <option> element.
* 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 {
String html = String("");
if (enable) {
if (label.length())
html = String(F("<label for=\"")) + name + String("\">") + label + String(F("</label>"));
html += String(F("<select name=\"")) + name + String(F("\" id=\"")) + name + String("\">");
for (const String option : _options)
html += String(F("<option value=\"")) + option + "\">" + option + String(F("</option>"));
html += String(F("</select>"));
uint8_t n = 1;
for (const String option : _options) {
html += String(F("<option value=\"")) + option + "\"";
if (n++ == selected)
html += String(F(" selected"));
html += ">" + option + String(F("</option>"));
}
html += String(F("</select>"));
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
* for form submission. An 'onclick' attribute calls fixed JavaScript

@ -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<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::_options = options;
AutoConnectSelectBasis::label = String(label);
AutoConnectSelectBasis::selected = selected;
}
~AutoConnectSelectJson() {}
size_t getObjectSize(void) const override;

@ -320,6 +320,7 @@ void AutoConnectRadioJson::serialize(JsonObject& json) {
json[F(AUTOCONNECT_JSON_KEY_ARRANGE)] = String(F(AUTOCONNECT_JSON_VALUE_VERTICAL));
break;
}
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<String>();
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<String>();
}
if (json.containsKey(F(AUTOCONNECT_JSON_KEY_OPTION))) {
empty();
ArduinoJsonArray optionArray = json[AUTOCONNECT_JSON_KEY_OPTION];
for (auto value : optionArray)
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;
}
}
@ -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;
}
/**

Loading…
Cancel
Save