Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WiFiManagerParameter Checkboxes and Radios #1775

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

dmadison
Copy link

@dmadison dmadison commented Oct 31, 2024

This PR adds checkbox and radio input classes derived from WiFiManagerParameter, allowing users to easily add those inputs to their config pages.

Checkboxes

Checkboxes are implemented with the WiFiManagerParameterCheckbox class. Checkboxes are declared similarly to regular parameters, but with a boolean checked value in place of maxLength:

WiFiManagerParameterCheckbox(
    const char* name,
    const char* label,
    const char* value,
    bool        checked = false,
    const char* custom = "",
    int         labelPlacement = WFM_LABEL_AFTER);

Because the library uses the parameter's 'value' to mean both 'default value' and 'current value', checkboxes implement their own value storage to indicate whether the checkbox is "checked" or not. This lets the value (string) and 'checked' state persist between server updates while requiring minimal additional storage:

bool getChecked() const;
void setChecked(bool checked);

Demo

Webpage

checkboxes

User Code

WiFiManagerParameterCheckbox checkboxes[] = {
	WiFiManagerParameterCheckbox("checkbox1", "Checkbox 1", "chk1", true),
	WiFiManagerParameterCheckbox("checkbox2", "Checkbox 2", "chk2", false),
	WiFiManagerParameterCheckbox("checkbox3", "Checkbox 3", "chk3", false),
};

for (auto& checkbox : checkboxes) {
	wm.addParameter(&checkbox);
}

HTML

<input type="checkbox" name="checkbox1" id="checkbox1" value="chk1" checked>
<label for="checkbox1">Checkbox 1</label>
<br>
<input type="checkbox" name="checkbox2" id="checkbox2" value="chk2">
<label for="checkbox2">Checkbox 2</label>
<br>
<input type="checkbox" name="checkbox3" id="checkbox3" value="chk3">
<label for="checkbox3">Checkbox 3</label>
<br>

Serial Debug

*wm:[3] checkbox1: chk1
*wm:[3] checkbox2: 
*wm:[3] checkbox3: 

Radios

Radios are implemented with the WiFiManagerParameterRadio class. Radios are different to regular parameters, because each radio object contains a number of individual inputs that are all collected under one parameter. Because of this radio objects are only declared with a name, custom html, and labelPlacement:

WiFiManagerParameterRadio(
    const char* name,
    const char* custom = "",
    int         labelPlacement = WFM_LABEL_AFTER);

Individual options are created as WiFiManagerParameterRadioOption classes. These reference the radio object and add themselves to a vector in the radio class on construction:

WiFiManagerParameterRadioOption(
    WiFiManagerParameterRadio& radio,
    const char* id,
    const char* label,
    const char* value,
    bool        checked = false);

When the params page is submitted, the string is validated against the stored options and then stored in the class as the value. This simplifies the user-side parameter saving code, because the relevant value is provided as part of a single parameter regardless of how many options there are.

Demo

Webpage

radios

User Code

WiFiManagerParameterRadio radio("radio");

WiFiManagerParameterRadioOption radioOptions[] = {
	WiFiManagerParameterRadioOption(radio, "radio1", "Radio 1", "rd1", true),
	WiFiManagerParameterRadioOption(radio, "radio2", "Radio 2", "rd2", false),
	WiFiManagerParameterRadioOption(radio, "radio3", "Radio 3", "rd3", false),
};

wm.addParameter(&radio);

HTML

<input type="radio" name="radio" id="radio1" value="rd1" checked>
<label for="radio1">Radio 1</label>
<br>
<input type="radio" name="radio" id="radio2" value="rd2">
<label for="radio2">Radio 2</label>
<br>
<input type="radio" name="radio" id="radio3" value="rd3">
<label for="radio3">Radio 3</label>
<br>

Serial Debug

*wm:[3] radio: rd1

Incidental Changes

  • Added a {T} token for type attribute to wm_consts_en.h and wm_consts_fr.h
  • Added a HTTP_FORM_PARAM_CHECK string, which compared to HTTP_FORM_PARAM:
    • Removes line break
    • Adds type attribute and token
    • Removes maxlength attribute

This PR contains no breaking changes.


Please note that this PR incorporates the necessary API changes #1773 and the HTML generation changes from #1774.

This does *not* refer to the length of the string passed in, or the length of the string currently stored. This refers to the maximum length of the HTML form, and the size of the class buffer to hold the value.

Note that this does *not* change the internal _length name, because the variable is exposed as protected and through friendship with WiFiManager. It is however marked deprecated and can be changed on the next major release.
To clarify that the function returns the *max* possible length, and not the length of the current value.

Deprecating getValueLength for removal on next major release.
In HTML forms names and IDs are two different things. Although this value is applied to both attributes, the form data corresponds to the name, *not* the ID. This causes confusion if we want the name and ID to differ, since we are currently calling the name the ID.
For intercepting the value received from the server in derived classes
Preventing a new default value from being assigned if the max length is set to a negative value
Because this is polymorphic, the destructor needs to be virtual to allow for properly clearing data
This creates better encapsulation, and allows it to be overridden by child classes.
This is unused and awkward because it must be done within the manager class to use the loop parameter, since passing the loop value to the parameter object would be odd. Removing it makes the most sense, although it is technically a breaking change if the user has custom string files.
This makes it possible to declare options at the same time as the radio object, and provides for more flexibility.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant