Skip to content
Snippets Groups Projects
Commit 769469e5 authored by Tomotaka Hosomi's avatar Tomotaka Hosomi Committed by Yas Naoi
Browse files

Issue #3401473 by hosomitm, yas: Refactor to native JavaScript from jQuery (openstack_form.js)

parent ac699d78
Branches
Tags
1 merge request!2117Issue #3401473: Refactor to native JavaScript from jQuery (openstack_form.js)
......@@ -60,6 +60,19 @@ select2:
theme:
https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/css/select2.min.css: { type: external, minified: true }
tom-select:
remote: https://github.com/orchidjs/tom-select
version: 2.3.1
license:
name: Apache License, Version 2.0
url: https://www.apache.org/licenses/LICENSE-2.0
gpl-compatible: false
js:
https://cdn.jsdelivr.net/npm/tom-select@2.3.1/dist/js/tom-select.complete.min.js: { type: external, minified: true }
css:
theme:
https://cdn.jsdelivr.net/npm/tom-select@2.3.1/dist/css/tom-select.css: { type: external, minified: true }
datatables:
remote: https://github.com/fiduswriter/Simple-DataTables
version: 3.1.2
......
.ts-control {
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
border: none;
}
.plugin-dropdown_input.focus.dropdown-active .ts-control {
border: none;
}
(function ($) {
(function () {
'use strict';
// Select2 custom results adapter.
$.fn.select2.amd.define('CustomResultsAdapter', [
'select2/utils',
'select2/results'
],
function (Utils, Results) {
function CustomResultsAdapter($element, options, dataAdapter) {
this.$element = $element;
this.data = dataAdapter;
this.options = options;
CustomResultsAdapter.__super__.constructor.call(this, $element, options, dataAdapter);
}
Utils.Extend(CustomResultsAdapter, Results);
CustomResultsAdapter.prototype.render = function () {
let $results = $(
'<tbody class="select2-results__options" role="tree"></tbody>'
);
if (this.options.get('multiple')) {
$results.attr('aria-multiselectable', 'true');
}
this.$results = $results;
return $results;
};
CustomResultsAdapter.prototype.option = function (data) {
let option = document.createElement('tr');
option.className = 'select2-results__option';
let attrs = {
'role': 'treeitem',
'aria-selected': 'false'
};
if (data.disabled) {
delete attrs['aria-selected'];
attrs['aria-disabled'] = 'true';
}
if (data.id === null) {
delete attrs['aria-selected'];
}
if (data._resultId !== null) {
option.id = data._resultId;
}
if (data.title) {
option.title = data.title;
}
if (data.children) {
attrs.role = 'group';
attrs['aria-label'] = data.text;
delete attrs['aria-selected'];
}
for (let attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
let val = attrs[attr];
option.setAttribute(attr, val);
}
}
this.template(data, option);
$.data(option, 'data', data);
return option;
};
return CustomResultsAdapter;
});
// Select2 custom dropdown adapter.
$.fn.select2.amd.define('CustomDropdownAdapter', [
'select2/utils',
'select2/dropdown',
'select2/dropdown/attachBody',
'select2/dropdown/attachContainer',
'select2/dropdown/search'
],
function (Utils, Dropdown, AttachBody, AttachContainer, Search) {
function CustomDropdownAdapter($element, options) {
this.$element = $element;
this.options = options;
CustomDropdownAdapter.__super__.constructor.call(this, $element, options);
// Resets the for attribute of Label rewritten by tom-select to its original value.
const resetLabel = function (label_for) {
const control_id = label_for + '-ts-control';
const query = "label[for='" + control_id + "']";
const label = document.querySelector(query);
if (label) {
label.setAttribute('for', label_for);
}
Utils.Extend(CustomDropdownAdapter, Dropdown);
CustomDropdownAdapter.prototype.render = function () {
let $dropdown = $(
'<div class="select2-dropdown"><table class="select2-results"><thead><tr><th>Name</th><th>vCPUs</th><th>RAM (MB)</th></tr></thead></table></div>'
);
$dropdown.attr('dir', this.options.get('dir'));
this.$dropdown = $dropdown;
return $dropdown;
};
let adapter = Utils.Decorate(CustomDropdownAdapter, Search);
adapter = Utils.Decorate(adapter, AttachContainer);
adapter = Utils.Decorate(adapter, AttachBody);
return adapter;
});
}
// Flavor.
$('#edit-field-flavor').select2({
width: '100%',
closeOnSelect: true,
dropdownAdapter: $.fn.select2.amd.require('CustomDropdownAdapter'),
resultsAdapter: $.fn.select2.amd.require('CustomResultsAdapter'),
templateResult: function (state) {
let parts = state.text.split(':').slice(0, 5);
let html = '<td>' + parts.join('</td><td>') + '</td>';
if (parts.length === 1) {
html = '<td colspan=5>' + parts[0] + '</td>';
}
let $state = $(html);
return $state;
},
templateSelection: (state) => {
if (!state.id) {
return state.text;
new TomSelect("#edit-field-flavor", {
create: false,
dropdownParent: 'body',
plugins: [
'dropdown_input',
'no_backspace_delete',
],
render: {
dropdown: function () {
return '<div><div style="font-weight: bold;">' +
'<span style="width: 50%; display: inline-block;">Name</span>' +
'<span style="width: 25%; display: inline-block;">vCPUs</span>' +
'<span style="width: 25%; display: inline-block;">RAM (MB)</span>' +
'</div></div>';
},
option: function (data, escape) {
const splitLabel = escape(data.text).split(':');
while (splitLabel.length < 3) {
splitLabel.push('');
}
return '<div>' +
'<span style="width: 50%; display: inline-block;">' + splitLabel[0] + '</span>' +
'<span style="width: 25%; display: inline-block;">' + splitLabel[1] + '</span>' +
'<span style="width: 25%; display: inline-block;">' + splitLabel[2] + '</span>' +
'</div>';
},
item: function (data, escape) {
const splitLabel = escape(data.text).split(':');
return '<div title="' + splitLabel[0] + '">' + splitLabel[0] + '</div>';
}
let $state = $(
'<span>' + state.text.split(':').shift() + '</span>'
);
return $state;
}
});
})(jQuery);
resetLabel("edit-field-flavor");
})();
......@@ -2,9 +2,11 @@ openstack_form:
version: 5.x-dev
js:
js/openstack_form.js: {}
css:
theme:
css/openstack_form.css: {}
dependencies:
- core/jquery
- cloud/select2
- cloud/tom-select
openstack_launch_template_radios:
version: 6.x-dev
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment