1
0
mirror of https://github.com/keeweb/keeweb.git synced 2024-06-26 07:39:04 +02:00
keeweb/app/scripts/views/dropdown-view.js

122 lines
3.6 KiB
JavaScript
Raw Normal View History

2019-09-16 22:57:56 +02:00
import { Events } from 'framework/events';
2019-09-16 20:42:33 +02:00
import { View } from 'framework/views/view';
2019-09-15 14:16:32 +02:00
import { Keys } from 'const/keys';
2019-09-16 07:06:55 +02:00
import template from 'templates/dropdown.hbs';
2015-10-17 23:49:24 +02:00
2019-09-16 07:06:55 +02:00
class DropdownView extends View {
parent = 'body';
2019-10-12 08:20:44 +02:00
modal = 'dropdown';
2015-10-17 23:49:24 +02:00
2019-09-16 07:06:55 +02:00
template = template;
events = {
2015-10-17 23:49:24 +02:00
'click .dropdown__item': 'itemClick'
2019-09-16 07:06:55 +02:00
};
constructor(model) {
super(model);
2015-10-17 23:49:24 +02:00
2019-09-16 22:57:56 +02:00
Events.emit('dropdown-shown');
2015-10-17 23:49:24 +02:00
this.bodyClick = this.bodyClick.bind(this);
2019-09-12 19:59:35 +02:00
2019-09-16 22:57:56 +02:00
this.listenTo(Events, 'show-context-menu', this.bodyClick);
this.listenTo(Events, 'dropdown-shown', this.bodyClick);
2019-09-12 19:59:35 +02:00
$('body').on('click contextmenu keydown', this.bodyClick);
2019-09-16 07:06:55 +02:00
this.onKey(Keys.DOM_VK_UP, this.upPressed, false, 'dropdown');
this.onKey(Keys.DOM_VK_DOWN, this.downPressed, false, 'dropdown');
this.onKey(Keys.DOM_VK_RETURN, this.enterPressed, false, 'dropdown');
this.onKey(Keys.DOM_VK_ESCAPE, this.escPressed, false, 'dropdown');
2019-09-12 19:59:35 +02:00
2019-09-16 07:06:55 +02:00
this.once('remove', () => {
$('body').off('click contextmenu keydown', this.bodyClick);
});
2020-12-19 17:33:19 +01:00
this.selectedOption = model?.selectedOption;
2019-09-16 07:06:55 +02:00
}
2015-10-17 23:49:24 +02:00
2019-08-18 10:17:09 +02:00
render(config) {
2015-10-17 23:49:24 +02:00
this.options = config.options;
2019-09-16 07:06:55 +02:00
super.render(config);
2017-01-31 07:50:28 +01:00
const ownRect = this.$el[0].getBoundingClientRect();
const bodyRect = document.body.getBoundingClientRect();
2019-08-16 23:05:39 +02:00
let left = config.position.left || config.position.right - ownRect.right + ownRect.left;
2016-07-30 11:25:22 +02:00
let top = config.position.top;
if (left + ownRect.width > bodyRect.right) {
left = Math.max(0, bodyRect.right - ownRect.width);
}
if (top + ownRect.height > bodyRect.bottom) {
top = Math.max(0, bodyRect.bottom - ownRect.height);
}
2019-08-18 10:17:09 +02:00
this.$el.css({ top, left });
if (typeof this.selectedOption === 'number') {
this.renderSelectedOption();
}
2019-09-16 07:06:55 +02:00
}
2015-10-17 23:49:24 +02:00
2019-09-12 19:59:35 +02:00
bodyClick(e) {
if (
2019-09-16 07:06:55 +02:00
e &&
2019-09-12 19:59:35 +02:00
[Keys.DOM_VK_UP, Keys.DOM_VK_DOWN, Keys.DOM_VK_RETURN, Keys.DOM_VK_ESCAPE].includes(
e.which
)
) {
return;
}
2019-09-16 07:06:55 +02:00
if (!this.removed) {
this.emit('cancel');
2016-07-30 11:25:22 +02:00
}
2019-09-16 07:06:55 +02:00
}
2015-10-17 23:49:24 +02:00
2019-08-18 10:17:09 +02:00
itemClick(e) {
2015-10-17 23:49:24 +02:00
e.stopPropagation();
2017-01-31 07:50:28 +01:00
const el = $(e.target).closest('.dropdown__item');
const selected = el.data('value');
2019-09-16 07:06:55 +02:00
this.emit('select', { item: selected, el });
}
2019-09-12 19:59:35 +02:00
upPressed(e) {
e.preventDefault();
if (!this.selectedOption) {
this.selectedOption = this.options.length - 1;
} else {
this.selectedOption--;
}
this.renderSelectedOption();
2019-09-16 07:06:55 +02:00
}
2019-09-12 19:59:35 +02:00
downPressed(e) {
e.preventDefault();
if (this.selectedOption === undefined || this.selectedOption === this.options.length - 1) {
this.selectedOption = 0;
} else {
this.selectedOption++;
}
this.renderSelectedOption();
2019-09-16 07:06:55 +02:00
}
2019-09-12 19:59:35 +02:00
renderSelectedOption() {
this.$el.find('.dropdown__item').removeClass('dropdown__item--active');
this.$el
.find(`.dropdown__item:nth(${this.selectedOption})`)
.addClass('dropdown__item--active');
2019-09-16 07:06:55 +02:00
}
2019-09-12 19:59:35 +02:00
enterPressed() {
2019-09-16 07:06:55 +02:00
if (!this.removed && this.selectedOption !== undefined) {
2019-09-12 19:59:35 +02:00
const el = this.$el.find(`.dropdown__item:nth(${this.selectedOption})`);
const selected = el.data('value');
2019-09-16 07:06:55 +02:00
this.emit('select', { item: selected, el });
2019-09-12 19:59:35 +02:00
}
2019-09-16 07:06:55 +02:00
}
2019-09-12 19:59:35 +02:00
escPressed(e) {
e.stopImmediatePropagation();
2019-09-16 07:06:55 +02:00
if (!this.removed) {
this.emit('cancel');
2019-09-12 19:59:35 +02:00
}
2015-10-17 23:49:24 +02:00
}
2019-09-16 07:06:55 +02:00
}
2015-10-17 23:49:24 +02:00
2019-09-15 14:16:32 +02:00
export { DropdownView };