How do I set multiple instances of the nouislider in Meteor?
I have initialed multiple sliders on a page like codes in this . I would like to set the value of sliders synchronized with a collection, but now I am only able to initialized the value with the collection in "start" option.
I've been trying calling a function on 'slide' event. But in the function I find no way to select all the sliders, or use .val().
var updateSliders=function(){
var slider=$(".sliderrr");
console.log(slider);
slider.each(function(){
console.log($(this).val());
})
};
I will base this answer on what you wrote on github
<div class="slider-container">
<div class="sliderrr"></div>
</div>
and
var slider=$(".sliderrr");
slider.each(function(){
console.log("value:",$(this).val());
})
The problem is that you are calling 'each' on the sliderrr instead of the slider-container.
Template.body.rendered = function () {
//init the slider
this.$('.sliderrr').noUiSlider({
start: 5,
connect: "lower",
step: 0,
format: wNumb({
decimals: 0,
}),
range: {
'min': 0,
'max': 30
}
});
//This is the part I changed
var sliderino = this.$('.slider-container');
sliderino.children('.sliderrr').each(function() {
console.log($(this).val());
});
};
Related
I'm trying to make a simple vue.js & d3.js code. In the code, I want to plot some charts. For that, I'm trying to make some spaces for charts, by defining a method('add_svg') and run the method in created.
But, the method('add_svg') doesn't work what i intended. I had checked that the method was working, by inserting console.log('Running') for the first part of the method.
I could saw the message, 'Running', but the svg_space, i wanted to insert, wasn't inserted.
But when I UPDATE charts with same method in computed: part, it works.
In the computed: part, it generates some spaces several times, which means that it's working and the method has no problem.
Why is that?
Below is my code:
// GIVES CONSOLE.LOG MESSAGE('RUNNING') BUT DOES NOT APPEND SVG
created () {
console.log("")
this.add_svg() // append svg for chart
this.plot([0, 0]) // basic plot with value = [0, 0]
},
...
// SAME METHOD, BUT IN HERE, IT GIVES ME WHAT I WANTED.
// BUT TO INITIALIZE, I WANT TO RUN THE METHOD IN created: part, not in computed
computed () {
this.add_svg()
this.plot( datum )
}
...
methods: {
add_svg: function () {
console.log("Adding some space for chart")
d3.select('.chart_test2')
.append('svg')
.attr('class', 'svg_chart_test2')
.attr('width', '10px')
.attr('height', '10px')
},
other methods...
}
In Vue, you have to draw d3 charts on the mounted hook, rather than the created hook. You can't draw the chart if the page is not rendered - which is what happens when you use the created hook.
mounted () {
this.add_svg() // append svg for chart
this.plot([0, 0]) // basic plot with value = [0, 0]
}
I'm trying to enable infinite scroll for an angular-meteor app I'm working on that draws objects from a meteor/mongo collection.
I've adapted step 12 of the angular-meteor tutorial to use pagination for the app I'm working on, and now I'd like to convert to infinite scrolling. I've been trying to adapt both the code from the tutorial and this example from ngInfiniteScroll for my purposes.
I imagine I'll need to use reactive variables, autorun, etc. similar to the tutorial, but I don't really know how to adapt it for infinite scroll. Considering the example below, how should I adjust my controller for it to use infinite scrolling, drawing from a database, with good angular-meteor practices for production?
Demo ngInfiniteScroll HTML:
<div infinite-scroll='loadMore()' infinite-scroll-distance='2'>
<img ng-repeat='image in images' ng-src='http://placehold.it/225x250&text={{image}}'>
</div>
Demo ngInfiniteScroll Function inside controller:
$scope.images = [1, 2, 3, 4, 5, 6, 7, 8];
$scope.loadMore = function() {
var last = $scope.images[$scope.images.length - 1];
for(var i = 1; i <= 8; i++) {
$scope.images.push(last + i);
}
};
My angular-meteor pagination code inside controller:
$scope.page = 1;
$scope.perPage = 1;
$scope.sort = {'_id': -1};
$scope.orderProperty = '1';
$scope.images = $meteor.collection(function() {
return Images.find({}, {
sort : $scope.getReactively('sort')
});
});
$meteor.autorun($scope, function() {
$meteor.subscribe('images', {
limit: parseInt($scope.getReactively('perPage')),
skip: (parseInt($scope.getReactively('page')) - 1) * parseInt($scope.getReactively('perPage')),
sort: $scope.getReactively('sort')
}).then(function(){
$scope.imagesCount = $meteor.object(Counts ,'numberOfImages', false);
});
});
$scope.pageChanged = function(newPage) {
$scope.page = newPage;
};
Please look at this basic example https://github.com/barbatus/ng-infinite-scroll.
Controller there re-subscribes every time onLoadMore is executed.
There is also a deployed demo http://ng-infinite-scroll.meteor.com.
Make sure this time angular.module('infinite-scroll').value('THROTTLE_MILLISECONDS', 500) is set properly (not very small) to avoid very frequent requests.
Pretty sure I have some fundamental mis-understanding of how/when fa-animate-enter is invoked. The following code works if you click on the box, it scales, but I was expecting that when the fa-view becomes active, it would also call the fa-animate-enter rather than necessitating a click. When a view becomes active, how do I call animateScale_enter()?
http://plnkr.co/edit/r2OSonPSvAQREAHvns7F
<fa-view fa-animate-enter="animateScale_enter()"
fa-animate-leave="animateScale_leave()"
fa-animate-halt="animateScale_halt()" >
<fa-modifier fa-origin="[0.5, 0.5]"
fa-align="[0.5, 0.5]"
fa-scale="scale.get()"
>
<fa-surface fa-background-color="'#dc322f'"
fa-size="[100, 100]"
fa-click="animateScale_enter()"
>{{text}}
</fa-surface>
</fa-modifier>
</fa-view>
.js
<script>
var app=angular.module('MyApp', ['famous.angular'])
.controller('MainController',
function($scope, $famous) {
var Transitionable = $famous['famous/transitions/Transitionable'];
var SpringTransition = $famous['famous/transitions/SpringTransition'];
Transitionable.registerMethod('spring', SpringTransition);
$scope.viewType="view2";
$scope.text="Scale=[1,1,1], click";
$scope.scale = new Transitionable([1, 1, 1]);
$scope.animateScale_enter = function() {
console.log("enter");
$scope.text="Scale=[2,2,1], enter";
$scope.scale.set([2, 2, 1], {
method: 'spring',
period: 750,
dampingRatio: 0.3
});
};
$scope.animateScale_leave = function() {
console.log("leave");
};
$scope.animateScale_halt = function() {
console.log("halt");
scope.transform.halt()
};
}
);
</script>
Apparently it is connected to ng-repeat, and from what I gather, anything that forces a dom update... ??
So just adding a dummy ng-repeat to the fa-view seems to make it work.
<fa-view ng-repeat="x in {x:1}"
fa-animate-enter="animateScale_enter()"
fa-animate-leave="animateScale_leave()"
fa-animate-halt="animateScale_halt()" >
I hope someone can give me a better way to do this. I just feel dirty doing it this way.
I am finally reaching out for help. I've been trying to get a no results message to show up on my Isotope image gallery for a week now, with only a little bit of luck. I had an example working at one point, but the message wouldn't hide until the animation was complete, so it didn't look good at all.
Surely someone has a solution.
I would greatly appreciate it if someone is able to help me. I have test site that I will link here in just a second.
For now here is the first half of my isotope configuration file. I have the '.message-div' placed at the bottom of my #isotopegallery div with css applying 'display: none;.'
jQuery(window).load(function() {
var $container = $('#isotopegallery').imagesLoaded(function() {
$container.isotope({
itemSelector: '.photo',
masonry: {
columnWidth: 161,
gutter: 10
},
transitionDuration: '0.6s'
});
// Filters
//
var filters = {};
$('#isotopefilters').on('click', '.menu-item', function() {
var $this = $(this);
// get group key
var $buttonGroup = $this.parents('.filter-title');
var filterGroup = $buttonGroup.attr('data-filter-group');
// set filter for group
filters[filterGroup] = $this.attr('data-filter');
// combine filters
var filterValue = '';
for (var prop in filters) {
filterValue += filters[prop];
}
$container.isotope({filter: filterValue});
// Possibility
$container.isotope( 'on', 'layoutComplete',
function( iso, laidOutItems ) {
if ( laidOutItems < 1 ) {
$('.message-div').fadeIn('slow');
} else {
$('.message-div').fadeOut('fast');
}
})
});
});
});
There is an easy workaround to achieve the "no result" message.
Consider ".photo" as class for the itemSelector. As isotope is simply attaching ".isotope-hidden" to the div-container if it does not match the filter, the number of these divs equals the total of all isotope items in case of "no result". Easy:
if($(".isotope-hidden").length == $(".photo").length) {
$("#mynoresults").show();
}
My requirement is to show a page with multiple filters to apply to grid data.
Suppose we are talking about Orders and an order has the following attributes
public class Order {
public int OrderID
public DateTime OrderDate
public DateTime ShipmentDate
public int OrderTotal
public int OrderStatus
}
Inside the jqgrid object I am showing all the attributes except the OrderStatus
The requirement is to create a view that has
the jqGrid on the left part
a panel on the right
Inside the right panel the user will see a list of checkboxes that represents every possible OrderStatus value and he want to search using both methods (for example selecting the checkbox "Shipped Orders" and then filtering the grid with Amount greater than a value)
I have already configured the advanced filtering (multiplesearch:true) inside the jqGrid object and I am able to create complex filters combining fields and logical operators.
Any ideas on how I can submit even the data from the right panel when the user press the search button?
Update 1:
Preamble: Oleg sample is fantastic but unfortunately does not fits requirements of my customer :(
#Oleg: I do not understand why you think that:
If the data are outside of the grid
you will be show the order details on
the right pane only for selected row.
So the user will have not so good
overview of the data.
maybe my description was not so clear but I am not going to show any order detail. To better clarify my requirement I have modified your sample to show you the desired final UI which is as in the following image:
The customer want to filter the data in the grid using two methods or both together:
Using the multiplesearch facilities provided by the grid itself (thanks for the workaround mention)
Using the custom Search Panel (the one with the checkboxes on the right) provided
From a functional point of view the requirement is very easy to express: When the user click on a checkbox or make a search using the native multiplesearch I should post values to the server including also the checkboxes state.
To summarize I should:
Add the checkboxes state when a post is made through the native multiplesearch
Add the current multiplesearch state (if any) when the user click on a checkbox
Is there a way to do this?
I understand this requirement very good. In the close case I used checkboxes inside of jqGrid. The most advantage to having the information inside of jqGrid is not only the possibility of easy searching. If the data are outside of the grid you will be show the order details on the right pane only for selected row. So the user will have not so good overview of the data.
To be able to place many checkboxes in the table without permanent horizontal scrolling I rotated headers of the columns having "checkbox with the technique described in Vertical text inside table headers using a JavaScript-based SVG library. This rotation looks not perfect in IE, but in other browser it works perfect.
You can hold the data from the OrderStatus field in a hidden column and decode the bitmask to boolean which build checkboxes either on the client or on the server side.
Because use want to use multiplesearch:true I have to mention about a bug in jQuery.clone which follow to the bug in jqGrid multi-search in all versions of IE browsers. If you define more as one search filters only the first one will be used because the operation field of all other filters will be read as undefined. It's a pity, but the bug is also not fixed in the jQuery 1.4.3 just published. To be able to use multiplesearch:true you can use workaround suggestion by Jiho Han on trirand.com forum.
All together you can see in the demo example which produce the grid
where you can search for multiple fields
The corresponding code:
var myData = [
{ orderID: "10", orderDate: "2010-09-18", shipmentDate: "2010-09-20", orderStatus: "2" },
{ orderID: "15", orderDate: "2010-09-20", shipmentDate: "2010-09-24", orderStatus: "3" },
{ orderID: "20", orderDate: "2010-10-16", shipmentDate: "2010-10-17", orderStatus: "1" }
];
// decode 'orderStatus' column and add additional boolean data based on the bitmap mask
for (var i=0, l=myData.length; i<l; i++) {
var myRow = myData[i];
var orderStatus = parseInt(myRow.orderStatus, 10);
myRow.airPost = (orderStatus & 2) != 0? "1": "0";
myRow.heavy = (orderStatus & 1) != 0? "1": "0";
}
var grid = jQuery('#list');
grid.jqGrid({
data: myData,
datatype: 'local',
caption: 'Order Details',
height: 'auto',
gridview: true,
rownumbers: true,
viewrecords: true,
pager: '#pager',
rownumbers: true,
colNames: ['Order ID', 'Order', 'Shipment', 'Air-Post', 'Heavy', 'RowVersion'],
colModel: [
{ name: 'orderID', index: 'orderID', key:true, width: 120, sorttype: 'int' },
{ name: 'orderDate', index: 'orderDate', width: 180,
sorttype: 'date', formatter: 'date' },
{ name: 'shipmentDate', index: 'shipmentDate', width: 180,
sorttype: 'date', formatter: 'date' },
{ name: 'airPost', width: 21, index: 'airPost', formatter: 'checkbox', align: 'center',
editoptions: { value: "1:0" }, stype: 'select', searchoptions: { value: "1:Yes;0:No" } },
{ name: 'heavy', width: 21, index: 'heavy', formatter: 'checkbox', align: 'center',
editoptions: { value: "1:0" }, stype: "select", searchoptions: { value: "1:Yes;0:No" } },
{ name: 'orderStatus', index: 'orderStatus', width: 50, hidden: true }
]
}).jqGrid ('navGrid', '#pager', { edit: false, add: false, del: false, refresh: true, view: false },
{},{},{},{multipleSearch:true})
.jqGrid ('navButtonAdd', '#pager', { caption: "", buttonicon: "ui-icon-calculator", title: "choose columns",
onClickButton: function() {
grid.jqGrid('columnChooser');
}
});
where rotateCheckboxColumnHeaders and the bugfix in the advanced search defined so
// we use workaround from http://www.trirand.com/blog/?page_id=393/bugs/in-multiple-search-second-and-subsequent-ops-are-sent-as-undefined-in-ie6/
// to fix the bug in the jQuery.clone (see http://bugs.jquery.com/ticket/6793 and
// dscussion on the http://api.jquery.com/clone/
jQuery.event.special.click = {
setup: function() {
if (jQuery(this).hasClass("ui-search")) {
jQuery(this).bind("click", jQuery.event.special.click.handler);
}
return false;
},
teardown: function() {
jQuery(this).unbind("click", jQuery.event.special.click.handler);
return false;
},
handler: function(event) {
jQuery(".ui-searchFilter td.ops select").attr("name", "op");
}
};
var rotateCheckboxColumnHeaders = function (grid, headerHeight) {
// we use grid as context (if one have more as one table on tnhe page)
var trHead = jQuery("thead:first tr", grid.hdiv);
var cm = grid.getGridParam("colModel");
jQuery("thead:first tr th").height(headerHeight);
headerHeight = jQuery("thead:first tr th").height();
for (var iCol = 0; iCol < cm.length; iCol++) {
var cmi = cm[iCol];
if (cmi.formatter === 'checkbox') {
// we must set width of column header div BEFOR adding class "rotate" to
// prevent text cutting based on the current column width
var headDiv = jQuery("th:eq(" + iCol + ") div", trHead);
headDiv.width(headerHeight).addClass("rotate");
if (!jQuery.browser.msie) {
if (jQuery.browser.mozilla) {
headDiv.css("left", (cmi.width - headerHeight) / 2 + 3).css("bottom", 7);
}
else {
headDiv.css("left", (cmi.width - headerHeight) / 2);
}
}
else {
var ieVer = jQuery.browser.version.substr(0, 3);
// Internet Explorer
if (ieVer !== "6.0" && ieVer !== "7.0") {
jQuery("span", headDiv).css("left", 0);
headDiv.css("left", cmi.width / 2 - 4).css("bottom", headerHeight / 2);
}
else {
headDiv.css("left", 3);
}
headDiv.parent().css("zoom",1);
}
}
}
};
If you do prefer to hold the checkboxes outside of the grid you can do the decoding of the bit-mask OrderStatus inside of onSelectRow event handler.
UPDATED: I really something misunderstood your requirements at the beginning. Look at the modified example. Now it looks like
and it is more close to what you need.
Just as a follow up I am including here another method that I have found to abtain the same result.
This method suppose to use the postData parameter of jqGrid. Inside the method I have defined various function that verify the checkboxes current status and sends a parameter to the server where it can be used for filtering.
This is a sample
postData: {
pending: function () {
if ($("#cb_pending").is(':checked')) {
return true;
} else {
return false;
}
}
}
The advantage of this solution respect to the one depicted by Oleg is that it is possible to use mixed logical operators (AND/OR) on the server side whereas using the filters section as in the Oleg answer it is not possible.
Happy coding!