1

Im working on creating a custom slider component in lightning. I don't want to use the one provided as it has quite limited functionality.

I'm seeing the slider on the page, but get the error:

[knob.addEventListener is not a function]

Component:

<!-- Should be auto-set -->
<aura:attribute name="Height" type="Integer"/>
<aura:attribute name="Width" type="Integer"/>

<aura:attribute name="Steps" type="Integer[]" default="[0,10,20,30,40,50,60,70,80,90,100]"/>
<aura:attribute name="stepChange" type="Integer" default="1"/>
<aura:attribute name="Tick" type="Integer" default="0.1"/>

<aura:attribute name="Orientation" type="String" default="Horizontal"/> 

<aura:attribute name="Min" type="Integer" default="0"/>
<aura:attribute name="Max" type="Integer" default="100"/>
<aura:attribute name="Value" type="Integer" default="10"/>

<!-- Handlers  -->
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

<div id='track' aura:id="track" class="track">
<div id="knob" aura:id="knob" onmousedown="{!c.onMouseDown}" class="knob"></div>
</div>

css:

   .THIS .track 
{
    width: 200px;
    height: 5px;
    margin:100px; 
    background: red
}
.THIS .knob 
{
    height: 10px; 
    width: 40px; 
    background: black;
    position: relative; 
}

helper.js

({
    initialLoad: function(component, event, helper) {

        var dragging = false;
        var knobOffset = 0;

        var track = component.find("track"),
            knob = component.find("knob"),

            trackWidth = track.offsetWidth,
            trackLeft = track.offsetLeft,
            trackRight = trackLeft + trackWidth,

            knobWidth = knob.offsetWidth,
            maxRight = trackWidth - knobWidth; // relatively to track

        window.addEventListener('mouseup', function(e) {
            dragging = false;
        })

        window.addEventListener('mousemove', function(e) {
            if (dragging) {
                // current knob offset, relative to track
                var offset = e.clientX - trackLeft - knobOffset;
                if (offset < 0) {
                    var offset = 0;
                } else if (offset > maxRight) {
                    var offset = maxRight;
                }

                knob.style.left = offset + "px"
            }
        });
    },

    onMouseDown: function(component, event, helper) {
        console.log(here);
        var knob = component.find("knob");

        knob.addEventListener('mousedown', function(e) {
            // knob offset relatively to track
            knobOffset = e.clientX - knob.offsetLeft;
            dragging = true;
        });
    },
})

controller.js

 ({
        doInit: function(component, event, helper) {
            helper.initialLoad(component, event, helper);
        },
        onMouseDown: function(component,event,helper) {
    console.log("mousedown");
    helper.onMouseDown(component,event,helper);
},
    })

Thanks in advance.

2
  • Some parts are missing. To help us understanding it, please add your whole component and your onRender method.
    – itsmebasti
    Commented Nov 27, 2017 at 14:48
  • @Basti Updated, i've removed the OnRender as it was a different approach i've since deleted.
    – CS456
    Commented Nov 27, 2017 at 14:55

2 Answers 2

1

Be it a custom component or an HTML element when you do component.find() we get an intended target's component instance rather than the actual DOM.

In order to access the DOM, you need this:

component.find().getElement(); // return the DOM of a component instance

So your onMouseDown method would look like this:

onMouseDown: function(component, event, helper) {
     var knob = component.find("knob").getElement();

     knob.addEventListener('mousedown', function(e) {
         // knob offset relatively to track
         knobOffset = e.clientX - knob.offsetLeft;
    });
},
1
  • Thanks, that removes the error, however theres still no movement from the slider, any idea as to why?
    – CS456
    Commented Nov 28, 2017 at 8:08
1

To apply the CSS to your elements you would need to define it like this:

.THIS.track 
{...}
.THIS.knob 
{...}

The divs are in the first level of your components, and .THIS (the class name of your Component) is applied to first level elements in your component. In the DOM it will look like this:

<div id="track" class="YourComponent">

Therefore you need to chain the selectors without spaces. .THIS .foo only applies to foo elements within the .THIS component.

Not sure if this fixes your viability issues, but it at least let's you apply your css to your elements.

BTW:

<div id="knob" aura:id="knob" mousedown="{!c.onMouseDown}" class="knob"></div>

should be:

<div id="knob" aura:id="knob" onmousedown="{!c.onMouseDown}" class="knob"></div>
5
  • For some reason only track shows with the CSS like that, the Knob is being treated as a class. However, its now showing at least. No movement on the slider, the mousedown isn't being recognised.
    – CS456
    Commented Nov 27, 2017 at 15:24
  • I just saw you edited your question and added the classes, I will quickly update my answer.
    – itsmebasti
    Commented Nov 27, 2017 at 15:25
  • So it is displaying, but you're having problems with your mthods? maybe you should clarify this in your question. console.log(here); would be undefined btw.. You are using the wrong event: mousedown should be onmousedown
    – itsmebasti
    Commented Nov 27, 2017 at 15:28
  • Thanks i didn't spot that! the error im getting is " [knob.addEventListener is not a function]", i will update the question.
    – CS456
    Commented Nov 27, 2017 at 15:41
  • 1
    just a quick note, try to avoid updating your question everytime there are new developments/errors in your code, insread, please open a new post with the new issue you are facing. Thanks!
    – glls
    Commented Nov 27, 2017 at 17:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .