jQuery Widget Factory setting options TypeError

260 views Asked by At

I want to create a custom slider plugin in Widget Factory, but it doesn't work. Why can't I use either the .option() function, or the .setMyOptions() custom function I created. I get the TypeError: <function> is not a function error. What am I doing wrong? I know this is some simple syntax tweak and has to do with scopes, but I don't know what exactly is wrong.

    $.widget("custom.niceSlider", {

    options: { 
        value:0
    },

    myOptions: { 
        handleWidth:'30px' 
    },

    _create: function(){
        this.element.addClass("niceSlider");
        this._bar = $("<div class='bar' id='bar'></div>")
            .appendTo(this.element);
        this._handle = $("<div class='handle' id='handle'></div>")
            .appendTo(this._bar)
            .css("width", this.myOptions.handleWidth ); 
    },

    _destroy: function(){

    },

    _setOption: function( key, value ){

    },

    setMyOptions: function(key, value){
        switch(key){
            case 'handleWidth':
                this.myOptions.handleWidth = value;
                break;
        }
    }


});

$(document).ready(function(){
    var slider = $("#slider").niceSlider();
    slider.setMyOptions('handleWidth','50px');
});
1

There are 1 answers

0
Twisty On

You will have a fair amount of work ahead of you to build your own slider widget. I would advise looking at just extending $.ui.slider a bit.

To address your question, I would examine this code:

$(function() {
  $.widget("custom.niceSlider", {
    options: {
      value: 0,
      max: 100,
      min: 0,
      orientation: "horizontal"
    },
    myOptions: {
      handleWidth: '30px'
    },
    _create: function() {
      this.element.addClass("ui-niceSlider ui-niceSlider-horizontal ui-widget");
      var barCount = $(".bar").length;
      barCount++;

      this._bar = $("<div>", {
          class: 'ui-niceSlider-bar ui-corner-all ui-widget-content',
          id: 'ui-niceSlider-bar-' + barCount
        })
        .appendTo(this.element);
      this._handle = $("<div>", {
          class: 'ui-niceSlider-handle ui-corner-all ui-state-default',
          id: 'ui-niceSlider-handle-' + barCount,
          style: "left: 0;"
        })
        .appendTo(this._bar)
        .css("width", this.myOptions.handleWidth);
    },
    setMyOptions: function(key, value) {
      console.log("setMyOptions", key, value);
      switch (key) {
        case 'handleWidth':
          this.myOptions.handleWidth = value;
          this.element.find(".ui-niceSlider-handle").css("width", this.myOptions.handleWidth);
          break;
      }
    }
  });
  var slider = $("#slider").niceSlider();
  slider.niceSlider("setMyOptions", 'handleWidth', '50px');
});

Working Example: https://jsfiddle.net/Twisty/q6e7t3pn/2/

First, I noticed you had assigned IDs that would not be unique. This is fine for 1 slider, but not for more than 1. Other than that, there was nothing major wrong with the code. It was more about how you called it. There are three ways to do that:

var slider = $("#slider").niceSlider();
slider.niceSlider("setMyOptions", 'handleWidth', '50px');

Or:

var slider = $("#slider").niceSlider();
var niceSlider = $("#slider").data("niceSlider");
niceSlider.setMyOptions('handleWidth', '50px');

Or:

var slider = $("#slider").niceSlider();
$("#slider").niceSlider("instance").setMyOptions('handleWidth', '50px');

Plugin Invocation

To invoke a method using the widget's plugin, pass the name of the method as a string. ... If the method requires arguments, pass them as additional parameters to the plugin.

Instance Invocation

Under the hoods, every instance of every widget is stored on the element using jQuery.data(). To retrieve the instance object, call jQuery.data() using the widget's full name as the key. This is shown below.

...

In jQuery UI 1.11, the new instance() method will make this process even easier.

From: Widget Method Invocation


Update

You may want to consider a simplier solution:

$(function() {
  $.widget("custom.niceSlider", $.ui.slider, {
    setMyOptions: function(key, value) {
      console.log("setMyOptions", key, value);
      switch (key) {
        case 'handleWidth':
          this.options.handleWidth = value;
          this.element.find(".ui-slider-handle").css("width", this.options.handleWidth);
          break;
      }
    }
  });
  var slider = $("#slider").niceSlider();
  slider.niceSlider("setMyOptions", 'handleWidth', '50px');
});

Example: https://jsfiddle.net/Twisty/q6e7t3pn/4/