Giter Club home page Giter Club logo

angular-slider's Introduction

angular-slider Build Status

Slider directive for AngularJS. https://venturocket.github.io/angular-slider
License: MIT

Features

  • Single or dual knob
  • Fully Stylable
  • Custom arbitrary scaling
  • Adjustable knob "Stickiness"
  • Adjustable minimum range width
  • Draggable selection range
  • Full touch event support

Known Issues

  • When hidden during initialization (display: none;) the slider might not display correctly when shown. Issue $scope.$broadcast('refreshSlider'); in a parent scope to tell the slider to update the DOM.
  • The step attribute conflicts with angular-foundation's step directive (docs). To remedy this, use step-width instead (it's an alias of step). step will be deprecated in the next minor release, so if you want to do a bit of future proofing you can start using step-width now and save yourself a bit of migration work later .

Installation

bower install venturocket-angular-slider

Usage

Requirements

Add <script>s to your html files for angular, angular-touch and angular-slider:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular-touch.min.js"></script>
<script src="build/angular-slider.min.js"></script>

And add vr.directives.slider as a dependency for your app:

angular.module('myApp', ['vr.directives.slider', ...]);

NOTE: in IE10/11 an annoying tooltip will show up unless you add the following css:

::-ms-tooltip {
	display: none;
}

Single Knob

Markup

As an element:

<slider
    ng-model="{expression}"
    floor="{float}"
    ceiling="{float}"
    step="{float}"
    precision="{integer}"
    stretch="{integer}"
    translate-fn="{expression}"
    scale-fn="{expression}"
    inverse-scale-fn="{expression}">
</slider>

As an attribute:

<div
    slider
    ng-model="{expression}"
    floor="{float}"
    ceiling="{float}"
    step="{float}"
    precision="{integer}"
    stretch="{integer}"
    translate-fn="{expression}"
    scale-fn="{expression}"
    inverse-scale-fn="{expression}">
</div>

Parameters

Param Type Required Default Details
ng-model expression Yes none Assignable angular expression to which to data-bind the value.
floor float Yes none The lowest value possible
ceiling float Yes none The highest value possible
step float No inf The width between each tick.
precision integer No 0 The numerical precision to which to round the value.
stretch integer No 3 How sticky the knobs will act. 1 = no stickiness
translate-fn expression No none A translation function to apply to all view values. Be sure to omit the parentheses (e.g. "transFunc" instead of "transFunc()")
scale-fn expression No none A scaling function to apply to the value. See the Scaling section below for more details. Be sure to omit the parentheses (e.g. "scaleFunc" instead of "scaleFunc()")
inverse-scale-fn expression No none The inverse of the scaling function. This is required if a scaling function is specified. See the Scaling section below for more details. Be sure to omit the parentheses (e.g. "scaleFunc" instead of "scaleFunc()")
--

Dual Knob

Markup

As an element:

<slider
    ng-model="{expression}"
    ng-model-range="{expression}"
    floor="{float}"
    ceiling="{float}"
    buffer="{float}"
    step="{float}"
    precision="{integer}"
    stretch="{integer}"
    translate-fn="{expression}"
    translate-range-fn="{expression}"
    translate-combined-fn="{expression}"
    scale-fn="{expression}"
    inverse-scale-fn="{expression}">
</slider>

As an attribute:

<div
    slider
    ng-model="{expression}"
    ng-model-range="{expression}"
    floor="{float}"
    ceiling="{float}"
    buffer="{float}"
    step="{float}"
    precision="{integer}"
    stretch="{integer}"
    translate-fn="{expression}"
    translate-range-fn="{expression}"
    translate-combined-fn="{expression}"
    scale-fn="{expression}"
    inverse-scale-fn="{expression}">
</div>

Parameters

Param Type Required Default Details
ng-model expression Yes none Assignable angular expression to which to data-bind the low value.
ng-model-range expression Yes none Assignable angular expression to which to data-bind the high value.
floor float Yes none The lowest value possible
ceiling float Yes none The highest value possible
buffer float No 0 The minimum difference between the low and high values
step float No inf The width between each tick.
precision integer No 0 The numerical precision to which to round the value.
stretch float No 3 How sticky the knobs will act. 1 = no stickiness
translate-fn expression No none A translation function to apply to most of the view values. Be sure to omit the parentheses (e.g. "transFunc" instead of "transFunc()")
translate-range-fn expression No none A translation function to apply to the range value. Be sure to omit the parentheses (e.g. "transFunc" instead of "transFunc()")
translate-combined-fn expression No none A translation function to apply to the combined value (when the knobs are too close together). Be sure to omit the parentheses (e.g. "transFunc" instead of "transFunc()")
scale-fn expression No none A scaling function to apply to the value. See the Scaling section below for more details. Be sure to omit the parentheses (e.g. "scaleFunc" instead of "scaleFunc()")
inverse-scale-fn expression No none The inverse of the scaling function. This is required if a scaling function is specified. See the Scaling section below for more details. Be sure to omit the parentheses (e.g. "scaleFunc" instead of "scaleFunc()")

