mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 12:11:33 -06:00

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.
222 lines
10 KiB
HTML
222 lines
10 KiB
HTML
{% macro Toggle(option_name, option) %}
|
|
{{ OptionTitle(option_name, option) }}
|
|
<div class="select-container">
|
|
<select id="{{ option_name }}" name="{{ option_name }}" {{ "disabled" if option.default == "random" }}>
|
|
{% if option.default == 1 %}
|
|
<option value="false">No</option>
|
|
<option value="true" selected>Yes</option>
|
|
{% else %}
|
|
<option value="false" selected>No</option>
|
|
<option value="true">Yes</option>
|
|
{% endif %}
|
|
</select>
|
|
{{ RandomizeButton(option_name, option) }}
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro Choice(option_name, option) %}
|
|
{{ OptionTitle(option_name, option) }}
|
|
<div class="select-container">
|
|
<select id="{{ option_name }}" name="{{ option_name }}" {{ "disabled" if option.default == "random" }}>
|
|
{% for id, name in option.name_lookup.items() %}
|
|
{% if name != "random" %}
|
|
{% if option.default == id %}
|
|
<option value="{{ name }}" selected>{{ option.get_option_name(id) }}</option>
|
|
{% else %}
|
|
<option value="{{ name }}">{{ option.get_option_name(id) }}</option>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
</select>
|
|
{{ RandomizeButton(option_name, option) }}
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro Range(option_name, option) %}
|
|
{{ OptionTitle(option_name, option) }}
|
|
<div class="range-container">
|
|
<input
|
|
type="range"
|
|
id="{{ option_name }}"
|
|
name="{{ option_name }}"
|
|
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">
|
|
{{ option.default | default(option.range_start) if option.default != "random" else option.range_start }}
|
|
</span>
|
|
{{ RandomizeButton(option_name, option) }}
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro NamedRange(option_name, option) %}
|
|
{{ OptionTitle(option_name, option) }}
|
|
<div class="named-range-container">
|
|
<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>
|
|
{% else %}
|
|
<option value="{{ val }}">{{ key|replace("_", " ")|title }} ({{ val }})</option>
|
|
{% endif %}
|
|
{% endfor %}
|
|
<option value="custom" hidden>Custom</option>
|
|
</select>
|
|
<div class="named-range-wrapper js-required">
|
|
<input
|
|
type="range"
|
|
id="{{ 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">
|
|
{{ option.default | default(option.range_start) if option.default != "random" else option.range_start }}
|
|
</span>
|
|
{{ RandomizeButton(option_name, option) }}
|
|
</div>
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro FreeText(option_name, option) %}
|
|
{{ OptionTitle(option_name, option) }}
|
|
<div class="free-text-container">
|
|
<input type="text" id="{{ option_name }}" name="{{ option_name }}" value="{{ option.default }}" />
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro TextChoice(option_name, option) %}
|
|
{{ OptionTitle(option_name, option) }}
|
|
<div class="text-choice-container">
|
|
<div class="text-choice-wrapper">
|
|
<select id="{{ option_name }}" name="{{ option_name }}" {{ "disabled" if option.default == "random" }}>
|
|
{% for id, name in option.name_lookup.items()|sort %}
|
|
{% if name != "random" %}
|
|
{% if option.default == id %}
|
|
<option value="{{ name }}" selected>{{ option.get_option_name(id) }}</option>
|
|
{% else %}
|
|
<option value="{{ name }}">{{ option.get_option_name(id) }}</option>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
<option value="custom" hidden>Custom</option>
|
|
</select>
|
|
{{ RandomizeButton(option_name, option) }}
|
|
</div>
|
|
<input type="text" id="{{ option_name }}-custom" name="{{ option_name }}-custom" data-option-name="{{ option_name }}" placeholder="Custom value..." />
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro ItemDict(option_name, option) %}
|
|
{{ OptionTitle(option_name, option) }}
|
|
<div class="option-container">
|
|
{% for item_name in (option.valid_keys|sort if (option.valid_keys|length > 0) else world.item_names|sort) %}
|
|
<div class="option-entry">
|
|
<label for="{{ option_name }}-{{ item_name }}-qty">{{ item_name }}</label>
|
|
<input type="number" id="{{ option_name }}-{{ item_name }}-qty" name="{{ option_name }}||{{ item_name }}||qty" value="{{ option.default[item_name]|default("0") }}" data-option-name="{{ option_name }}" data-item-name="{{ item_name }}" />
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro OptionList(option_name, option) %}
|
|
{{ OptionTitle(option_name, option) }}
|
|
<div class="option-container">
|
|
{% for key in (option.valid_keys if option.valid_keys is ordered else option.valid_keys|sort) %}
|
|
<div class="option-entry">
|
|
<input type="checkbox" id="{{ option_name }}-{{ key }}" name="{{ option_name }}" value="{{ key }}" {{ "checked" if key in option.default }} />
|
|
<label for="{{ option_name }}-{{ key }}">{{ key }}</label>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro LocationSet(option_name, option) %}
|
|
{{ OptionTitle(option_name, option) }}
|
|
<div class="option-container">
|
|
{% for group_name in world.location_name_groups.keys()|sort %}
|
|
{% if group_name != "Everywhere" %}
|
|
<div class="option-entry">
|
|
<input type="checkbox" id="{{ option_name }}-{{ group_name }}" name="{{ option_name }}" value="{{ group_name }}" {{ "checked" if group_name in option.default }} />
|
|
<label for="{{ option_name }}-{{ group_name }}">{{ group_name }}</label>
|
|
</div>
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% if world.location_name_groups.keys()|length > 1 %}
|
|
<div class="option-divider"> </div>
|
|
{% endif %}
|
|
{% for location_name in (option.valid_keys|sort if (option.valid_keys|length > 0) else world.location_names|sort) %}
|
|
<div class="option-entry">
|
|
<input type="checkbox" id="{{ option_name }}-{{ location_name }}" name="{{ option_name }}" value="{{ location_name }}" {{ "checked" if location_name in option.default }} />
|
|
<label for="{{ option_name }}-{{ location_name }}">{{ location_name }}</label>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro ItemSet(option_name, option) %}
|
|
{{ OptionTitle(option_name, option) }}
|
|
<div class="option-container">
|
|
{% for group_name in world.item_name_groups.keys()|sort %}
|
|
{% if group_name != "Everything" %}
|
|
<div class="option-entry">
|
|
<input type="checkbox" id="{{ option_name }}-{{ group_name }}" name="{{ option_name }}" value="{{ group_name }}" {{ "checked" if group_name in option.default }} />
|
|
<label for="{{ option_name }}-{{ group_name }}">{{ group_name }}</label>
|
|
</div>
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% if world.item_name_groups.keys()|length > 1 %}
|
|
<div class="option-divider"> </div>
|
|
{% endif %}
|
|
{% for item_name in (option.valid_keys|sort if (option.valid_keys|length > 0) else world.item_names|sort) %}
|
|
<div class="option-entry">
|
|
<input type="checkbox" id="{{ option_name }}-{{ item_name }}" name="{{ option_name }}" value="{{ item_name }}" {{ "checked" if item_name in option.default }} />
|
|
<label for="{{ option_name }}-{{ item_name }}">{{ item_name }}</label>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro OptionSet(option_name, option) %}
|
|
{{ OptionTitle(option_name, option) }}
|
|
<div class="option-container">
|
|
{% for key in (option.valid_keys if option.valid_keys is ordered else option.valid_keys|sort) %}
|
|
<div class="option-entry">
|
|
<input type="checkbox" id="{{ option_name }}-{{ key }}" name="{{ option_name }}" value="{{ key }}" {{ "checked" if key in option.default }} />
|
|
<label for="{{ option_name }}-{{ key }}">{{ key }}</label>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endmacro %}
|
|
|
|
{% macro OptionTitle(option_name, option) %}
|
|
<label for="{{ option_name }}">
|
|
{{ option.display_name|default(option_name) }}:
|
|
<span
|
|
class="interactive tooltip-container"
|
|
{% if not (option.rich_text_doc | default(world.web.rich_text_options_doc, true)) %}
|
|
data-tooltip="{{(option.__doc__ | default("Please document me!"))|replace('\n ', '\n')|escape|trim}}"
|
|
{% endif %}>
|
|
(?)
|
|
{% if option.rich_text_doc | default(world.web.rich_text_options_doc, true) %}
|
|
<div class="tooltip">
|
|
{{ option.__doc__ | default("**Please document me!**") | rst_to_html | safe }}
|
|
</div>
|
|
{% endif %}
|
|
</span>
|
|
</label>
|
|
{% endmacro %}
|
|
|
|
{% macro RandomizeButton(option_name, option) %}
|
|
<div class="randomize-button" data-tooltip="Toggle randomization for this option!">
|
|
<label for="random-{{ option_name }}">
|
|
<input type="checkbox" id="random-{{ option_name }}" name="random-{{ option_name }}" class="randomize-checkbox" data-option-name="{{ option_name }}" {{ "checked" if option.default == "random" }} />
|
|
🎲
|
|
</label>
|
|
</div>
|
|
{% endmacro %}
|