|
/** |
|
* Responsável por converter um select para lista de botões. |
|
* Mantém o select intacto e oculto, alterando seu valor selecionado à cada click nos botões. |
|
*/ |
|
export default class SelectButtons { |
|
constructor($select) { |
|
if (! this.initializeElements($select)) { |
|
return; |
|
} |
|
this.selectHiddenClass = 'd-none'; |
|
this.textsToReplace = { |
|
'from': 'to', |
|
}; |
|
this.buildButtonsBySelectOptions(); |
|
this.addButtonClickSelectEvent(); |
|
this.markFirstButton(); |
|
} |
|
|
|
/** |
|
* Inicializa propriedades relacionadas aos elementos jQuery do componente. |
|
* Recebe elemento jQuery do elemento à ser convertido para botões. |
|
* @param JQuery $select |
|
*/ |
|
initializeElements($select) { |
|
if (! $select.length) { |
|
return false; |
|
} |
|
this.elements = { |
|
$select: $select, |
|
$selectOptions: $select.find('option').not(':eq(0)'), |
|
}; |
|
this.selectId = $select.attr('id'); |
|
this.buttonsSelector = `.button-select[data-id="${this.selectId}"]`; |
|
return true; |
|
} |
|
|
|
/** |
|
* Constrói os botões com base nos selects, ignora |
|
* a primeira option por ser o valor default sem valor. |
|
* @see initializeElements |
|
*/ |
|
buildButtonsBySelectOptions() { |
|
const buttonsToRender = []; |
|
this.elements.$selectOptions.each((_, option) => { |
|
const $option = $(option), |
|
buttonLabel = this.replaceTexts($option.text()), |
|
buttonHTML = |
|
`<button class="button-select btn btn-pill" data-id="${this.selectId}" data-value="${$option.val()}"> |
|
${buttonLabel} |
|
</button>`; |
|
buttonsToRender.push(buttonHTML); |
|
}); |
|
this.elements.$select.after(`<div class="button-select-wrapper">${buttonsToRender.join('')}</div>`); |
|
this.elements.$select.addClass(this.selectHiddenClass); |
|
} |
|
|
|
/** |
|
* Adiciona o evento de click aos botões gerados, troca |
|
* option selecionado no select e as cores dos botões. |
|
*/ |
|
addButtonClickSelectEvent() { |
|
$(document).on('click', this.buttonsSelector, event => { |
|
event.preventDefault(); |
|
const $buttonClicked = $(event.currentTarget), |
|
value = $buttonClicked.data('value'), |
|
$optionToSelect = $(`#${this.selectId} [value="${value}"]`); |
|
this.markOptionItem($optionToSelect, $buttonClicked); |
|
}); |
|
} |
|
|
|
/** |
|
* Marca o primeiro botão do grupo. |
|
*/ |
|
markFirstButton() { |
|
const $buttonToMark = $(`${this.buttonsSelector}:eq(0)`); |
|
$buttonToMark.trigger('click'); |
|
} |
|
|
|
/** |
|
* Marca um botão específico do grupo. |
|
* @param JQuery $optionToSelect Opção do select à ser marcada |
|
* @param JQuery $buttonToMark Botão mo grupo à ser marcado. |
|
*/ |
|
markOptionItem($optionToSelect, $buttonToMark) { |
|
if (! $optionToSelect.length) { |
|
return; |
|
} |
|
this.elements.$selectOptions.removeAttr('selected'); |
|
$optionToSelect.attr('selected', 'selected'); |
|
$optionToSelect.trigger('change'); |
|
const $allButtons = $(this.buttonsSelector); |
|
if (! $allButtons.length) { |
|
return; |
|
} |
|
$allButtons.removeClass('active'); |
|
$buttonToMark.addClass('active'); |
|
} |
|
|
|
/** |
|
* Texto à substituir usando chaves e valores da propriedade 'textsToReplace'. |
|
* @param strong textToChange |
|
* @see constructor |
|
*/ |
|
replaceTexts(textToChange) { |
|
let changedText = textToChange; |
|
for (let textFrom in this.textsToReplace) { |
|
const textTo = this.textsToReplace[textFrom]; |
|
changedText = changedText.replace(textFrom, textTo); |
|
} |
|
return changedText; |
|
} |
|
} |