Scaling

You can supply any arbitrary scaling function (and its inverse) to the slider to suit your needs. The inverse scaling function MUST be specified if a scaling function is specified (and vice versa). The scaling/inverse function can be pretty much anything as long as they take a number as a parameter and return a number. Like this:

function scaleFn(value) {
    return Math.pow(value,3);
}
function inverseScaleFn(value) {
	var sign = (value == 0) ? 1 : (value/Math.abs(value));
    return sign * Math.pow(Math.abs(value),1/3);
}

A few notes:

  • scaleFn(inverseScaleFn(x)) MUST produce x or you're gonna have a bad time
  • If your scale function returns the same y for multiple x's within the range of the slider you're gonna have a bad time
  • If the floor of your slider dips into negative numbers and you don't account for possible imaginary numbers you're gonna have a bad time

Additional Features

  • ngChange support (docs)
  • ngDisabled support (docs)
  • implements ngModelController for form validation and dirty/pristine states (docs)

Development

Run npm install, then bower install and then npm run dev for continuously running the tests in PhantomJS whilst developing.

angular-slider's People

Contributors

drgould avatar jlinn avatar joscha avatar kimchouard avatar natbur avatar perelin avatar perry avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

angular-slider's Issues

Invalid knob position on init

On init if ng-model has been set to some value initial knob position doesn't correspond it. Once being clicked knob moves to correct position. JQuery 2.1, Angular 1.2.14

Strange dragging behavior

If you drag with the mouse faster than the knob follows your cursor and you leave the knob, dragging stops.
If you then release your mouse button and return to the knob you drag again. Sometimes the left knob doesn't start to move if you click hold the button and move the mouse.

Here is my reproduction: http://plnkr.co/edit/Cm7r0gQk1xYmVQzlhB98?p=preview

No demo and no styles

You need to add an example/demo to the page and also...are there no default styles? do you expect everyone to style the whole thing on their own?

Slider horizontally

Hello,
Is it possible to put the slider in the horizontal position?
Thank you

Explain buffer attribute

I found it in your example page but it's not explained in the README. In code, a comment says:

how close can the two knobs of a dual knob slider get?

Add prefixes

It's considered good convention to add a prefix to your directives and options. This library currently conflicts with angular-foundation.

slide-page perhaps instead of the currently conflicting slide option?

or sl-slide? Etc.

Bind a array of data instead of a range

Hi,

I just recently started to use this slider which is pretty nice, but i'd like to have a slider for a few dates, but that have no mathematical links (step can be from 2 to 7).
Is there a way to use something like a ng-repeat="date in [2018,2021,2023,2026,2033,2038,2043] in the call for slider ?

/* form.html */
<slider
    ng-model="formCtrl.endDate",
    ng-repeat="date in [2018,2021,2023,2026,2033,2038,2043]"
>

Instead of a floor/ceiling/step definition ?

I don't really care if it will visually impact the slider with differents gaps (best would be to have the same gap even though the numerical values aren't regularly spaced) but i'd like to have the values matching an array.

Any ideas ? ๐Ÿ˜ƒ

knob "jumpiness"

Thanks for this slider !

One thing I am experiencing though is what I would call the "jumpiness" of the slider knob:
If I use your example.html and click on a knob it "jumps" to the value I have clicked (mostly one value next to the current value). But I am not clicking to go to a value. I am clicking on the knob to grab it.

I know it is a minor detail, but I think solving this makes this control look and work even better.

Sander.

Styling issue - :hover not working

Hi ! While you integrated an empty selector for :hover on your exemple files, it does not seem to work. The :hover state is juste not triggered. Maybe a .hover class should be added, like the (working) .active class ?

bar background color in single knob sliders

Hello,

Thanks for this great module!

When using single knob sliders, is it possible to give the bar a different background color from the floor point until the selection point? (i.e., if the slider goes from 0 to 1 and the knob is in 0.7, I want the bar to be red from 0 to 0.7 and grey from 0.7 to 1).

I've been playing with the CSS, but I didn't manage to get it working.

Thanks!

Empty start value

Hello,

I am trying to make the slider aware of an "empty" start value (e.g. lets say false) same as https://github.com/bgrins/spectrum supports - the knob should then be displayed in the middle and the model not changed.
Only after moving the knob, the model would update and never revert to that "empty" start value.
Could you give me a starting point for that (currently the post method looks like the place to add something like that?)?

