Waypoints with CoffeeScript - coffeescript

I want to notify event based on scrolling. I found Waypoints which can solve my problem but I am getting all examples with jQuery and Reactjs. How can I use it in CoffeeScript ?
I am using below code. It is being fired everytime but i want it to fire only when it reaches at waypoint-header. I have this div in repeating mode, I mean this div is available after some list items (after each 20 items in list). Please help me to solve this.
$(window).scroll ->
waypoint = new Waypoint(
element: document.getElementById('waypoint-header'),
handler:(direction) ->
console.debug 'hello'
)

Here is an example in CoffeeScript with no jQuery and React:
waypoint = new Waypoint
element: document.getElementById('waypoint-header'),
handler: (direction) ->
console.log 'hello'
You don't need to add an event listener, Waypoints library does it itself.
working codepen

If I get it right, it is normal for current code to be fired on any scroll event.
If you need just trigger once when reach to waypoint-header I guess, you should just create a waypoint without any scroll event as indicated here
waypoint = new Waypoint
element: document.getElementById('waypoint-header'),
handler:(direction) ->
console.debug 'hello'
To notify for each element inside list, I recommend to change id's to class and try this.
waypoint = $(".waypoint-header").waypoint ->
element: document.getElementById('waypoint-header'),
handler:(direction) ->
console.debug 'hello'

Related

DC.js - deselect feature or filter all but the ones that are clicked

I'm not sure if this is possible and no luck on researching this. I'm working on a dashboard using DC.js charts and crossfilter.js. I'm going to use a Row chart as an example. Instead of clicking on the items to filter, is it possible to do that opposite?
For example. When I click on an item from a row chart, instead of filtering on that selected item, it will deselect that item and filter the rest of the other items. And then I will keep clicking on other items to deselect.
Pretty much my goal is to implement a feature where a user can hold the 'CTRL key' and 'left click' the items in the Row Chart to deselect. This way a user dont need to click more than 50+ items in the row chart to filter and have few items not to filter.
I do have a code where Javascript detect an event where "CTRL" and "Left click" triggers. but not sure of how to filter all except the ones that are clicked.
I hope this makes sense. I tried to look at the DC.js or Crossfilter api and I cannot find a function that can do that or am i missing something.
It sounds like you want the same behavior except for the very first click, where you want to keep everything else and remove the clicked item if ctrl is pressed.
If there is anything selected, then a click should toggle as usual, whether or not ctrl is pressed.
As Ethan suggests, you could probably implement this as a filterHandler. That should work too, but since it's mostly the same behavior, I'd suggest using an override of onClick.
Unfortunately the technique for overriding this method is not pretty, but it works!
var oldClick = rowChart.onClick;
rowChart.onClick = function(d) {
var chart = this;
if(!d3.event.altKey)
return oldClick.call(chart, d); // normal behavior if no mod key
var current = chart.filters();
if(current.length)
return oldClick.call(chart, d); // normal behavior if there is already a selection
current = chart.group().all()
.map(kv => kv.key)
.filter(k => k != d.key);
chart.replaceFilter([current]).redrawGroup();
};
I used the alt key instead of ctrl because ctrl-click on Macs is a synonym for right-click.
I'm using this on the rowcharts where I need this feature.
It's a little bit shorter than the other answer, maybe it can be useful to someone (I don't know which is better).
// select only one category at a time
mychart.onClick = function(_chart){ return function (d) {
var filter = _chart.keyAccessor()(d);
dc.events.trigger(function () {
_chart.filter(null);
_chart.filter(filter);
_chart.redrawGroup();
});
}; }(mychart)
Where mychart is the name of your dc.rowchart
var mychart = dc.rowChart('#mychart');
[EDIT]
This one works too, is shorter, and works with barcharts
mychart.addFilterHandler(function (filters, filter) {
filters.length = 0; // empty the array
filters.push(filter);
return filters;
});

How to get n(th) element's top in angular's ng-repeat?

