Star Rating Widget

Hi team,

May I know how could we simulate the rating widget system, let say 1 - 5 star with the existing webix component?

Comments

  • @integral It is perfect...

  • 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
    
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!