1

I have created a slider component with jQuery. now I want to implement it as a plugin so I can use it on multiple projects.

but I have problems when I have multiple instances of the slider in my HTML form. how can I detect which slider instance the user is working with?

I have read these but couldn't find out what to do:

https://learn.jquery.com/plugins/basic-plugin-creation/

https://learn.jquery.com/plugins/advanced-plugin-concepts/

HTML:

<body>
    <div id="myslider" style="position: absolute; top:20px; left:20px;"></div>
    <div id="myslider2" style="position: absolute; top:200px; left:200px;"></div>
<script>
    $("#myslider").vslider();
    $("#myslider2").vslider();
</script>

CSS:

.slider_holder{
        height: 3px;
        width: 300px;
        position: absolute;
        float: left;
        left: 0px;
        top: 0px;
        background-color: #C2C2C2;
        border-radius: 3px;
}
.slider_holder span{
        height: 5px;
        position: absolute;
        width: 100%;
        top: -1px;
        background-color: #FF5A5F;
        left: 0px;
}
.slider_holder div{
        width: 16px;
        height: 16px;
        border-radius: 50%;
        border: solid 1px #333;
        background-color: #fff;
        position: absolute;
        top: -8px;
        cursor: pointer;
}
.slider_holder #fpoint{
        left: 0px;
}
.slider_holder_right_slider{
        right: 0px;
}

jQuery Plugin file:

(function( $ ){

$.fn.vslider = function() {

var el = "";
var timer_handle;
var currentMousePos = { x: -1, y: -1 };
var min_val = 50000;
var max_val = 1000000;
var from_val = 0;
var to_val = 0;
var container;

    container = "#" + this.prop("id");
    this.html('<div class="slider_holder">'+
                '<span></span>'+
                '<div id="fpoint" ondragstart="return false;" title="" data-value=""></div>'+
                '<div id="tpoint" ondragstart="return false;" title="" data-value="" class="slider_holder_right_slider"></div>'+
                '</div>');

$(".slider_holder div").on( "mousedown", function( event ) {
    el = $(this).prop("id");
    timer_handle = setInterval(function(){slider_timer();}, 50);
});

$( document ).on( "mouseup", function( event ) {
    el = "";
    clearInterval(timer_handle);
});


$( document ).on( "mousemove", function( event ) {
  currentMousePos.x = event.pageX;
  currentMousePos.y = event.pageY;
});



function slider_timer() {
    if (el != ""){

        $("#" + el).css("left", currentMousePos.x - $(".slider_holder").offset().left - 10 + "px");

        if ($("#fpoint").position().left + $("#fpoint").width() > $("#tpoint").position().left){
            if (el == "fpoint")
                $("#fpoint").css("left", $("#tpoint").position().left - $("#tpoint").width() - 2 + "px"); else
                $("#tpoint").css("left", $("#fpoint").position().left + $("#fpoint").width() + 2 + "px");               
        }


        if ($("#" + el).position().left < 0) $("#" + el).css("left", "0px");

        if ($("#" + el).position().left + $("#" + el).width() > $(".slider_holder").width()) 
            $("#" + el).css("left", $(".slider_holder").width() - $("#" + el).width() + "px");
console.log(container);
        $(container + " .slider_holder span").css("visibility", "visible");
        $(container + " .slider_holder span").css("left", $("#fpoint").position().left + "px");
        $(container + " .slider_holder span").css("width", $("#tpoint").position().left - $("#fpoint").position().left + "px");         


        from_val = parseInt((($("#fpoint").position().left / $(".slider_holder").width()) * max_val) + min_val);
        to_val = parseInt(((($("#tpoint").position().left + $("#tpoint").width()) / $(".slider_holder").width()) * max_val) + min_val);
        if (to_val > max_val) to_val = max_val;
        if (from_val < min_val) from_val = min_val;

        console.log(from_val + ', ' + to_val);

        //$("#fpoint").prop("title", from_val);
        //$("#tpoint").prop("title", to_val);

    }

}   


  return this;
   }; 


})( jQuery );
2
  • The plugin should be bound to the element. You should access/build it contextually. The problem is your using selectors in your plugin, not stored varibales to contain the bound element. You should use a boilerplate to structure your plugin and then access the bound element using $element, etc. Commented May 28, 2015 at 9:25
  • @Liam thanks for your solution. it was great. I managed to create the plug-in. please submit your comment as an answer and I would accept it as the "best answer". Commented May 28, 2015 at 22:19

