Hi team,
May I know how could we simulate the rating widget system, let say 1 - 5 star with the existing webix component?
Hi team,
May I know how could we simulate the rating widget system, let say 1 - 5 star with the existing webix component?
I expanded on it to add editor support:
rating widget:
export function renderRating(value: number, readOnly: boolean = false, height: number = 20, id?: number, scale: number = 5) {
id = id || webix.uid()
let div = '<input type="hidden" id="' + id + '" value="' + value + '" />'
if (!readOnly) {
div += '<span class="webix_icon webix_rating_zero mdi mdi-close" data-value="0"></span>'
}
for (let i = 0; i < scale; i++) {
div += '<span class="webix_icon webix_rating_point mdi mdi-star'
if (value > i) {
div += ' webix_rating_selected'
}
div += '" style="line-height:' + height + 'px;"'
div += ' data-value="' + (i + 1) + '"></span>'
}
return div
}
webix.protoUI({
name: 'rating',
$cssName: 'text',
$init: function () {
this.on_click.webix_rating_point = function (e, id, target) {
if (!this.config.readonly) {
this.setValue(target.getAttribute('data-value'))
}
}
this.on_click.webix_rating_zero = function (e, id, target) {
if (!this.config.readonly) {
this.setValue(target.getAttribute('data-value'))
}
}
},
$renderInput: function (config, div, id: number) {
const value = parseInt(config.value || 0)
div = renderRating(value, config.readonly as boolean, config.cheight as number, id)
return webix.ui.text.prototype.$renderInput.apply(this, [config, div, id] as any)
},
$renderIcon: function () {
return ''
},
$setValue: function () {
this.refresh()
},
$getValue: function () {
return this.config.value || 0
}
}, webix.ui.text)
editor:
webix.editors.rating = {
focus: function () { },
onRatingClick(el: HTMLElement) {
const val: number = parseInt(el.dataset.value as string)
this.setValue(val)
},
getValue: function () {
return this.getInputNode(this.node).value
},
setValue: function (value) {
this.getInputNode(this.node).value = value
this.node.innerHTML = renderRating(value)
const stars = this.node.querySelectorAll('.webix_rating_point') as HTMLElement[]
stars.forEach(el => {
el.addEventListener('click', () => this.onRatingClick(el))
})
const zero = this.node.querySelector('.webix_rating_zero') as HTMLElement
zero.addEventListener('click', () => this.onRatingClick(zero))
},
getInputNode: function () {
return this.node.firstChild
},
render: function (value: number = 0): HTMLElement {
return webix.html.create('div',
{
class: 'webix_dt_editor rating'
},
renderRating(value)
)
}
}
scss:
.webix_rating_zero {
display: none;
position: relative;
top: 1px;
color: $grey !important;
cursor: pointer;
&:hover {
color: $font-color !important;
}
}
.webix_dt_editor.rating {
.webix_rating_zero {
display: initial;
}
.webix_icon.webix_rating_point {
cursor: pointer;
color: $grey !important;
&:hover {
color: $gold !important;
}
&.webix_rating_selected {
color: $gold !important;
&:hover {
color: darken($gold, 10%) !important;
}
}
}
}
.webix_dt_editor.rating {
padding-left: 12px;
}
.webix_icon.webix_rating_point {
color: transparent !important;
&.webix_rating_selected {
color: $gold !important;
}
}
column editor usage:
column.editor = 'rating'
column.template = renderRating(3) // Initial value