[REF] web, *: BS4, use custom BS4 checkbox everywhere
Before this commit, Odoo used checkboxes in three different ways: - A simple <input type="checkbox"/>, mainly in the frontend. The style is browser dependant. - Same as above but with the BS3, checkbox structure. The style is still the same, but the alignement is supposed to be better (which is not always the case). - The Odoo official structure: ``` <div class="o_checkbox"> <input type="checkbox"/> <span/> </div> ``` which allows to have a cross-browser checkbox style and correct alignements. The goal after this commit is to only use the BS4 *custom* checkbox structure to achieve the same goal as our official structure (and remove that one): ``` <div class="custom-control custom-checkbox"> <input type="checkbox" class="custom-control-input" id="customCheck1"> <label class="custom-control-label" for="customCheck1">...</label> </div> ``` /!\ Labels are now required (use a zero-width space if necessary)
This commit is contained in:
@@ -29,7 +29,7 @@ tour.register('hr_expense_tour' ,
|
||||
content: _t('<p>Click on <b> Create Report </b> to create the report.</p>'),
|
||||
position: 'right',
|
||||
}, {
|
||||
trigger: '.o_expense_tree .o_checkbox > input[type=checkbox]',
|
||||
trigger: '.o_expense_tree input[type=checkbox]',
|
||||
content: _t('<p>Select expenses to submit them to your manager</p>'),
|
||||
position: 'bottom'
|
||||
}, {
|
||||
|
||||
@@ -28,14 +28,17 @@
|
||||
<div class="o_composer_suggestedPartners">
|
||||
<t t-foreach='widget.suggestedPartners' t-as='recipient'>
|
||||
<div t-attf-title="Add as recipient and follower (reason: #{recipient.reason})">
|
||||
<div class="o_checkbox">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox"
|
||||
class="custom-control-input"
|
||||
t-attf-id="o_composer_suggested_partners_p#{recipient_index}"
|
||||
t-att-checked="recipient.checked ? 'checked' : undefined"
|
||||
t-att-data-fullname="recipient.full_name"/>
|
||||
<span/>
|
||||
<label t-attf-for="o_composer_suggested_partners_p#{recipient_index}" class="custom-control-label">
|
||||
<t t-esc="recipient.name"/>
|
||||
<t t-if="recipient.email_address">(<t t-esc="recipient.email_address"/>)</t>
|
||||
</label>
|
||||
</div>
|
||||
<t t-esc="recipient.name"/>
|
||||
<t t-if="recipient.email_address">(<t t-esc="recipient.email_address"/>)</t>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
@@ -70,15 +70,18 @@
|
||||
-->
|
||||
<t t-name="mail.Followers.subtype">
|
||||
<div role="menuitem" class="o_subtype dropdown-item">
|
||||
<div class="o_checkbox">
|
||||
<input type="checkbox" t-att-checked="record.followed"
|
||||
t-att-id="'input_mail_followers_subtype_'+record.id+(dialog ? '_in_dialog': '')"
|
||||
t-att-data-id="record.id" t-att-name="record.name" class="o_subtype_checkbox"/>
|
||||
<span/>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox"
|
||||
t-attf-id="input_mail_followers_subtype_#{record.id + (dialog ? '_in_dialog': '')}"
|
||||
t-att-name="record.name"
|
||||
class="custom-control-input o_subtype_checkbox"
|
||||
t-att-checked="record.followed"
|
||||
t-att-data-id="record.id"/>
|
||||
<label t-attf-for="input_mail_followers_subtype_#{record.id + (dialog ? '_in_dialog': '')}"
|
||||
class="custom-control-label">
|
||||
<t t-esc="record.name"/>
|
||||
</label>
|
||||
</div>
|
||||
<span t-att-for="'input_mail_followers_subtype_'+record.id+(dialog ? '_in_dialog': '')">
|
||||
<t t-esc="record.name"/>
|
||||
</span>
|
||||
<i t-if="display_warning" class="fa fa-warning text-warning" role="img" aria-label="Warning" title="Warning"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -857,7 +857,7 @@ QUnit.test('chatter: discard changes on message post with post_refresh "recipien
|
||||
$input.trigger($.Event('keyup', {which: $.ui.keyCode.ENTER}));
|
||||
|
||||
// untick recipient as follower (prompts a res.partner form otherwise)
|
||||
form.$('.o_checkbox input').prop('checked', false);
|
||||
form.$('input[type="checkbox"]').prop('checked', false);
|
||||
|
||||
// send message
|
||||
form.$('.oe_chatter .o_composer_button_send').click();
|
||||
|
||||
@@ -261,33 +261,41 @@ return {
|
||||
return $button;
|
||||
},
|
||||
/**
|
||||
* Renders a checkbox with standard odoo template. This does not use any xml
|
||||
* template to avoid forcing the frontend part to lazy load a xml file for
|
||||
* each widget which might want to create a simple checkbox.
|
||||
* Renders a checkbox with standard odoo/BS template. This does not use any
|
||||
* xml template to avoid forcing the frontend part to lazy load a xml file
|
||||
* for each widget which might want to create a simple checkbox.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* @param {Object} [options.prop]
|
||||
* Allows to set the input properties (disabled and checked states).
|
||||
* @param {string} [options.text]
|
||||
* The checkbox's associated text. If none is given then a simple
|
||||
* checkbox without label structure is rendered.
|
||||
* checkbox is rendered.
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
renderCheckbox: function (options) {
|
||||
var $container = $('<div class="o_checkbox"><input type="checkbox"/><span/></div>');
|
||||
var id = _.uniqueId('checkbox-');
|
||||
var $container = $('<div/>', {
|
||||
class: 'custom-control custom-checkbox',
|
||||
});
|
||||
var $input = $('<input/>', {
|
||||
type: 'checkbox',
|
||||
id: id,
|
||||
class: 'custom-control-input',
|
||||
});
|
||||
var $label = $('<label/>', {
|
||||
for: id,
|
||||
class: 'custom-control-label',
|
||||
text: options && options.text || '',
|
||||
});
|
||||
if (!options || !options.text) {
|
||||
$label.html('​'); // BS checkboxes need some label content (so
|
||||
// add a zero-width space when there is no text)
|
||||
}
|
||||
if (options && options.prop) {
|
||||
$container.children('input').prop(options.prop);
|
||||
$input.prop(options.prop);
|
||||
}
|
||||
if (options && options.text) {
|
||||
$container = $('<label/>').append(
|
||||
$container,
|
||||
$('<span/>', {
|
||||
class: 'ml8',
|
||||
text: options.text,
|
||||
})
|
||||
);
|
||||
}
|
||||
return $container;
|
||||
return $container.append($input, $label);
|
||||
},
|
||||
/**
|
||||
* Sets the selection range of a given input or textarea
|
||||
|
||||
@@ -304,7 +304,6 @@ var AbstractField = Widget.extend({
|
||||
this._reset(record, event);
|
||||
return this._render() || $.when();
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove the invalid class on a field
|
||||
*/
|
||||
@@ -312,7 +311,15 @@ var AbstractField = Widget.extend({
|
||||
this.$el.removeClass('o_field_invalid');
|
||||
this.$el.removeAttr('aria-invalid');
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the given id on the focusable element of the field and as 'for'
|
||||
* attribute of potential internal labels.
|
||||
*
|
||||
* @param {string} id
|
||||
*/
|
||||
setIDForLabel: function (id) {
|
||||
this.getFocusableElement().attr('id', id);
|
||||
},
|
||||
/**
|
||||
* add the invalid class on a field
|
||||
*/
|
||||
@@ -320,7 +327,6 @@ var AbstractField = Widget.extend({
|
||||
this.$el.addClass('o_field_invalid');
|
||||
this.$el.attr('aria-invalid', 'true');
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the modifiers with the newest value.
|
||||
* Now this.attrs.modifiersValue can be used consistantly even with
|
||||
|
||||
@@ -701,8 +701,8 @@ var FieldBoolean = AbstractField.extend({
|
||||
// The formatValue of boolean fields renders HTML elements similar to
|
||||
// the one rendered by the widget itself. Even though the event might
|
||||
// have been fired on the non-widget version of this field, we can still
|
||||
// test the presence of its o_checkbox class.
|
||||
if (activated && options && options.event && $(options.event.target).parents('.o_checkbox').length) {
|
||||
// test the presence of its custom class.
|
||||
if (activated && options && options.event && $(options.event.target).closest('.custom-control.custom-checkbox').length) {
|
||||
this._setValue(!this.value); // Toggle the checkbox
|
||||
}
|
||||
return activated;
|
||||
@@ -737,6 +737,15 @@ var FieldBoolean = AbstractField.extend({
|
||||
}
|
||||
return rendered;
|
||||
},
|
||||
/**
|
||||
* Associates the 'for' attribute of the internal label.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
setIDForLabel: function (id) {
|
||||
this._super.apply(this, arguments);
|
||||
this.$('.custom-control-label').attr('for', id);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
|
||||
@@ -1887,7 +1887,7 @@ var FormFieldMany2ManyTags = FieldMany2ManyTags.extend({
|
||||
this.$color_picker.dropdown('toggle');
|
||||
this.$color_picker.attr("tabindex", 1).focus();
|
||||
if (!tagColor) {
|
||||
this.$('.o_checkbox input').prop('checked', true);
|
||||
this.$('.custom-checkbox input').prop('checked', true);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1909,7 +1909,7 @@ var FormFieldMany2ManyTags = FieldMany2ManyTags.extend({
|
||||
var changes = {};
|
||||
|
||||
if ($target.is('.o_hide_in_kanban')) {
|
||||
var $checkbox = $('.o_hide_in_kanban .o_checkbox input');
|
||||
var $checkbox = $('.o_hide_in_kanban .custom-checkbox input');
|
||||
$checkbox.prop('checked', !$checkbox.prop('checked')); // toggle checkbox
|
||||
this.prevColors = this.prevColors ? this.prevColors : {};
|
||||
if ($checkbox.is(':checked')) {
|
||||
|
||||
@@ -98,7 +98,7 @@ var SidebarFilter = Widget.extend(FieldManagerMixin, {
|
||||
this.many2one.filter_ids = _.without(_.pluck(this.filters, 'value'), 'all');
|
||||
}
|
||||
this.$el.on('click', '.o_remove', this._onFilterRemove.bind(this));
|
||||
this.$el.on('click', '.o_checkbox input', this._onFilterActive.bind(this));
|
||||
this.$el.on('click', '.custom-checkbox input', this._onFilterActive.bind(this));
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -902,7 +902,7 @@ var FormRenderer = BasicRenderer.extend({
|
||||
// enterprise label will be displayed as many times as the field
|
||||
// exists on settings.
|
||||
var $widgets = self.$('.o_field_widget[name=' + widget.name + ']');
|
||||
var $label = idForLabel ? self.$('label[for=' + idForLabel + ']') : $();
|
||||
var $label = idForLabel ? self.$('.o_form_label[for=' + idForLabel + ']') : $();
|
||||
$label = $label.eq($widgets.index(widget.$el));
|
||||
if (config.debug || widget.attrs.help || widget.field.help) {
|
||||
self._addFieldTooltip(widget, $label);
|
||||
@@ -922,7 +922,7 @@ var FormRenderer = BasicRenderer.extend({
|
||||
* @param {idForLabel} string
|
||||
*/
|
||||
_setIDForLabel: function (widget, idForLabel) {
|
||||
widget.getFocusableElement().attr('id', idForLabel);
|
||||
widget.setIDForLabel(idForLabel);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// Checkbox in editable list
|
||||
// should be clickable and activate the row
|
||||
&.o_editable_list .o_data_row:not(.o_selected_row) .o_data_cell {
|
||||
.o_checkbox:not(.o_readonly_modifier) {
|
||||
.custom-checkbox:not(.o_readonly_modifier) {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Checkboxes
|
||||
//------------------------------------------------------------------------------
|
||||
div.o_checkbox {
|
||||
display: inline-block;
|
||||
vertical-align: sub;
|
||||
> input + span {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -868,10 +868,10 @@
|
||||
<div role="menuitem" class="o_hide_in_kanban"
|
||||
t-att-data-id="tag_id"
|
||||
t-att-data-color="0">
|
||||
<div class="o_checkbox">
|
||||
<input type="checkbox"/>
|
||||
<span/>
|
||||
</div> Hide in Kanban
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" id="o_hide_in_kanban_checkbox" class="custom-control-input"/>
|
||||
<label for="o_hide_in_kanban_checkbox" class="custom-control-label">Hide in Kanban</label>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -1283,10 +1283,16 @@
|
||||
<input type="text" class="o_input"></input>
|
||||
</div>
|
||||
<div role="menuitem" class="dropdown-item-text o_save_name">
|
||||
<span><div class="o_checkbox"><input type="checkbox"/><span/></div> Use by default</span>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" id="o_fav_menu_use_by_default" class="custom-control-input"/>
|
||||
<label for="o_fav_menu_use_by_default" class="custom-control-label">Use by default</label>
|
||||
</div>
|
||||
</div>
|
||||
<div role="menuitem" class="dropdown-item-text o_save_name">
|
||||
<span><div class="o_checkbox"><input type="checkbox"/><span/></div> Share with all users </span><span class="fa fa-users" role="img" aria-label="Users" title="Users"/>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" id="o_fav_menu_share_all_users" class="custom-control-input"/>
|
||||
<label for="o_fav_menu_share_all_users" class="custom-control-label">Share with all users <span class="fa fa-users" role="img" aria-label="Users" title="Users"/></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-item-text o_save_name">
|
||||
<button role="menuitem" type="button" class="btn btn-primary">Save</button>
|
||||
@@ -1392,11 +1398,10 @@
|
||||
<div aria-atomic="true">
|
||||
<div t-foreach="widget.m2mValues" t-as="m2m_value">
|
||||
<t t-set="id_for_label" t-value="'o_many2many_checkbox_' + _.uniqueId()"/>
|
||||
<div class="o_checkbox">
|
||||
<input type="checkbox" t-att-id="id_for_label" t-att-data-record-id="JSON.stringify(m2m_value[0])"/>
|
||||
<span/>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" t-att-id="id_for_label" class="custom-control-input" t-att-data-record-id="JSON.stringify(m2m_value[0])"/>
|
||||
<label t-att-for="id_for_label" class="custom-control-label o_form_label"><t t-esc="m2m_value[1]"/></label>
|
||||
</div>
|
||||
<label t-att-for="id_for_label" class="o_form_label"><t t-esc="m2m_value[1]"/></label>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -40,22 +40,29 @@
|
||||
<h3 t-if="widget.title"><t t-esc="widget.title"/></h3>
|
||||
<div class="o_calendar_filter_items">
|
||||
<div t-foreach="widget.filters" t-as="filter" t-if="filter.display == null || filter.display" class="o_calendar_filter_item" t-att-data-value="filter.value" t-att-data-id="filter.id">
|
||||
<div class="o_checkbox">
|
||||
<input type="checkbox" name="selection" t-att-checked="(filter.active ? true : undefined)"/><span/>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox"
|
||||
t-attf-id="o_calendar_filter_item_#{filter_index}"
|
||||
name="selection"
|
||||
class="custom-control-input"
|
||||
t-att-checked="(filter.active ? true : undefined)"/>
|
||||
<label t-attf-for="o_calendar_filter_item_#{filter_index}"
|
||||
class="custom-control-label">
|
||||
<t t-if="filter.value == 'all'">
|
||||
<span><i class="fa fa-users fa-fw o_cal_avatar" role="img" aria-label="Avatar" title="Avatar"/></span>
|
||||
</t>
|
||||
<t t-if="widget.avatar_field && (filter.value != 'all')">
|
||||
<img t-attf-src="/web/image/#{widget.avatar_model}/#{filter.value}/#{widget.avatar_field}" class="o_cal_avatar" alt="Avatar"/>
|
||||
</t>
|
||||
<t t-set="color" t-value="widget.getColor(filter.color_index)"/>
|
||||
<span t-if="typeof color === 'number'" t-attf-class="color_filter o_underline_color_#{widget.getColor(filter.color_index)}"><t t-esc="filter.label"/></span>
|
||||
<span t-elif="color" t-attf-style="border-bottom: 4px solid #{color};"><t t-esc="filter.label"/></span>
|
||||
<span t-else=""><t t-esc="filter.label"/></span>
|
||||
</label>
|
||||
</div>
|
||||
<t t-if="filter.value == 'all'">
|
||||
<span><i class="fa fa-users fa-fw o_cal_avatar" role="img" aria-label="Avatar" title="Avatar"/></span>
|
||||
</t>
|
||||
<t t-if="widget.avatar_field && (filter.value != 'all')">
|
||||
<img t-attf-src="/web/image/#{widget.avatar_model}/#{filter.value}/#{widget.avatar_field}" class="o_cal_avatar" alt="Avatar"/>
|
||||
</t>
|
||||
<t t-set="color" t-value="widget.getColor(filter.color_index)"/>
|
||||
<span t-if="typeof color === 'number'" t-attf-class="color_filter o_underline_color_#{widget.getColor(filter.color_index)}"><t t-esc="filter.label"/></span>
|
||||
<span t-elif="color" t-attf-style="border-bottom: 4px solid #{color};"><t t-esc="filter.label"/></span>
|
||||
<span t-else=""><t t-esc="filter.label"/></span>
|
||||
<t t-if="filter.id">
|
||||
<span class="o_remove fa fa-times" title="Remove this favorite from the list" role="img" aria-label="Remove this favorite from the list"/>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -233,12 +233,12 @@ QUnit.module('basic_fields', {
|
||||
"checkbox should now be unchecked");
|
||||
|
||||
// check the checkbox by clicking on label
|
||||
form.$('label').click();
|
||||
form.$('label:first').click();
|
||||
assert.strictEqual(form.$('.o_field_boolean input:checked').length, 1,
|
||||
"checkbox should now be checked");
|
||||
|
||||
// uncheck it back
|
||||
form.$('label').click();
|
||||
form.$('label:first').click();
|
||||
assert.strictEqual(form.$('.o_field_boolean input:checked').length, 0,
|
||||
"checkbox should now be unchecked");
|
||||
|
||||
@@ -273,52 +273,52 @@ QUnit.module('basic_fields', {
|
||||
arch: '<tree editable="bottom"><field name="bar"/></tree>',
|
||||
});
|
||||
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector) .o_checkbox input').length, 5,
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector) .custom-checkbox input').length, 5,
|
||||
"should have 5 checkboxes");
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector) .o_checkbox input:checked').length, 4,
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector) .custom-checkbox input:checked').length, 4,
|
||||
"should have 4 checked input");
|
||||
|
||||
// Edit a line
|
||||
var $cell = list.$('tr.o_data_row:has(.o_checkbox input:checked) td:not(.o_list_record_selector)').first();
|
||||
assert.ok($cell.find('.o_checkbox input:checked').prop('disabled'),
|
||||
var $cell = list.$('tr.o_data_row:has(.custom-checkbox input:checked) td:not(.o_list_record_selector)').first();
|
||||
assert.ok($cell.find('.custom-checkbox input:checked').prop('disabled'),
|
||||
"input should be disabled in readonly mode");
|
||||
$cell.click();
|
||||
assert.ok(!$cell.find('.o_checkbox input:checked').prop('disabled'),
|
||||
assert.ok(!$cell.find('.custom-checkbox input:checked').prop('disabled'),
|
||||
"input should not have the disabled property in edit mode");
|
||||
$cell.find('.o_checkbox input:checked').click();
|
||||
$cell.find('.custom-checkbox input:checked').click();
|
||||
|
||||
// save
|
||||
list.$buttons.find('.o_list_button_save').click();
|
||||
$cell = list.$('tr.o_data_row:has(.o_checkbox input:not(:checked)) td:not(.o_list_record_selector)').first();
|
||||
assert.ok($cell.find('.o_checkbox input:not(:checked)').prop('disabled'),
|
||||
$cell = list.$('tr.o_data_row:has(.custom-checkbox input:not(:checked)) td:not(.o_list_record_selector)').first();
|
||||
assert.ok($cell.find('.custom-checkbox input:not(:checked)').prop('disabled'),
|
||||
"input should be disabled again");
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector) .o_checkbox input').length, 5,
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector) .custom-checkbox input').length, 5,
|
||||
"should still have 5 checkboxes");
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector) .o_checkbox input:checked').length, 3,
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector) .custom-checkbox input:checked').length, 3,
|
||||
"should now have only 3 checked input");
|
||||
|
||||
// Re-Edit the line and fake-check the checkbox
|
||||
$cell.click();
|
||||
$cell.find('.o_checkbox input').click(); // Change the checkbox
|
||||
$cell.find('.o_checkbox input').click(); // Undo the change
|
||||
$cell.find('.custom-checkbox input').click(); // Change the checkbox
|
||||
$cell.find('.custom-checkbox input').click(); // Undo the change
|
||||
|
||||
// Save
|
||||
list.$buttons.find('.o_list_button_save').click();
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector) .o_checkbox input').length, 5,
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector) .custom-checkbox input').length, 5,
|
||||
"should still have 5 checkboxes");
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector) .o_checkbox input:checked').length, 3,
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector) .custom-checkbox input:checked').length, 3,
|
||||
"should still have only 3 checked input");
|
||||
|
||||
// Re-Edit the line to check the checkbox back but this time click on
|
||||
// the checkbox directly in readonly mode !
|
||||
$cell = list.$('tr.o_data_row:has(.o_checkbox input:not(:checked)) td:not(.o_list_record_selector)').first();
|
||||
$cell.find('.o_checkbox span').click();
|
||||
$cell = list.$('tr.o_data_row:has(.custom-checkbox input:not(:checked)) td:not(.o_list_record_selector)').first();
|
||||
$cell.find('.custom-checkbox .custom-control-label').click();
|
||||
|
||||
// save
|
||||
list.$buttons.find('.o_form_button_save').click();
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector) .o_checkbox input').length, 5,
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector) .custom-checkbox input').length, 5,
|
||||
"should still have 5 checkboxes");
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector) .o_checkbox input:checked').length, 4,
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector) .custom-checkbox input:checked').length, 4,
|
||||
"should now have 4 checked input back");
|
||||
list.destroy();
|
||||
});
|
||||
@@ -370,8 +370,8 @@ QUnit.module('basic_fields', {
|
||||
res_id: 2,
|
||||
});
|
||||
|
||||
assert.strictEqual(form.$(".o_checkbox.o_boolean_toggle").length, 1, "Boolean toggle widget applied to boolean field");
|
||||
assert.strictEqual(form.$(".o_checkbox.o_boolean_toggle").find(".slider").length, 1, "Boolean toggle contains slider to toggle");
|
||||
assert.strictEqual(form.$(".custom-checkbox.o_boolean_toggle").length, 1, "Boolean toggle widget applied to boolean field");
|
||||
assert.strictEqual(form.$(".custom-checkbox.o_boolean_toggle").find(".slider").length, 1, "Boolean toggle contains slider to toggle");
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
|
||||
@@ -10698,23 +10698,23 @@ QUnit.module('relational_fields', {
|
||||
}
|
||||
});
|
||||
|
||||
assert.notOk(form.$('.o_checkbox input').eq(0).prop('checked'),
|
||||
assert.notOk(form.$('.custom-checkbox input').eq(0).prop('checked'),
|
||||
"first checkbox should not be checked");
|
||||
assert.notOk(form.$('.o_checkbox input').eq(1).prop('checked'),
|
||||
assert.notOk(form.$('.custom-checkbox input').eq(1).prop('checked'),
|
||||
"second checkbox should not be checked");
|
||||
assert.ok(form.$('.o_checkbox input').eq(2).prop('checked'),
|
||||
assert.ok(form.$('.custom-checkbox input').eq(2).prop('checked'),
|
||||
"third checkbox should be checked");
|
||||
|
||||
form.$('.o_checkbox input:checked').click(); // Uncheck default record
|
||||
form.$('.o_checkbox input').first().click(); // Check first record
|
||||
form.$('.o_checkbox input').first().click(); // Uncheck first record
|
||||
form.$('.o_checkbox input').first().click(); // Recheck first record
|
||||
form.$('.custom-checkbox input:checked').click(); // Uncheck default record
|
||||
form.$('.custom-checkbox input').first().click(); // Check first record
|
||||
form.$('.custom-checkbox input').first().click(); // Uncheck first record
|
||||
form.$('.custom-checkbox input').first().click(); // Recheck first record
|
||||
|
||||
assert.ok(form.$('.o_checkbox input').eq(0).prop('checked'),
|
||||
assert.ok(form.$('.custom-checkbox input').eq(0).prop('checked'),
|
||||
"first checkbox should be checked");
|
||||
assert.notOk(form.$('.o_checkbox input').eq(1).prop('checked'),
|
||||
assert.notOk(form.$('.custom-checkbox input').eq(1).prop('checked'),
|
||||
"second checkbox should not be checked");
|
||||
assert.notOk(form.$('.o_checkbox input').eq(2).prop('checked'),
|
||||
assert.notOk(form.$('.custom-checkbox input').eq(2).prop('checked'),
|
||||
"third checkbox should not be checked");
|
||||
|
||||
form.$buttons.find('.o_form_button_save').click();
|
||||
@@ -10745,23 +10745,23 @@ QUnit.module('relational_fields', {
|
||||
}
|
||||
});
|
||||
|
||||
assert.notOk(form.$('.o_checkbox input').eq(0).prop('checked'),
|
||||
assert.notOk(form.$('.custom-checkbox input').eq(0).prop('checked'),
|
||||
"first checkbox should not be checked");
|
||||
assert.notOk(form.$('.o_checkbox input').eq(1).prop('checked'),
|
||||
assert.notOk(form.$('.custom-checkbox input').eq(1).prop('checked'),
|
||||
"second checkbox should not be checked");
|
||||
assert.ok(form.$('.o_checkbox input').eq(2).prop('checked'),
|
||||
assert.ok(form.$('.custom-checkbox input').eq(2).prop('checked'),
|
||||
"third checkbox should be checked");
|
||||
|
||||
form.$('.o_checkbox input:checked').click(); // Uncheck default record
|
||||
form.$('.o_checkbox input').first().click(); // Check first record
|
||||
form.$('.o_checkbox input').first().click(); // Uncheck first record
|
||||
form.$('.o_checkbox input').first().click(); // Recheck first record
|
||||
form.$('.custom-checkbox input:checked').click(); // Uncheck default record
|
||||
form.$('.custom-checkbox input').first().click(); // Check first record
|
||||
form.$('.custom-checkbox input').first().click(); // Uncheck first record
|
||||
form.$('.custom-checkbox input').first().click(); // Recheck first record
|
||||
|
||||
assert.ok(form.$('.o_checkbox input').eq(0).prop('checked'),
|
||||
assert.ok(form.$('.custom-checkbox input').eq(0).prop('checked'),
|
||||
"first checkbox should be checked");
|
||||
assert.notOk(form.$('.o_checkbox input').eq(1).prop('checked'),
|
||||
assert.notOk(form.$('.custom-checkbox input').eq(1).prop('checked'),
|
||||
"second checkbox should not be checked");
|
||||
assert.notOk(form.$('.o_checkbox input').eq(2).prop('checked'),
|
||||
assert.notOk(form.$('.custom-checkbox input').eq(2).prop('checked'),
|
||||
"third checkbox should not be checked");
|
||||
|
||||
form.$buttons.find('.o_form_button_save').click();
|
||||
@@ -11649,10 +11649,10 @@ QUnit.module('relational_fields', {
|
||||
// checkbox 'Hide in Kanban'
|
||||
$input = form.$('.o_field_many2manytags button[data-id=13]'); // selects 'red' tag
|
||||
$input.click(); // opens the colorpicker dropdown
|
||||
assert.ok(form.$('.o_field_many2manytags button[data-id=13] .o_colorpicker .o_checkbox'), "should have a checkbox in the colorpicker dropdown menu");
|
||||
assert.ok(form.$('.o_field_many2manytags button[data-id=13] .o_colorpicker .custom-checkbox'), "should have a checkbox in the colorpicker dropdown menu");
|
||||
|
||||
$input.click();
|
||||
var $checkBox = form.$('.o_field_many2manytags button[data-id=13] .o_colorpicker .o_checkbox input');
|
||||
var $checkBox = form.$('.o_field_many2manytags button[data-id=13] .o_colorpicker .custom-checkbox input');
|
||||
assert.notOk($checkBox.is(':checked'), "should have unticked checkbox in colorpicker dropdown menu");
|
||||
|
||||
$checkBox.mousedown();
|
||||
@@ -11660,7 +11660,7 @@ QUnit.module('relational_fields', {
|
||||
assert.equal($input.data('color'), "0", "should become transparent when toggling on checkbox");
|
||||
|
||||
$input.click();
|
||||
$checkBox = form.$('.o_field_many2manytags button[data-id=13] .o_colorpicker .o_checkbox input'); // refresh
|
||||
$checkBox = form.$('.o_field_many2manytags button[data-id=13] .o_colorpicker .custom-checkbox input'); // refresh
|
||||
assert.ok($checkBox.is(':checked'), "should have a ticked checkbox in colorpicker dropdown menu after mousedown");
|
||||
|
||||
$checkBox.mousedown();
|
||||
@@ -11668,7 +11668,7 @@ QUnit.module('relational_fields', {
|
||||
assert.equal($input.data('color'), "8", "should revert to old color when toggling off checkbox");
|
||||
|
||||
$input.click();
|
||||
$checkBox = form.$('.o_field_many2manytags button[data-id=13] .o_colorpicker .o_checkbox input'); // refresh
|
||||
$checkBox = form.$('.o_field_many2manytags button[data-id=13] .o_colorpicker .custom-checkbox input'); // refresh
|
||||
assert.notOk($checkBox.is(':checked'), "should have an unticked checkbox in colorpicker dropdown menu after 2nd click");
|
||||
|
||||
// TODO: it would be nice to test the behaviors of the autocomplete dropdown
|
||||
@@ -12285,24 +12285,24 @@ QUnit.module('relational_fields', {
|
||||
res_id: 1,
|
||||
});
|
||||
|
||||
assert.strictEqual(form.$('div.o_field_widget div.o_checkbox').length, 2,
|
||||
assert.strictEqual(form.$('div.o_field_widget div.custom-checkbox').length, 2,
|
||||
"should have fetched and displayed the 2 values of the many2many");
|
||||
|
||||
assert.ok(form.$('div.o_field_widget div.o_checkbox input').eq(0).prop('checked'),
|
||||
assert.ok(form.$('div.o_field_widget div.custom-checkbox input').eq(0).prop('checked'),
|
||||
"first checkbox should be checked");
|
||||
assert.notOk(form.$('div.o_field_widget div.o_checkbox input').eq(1).prop('checked'),
|
||||
assert.notOk(form.$('div.o_field_widget div.custom-checkbox input').eq(1).prop('checked'),
|
||||
"second checkbox should not be checked");
|
||||
|
||||
assert.ok(form.$('div.o_field_widget div.o_checkbox input').prop('disabled'),
|
||||
assert.ok(form.$('div.o_field_widget div.custom-checkbox input').prop('disabled'),
|
||||
"the checkboxes should be disabled");
|
||||
|
||||
form.$buttons.find('.o_form_button_edit').click();
|
||||
|
||||
assert.notOk(form.$('div.o_field_widget div.o_checkbox input').prop('disabled'),
|
||||
assert.notOk(form.$('div.o_field_widget div.custom-checkbox input').prop('disabled'),
|
||||
"the checkboxes should not be disabled");
|
||||
|
||||
// add a m2m value by clicking on input
|
||||
form.$('div.o_field_widget div.o_checkbox input').eq(1).click();
|
||||
form.$('div.o_field_widget div.custom-checkbox input').eq(1).click();
|
||||
form.$buttons.find('.o_form_button_save').click();
|
||||
assert.deepEqual(this.data.partner.records[0].timmy, [12, 14],
|
||||
"should have added the second element to the many2many");
|
||||
@@ -12311,13 +12311,13 @@ QUnit.module('relational_fields', {
|
||||
|
||||
// remove a m2m value by clinking on label
|
||||
form.$buttons.find('.o_form_button_edit').click();
|
||||
form.$('div.o_field_widget div.o_checkbox + label').eq(0).click();
|
||||
form.$('div.o_field_widget div.custom-checkbox > label').eq(0).click();
|
||||
form.$buttons.find('.o_form_button_save').click();
|
||||
assert.deepEqual(this.data.partner.records[0].timmy, [14],
|
||||
"should have removed the first element to the many2many");
|
||||
assert.notOk(form.$('div.o_field_widget div.o_checkbox input').eq(0).prop('checked'),
|
||||
assert.notOk(form.$('div.o_field_widget div.custom-checkbox input').eq(0).prop('checked'),
|
||||
"first checkbox should be checked");
|
||||
assert.ok(form.$('div.o_field_widget div.o_checkbox input').eq(1).prop('checked'),
|
||||
assert.ok(form.$('div.o_field_widget div.custom-checkbox input').eq(1).prop('checked'),
|
||||
"second checkbox should not be checked");
|
||||
|
||||
form.destroy();
|
||||
@@ -12338,12 +12338,12 @@ QUnit.module('relational_fields', {
|
||||
viewOptions: {mode: 'edit'},
|
||||
});
|
||||
|
||||
form.$('div.o_field_widget div.o_checkbox input').eq(0).click();
|
||||
form.$('div.o_field_widget div.o_checkbox input').eq(1).click();
|
||||
form.$('div.o_field_widget div.custom-checkbox input').eq(0).click();
|
||||
form.$('div.o_field_widget div.custom-checkbox input').eq(1).click();
|
||||
form.$buttons.find('.o_form_button_save').click();
|
||||
assert.notOk(form.$('div.o_field_widget div.o_checkbox input').eq(0).prop('checked'),
|
||||
assert.notOk(form.$('div.o_field_widget div.custom-checkbox input').eq(0).prop('checked'),
|
||||
"first checkbox should not be checked");
|
||||
assert.notOk(form.$('div.o_field_widget div.o_checkbox input').eq(1).prop('checked'),
|
||||
assert.notOk(form.$('div.o_field_widget div.custom-checkbox input').eq(1).prop('checked'),
|
||||
"second checkbox should not be checked");
|
||||
|
||||
form.destroy();
|
||||
|
||||
@@ -193,7 +193,7 @@ QUnit.module('Views', {
|
||||
|
||||
// filters which has no value should show with string "Undefined" and should show at the last
|
||||
assert.strictEqual($typeFilter.find('.o_calendar_filter_item:last').data('value'), false, "filters having false value should be displayed at last in filter items");
|
||||
assert.strictEqual($typeFilter.find('.o_calendar_filter_item:last > span').text(), "Undefined", "filters having false value should display 'Undefined' string");
|
||||
assert.strictEqual($typeFilter.find('.o_calendar_filter_item:last span').text(), "Undefined", "filters having false value should display 'Undefined' string");
|
||||
|
||||
var $attendeesFilter = $sidebar.find('.o_calendar_filter:has(h3:contains(attendees))');
|
||||
assert.ok($attendeesFilter.length, "should display 'attendees' filter");
|
||||
@@ -202,9 +202,9 @@ QUnit.module('Views', {
|
||||
|
||||
assert.strictEqual(calendar.$('.fc-event').length, 7,
|
||||
"should display 7 events ('event 5' counts for 2 because it spans two weeks and thus generate two fc-event elements)");
|
||||
calendar.$('.o_calendar_filter .o_checkbox input').first().click(); // Disable first filter
|
||||
calendar.$('.o_calendar_filter .custom-checkbox input').first().click(); // Disable first filter
|
||||
assert.strictEqual(calendar.$('.fc-event').length, 4, "should now only display 4 event");
|
||||
calendar.$('.o_calendar_filter .o_checkbox input').eq(1).click(); // Disable second filter
|
||||
calendar.$('.o_calendar_filter .custom-checkbox input').eq(1).click(); // Disable second filter
|
||||
assert.strictEqual(calendar.$('.fc-event').length, 0, "should not display any event anymore");
|
||||
|
||||
// test search bar in filter
|
||||
|
||||
@@ -165,7 +165,7 @@ QUnit.module('Views', {
|
||||
assert.strictEqual(form.$('div.o_field_one2many table').length, 1,
|
||||
"should render a one2many relation");
|
||||
|
||||
assert.strictEqual(form.$('tbody td:not(.o_list_record_selector) .o_checkbox input:checked').length, 1,
|
||||
assert.strictEqual(form.$('tbody td:not(.o_list_record_selector) .custom-checkbox input:checked').length, 1,
|
||||
"1 checkboxes should be checked");
|
||||
|
||||
assert.strictEqual(form.get('title'), "second record",
|
||||
@@ -2102,10 +2102,10 @@ QUnit.module('Views', {
|
||||
res_id: 1,
|
||||
});
|
||||
|
||||
assert.strictEqual(form.$("label").length, 2, "should have rendered only two label");
|
||||
assert.strictEqual(form.$("label").first().text(), "Product",
|
||||
assert.strictEqual(form.$("label.o_form_label").length, 2, "should have rendered only two label");
|
||||
assert.strictEqual(form.$("label.o_form_label").first().text(), "Product",
|
||||
"one should be the one for the product field");
|
||||
assert.strictEqual(form.$("label").eq(1).text(), "Bar",
|
||||
assert.strictEqual(form.$("label.o_form_label").eq(1).text(), "Bar",
|
||||
"one should be the one for the bar field");
|
||||
|
||||
assert.strictEqual(form.$('.firstgroup td').first().attr('colspan'), undefined,
|
||||
@@ -4265,9 +4265,9 @@ QUnit.module('Views', {
|
||||
|
||||
assert.strictEqual(form.$('.oe_button_box').children().length, 2,
|
||||
"button box should contain two children");
|
||||
assert.strictEqual(form.$('.oe_button_box .oe_stat_button').length, 1,
|
||||
assert.strictEqual(form.$('.oe_button_box > .oe_stat_button').length, 1,
|
||||
"button box should only contain one button");
|
||||
assert.strictEqual(form.$('.oe_button_box label').length, 1,
|
||||
assert.strictEqual(form.$('.oe_button_box > label').length, 1,
|
||||
"button box should only contain one label");
|
||||
|
||||
form.destroy();
|
||||
@@ -6547,7 +6547,7 @@ QUnit.module('Views', {
|
||||
'</form>',
|
||||
});
|
||||
|
||||
assert.strictEqual(form.$el.text(), '{"foo":"My little Foo Value","bar":false}',
|
||||
assert.strictEqual(form.$('.o_widget').text(), '{"foo":"My little Foo Value","bar":false}',
|
||||
"widget should have been instantiated");
|
||||
|
||||
form.destroy();
|
||||
|
||||
@@ -3235,7 +3235,7 @@ QUnit.module('Views', {
|
||||
});
|
||||
|
||||
assert.verifySteps(['bar', 'res_currency'], "should have done 1 name_get by model in reference values");
|
||||
assert.strictEqual(list.$('tbody td').text(), "Value 1USDEUREUR",
|
||||
assert.strictEqual(list.$('tbody td:not(.o_list_record_selector)').text(), "Value 1USDEUREUR",
|
||||
"should have the display_name of the reference");
|
||||
list.destroy();
|
||||
});
|
||||
|
||||
@@ -1254,7 +1254,7 @@ body.editor_enable {
|
||||
align-items: center;
|
||||
font-size: 11px;
|
||||
|
||||
> .o_checkbox {
|
||||
> .custom-control {
|
||||
margin-right: $grid-gutter-width/4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,16 +14,22 @@
|
||||
<select id="ace-view-list" class="o_res_list"/>
|
||||
<select id="ace-scss-list" class="o_res_list d-none"/>
|
||||
<label class="o_include_option oe_include_bundles">
|
||||
<div class="o_checkbox">
|
||||
<input type="checkbox" class="js_include_bundles" t-att-checked="widget.options.includeBundles ? 'checked' : undefined"/><span/>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" id="o_ace_view_editor_include_bundle"
|
||||
class="custom-control-input js_include_bundles"
|
||||
t-att-checked="widget.options.includeBundles ? 'checked' : undefined"/>
|
||||
<label for="o_ace_view_editor_include_bundle"
|
||||
class="custom-control-label">Include Asset Bundles</label>
|
||||
</div>
|
||||
Include Asset Bundles
|
||||
</label>
|
||||
<label class="o_include_option o_include_all_scss d-none">
|
||||
<div class="o_checkbox">
|
||||
<input type="checkbox" class="js_include_all_scss" t-att-checked="widget.options.includeAllSCSS ? 'checked' : undefined"/><span/>
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" id="o_ace_view_editor_include_all_scss"
|
||||
class="custom-control-input js_include_all_scss"
|
||||
t-att-checked="widget.options.includeAllSCSS ? 'checked' : undefined"/>
|
||||
<label for="o_ace_view_editor_include_all_scss"
|
||||
class="custom-control-label">Include All SCSS Files</label>
|
||||
</div>
|
||||
Include All SCSS Files
|
||||
</label>
|
||||
<div class="o_button_section">
|
||||
<button data-action="save" type="submit" class="btn btn-primary">Save</button>
|
||||
|
||||
@@ -45,15 +45,15 @@ tour.register('main_flow_tour', {
|
||||
content: _t('Go to inventory tab'),
|
||||
position: 'top',
|
||||
}, {
|
||||
trigger: '.o_field_widget[name=route_ids] .o_checkbox + label:contains("Manufacture")',
|
||||
trigger: '.o_field_widget[name=route_ids] .custom-checkbox > label:contains("Manufacture")',
|
||||
content: _t('Check Manufacture'),
|
||||
position: 'right',
|
||||
}, {
|
||||
trigger: '.o_field_widget[name=route_ids] .o_checkbox + label:contains("Buy")',
|
||||
trigger: '.o_field_widget[name=route_ids] .custom-checkbox > label:contains("Buy")',
|
||||
content: _t('Uncheck Buy'),
|
||||
position: 'right',
|
||||
}, {
|
||||
trigger: '.o_field_widget[name=route_ids] .o_checkbox + label:contains("Make To Order")',
|
||||
trigger: '.o_field_widget[name=route_ids] .custom-checkbox > label:contains("Make To Order")',
|
||||
content: _t('Uncheck Make To Order'),
|
||||
position: 'right',
|
||||
}, {
|
||||
@@ -109,7 +109,7 @@ tour.register('main_flow_tour', {
|
||||
content: _t('Go to inventory tab'),
|
||||
position: 'top',
|
||||
}, {
|
||||
trigger: '.o_field_widget[name=route_ids] .o_checkbox + label:contains("Make To Order")',
|
||||
trigger: '.o_field_widget[name=route_ids] .custom-checkbox > label:contains("Make To Order")',
|
||||
content: _t('Check Make To Order'),
|
||||
position: 'right',
|
||||
}, {
|
||||
|
||||
Reference in New Issue
Block a user