I need to get the .top() of an item inside ng-repeat.
How do I get access to the top value after it has been rendered?
Thanks
$index points to current item index in a ng-repeat. Now let say your ng-repeat is something like -
div(ng-if="feeds.length>0" ng-repeat="post in feeds")
then to add a div to the required element you can use -
div(ng-if="feeds.length>0" ng-repeat="post in feeds")
div.bottomEl(ng-if="(feeds.length - $index)==3")
So, now even if you dynamically change the feeds array the bottomEl automatically shifts to the calculated item index.
After which you can easily determine if window has been scrolled till bottomEl by using waypoints like this -
$('.bottomEl').waypoint(function() {
//trigger code here
});
Be sure to initialize waypoint library
<script src="/path/to/waypoints.min.js"></script>

jQuery accordion section index

How can I make this accordion generic? That is, instead of active:2 I want it to point to the next section(may be some function like next() or such...). Similarly, for previous section.
$('#accordion').accordion({collapsible: true, active:2});
Also once if it opens a section , is there a way to focus on the first or last input field of the section?
Any help is appreciated.
$("#selector").accordion({
change : function(event, ui) {
// Your code to expand the next section and/or select the first element
}
// There is also a changestart event you could use instead of change
});

Dojo: dijit.form.select won't fire "onClick" event the first time clicked

I've been through the Dojo docs as well as the API and tried Google but can't find a solution to my problem, I hope anybody here can help me out.
I'm trying to create a dijit.form.select programmatically (using Dojo 1.4) and connect to the "onClick"-event of the widget.
Here's a part of my code:
var dataSelect = new dijit.form.Select({
id : "myselect",
name : "myselect",
labelAttr: "label",
labelType: "html"
},
"selectid");
dataSelect.addOption({value: "value", label: "first item label"});
dojo.connect(dataSelect, "onClick", function() {
alert("clicked!");
});
What it does: A select-box is created replacing an input-field with the ID "selectid", an option "first item label" is created. Everythings all right until here.
Then I connect to the "onClick"-event of the select, which is supposed to load more options via AJAX (but will just display an alert for testing purposes in this example).
The problem: When I click on the little arrow next to the dropdown, the event is fired (OK). But when I click on the select box itself (the area containing the option), the event is NOT fired the first time I click it (unless I clicked on the arrow before).
When I click the select box a second time (and every time after that), the event will fire!
I've tried to use "onFocus" instead of "onClick" which does work, but then the dropdown will not open when first clicked, even if I use the "openDropDown"-function (which does work when connecting to "onClick"!).
Is it me, did I run into a Dojo bug or is it a strange feature I just don't get?
Any help is appreciated.
Greetings,
Select0r
Here is a cross-browser solution:
var sizeSelect = new dijit.form.Select({
id: "sizeSelect",
name: "state",
options: size,
onChange: function(val) {
dojo.style(dojo.byId("textInput"), {"fontSize":val});
}
}, "sizeSelect");
Try to connect not to the widget itself but to it's dom node:
dojo.connect(dataSelect.domNode, "onclick", function() {
alert("clicked!");
});
Select (which extends _HasDropDown) has fancy code to handle:
mouse down on select widget
mouse move to one of the options
mouse up
Maybe that's canceling the click event.
Maybe you can connect to _loadChildren() instead.
The root cause for this issue is that the _onDropDownMouseDown method of dijit._HasDropDown will manipulate the dom node, which cause the e.target of onmousedown and onmouseup changes for the first initialization.
As we know, the onclick event will be triggered only when the target of onmousedown and onmouseup are the same target.
So in this case, the onclick event is not triggered.
It seems that in Dojo 1.5, the problem still remains.

How do I center and show an infobox in bing maps?