Is there any way to invert the slider?

Hi,
I'm working on a project with a graph zoom slider. I want to turn the slide the other way round (so that rather than go from zoom of 1 -> 7, it goes from a zoom of 7 -> 1).

I've tried changing these values -
floor="1"
ceiling="7"
step="1"

to these -
floor="7"
ceiling="1"
step="-1"

I've tried multiple different configurations along these lines, but I can't seem to get the slider to flip round. The reason I would like to do it in this way is that the translate and scale functions are rather complicated and it would be a lot easier alter it this way round rather than go through and change the functions.

Is there a simple way to do this?

Sorry if I'm being dumb and missing something.

Changing when ngModel and ngModelRange get updated

Hi.

I'm using this slider in a project at work, and I would like to modify the behavior of when ngModel and ngModelRange get updated.

I would like to modify the slider so that ngModel and ngModelRange are updated only when the dragging of the knobs or the range ends, not during the actual dragging of the knobs.

From what I can tell from playing with the source for the past two days, updating the UI is tightly coupled with updating ngModel and ngModelRange.

Any thoughts or suggestions?

Incorrect behavior when slider shown using ng-show

Hi!

I'm trying to use the slider on one of my Angular pages and it doesn't seem to be behaving when it's hidden using ng-show.

This is basically the markup I'm using:

<div ng-show="someCondition">
    <slider ng-model="test" floor="-10" ceiling="10" step="5"></slider>
</div>

I can see the slider directive is running code when you first load the page (as directives do), and I think it's incorrectly determining the widths and offsets of its elements because the element is hidden when the slider initializes. It ends up looking something like this: http://i.imgur.com/jJrY8N4.png

Then, after it's clicked, it seems to reset itself back to normal: http://i.imgur.com/cgRxeMB.png

Is there any way to "recalculate" its widths and offsets when the element with the slider directive is shown?

