1
\$\begingroup\$

I'm struggling to integrate a jquery-ui slider widget into my Meteor app. The idea is to have a slider value in a Mongo collection and the slider needs to be reactive (automatically synced between clients). I've achieved this and it works but the implementation is not very elegant and clean. It's quite hard to maintain, test and extend such code. I've achieved this via Tracker.autorun and jquery slider slide handle (_.throttle is used to limit mongo update interval).

I'm new to Meteor, and it's awesome, but so far couldn't find better way to implement this (which I bet exists):

Live example

Slider = new Meteor.Collection("Slider");
if (Meteor.isClient) {
 Template.slide.rendered = function() {
 var handler = _.throttle(function(event, ui) {
 var val = Slider.findOne({});
 Slider.update({ _id: val._id }, {$set: {slide: ui.value}});
 }, 50, { leading: false });
 if (!this.$('#slider').data('uiSlider')) {
 $("#slider").slider({
 slide: handler
 });
 }
 Tracker.autorun(function() {
 var slider = Slider.findOne({});
 if (slider) {
 this.$('#slider').data('uiSlider').value(slider.slide);
 }
 });
 };
}
//seed Collection
if (Meteor.isServer) {
 if (Slider.find().count() == 0) {
 Slider.insert({
 slide: 20
 });
 }
}

HTML

<body>
 <h1>jquery-ui slider test</h1>
 {{> slide}}
</body>
<template name="slide">
 <div id="slider"></div>
</template>
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Apr 22, 2015 at 22:23
\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

I think you can avoid the Tracker.autorun completely by updating the value in a template helper -- this is possible because your data is coming from a Collection, so it's already reactive. You can play around with it in this MeteorPad, but a brief summary follows:

<!--HTML-->
<template name="slider">
 <div id="slider"></div>
 Slider's current value is...{{sliderVal}}<!-- You could get rid of this and just do {{sliderVal}} and have that return nothing if you want no text-->
</template>
//JS -- ommitted the rendered bit, which looks identical to yours w/o the Tracker.autorun
Template.slider.helpers({
 sliderVal: function() { 
 var slider = Slider.findOne(); // this guy is reactive, so when another client updates the Collection, it'll get pushed to us
 if (slider) { Template.instance().$('#slider').data('uiSlider').value(slider.slide); // Template.instance() b/c `this` doesn't return a template instance in a helper
 return slider.slide; // again, here you can return nothing if you'd rather have no text
 }
 }
});
answered Apr 22, 2015 at 22:42
\$\endgroup\$
1
  • 1
    \$\begingroup\$ The finest first posts are definitely answers. Welcome to CodeReview, Carson. \$\endgroup\$ Commented Apr 22, 2015 at 23:17

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.