My code does a .pantolatlong then a .showinfobox
The info box does not appear, unless I remove the pantolatlong. I guess it is stopping it. I tried adding it to the endpan event but that did not work.
What is the simplest way to pan to a pushpin and display the infobox for it?
I was using setcenter, but I discovered that sometimes setcenter pans, and this breaks it.
After some insane googling, I came up with the solution, and I'll share it here so that others can hopefully not have the grief I went through.
I created and power my bing map using pure javascript, no sdk or iframe solutions. In my code, I generate the javascript to add all of the pins I want to the map, and inject it using an asp.net label.
If you call the setCenter() method on your Bing Map, it is supposed to instantly set the map, surprise surprise, to the coordinates you specify. And it does... most of the time. Occasionally though, it decides to pan between points. If you do a SetCenter, followed by a ShowInfoBox, it will work great, unless it decides to pan.
The solution? Being great programmers we are, we dive into the sdk, and it reveals there are events we can hook into to deal with these. There is an onendpan event, which is triggered after a pan is completed. There is also an onchangeview event, which triggers when the map jumps.
So we hook into these events, and try to display the infobox for our pushpin shape... but nothing happens. Why not?
You have to give it a few milliseconds to catch its breath, for unknown reasons, when the event is called. Using a setTimeout with 10 milliseconds seems to be fine. Your box will appear great after this.
The next problem is, you only want it to appear when it pans via whatever you used to make it flick between your pushpins (in my case, a table with onclick methods). I create/destroy the event handlers on the fly, although there are other options such as using a global variable to track if the user is panning, or if the system is panning in response to a click.
Finally, you have the one bug that comes from this. If you click a place in your list, and it jumps/pans to that location, the infobox will display fine. If the user dismisses it though, then clicks again on the list item, the map does not move, and therefore no events are triggered.
My solution to this is to detect if the map moved or not, by recording its long/lat, and using another setTimeout method, detecting if they changed 100ms later. If they did not, display the infobox.
There are other things you need to keep track of, as there is no way I can see to pass parameters to the eventhandlers so I use global javascript variables for this - you have to know which pushpin shape you are displaying, and also keep track of the previous mapcoordinates before checking to see if they changed.
It took me a while to piece all this together, but it seems to work. Here is my code, some sections are removed:
// An array of our pins to allow panning to them
var myPushPins = [];
// Used by the eventhandler
var eventPinIndex;
var oldMapCenter;
// Zoom in and center on a pin, then show its information box
function ShowPushPin(pinIndex) {
eventPinIndex = pinIndex;
oldMapCenter = map.GetCenter();
map.AttachEvent("onendpan", EndPanHandler);
map.AttachEvent("onchangeview", ChangeViewHandler);
setTimeout("DetectNoMapChange();", 200);
map.SetZoomLevel(9);
map.SetCenter(myPushPins[pinIndex].GetPoints()[0]);
}
function EndPanHandler(e) {
map.DetachEvent("onendpan", EndPanHandler);
setTimeout("map.ShowInfoBox(myPushPins[eventPinIndex]);", 10);
}
function ChangeViewHandler(e) {
map.DetachEvent("onchangeview", ChangeViewHandler);
setTimeout("map.ShowInfoBox(myPushPins[eventPinIndex]);", 10);
}
function DetectNoMapChange(centerofmap) {
if (map.GetCenter().Latitude == oldMapCenter.Latitude && map.GetCenter().Longitude == oldMapCenter.Longitude) {
map.ShowInfoBox(myPushPins[eventPinIndex]);
}
}
Here is another way:
function addPushpin(lat,lon,pinNumber) {
var pinLocation = new Microsoft.Maps.Location(lat, lon);
var pin = new Microsoft.Maps.Pushpin(map.getCenter(), { text: pinNumber.toString() });
pinInfobox = new Microsoft.Maps.Infobox(pinLocation,
{ title: 'Details',
description: 'Latitude: ' + lat.toString() + ' Longitude: ' + lon.toString(),
offset: new Microsoft.Maps.Point(0, 15)
});
map.entities.push(pinInfobox);
map.entities.push(pin);
pin.setLocation(pinLocation);
map.setView({ center: pinLocation});
}