WebHost: Fix NamedRange values clamping to the range (#3613)

If a NamedRange has a `special_range_names` entry outside the
`range_start` and `range_end`, the HTML5 range input will clamp the
submitted value to the closest value in the range.

These means that, for example, Pokemon RB's "HM Compatibility" option's
"Vanilla (-1)" option would instead get posted as "0" rather than "-1".

This change updates NamedRange to behave like TextChoice, where the
select element has a `name` attribute matching the option, and there is
an additional element to be able to provide an option other than the
select element's choices.

This uses a different suffix of `-range` rather than `-custom` that
TextChoice uses. The reason is we need some way to decide whether to use
the custom value or the select value, and that method needs to work
without JavaScript. For TextChoice this is easy, if the custom field is
empty use the select element. For NamedRange this is more difficult as
the browser will always submit *something*. My choice was to only use
the value from the range if the select box is set to "custom". Since
this only happens with JS as "custom' is hidden, I made the range hidden
under no-JS. If it's preferred, I could make the select box hidden
instead. Let me know.

This PR also makes the `js-required` class set `display: none` with
`!important` as otherwise the class wouldn't work on any rule that
had `display: flex` with more specificity than a single class.
This commit is contained in:
Remy Jette 2024-07-29 20:13:44 -04:00 committed by GitHub
parent 954d728005
commit 77e3f9fbef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 12 additions and 5 deletions

View File

@ -231,6 +231,13 @@ def generate_yaml(game: str):
del options[key]
# Detect keys which end with -range, indicating a NamedRange with a possible custom value
elif key_parts[-1].endswith("-range"):
if options[key_parts[-1][:-6]] == "custom":
options[key_parts[-1][:-6]] = val
del options[key]
# Detect random-* keys and set their options accordingly
for key, val in options.copy().items():
if key.startswith("random-"):

View File

@ -54,7 +54,7 @@
{% macro NamedRange(option_name, option) %}
{{ OptionTitle(option_name, option) }}
<div class="named-range-container">
<select id="{{ option_name }}-select" data-option-name="{{ option_name }}" {{ "disabled" if option.default == "random" }}>
<select id="{{ option_name }}-select" name="{{ option_name }}" data-option-name="{{ option_name }}" {{ "disabled" if option.default == "random" }}>
{% for key, val in option.special_range_names.items() %}
{% if option.default == val %}
<option value="{{ val }}" selected>{{ key|replace("_", " ")|title }} ({{ val }})</option>
@ -64,17 +64,17 @@
{% endfor %}
<option value="custom" hidden>Custom</option>
</select>
<div class="named-range-wrapper">
<div class="named-range-wrapper js-required">
<input
type="range"
id="{{ option_name }}"
name="{{ option_name }}"
name="{{ option_name }}-range"
min="{{ option.range_start }}"
max="{{ option.range_end }}"
value="{{ option.default | default(option.range_start) if option.default != "random" else option.range_start }}"
{{ "disabled" if option.default == "random" }}
/>
<span id="{{ option_name }}-value" class="range-value js-required">
<span id="{{ option_name }}-value" class="range-value">
{{ option.default | default(option.range_start) if option.default != "random" else option.range_start }}
</span>
{{ RandomizeButton(option_name, option) }}

View File

@ -11,7 +11,7 @@
<noscript>
<style>
.js-required{
display: none;
display: none !important;
}
</style>
</noscript>