[% WRAPPER bug_modal/field.html.tmpl
field = bug_fields.bug_type
field_type = constants.FIELD_TYPE_SINGLE_SELECT
+ use_buttons = 1
help = "https://wiki.mozilla.org/BMO/UserGuide/BugFields#bug_type"
%]
<span class="bug-type-label iconic-text" data-type="[% bug.bug_type FILTER html %]">
<div class="field
[%~ " indent" IF no_label && !no_indent %]
[%~ " inline" IF inline %]
+ [%~ " contains-buttons" IF use_buttons ~%]
[%~ " edit-hide" IF hide_on_edit %]
[%~ " edit-show" IF hide_on_view && !hide_on_edit %]"
[% IF name %] id="field-[% name FILTER html %]"[% END %]
[% CASE constants.FIELD_TYPE_SINGLE_SELECT %]
[%# single value select %]
<input type="hidden" id="[% name FILTER html %]-dirty">
+ [% IF use_buttons %]
+ <div role="radiogroup" class="buttons toggle" id="[% name FILTER html %]" [% aria_labelledby_html FILTER none %]>
+ [% IF values.defined %]
+ [% FOREACH v IN values %]
+ [% NEXT IF NOT v.is_active AND NOT value.contains(v.name).size %]
+ [% NEXT IF NOT bug.check_can_change_field(name, bug.${field_name}, v.name) %]
+ <div class="item">
+ <input id="v[% v.id FILTER html %]_[% name FILTER html %]" type="radio" name="[% name FILTER html %]"
+ value="[% v.name FILTER html %]" [% " checked" IF value.contains(v.name).size %]>
+ <label for="v[% v.id FILTER html %]_[% name FILTER html %]">
+ [% IF name == 'bug_type' %]
+ <span class="bug-type-label iconic-text" data-type="[% v.name FILTER html %]">
+ <span class="icon" aria-hidden="true"></span>[% v.name FILTER html %]
+ </span>
+ [% ELSE %]
+ [%~ v.name FILTER html ~%]
+ [% END %]
+ </label>
+ </div>
+ [% END %]
+ [% ELSE %]
+ <div class="item">
+ <input id="[% name FILTER html %]_[% value FILTER html %]_radio" type="radio"
+ name="[% name FILTER html %]" value="[% value FILTER html %]" checked>
+ <label for="[% name FILTER html %]_[% value FILTER html %]_radio">
+ [% IF name == 'bug_type' %]
+ <span class="bug-type-label iconic-text" data-type="[% value FILTER html %]">
+ <span class="icon" aria-hidden="true"></span>[% value FILTER html %]
+ </span>
+ [% ELSE %]
+ [%~ value FILTER html ~%]
+ [% END %]
+ </label>
+ </div>
+ [% END %]
+ </div>
+ [% ELSE %]
<select name="[% name FILTER html %]" id="[% name FILTER html %]" [% aria_labelledby_html FILTER none %]>
[% IF values.defined %]
[% FOREACH v IN values %]
<option value="[% value FILTER html %]" selected>[% value FILTER html %]</option>
[% END %]
</select>
+ [% END %]
[% CASE constants.FIELD_TYPE_MULTI_SELECT %]
[%# multi value select %]
width: 170px;
}
+.module .field.contains-buttons {
+ margin: 8px 0;
+}
+
+.module .field.contains-buttons .name {
+ vertical-align: middle;
+}
+
.field-button {
float: right;
margin-left: 8px;
$('#mode-btn').hide();
// populate select menus
- $.each(data.options, function(key, value) {
- var el = $('#' + key);
- if (!el) return;
- var selected = el.val();
- el.empty();
- $(value).each(function(i, v) {
- el.append($('<option>', { value: v.name, text: v.name }));
+ Object.entries(data.options).forEach(([key, value]) => {
+ const $select = document.querySelector(`#${key}`);
+ if (!$select) return;
+ // It can be radio-button-like UI
+ const use_buttons = $select.matches('.buttons.toggle');
+ const selected = use_buttons ? $select.querySelector('input').value : $select.value;
+ $select.innerHTML = '';
+ value.forEach(({ name }) => {
+ if (use_buttons) {
+ $select.insertAdjacentHTML('beforeend', `
+ <div class="item">
+ <input id="${$select.id}_${name}_radio" type="radio" name="${$select.id}"
+ value="${name}" ${name === selected ? 'checked' : ''}>
+ <label for="${$select.id}_${name}_radio">
+ ${$select.id === 'bug_type' ? `
+ <span class="bug-type-label iconic-text" data-type="${name}">
+ <span class="icon" aria-hidden="true"></span>${name}
+ </span>
+ ` : `${name}`}
+ </label>
+ </div>
+ `);
+ } else {
+ $select.insertAdjacentHTML('beforeend', `
+ <option value="${name}" ${name === selected ? 'selected' : ''}>${name}</option>
+ `);
+ }
});
- el.val(selected);
- if (el.attr('multiple') && value.length < 5) {
- el.attr('size', value.length);
+ if ($select.matches('[multiple]') && value.length < 5) {
+ $select.size = value.length;
}
});
log_in($sel, $config, 'QA_Selenium_TEST');
file_bug_in_product($sel, 'TestProduct');
-$sel->select_ok("bug_type", "label=defect");
+$sel->check_ok('//input[@name="bug_type" and @value="defect"]');
$sel->select_ok("bug_severity", "label=critical");
$sel->type_ok("short_desc", "Test bug editing");
$sel->type_ok("comment", "ploc");
log_in($sel, $config, 'QA_Selenium_TEST');
file_bug_in_product($sel, 'TestProduct');
-$sel->select_ok("bug_type", "label=defect");
+$sel->check_ok('//input[@name="bug_type" and @value="defect"]');
$sel->select_ok("bug_severity", "label=blocker");
$sel->type_ok("short_desc", "New bug from me");
my @labels = $sel->get_select_options("cf_qa_list_$bug1_id");
ok(grep(/^ghost$/, @labels), "ghost is in the DOM of the page...");
my $disabled = $sel->get_attribute("v4_cf_qa_list_$bug1_id\@disabled");
-ok($disabled, "... but is not available for selection by default");
+ok(defined $disabled, "... but is not available for selection by default");
$sel->select_ok("bug_status", "label=RESOLVED");
$sel->select_ok("resolution", "label=FIXED");
$sel->select_ok("cf_qa_list_$bug1_id", "label=ghost");
max-width: 35em;
}
+/* Adjust style for fields using radio-button-like UI */
+#Create .field_label.for-buttons {
+ vertical-align: middle;
+}
+
+#Create .field_value.contains-buttons {
+ padding: .5em .25em;
+}
+
/* Text inputs need to be a little shorter on enter_bug
* than the 100% that they are on show_bug.
*/
}
.buttons.toggle[role="radiogroup"] .item:first-child label {
- border-radius: 4px 0 0 4px;
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
}
.buttons.toggle[role="radiogroup"] .item:last-child label {
- border-radius: 0 4px 4px 0;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
}
.buttons.toggle[role="radiogroup"] .item:not(:first-child) label {
initCrashSignatureField();
init_take_handler('[% user.login FILTER js %]');
bz_attachment_form.update_requirements(false);
+
+ document.querySelector('#bug_type').addEventListener('change', () => {
+ bug_type_changed = true;
+ }, { once: true });
}
function initCrashSignatureField() {
var initialowners = new Array([% product.components.size %]);
var last_initialowner;
var default_bug_types = new Array([% product.components.size %]);
+let bug_type_changed = false;
var initialccs = new Array([% product.components.size %]);
var components = new Array([% product.components.size %]);
var comp_desc = new Array([% product.components.size %]);
last_initialowner = owner;
}
- form.bug_type.value = default_bug_types[index];
+ if (!bug_type_changed) {
+ form.bug_type.value = default_bug_types[index];
+ }
+
document.getElementById('initial_cc').innerHTML = initialccs[index];
document.getElementById('comp_desc').innerHTML = comp_desc[index];
</td>
[% INCLUDE bug/field.html.tmpl
- bug = default, field = bug_fields.bug_type, editable = 1,
+ bug = default, field = bug_fields.bug_type, editable = 1, use_buttons = 1,
value = default.bug_type %]
</tr>
[% DEFAULT tag_name = "th" %]
<[% tag_name FILTER html %] class="field_label [% ' bz_hidden_field' IF hidden %]
- [%- ' required' IF field.is_mandatory && NOT bug.id %]"
+ [%- ' required' IF field.is_mandatory && NOT bug.id; ' for-buttons' IF use_buttons %]"
id="field_label_[% field.name FILTER html %]"
[% IF rowspan %] rowspan="[% rowspan FILTER html %]"[% END %]>
[% IF NOT no_tds %]
[% PROCESS "bug/field-label.html.tmpl" %]
- <td class="field_value [% ' bz_hidden_field' IF hidden %]"
+ <td class="field_value [% ' bz_hidden_field' IF hidden; ' contains-buttons' IF use_buttons %]"
id="field_container_[% field.name FILTER html %]"
[% " colspan=\"$value_span\"" FILTER none IF value_span %]>
[% END %]
[% CASE [ constants.FIELD_TYPE_SINGLE_SELECT
constants.FIELD_TYPE_MULTI_SELECT ] %]
<input type="hidden" id="[% field.name FILTER html %]_dirty">
+ [% IF use_buttons %]
+ <div role="radiogroup" class="buttons toggle" id="[% field.name FILTER html %]">
+ [% ELSE %]
<select id="[% field.name FILTER html %]"
name="[% field.name FILTER html %]"
[% IF field.type == constants.FIELD_TYPE_MULTI_SELECT %]
[% dontchange FILTER html %]
</option>
[% END %]
+ [% END %]
[% IF override_legal_values %]
[% legal_values = override_legal_values %]
[% ELSE %]
[% legal_values = field.legal_values %]
[% END %]
[% FOREACH legal_value = legal_values %]
- [% NEXT IF NOT legal_value.is_active AND NOT value.contains(legal_value.name).size %]
+ [%
+ selected = value.contains(legal_value.name).size;
+ NEXT IF NOT legal_value.is_active AND NOT selected;
+ option_id = "v" _ legal_value.id _ "_" _ field.name;
+ disabled = bug AND !legal_value.is_visible_on_bug(bug);
+ %]
[%# Purpose: hide field values from those who can't change them %]
[% IF field.name.match("^cf_blocking_") OR
field.name == "cf_cab_review" OR
field.name == "resolution" %]
[% NEXT UNLESS bug.check_can_change_field(field.name, '---', legal_value.name) OR
- value.contains(legal_value.name).size %]
+ selected %]
[% END %]
[% IF field.name == "resolution" &&
[% NEXT IF r == "EXPIRED" %]
[% END %]
- <option value="[% legal_value.name FILTER html %]"
- id="v[% legal_value.id FILTER html %]_
- [%- field.name FILTER html %]"
- [%# We always show selected values, even if they should be
- # hidden %]
- [% IF value.contains(legal_value.name).size %]
- selected="selected"
- [% ELSIF bug AND !legal_value.is_visible_on_bug(bug) %]
- class="bz_hidden_option" disabled="disabled"
- [% END %]>
+ [% IF use_buttons %]
+ <div class="item">
+ <input id="[% option_id FILTER html %]" type="radio"
+ name="[% field.name FILTER html %]" value="[% legal_value.name FILTER html %]"
+ [%# We always show selected values, even if they should be hidden %]
+ [% IF selected %]checked[% ELSIF disabled %]disabled class="bz_hidden_option"[% END %]>
+ <label for="[% option_id FILTER html %]">
+ [% IF field.name == 'bug_type'%]
+ <span class="bug-type-label iconic-text" data-type="[% legal_value.name FILTER html %]">
+ <span class="icon" aria-hidden="true"></span>[% legal_value.name FILTER html %]
+ </span>
+ [% ELSE %]
+ [%- display_value(field.name, legal_value.name) FILTER html ~%]
+ [% END %]
+ </label>
+ </div>
+ [% ELSE %]
+ <option id="[% option_id FILTER html %]" value="[% legal_value.name FILTER html %]"
+ [%# We always show selected values, even if they should be hidden %]
+ [% IF selected %]selected[% ELSIF disabled %]disabled class="bz_hidden_option"[% END %]>
[%- display_value(field.name, legal_value.name) FILTER html ~%]
</option>
+ [% END %]
[% END %]
+ [% IF use_buttons %]
+ </div>
+ [% ELSE %]
</select>
+ [% END %]
[%# When you pass an empty multi-select in the web interface,
# it doesn't appear at all in the CGI object. Instead of
# forcing all users of process_bug to always specify every