1 Answer 1

1

how can I detect which slider instance the user is working with?

Plugin's should be contextual. By this I mean they are aware of what element they are bound to and work on them. Your issue above is that your accessing the element via selectors still (as if it wasn't a plugin):

$(".slider_holder div")

This then turns your plugin into a common or garden jquery function.

You need to change your plugin to ustilise the bound element. The best way to do this is to write your plugin using boilerplate code (like this one or this one).

This should structure your plugin something like:

// jQuery Plugin Boilerplate
// A boilerplate for jumpstarting jQuery plugins development
// version 1.1, May 14th, 2011
// by Stefan Gabos

// remember to change every instance of "pluginName" to the name of your plugin!
(function($) {

    // here we go!
    $.pluginName = function(element, options) {

        // plugin's default options
        // this is private property and is  accessible only from inside the plugin
        var defaults = {

            foo: 'bar',

            // if your plugin is event-driven, you may provide callback capabilities
            // for its events. execute these functions before or after events of your 
            // plugin, so that users may customize those particular events without 
            // changing the plugin's code
            onFoo: function() {}

        }

        // to avoid confusions, use "plugin" to reference the 
        // current instance of the object
        var plugin = this;

        // this will hold the merged default, and user-provided options
        // plugin's properties will be available through this object like:
        // plugin.settings.propertyName from inside the plugin or
        // element.data('pluginName').settings.propertyName from outside the plugin, 
        // where "element" is the element the plugin is attached to;
        plugin.settings = {}

        var $element = $(element), // reference to the jQuery version of DOM element
             element = element;    // reference to the actual DOM element

        // the "constructor" method that gets called when the object is created
        plugin.init = function() {

            // the plugin's final properties are the merged default and 
            // user-provided options (if any)
            plugin.settings = $.extend({}, defaults, options);

            // code goes here

        }

        // public methods
        // these methods can be called like:
        // plugin.methodName(arg1, arg2, ... argn) from inside the plugin or
        // element.data('pluginName').publicMethod(arg1, arg2, ... argn) from outside 
        // the plugin, where "element" is the element the plugin is attached to;

        // a public method. for demonstration purposes only - remove it!
        plugin.foo_public_method = function() {

            // code goes here

        }

        // private methods
        // these methods can be called only from inside the plugin like:
        // methodName(arg1, arg2, ... argn)

        // a private method. for demonstration purposes only - remove it!
        var foo_private_method = function() {

            // code goes here

        }

        // fire up the plugin!
        // call the "constructor" method
        plugin.init();

    }

    // add the plugin to the jQuery.fn object
    $.fn.pluginName = function(options) {

        // iterate through the DOM elements we are attaching the plugin to
        return this.each(function() {

            // if plugin has not already been attached to the element
            if (undefined == $(this).data('pluginName')) {

                // create a new instance of the plugin
                // pass the DOM element and the user-provided options as arguments
                var plugin = new $.pluginName(this, options);

                // in the jQuery version of the element
                // store a reference to the plugin object
                // you can later access the plugin and its methods and properties like
                // element.data('pluginName').publicMethod(arg1, arg2, ... argn) or
                // element.data('pluginName').settings.propertyName
                $(this).data('pluginName', plugin);

            }

        });

    }

})(jQuery);

Source

You should now (depending on which boilerplate your using) have a piece of code like:

var $element = $(element), // reference to the jQuery version of DOM element
    element = element;    // reference to the actual DOM element

So now you know which element your plugin is bound to, it's $element!

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.