Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hover over ticks to view their value #638

Merged
merged 9 commits into from
Oct 21, 2016
Merged

Conversation

snurby7
Copy link
Contributor

@snurby7 snurby7 commented Oct 18, 2016

Pull Requests

Please accompany all pull requests with the following (where appropriate):

  • unit tests (we use Jasmine 1.3)
  • JSFiddle (Plunker link)
  • Link to original Github issue (Feature Request Feature Request: Show tooltip on tick mark hover #632 )
  • documentation updates to README file
  • examples within /tpl/index.tpl (for new options being added)
  • Passes CI-server checks (runs automated tests, JS source-code linting, etc..). To run these on your local machine, type grunt test in your Terminal within the bootstrap-slider repository directory

@@ -398,6 +398,21 @@ const windowIsDefined = (typeof window === "object");
}
}

function createTickMouseOverListener(reference, tick, index){
tick.addEventListener("mouseenter", function(){
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please fix this indentation

@seiyria
Copy link
Owner

seiyria commented Oct 18, 2016

high quality PR! very nice job. my only concern I saw at a glance was the indentation. @rovolution will have more comments I'm sure.

@snurby7
Copy link
Contributor Author

snurby7 commented Oct 18, 2016

thanks @seiyria!

Copy link
Collaborator

@rovolution rovolution left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@snurby7 looks great! I left some feedback in my PR so once that is addressed just tag me again.

@@ -398,6 +398,21 @@ const windowIsDefined = (typeof window === "object");
}
}

function createTickMouseOverListener(reference, tick, index){
tick.addEventListener("mouseenter", function(){
var tempState = $.extend(true, reference._state, {});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you write this without JQuery? One of this libraries requirements is that it should work in environments without JQuery

function createTickMouseOverListener(reference, tick, index){
tick.addEventListener("mouseenter", function(){
var tempState = $.extend(true, reference._state, {});
var idString = index >= 0 ? index : $(this).attr('aria-valuenow');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you write this without JQuery? One of this libraries requirements is that it should work in environments without JQuery


********************************/
_removeSliderEventHandlers: function() {
// Remove keydown event listeners
this.handle1.removeEventListener("keydown", this.handle1Keydown, false);
this.handle2.removeEventListener("keydown", this.handle2Keydown, false);

if(this.options.ticks_tooltip){
$('.slider-tick-container div').each(function(){
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you write this without JQuery? One of this libraries requirements is that it should work in environments without JQuery

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also add a comment above this section indicating that you are removing the hover event listeners from the ticks?

@snurby7
Copy link
Contributor Author

snurby7 commented Oct 18, 2016

@rovolution updated per your requests to remove the jQuery, sorry for all the commits.

Copy link
Collaborator

@rovolution rovolution left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@snurby7 left some further feedback


********************************/
_removeSliderEventHandlers: function() {
// Remove keydown event listeners
this.handle1.removeEventListener("keydown", this.handle1Keydown, false);
this.handle2.removeEventListener("keydown", this.handle2Keydown, false);

//rmove the listeners from the ticks if they had their own listeners
if(this.options.ticks_tooltip){
var ticks = document.getElementsByClassName('slider-tick-container')[0].children;
Copy link
Collaborator

@rovolution rovolution Oct 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will work fine if there is only 1 slider in the DOM, but what if multiple slider instances are in the DOM? could you refactor this so that it only selects the ticks within this slider instance's .slider-tick-container?

On line 481, we bind the element reference for the tick container to the this.ticksContainer instance variable.

Therefore, should be able to access the ticks for a specific slider instance like so:

var ticks = this.ticksContainer.getElementsByClassName(".slider-tick");

if(this.options.ticks_tooltip){
var ticks = document.getElementsByClassName('slider-tick-container')[0].children;
for(var i = 0; i < ticks.length; i++ ){
ticks[i].removeEventListener('mouseenter', this.createTickMouseOverListener, false);
Copy link
Collaborator

@rovolution rovolution Oct 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is not actually removing the mouseenter and mouseleave event listeners from the ticks.

Within the this._createTickMouseOverListener function, you are binding event listeners for the events. However, when removeEventListener is called, you need to pass in the specific function reference for the actual listener itself.

For example:

// Create a function reference
var myEventListener = function() { console.log("yolo"); };

// Create an event listener by binding a DOM event to the specific function reference
myElementReference.addEventListener("mouseenter", myEventListener);

// This line properly removes the listener because myEventListener refers to the same function reference in memory that was originally bound in the line above
myElementReference. removeEventListener("mouseenter", myEventListener, false);

Copy link
Collaborator

@rovolution rovolution Oct 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is what is currently happening:

// This method is acting similar to your createTickMouseOverListener
function bindListener(element) {
    element.addEventListener("mouseenter", function() {
          console.log("yolo");
    });
}

// call your function
bindListener(myElementReference);

/*
   This will not actually remove the listener bound in the bindListener() function because the 
   function references for `bindListener()` and `function() { console.log("yolo"); }` are different

You need to find a way to pass the memory reference  for the `function() { console.log("yolo"); }` function to the removeEventListener() call
*/
myElementReference.removeEventListener("mouseenter", bindListener, false);

Copy link
Collaborator

@rovolution rovolution Oct 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@snurby7
Copy link
Contributor Author

snurby7 commented Oct 19, 2016

@rovolution, fixed up to your comments, that was a fun experience!

Copy link
Collaborator

@rovolution rovolution left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@snurby7 Added some more feedback.

  1. In the _destroy() method, you will need to nullify the this.ticksCallbackMap and this.handleCallbackMap so that the objects they reference are marked for garbage collection.
this.ticksCallbackMap = null;
this.handleCallbackMap = null;
  1. Could you also fix the spacing issues as well? Thanks!

var tickListenerReference = this._addTickListener();
var enterCallback = tickListenerReference.addMouseEnter(this, tick, i);
var leaveCallback = tickListenerReference.addMouseLeave(this, tick);
if(i === 0){
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you need to actually map each tick index to an object that contains the function references for its callbacks:

Currently, you are just overwriting the this.ticksCallbackMap variable on each iteration of the loop

Try something like the following:

// Generate event listeners for tick
var tickListenerReference = this._addTickListener();
var enterCallback = tickListenerReference.addMouseEnter(this, tick, i);
var leaveCallback = tickListenerReference.addMouseLeave(this, tick);

// Map tick index to event listeners
this.ticksCallbackMap[i] = {
  mouseEnter: enterCallback,
  mouseLeave: leaveCallback
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoops.

for(var i = 0; i < ticks.length; i++ ){
ticks[i].removeEventListener('mouseenter', this.createTickMouseOverListener, false);
ticks[i].removeEventListener('mouseleave', this.createTickMouseOverListener, false);
ticks[i].removeEventListener('mouseenter', this.ticksCallbackMap.mouseEnter, false);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you map the tick index to the event listener references as I mentioned above, you should be able to do the following here in order to cleanup the references:

var tickEventListeners = this.ticksCallbackMap[i];
var tickElement = ticks[i];

tickElement.removeEventListener('mouseenter', tickEventListeners.mouseEnter, false);
tickElement.removeEventListener('mouseleave', tickEventListeners.mouseLeave, false);

var mouseLeave = callbackHandle.addMouseLeave(this, this.handle1);
callbackHandle.addMouseEnter(this, this.handle2);
callbackHandle.addMouseLeave(this, this.handle2);
this.handleCallbackMap = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

likewise, need to map each handle to its event listeners.

I would recommend something like the following:

var callbackHandle = this._addTickListener();

// generate event listeners for handle1 and store in map
var mouseEnter = callbackHandle.addMouseEnter(this, this.handle1);
var mouseLeave = callbackHandle.addMouseLeave(this, this.handle1);

this.handleCallbackMap["handle1"] = {
  mouseEnter: mouseEnter,
  mouseLeave: mouseLeave
};

// generate event listeners for handle2 and store in map
mouseEnter = callbackHandle.addMouseEnter(this, this.handle2);
mouseLeave = callbackHandle.addMouseLeave(this, this.handle2);

this.handleCallbackMap["handle2"] = {
  mouseEnter: mouseEnter,
  mouseLeave: mouseLeave
};

}
}
this.handle1.removeEventListener('mouseenter', this.handleCallbackMap.mouseEnter, false);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to remove listeners from handles.

Something like the following:

this.handle1.removeEventListener('mouseenter', this.handleCallbackMap["handle1"].mouseEnter, false);
this.handle2.removeEventListener('mouseenter', this.handleCallbackMap["handle2"].mouseEnter, false);
this.handle1.removeEventListener('mouseleave', this.handleCallbackMap["handle1"].mouseLeave, false);
this.handle2.removeEventListener('mouseleave', this.handleCallbackMap["handle2"].mouseLeave, false);

@snurby7
Copy link
Contributor Author

snurby7 commented Oct 20, 2016

@rovolution cleaned it up again to your comments, also went through and removed some of the old white spaces that were still in the file, might as well fix it while I was in there.

@rovolution
Copy link
Collaborator

@snurby7 check out #638 (comment)

@rovolution
Copy link
Collaborator

@snurby7 alright i just pulled your branch down locally and QA'ed it. Everything checks out.

Thanks again for making this PR and taking the time to incorporate my feedback!

@rovolution rovolution merged commit 8d8c702 into seiyria:master Oct 21, 2016
@rovolution
Copy link
Collaborator

Merged and published to v9.3.0

Thanks again @snurby7!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants