Skip to content

Refactor to add an rzSliderOptions attribute #158

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

Merged
merged 15 commits into from
Nov 12, 2015
Merged

Refactor to add an rzSliderOptions attribute #158

merged 15 commits into from
Nov 12, 2015

Conversation

ValentinH
Copy link
Member

Waiting for feedback / votes / remarks / advices!

The goal is to reduce the number of options we need to set on the DOM element and to enable each options to be changed at runtime (step for instance #103).

Before, we had to add one watch for each property that needed to be update-able at runtime, now there is only one watch on the rzSliderOptions object.
The only remaining attributes are rzSliderModel and rzSliderHigh; all other attributes are moved to rzSliderOptions.

rzSliderOptions accepts an object that can contains these properties:

{
    floor: 0,
    ceil: null, //defaults to rz-slider-model
    step: 1,
    precision: 0,
    id: null,
    translate: null,
    stepsArray: null,
    draggableRange: false, 
    showSelectionBar: false,
    hideLimitLabels: false,
    readOnly: false,
    disabled: false,
    interval: 350,
    showTicks: false,
    showTicksValues: false,
    ticksValuesTooltip: null,
    scale: 1,
    onStart: null,
    onChange: null,
    onEnd: null
}

Moreover, now, you can set a bunch of custom global options applied to all sliders using the RzSliderOptions.options() method:

angular.module('App', ['rzModule'])
    .run(function( RzSliderOptions ) {
        // show ticks for all sliders
        RzSliderOptions.options( { showTicks: true } );
    });

Example

Before

<rzslider
    rz-slider-floor="0.5"
    rz-slider-ceil="10.5"
    rz-slider-step="0.3"
    rz-slider-precision="1"
    rz-slider-model="slider_data.value"
    rz-slider-on-start="onStart()"
    rz-slider-on-change="onChange()"
    rz-slider-on-end="onEnd()"></rzslider>
  $scope.slider_data = {
    value: 10
  };

Now

  <rzslider
      rz-slider-model="slider_data.value"
      rz-slider-options="slider_data.options"
      ></rzslider>
  $scope.slider_data = {
    value: 10,
    options: {
        floor: 0.5,
        ceil: 10.5,
        step: 0.3,
        precision: 1,
        onStart: function() {},
        onChange: function() {},
        onEnd: function() {}
    }
  };

I'm aware that this will break current implementation (that's why it will be 2.0.0 based on semantic-version) but the goal is to reduce the DOM size, share configs among sliders and reduce the number of watchers.

Demo: https://jsfiddle.net/h5udppp5/embedded/result/

@vitamink
Copy link

This approach looks a lot cleaner... I like it :-)

@tommhuth
Copy link

+1 cleaner and neat!

@tommhuth
Copy link

can this also handle raw objects, usefull when few options are required:

rz-slider-options="{ floor: .5, ceil: 2}"

@ValentinH
Copy link
Member Author

I was going to answer Nope, but after testing on the JSFiddle listed above, it does work! 😃 I thought it would fire an exception since the object passed to options is not updatable...
Actually, you can even use rz-slider-options="{ floor: myFloorVar}"!! This is magic! 😄I love Angular.

@termita81
Copy link

Hi, thanks for the slider! I am using this for a project at work.

Not sure if this is the right thread to post this, but I have resorted to hacking it a little to add the following:

  • changing color for the selected part, so that for instance at 20% it's green and at 80% it's red
  • adding bootstrap tooltips - this turned out to be ugly, I'm calling $('data-toggle="tooltip"]').tooltip(); at the end of updateTicksScale, as well as having all ticks inside div elements; I don't know why but the ticks and the corresponding tooltips "tremble" a bit when hovering over the ticks

Thanks!

@ValentinH
Copy link
Member Author

Nope this is definitively not the correct place to post this! ^^ I have created an issue for the changing color.

For the tooltip, I actually added it yesterday to this PR. You can see it in the JSfiddle example (https://jsfiddle.net/h5udppp5/embedded/result/ at "Slider with ticks and values and tooltip")

ValentinH added a commit that referenced this pull request Nov 12, 2015
Refactor to add an rzSliderOptions attribute
@ValentinH ValentinH merged commit 2c3ca88 into master Nov 12, 2015
@ValentinH ValentinH deleted the 2.0.0 branch November 12, 2015 09:59
@vdsabev
Copy link

vdsabev commented Dec 7, 2015

This refactor removed the ability to call events with local scope variables, which was especially useful in directives like ngRepeat:

Before

<div ng-repeat="filter in vm.filters">
  <rzslider ... rz-slider-on-end="vm.onEnd(filter, $index)" />
</div>

After

<div ng-repeat="filter in vm.filters">
  <!--we can't pass custom local scope variables here-->
  <rzslider ... rz-slider-options="{ onEnd: vm.filterChanged }" />
</div>

I understand why this change was useful - when you get rid of directive attributes, the size of the DOM is reduced. But now the controller logic becomes heavier, because you have to generate the options using JavaScript. And not being able to pass local scope variables is a blocker for our use case.

Unless someone has an idea (other than invoking a function that returns a function), I think supporting both syntaxes would solve our issue. To reduce the performance load, you can only create scope watches if the attribute is present.

@ValentinH
Copy link
Member Author

I understand your point. Can you open a dedicated issue so we can discussed there?

Just a quick idea, what if you use the id option?

<div ng-repeat="filter in vm.filters">
  <rzslider ... rz-slider-options="{ onEnd: vm.filterChanged, id: $index }" />
</div>

Then vm.filterChanged will be called with the correct index.

Actually, using a local object option like above was not the original idea so this is not the cleanest way. I know that this is not easy, but this change has changed the whole slider logic and you might rethink your implementation to use the whole power of this syntax. For instance, your vm.filters list could contain the sliders options (with id).

quick example: http://jsfiddle.net/qrk0vjxa/

@vdsabev
Copy link

vdsabev commented Dec 7, 2015

That's what I ended up doing, I used the id option. It's an acceptable workaround, but I can see someone wanting to do something more complex.

@ValentinH
Copy link
Member Author

If someone has a more complex issue, we'll see how we can handle it. But for now, I don't like the idea of re-adding all the attributes. I'm pretty sure that most of issues will be for people who were used to the old way and that new users won't have such problems since they will directly think with the new way in mind.

I'm using this library in a big project and I spent a couple of hours to update the library for all my views but now it feels cleaner and easier to reason about.

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

Successfully merging this pull request may close these issues.

5 participants