It's a shame this problem exists, this is the best slider I've found for Angular. :(

Slide completed event

Maybe I'm missing this due to the sparse documentation. Is there a slide completed event which would contain the model/position value(s) of the slider?

I tried doing $scope.$watch( 'slider.model', fct ) but it fires while the user is actively sliding. I need to run a test when the slide operation is entirely complete (specifically after the directive runs the updateDOM code.

Clicking on left pointer is triggering the right pointer

My situation:
I have a slider with two knobs (pointers).

It's working great (thanks for the gem!), but: clicking on the left pointer begins in fact clicks on right pointer and starts to move the range as I wanted to change the right's end of range. Thus, moving the minimum limit of the range is really difficult for the user.

Let's look at the screen:
image

When I looked into source:
.input.high has the width as the yellow rectangle on the picture, but should be of width of the green square.

.input.high and .input.low offsets should be -= $('.pointer').width()

I wanted to changed it but unfortunately source code currently is hardly readable right now (seems like it's translated from coffescript and there are no .coffee files here).

Meanwhile, if someone'd have the same issue, here's quick fix:

slider .input.high {
  margin-left: 20px; // if your span.pointer has 20px width
}

Doesn't Work

Ah, I just installed via bower and there are no js files in the build directory. When I manually download and put the files there and start to use it. I just get some overlapping text where the slider should be. Where's the CSS?

Not working in ng-repeat

I have sliders in directives that are being generated via ng-repeat. When I put the directives in directly it works fine, but as soon as I consolidate in ng-repeat, the values are fine but the "knob" and all labels are all the way to the left. I have tried making the ng-repeat <div a direct child of <body, so I know it's not a weird display issue stemming from a container element.

Thanks!
image

Is a $apply missing?

Running the provided example.html completely unaltered...

angular-slider

The single slider is being declared as...

<slider //configRemovedForClarity// ng-model='value' style="width: {{ sliderWidth }};">
Value:

and $scope.value is defined in the controller like...

$scope.value = 5;

However, the controller's 'value' isnt getting updated. In Models for (003) you can see that 'value' is 9. But in the slider on the left, you can see I dragged the slider to 6 and if we were to look inside Scope (004) value would be equal to 6 matching what's in the DOM.

If I run a $scope.$apply(), the bindings will get sync'd and the controller's 'value' will change to 6.

Thanks,

Jim

The specified value ':)' does not conform to the required format, 'yyyy-MM-dd'.

I get these errors in the latest version of Google Chrome Canary (Version 39.0.2127.0 canary (64-bit))
The specified value ':)' does not conform to the required format, 'yyyy-MM-dd'.

angular-slider.js:131
angular-slider.js:136

A similar bug report has been filed with Modernizr in February 2012: Modernizr/Modernizr#483 (Sorry if this bug should be filed with Modernizr too)

This was not an issue in previous versions of Canary.

onMove question

I'm dealing with a complex dataset and the onMove approach, while it works brilliantly, causes angular to immediately filter the results. Looking at the code, is there a way to stop the scope.$apply until mouse-up/finger-up?

Otherwise, the dataset is changed during each "step"

Thanks for your hard work and your willingness to share it with us!

Touch Events Not Working

Seems there is an issue with pulling 'clientX' from the captured events. I believe event.touches[0].clientX is not being captured, or not being accounted for properly.

Please see OnMove (Line 1419) and OnStart (Line 1623) functions.
(Angular-slider.js --Version 0.3.2)

  • No jQuery library, using angular's JQLite.
  • Yes, I have ngTouch as a dependency.
  • No, I'm not doing anything extreme with the slider. Pretty much cut and paste the single bubble slider.

If I add " || event.touches[0].clientX; " to that line, the sliding works, but throws an error (probably just needs some additional checks)

Has anyone else experienced this issue? Or hopefully I just overlooked something simple.. I'll try to throw a punkr together this evening.

Exponential slider

I need the slider to start to slowly increase values such as 1 - 10 in +1 increments, but from then on wards, it increases from 10 to 10,000 by +10 increments, and then so on.

What would be the best way to implement this in angular-slider?

IE8 Support

I was just wondering what the issues with older IE are. This slider looks great but as I am stuck with IE8 currently I was curious as to what issues I might face if I was to look at adding support.

Thanks

polluting the global window object

the modernizr input check does not play well with browserify. including in the build two files one for modernizer check and one for slider module would work in most cases so modernizer could be added as an option.

Combined total for multiple Sliders

I'm trying to implement a page where there are 4 sliders, and I want to make it so the combined total of all 4 sliders will never go over 100.

Is this possible?

Dual-knob doesn't work well with ng-repeat

Hi there!

I tried creating multiple dual-knob sliders using ng-repeat, and I don't see any issues when I'm dragging the left knobs to the left, and the right knobs to the right, but the knobs won't move when I'm dragging the left and right knobs in (left knob to the right, right knob to the left). Is there any way to fix this? It's unfortunate as this is the best slider directive I've found so far..

Slider doesn't set form to a dirty state

The pristine state on a <form> is only changed when the model is directly changed by the <input>.

We could potentially pass the form object and a field name (this would also require you adding a hidden <input> field with a name attribute to register it in the form) in to the slider and do something like scope.myForm.myField.$setViewValue(scope.myForm.myField.$viewValue); when the ngModel changes - this would handle all of the state changes that a form could have.

Any ideas on a better way to do this?

Vertical support

I cant seem to find any support for a vertical slider, has this been implemented? I tried just simply adding css transform to rotate it, but it still listens on moving the mouse left to right.

There is a listener on the mousemove but it is baked in to listen to x.

We could quite easily add a switch here for vertical support, but i don't know what else this would effect

a quick hack of the onMove function line 267 does the desired effect. (changing X to Y)


 onMove = function (event) {
     var eventX, newOffset, newPercent, newValue;

     eventY = event.clientY || event.touches[0].clientY;
     newOffset = eventY + offsetLeft(element) - halfWidth(pointer);
     newOffset = Math.max(Math.min(newOffset, maxOffset), minOffset);
     newPercent = percentOffset(newOffset);
     newValue = minValue + (valueRange * newPercent / 100.0);
     if (range) {
         if (ref === refLow) {
             if (newValue > scope[refHigh]) {
                 ref = refHigh;
                 minPtr.removeClass('active');
                 maxPtr.addClass('active');
             }
         } else {
             if (newValue < scope[refLow]) {
                 ref = refLow;
                 maxPtr.removeClass('active');
                 minPtr.addClass('active');
             }
         }
     }
     newValue = roundStep(newValue, parseInt(scope.precision), parseFloat(scope.step));
     scope[ref] = newValue;
     return scope.$apply();
 };

No style on the slider

Tried to implement the slider but there seem to be no style attached.

I just get a blank thing with a number I can move around :

example

To get this result I used this code :

<div
    slider
    ng-model="percentage"
    floor="0"
    ceiling="100">
</div>
<div>
    {{ percentage }} %
</div>

ng-change doesn't fire

Using this code (less syntax):

slider(
  floor="0"
  ceiling="{{ placement.contracted_delivery }}"
  ng-model="flight.target"
  step="1"
  stretch="1"
  ng-change="allocate(flight)")

...the ng-change function never fires, it seems like it get sucked up by the directive.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.