WordPress remove manual Ajax trigger and use infinite scroll - ajax

I have a problem with my script. I want to remove the load more button and instead do an infinite scroll when I get to bottom of the page.
I'm using a WordPress template and without support I'm stuck on this nonsense.
What should I change to do to this script?
jQuery(document).ready(function($){
var $container = $('#hentry-wrapper');
// Isotope
// modified Isotope methods for gutters in masonry
$.Isotope.prototype._getMasonryGutterColumns = function() {
var gutter = this.options.masonry && this.options.masonry.gutterWidth || 0;
containerWidth = this.element.width();
this.masonry.columnWidth = this.options.masonry && this.options.masonry.columnWidth ||
// or use the size of the first item
this.$filteredAtoms.outerWidth(true) ||
// if there's no items, use size of container
containerWidth;
this.masonry.columnWidth += gutter;
this.masonry.cols = Math.floor( ( containerWidth + gutter ) / this.masonry.columnWidth );
this.masonry.cols = Math.max( this.masonry.cols, 1 );
};
$.Isotope.prototype._masonryReset = function() {
// layout-specific props
this.masonry = {};
// FIXME shouldn't have to call this again
this._getMasonryGutterColumns();
var i = this.masonry.cols;
this.masonry.colYs = [];
while (i--) {
this.masonry.colYs.push( 0 );
}
};
$.Isotope.prototype._masonryResizeChanged = function() {
var prevSegments = this.masonry.cols;
// update cols/rows
this._getMasonryGutterColumns();
// return if updated cols/rows is not equal to previous
return ( this.masonry.cols !== prevSegments );
};
var loadMore = $('#load-more');
var posts_per_page = parseInt(loadMore.attr('data-perpage'));
var offset = posts_per_page;
var totalPosts = parseInt(loadMore.attr('data-total-posts'));
var author = parseInt(loadMore.attr('data-author'));
var category = parseInt(loadMore.attr('data-category'));
var tag = loadMore.attr('data-tag');
var datemonth = loadMore.attr('data-month');
var dateyear = loadMore.attr('data-year');
var search = loadMore.attr('data-search');
var loader = $('#posts-count').attr('data-loader');
if (!author) author = 0;
if (!category) category = 0;
if (!tag) tag = '';
if (!datemonth) datemonth = 0;
if (!dateyear) dateyear = 0;
if (!search) search = '';
// cache jQuery window
var $window = $(window);
// start up isotope with default settings
$(window).load(function(){
reLayout();
$window.smartresize( reLayout );
if (offset < totalPosts) {
$('#nav-pagination-load-more').fadeIn(200);
mega_initLoadMore();
}
});
function reLayout() {
var mediaQueryId = getComputedStyle( document.body, ':after' ).getPropertyValue('content');
// fix for firefox, remove double quotes "
//mediaQueryId = mediaQueryId.replace( /"/g, '' );
//console.log( mediaQueryId );
var windowSize = $window.width();
var masonryOpts;
// update sizing options
switch ( mediaQueryId ) {
case 'large' :
masonryOpts = {
gutterWidth: 0
};
break;
case 'big' :
masonryOpts = {
//columnWidth: 297,
gutterWidth: 0
};
break;
case 'medium' :
masonryOpts = {
//columnWidth: 269,
gutterWidth: 0
};
break;
case 'small' :
masonryOpts = {
//columnWidth: $container.width() / 4,
gutterWidth: 0
};
break;
case 'tiny' :
masonryOpts = {
//columnWidth: $container.width() / 1,
gutterWidth: 0
};
break;
}
$container.isotope({
resizable: false, // disable resizing by default, we'll trigger it manually
itemSelector : '.type-post',
transformsEnabled: false, // Firefox Vimeo issue
masonry: masonryOpts
}).isotope( 'reLayout' );
}
function mega_initLoadMore(){
loadMore.click(function(e) {
$(this).unbind("click").addClass('active');
$('#posts-count').html('<img src="'+ loader +'"/>');
e.preventDefault();
mega_loadMorePosts();
});
}
function mega_reLayout(){
$container.isotope( 'reLayout' );
}
function mega_loadMorePosts(){
jQuery.ajax({
url: megaAjax.ajaxurl,
type: 'POST',
data: {
action : 'mega_ajax_blog',
nonce : megaAjax.nonce,
category: category,
author: author,
tag: tag,
datemonth: datemonth,
dateyear: dateyear,
search: search,
offset: offset
},
success: function( data ) {
var $newElems = $(data);
// ensure that images load before adding to masonry layout
$newElems.imagesLoaded( function(){
// FitVids
$('.fluid-video, .entry-content', $newElems).fitVids();
$container.append($newElems).isotope( 'appended', $newElems );
// Flex Slider
$('.flexslider', $newElems).flexslider({
animation: "fade",
slideshow: false,
keyboard: false,
directionNav: true,
touch: true,
prevText: "",
nextText: ""
});
setTimeout(function(){
mega_reLayout();
}, 1000);
offset = offset + posts_per_page;
loadMore.removeClass('active');
if (offset < totalPosts){
$('#posts-count').text('');
loadMore.bind("click", mega_initLoadMore());
}
else {
setTimeout(function(){
loadMore.parent().remove();
}, 1000 );
}
});
}
});
return false;
}
});

I think this script is taken from "HEAT WORDPRESS THEME" directly which is located in js folder of the theme. Its simple to modify,you just need to remove Ajax post loading function and keep Isotop initializing function only. For help see this link
http://www.shambix.com/en/isotope-twitter-bootstrap-infinite-scroll-fluid-responsive-layout/

Related

Mapbox GL Menu Doesn't Respond to First Click

Similar to this question, the layer switcher in my Map does not react to the first click. I learned that this issue has something to do with the definition of the initial visibility on the layers.
Here is the code. Unfortunately I don't know how and where to insert default visibility - do you have an idea?
map.on('click', ({ point }) => {
const features = map.queryRenderedFeatures(point, {
layers: ['City'] // replace with your layer name
});
if (!features.length) {
return;
}
const feature = features[0]; const popup = new mapboxgl.Popup({offset: [0, -15], closeButton: false, closeOnMove: true})
.setMaxWidth("auto")
.setLngLat(feature.geometry.coordinates)
.setHTML(
`<table>\
<tr>\
<td>City</td>\
<td>${feature.properties.City}</td>
</tr>\ </table>`
)
.addTo(map); }); var toggleableLayerIds = ['City']
for (var i = 0; i < toggleableLayerIds.length; i++) {
var id = toggleableLayerIds[i]
var link = document.createElement('a')
link.href = '#'
link.className = 'active'
link.textContent = id
link.onclick = function (e) {
var clickedLayer = this.textContent
e.preventDefault()
e.stopPropagation()
var visibility = map.getLayoutProperty(clickedLayer, 'visibility')
if (visibility === 'visible') {
map.setLayoutProperty(clickedLayer, 'visibility', 'none')
this.className = ''
} else {
this.className = 'active'
map.setLayoutProperty(clickedLayer, 'visibility', 'visible')
}
}
var layers = document.getElementById('menu')
layers.appendChild(link)
}

Google Maps: add listener to dynamically created marker outside initialize function

I have been trying for days to add an event listener for an infoWindow to markers that are created on Ajax success.
The mouseover event is never fired, so there must be something I'm doing wrong in adding the listener.
The listener that does NOT work is for the marker restMarker. The dragend listener for addressMarker in the initialize() function works fine.
I have tried adding the listener in multiple ways: google.maps.event.addListener(markerObject,'mouseover',function(){}) and markerObject.addListener('mouseover',function(){}).
I have tried giving the restMarker global scope.
I have read the following:
Dynamically Adding Listeners To Google Maps Markers
create event listener to dynamically created google-map marker
...and more.
I have infoWindows working fine with dynamically created markers in other projects. The only difference I'm aware of in the working projects is that the markers are created in the map initialize() function instead of in an ajax success function.
Am I doing anything obviously wrong?
<script type='text/javascript'>
var zoneMap;
var currentRestMarkers = [];
var markerInfoWindow;
var distances = [{"fee":2,"distance":5,"available":1},{"fee":3,"distance":7,"available":1},{"available":1,"distance":9,"fee":7},{"fee":9,"available":0,"distance":10}];
var ajaxResponse = {"success":[{"duration":"11.5","name":"Backyard Bistro","lng":-78.7253,"lat":35.7989,"distance":6.64,"restId":"179"},{"lat":35.7796,"lng":-78.6758,"restId":"180","distance":7.5,"name":"Baja Burrito","duration":"13.3"},{"name":"Mi Rancho","duration":"15.6","lng":-78.6482,"lat":35.7491,"restId":"183","distance":6.32},{"lat":35.7757,"lng":-78.6363,"distance":4.67,"restId":"188","name":"El Rodeo Downtown","duration":"13.7"},{"duration":"9.2","name":"El Rodeo North","lng":-78.6262,"lat":35.8137,"distance":3.35,"restId":"189"},{"name":"Fallon's Flowers","duration":"9.1","restId":"192","distance":2.92,"lat":35.789,"lng":-78.6507},{"lng":-78.6397,"lat":35.7742,"restId":"193","distance":4.62,"name":"Fire Wok","duration":"14.1"},{"lng":-78.6131,"lat":35.8051,"restId":"194","distance":6.21,"name":"Gateway","duration":"9.8"},{"restId":"195","distance":27.99,"lng":-79.0564,"lat":35.9152,"name":"Gift Cards ","duration":"35.6"},{"name":"Jumbo China","duration":"8.5","lng":-78.6262,"lat":35.819,"distance":2.87,"restId":"197"},{"lng":-78.6456,"lat":35.8817,"restId":"198","distance":4.93,"name":"La Rancherita","duration":"12.0"},{"duration":"8.9","name":"Mami Nora's","restId":"205","distance":3.35,"lat":35.8137,"lng":-78.6271},{"distance":2.94,"restId":"209","lat":35.7883,"lng":-78.6474,"duration":"8.0","name":"Mellow Mushroom"},{"distance":7.88,"restId":"212","lng":-78.7387,"lat":35.7878,"duration":"12.3","name":"Ole Time BBQ"},{"lng":-78.6388,"lat":35.8374,"restId":"214","distance":2.23,"duration":"7.0","name":"Piola"},{"name":"The Remedy Diner 2.0 - Brunch","duration":"11.9","lng":-78.656,"lat":35.7824,"distance":4.24,"restId":"216"},{"lng":-78.656,"lat":35.7824,"restId":"217","distance":4.24,"duration":"11.9","name":"The Remedy Diner 2.0"},{"distance":7.66,"restId":"218","lng":-78.6773,"lat":35.7777,"name":"Sammy's Tap & Grill","duration":"13.4"},{"lng":-78.621,"lat":35.8238,"distance":4.39,"restId":"219","duration":"8.4","name":"Shaba Shabu"},{"name":"Spring Rolls","duration":"5.9","distance":1.88,"restId":"220","lng":-78.6409,"lat":35.8399},{"duration":"9.6","name":"Thaiphoon","restId":"222","distance":3.2,"lat":35.7845,"lng":-78.6477},{"lat":35.7776,"lng":-78.6398,"restId":"223","distance":4.3,"duration":"11.6","name":"The Big Easy"},{"lng":-78.6433,"lat":35.8364,"restId":"225","distance":1.68,"duration":"5.5","name":"The Q Shack"},{"duration":"14.4","name":"Vic's Italian","lng":-78.6356,"lat":35.7759,"restId":"226","distance":4.72},{"restId":"227","distance":1.68,"lng":-78.6433,"lat":35.8364,"name":"Which Wich North Hills","duration":"5.5"},{"lat":35.7912,"lng":-78.6799,"restId":"245","distance":5.89,"duration":"10.5","name":"The Wild Cook's Indian Grill"},{"lng":-78.6237,"lat":35.873,"restId":"301","distance":4.68,"name":"Taj Mahal North","duration":"12.9"},{"restId":"820","distance":6.29,"lng":-78.6825,"lat":35.8986,"duration":"14.5","name":"El Dorado "},{"name":"Taza Grill","duration":"12.8","restId":"821","distance":4.84,"lat":35.8693,"lng":-78.6211},{"duration":"14.9","name":"Sassool","restId":"824","distance":6.83,"lat":35.9043,"lng":-78.6567},{"lng":-78.5797,"lat":35.8477,"distance":8.45,"restId":"830","name":"Alpaca Peruvian Charcoal Chicken","duration":"13.9"},{"distance":6.21,"restId":"831","lat":35.899,"lng":-78.653,"name":"Shish Kabob Six Forks","duration":"14.1"},{"distance":2.87,"restId":"923","lng":-78.6262,"lat":35.819,"name":"Tropical Picken Chicken","duration":"8.5"},{"duration":"10.3","name":"Wicked Taco","lat":35.7852,"lng":-78.6923,"restId":"931","distance":6.48},{"duration":"14.8","name":"Despina's Cafe","restId":"1142","distance":6.31,"lng":-78.6824,"lat":35.9015},{"duration":"4.7","name":"WhichWich Crabtree","lat":35.8391,"lng":-78.6752,"distance":1.7,"restId":"1242"},{"duration":"6.3","name":"Pharaoh's Grill at North Hills","distance":1.86,"restId":"1296","lng":-78.6434,"lat":35.8403},{"name":"Pharaoh's at the Museum","duration":"12.2","restId":"1297","distance":4.43,"lat":35.7818,"lng":-78.6386},{"restId":"1298","distance":2.54,"lng":-78.6298,"lat":35.8215,"name":"Gorilla Grill","duration":"6.5"},{"name":"My Way Tavern","duration":"9.8","lng":-78.6506,"lat":35.7872,"restId":"1307","distance":3.04}]};
function initialize() {
var myLatlng = new google.maps.LatLng(35.8013,-78.6409);
var geocoder = new google.maps.Geocoder();
var mapOptions = {
zoom: 13,
center: myLatlng,
panControl: false,
zoomControl: true,
mapTypeControl: false,
scaleControl: true,
streetViewControl: false,
overviewMapControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
zoneMap = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
var addressMarker = new google.maps.Marker({
position: zoneMap.center,
map: zoneMap,
clickable: true,
draggable: true,
flat: true,
icon: 'https://maps.google.com/mapfiles/ms/icons/blue-dot.png'
});
google.maps.event.addListener(addressMarker, 'dragend', function(event) {
var markerNewLatLng=event.latLng;
geocoder.geocode({'latLng': markerNewLatLng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
showAvailableRests(markerNewLatLng.lat(),markerNewLatLng.lng());
}
else {
console.log('Geocoder failed due to: ' + status);
}
});
});
}
function loadScript() {
var acScript = document.createElement('script');
acScript.type = 'text/javascript';
acScript.src = 'https://maps.googleapis.com/maps/api/js?libraries=places&callback=initialize';
document.body.appendChild(acScript);
}
function showAvailableRests(whichLat,whichLng) {
var rest_list = jQuery('#rest_list');
jQuery(rest_list).empty();
jQuery('#restCount').html('');
if (currentRestMarkers.length > 0) {
for (var i in currentRestMarkers) {
currentRestMarkers[i].setMap(null);
}
currentRestMarkers = [];
}
var restCount = 0;
for (var i=0; i < ajaxResponse.success.length; i++ ) {
var iconColor = 'green.png';
var available = 1;
var tierClass = 'tier1';
for (var j=0; j < distances.length; j++ ) {
if (ajaxResponse.success[i].distance >= distances[j].distance) {
if (distances[j].available == 0) {
available = 0;
}
if (j === 0) {
iconColor = 'yellow.png';
tierClass = 'tier2';
}
else if (j === 1) {
iconColor = 'orange.png';
tierClass = 'tier3';
}
else if (j > 1) {
iconColor = 'purple.png';
tierClass = 'tier4';
}
}
else {
break; // if it is not greater than the shorter distance, it is not greater than longer ones either
}
}
if (available === 0) { // if this restaurant is not available at this distance
//continue; // skip the rest for unavailable
iconColor = 'red.png';
tierClass = 'unavailable';
}
else {
restCount++;
}
var restDiv = jQuery(document.createElement('div'));
var distanceTier = jQuery(document.createElement('span')).html(' ').addClass('distance-tier ' + tierClass).appendTo(restDiv);
var restDist = jQuery(document.createElement('span')).html(ajaxResponse.success[i].distance + ' mi.').addClass('rest-distance').appendTo(restDiv);
var restName = jQuery(document.createElement('span')).html(ajaxResponse.success[i].name).addClass('rest-name').appendTo(restDiv);
jQuery(restDiv).appendTo(rest_list);
var restMarkerPosition = new google.maps.LatLng(ajaxResponse.success[i].lat,ajaxResponse.success[i].lng);
var restMarker = new google.maps.Marker({
position: restMarkerPosition,
map: zoneMap,
clickable: false,
draggable: false,
flat: true,
icon: 'https://maps.google.com/mapfiles/ms/icons/' + iconColor
});
currentRestMarkers.push(restMarker);
google.maps.event.addListener(restMarker, 'mouseover', function(e) {
console.log('mouseover event fired'); // the mouseover event is never fired!!!
showRestWindow(e, ajaxResponse.success[i].name, ajaxResponse.success[i].distance);
});
/*restMarker.addListener('mouseover', function() {
new google.maps.InfoWindow({
content: "<div><strong>" + ajaxResponse.success[i].name + "<\/strong><br>" + ajaxResponse.success[i].distance + " miles<\/div>",
disableAutoPan: true,
});
markerInfoWindow.open(zoneMap, this);
});*/
jQuery('#restCount').html(restCount);
}
}
function showRestWindow(event, name, distance) {
markerInfoWindow = new google.maps.InfoWindow({
content: "<div><strong>" + name + "<\/strong><br>" + distance + " miles<\/div>",
disableAutoPan: true,
position: event.latLng,
});
markerInfoWindow.open(zoneMap);
};
jQuery(document).ready(function () {
loadScript();
return false;
});
</script>
<div id='map_container'>
<div id='map_canvas'></div>
</div>
<div id='column_right'>
<p><b>Available Restaurants: <span id='restCount'></span></b></p>
<div id='rest_list'></div>
</div>

OpenLayers3 : Draggable OverviewMapControl

In OpenLayers 2, in the OverviewMapControl, you can drag the "box" to move the map.
You can not do this in OpenLayers 3.
I've tried to implement a custom control based on https://github.com/openlayers/ol3/blob/master/src/ol/control/overviewmapcontrol.js, but you can not use goog.xxx or other fancy stuff like ol.extent.scaleFromCenter when you are not in debug !
How should I proceed ?
basically, implementing drag'n drop is fairly "simple" :
var dragging = null;
var getMap = this.getMap.bind(this); //during ctor of a control, we have no access to the map !
$(document.body).on("mousemove", function (e) {
if (dragging) {
dragging.el.offset({
top: e.pageY,
left: e.pageX
});
}
});
$(box).on("mousedown", function (e) {
dragging = {
el: $(e.target)
};
});
$(document.body).on("mouseup", function (e) {
if (dragging) {
debugger;
var coords = ovmap.getEventCoordinate(e.originalEvent);
//TODO: taking event coordinates is not good, we must use center of the box coordinates
//the problem is that ovmap.getCoordinateFromPixel(dragging.el.offset()) is not working at all because we need to adjust ovmap viewport
getMap().getView().setCenter(coords);
dragging = null;
}
});
For those interested (which does not seem to be the case at the moment :)), here is the way I solved
/**
* Mostly a big copy/paste from https://raw.githubusercontent.com/openlayers/ol3/master/src/ol/control/overviewmapcontrol.js
* without rotation and zoom/dezoom plus some adapations from http://ol3.qtibia.ro/build/examples/overviewmap-custom-drag.html
* to add the possibility to drag the box on the minimap to move the main map
*/
ol.control.CustomOverviewMap = function (opt_options) {
var options = typeof opt_options !== 'undefined' ? opt_options : {};
this.collapsed_ = typeof options.collapsed !== 'undefined' ? options.collapsed : true;
this.onCollapseOrExpand = options.onCollapseOrExpand || function () { };
this.needFirstRenderUpdate_ = this.collapsed_; //prepare the hack to render the map when uncollapsed the first time
var tipLabel = typeof options.tipLabel !== 'undefined' ? options.tipLabel : 'Overview map';
this.collapseLabel_ = $('<span>\u00BB</span>').get(0);
this.label_ = $('<span>\u00AB</span>').get(0);
var activeLabel = (!this.collapsed_) ? this.collapseLabel_ : this.label_;
var button = $('<button type="button" title="{0}"></button>'.replace('{0}', tipLabel)).append(activeLabel);
button.on('click', this.handleClick_.bind(this));
//ol.control.Control.bindMouseOutFocusOutBlur(button);
button.on('mouseout', function () { this.blur(); });
button.on('focusout', function () { this.blur(); });
var ovmapDiv = $('<div class="ol-overviewmap-map"></div>').get(0);
this.ovmap_ = new ol.Map({
controls: new ol.Collection(),
interactions: new ol.Collection(),
layers: [options.tileLayer],
target: ovmapDiv,
view: new ol.View(opt_options.view)
});
var box = $('<div class="ol-overviewmap-box"></div>');
this.boxOverlay_ = new ol.Overlay({
position: [0, 0],
positioning: 'bottom-left',
element: box.get(0)
});
this.ovmap_.addOverlay(this.boxOverlay_);
var cssClasses = 'ol-overviewmap ol-unselectable ol-control' +
(this.collapsed_ ? ' ol-collapsed' : '');
var element = $('<div class="{0}"></div>'.replace('{0}', cssClasses)).append(ovmapDiv).append(button).get(0);
ol.control.Control.call(this, {
element: element,
render: ol.control.CustomOverviewMap.render
});
// deal with dragable minimap
this.dragging = null;
box.on("mousedown", this.onStartDrag.bind(this));
$(document.body).on("mousemove", this.onDrag.bind(this));
$(document.body).on("mouseup", this.onEndDrag.bind(this));
};
ol.inherits(ol.control.CustomOverviewMap, ol.control.Control);
ol.control.CustomOverviewMap.prototype.onStartDrag = function (e) {
// remember some data to use during onDrag or onDragEnd
var box = $(e.target);
this.dragging = {
el: box,
evPos: { top: e.pageY, left: e.pageX },
elPos: box.offset()
};
}
ol.control.CustomOverviewMap.prototype.onDrag = function (e) {
if (this.dragging) {
//set the position of the box to be oldPos+translation(ev)
var curOffset = this.dragging.el.offset();
var newOffset = {
top: curOffset.top + (e.pageY - this.dragging.evPos.top),
left: curOffset.left + (e.pageX - this.dragging.evPos.left)
};
this.dragging.evPos = { top: e.pageY, left: e.pageX };
this.dragging.el.offset(newOffset);
}
}
ol.control.CustomOverviewMap.prototype.onEndDrag = function (e) {
if (this.dragging) {
//see ol3.qtibia.ro href at the top of the class to understand this
var map = this.getMap();
var offset = this.dragging.el.position();
var divSize = [this.dragging.el.width(), this.dragging.el.height()];
var mapSize = map.getSize();
var c = map.getView().getResolution();
var xMove = offset.left * (Math.abs(mapSize[0] / divSize[0]));
var yMove = offset.top * (Math.abs(mapSize[1] / divSize[1]));
var bottomLeft = [0 + xMove, mapSize[1] + yMove];
var topRight = [mapSize[0] + xMove, 0 + yMove];
var left = map.getCoordinateFromPixel(bottomLeft);
var top = map.getCoordinateFromPixel(topRight);
var extent = [left[0], left[1], top[0], top[1]];
map.getView().fitExtent(extent, map.getSize());
map.getView().setResolution(c);
//reset the element at the original position so that when the main map will trigger
//the moveend event, this event will be replayed on the box of the minimap
this.dragging.el.offset(this.dragging.elPos);
this.dragging = null;
}
}
ol.control.CustomOverviewMap.render = function (mapEvent) {
//see original OverviewMap href at the top of the class to understand this
var map = this.getMap();
var ovmap = this.ovmap_;
var mapSize = map.getSize();
var view = map.getView();
var ovview = ovmap.getView();
var overlay = this.boxOverlay_;
var box = this.boxOverlay_.getElement();
var extent = view.calculateExtent(mapSize);
var ovresolution = ovview.getResolution();
var bottomLeft = ol.extent.getBottomLeft(extent);
var topRight = ol.extent.getTopRight(extent);
overlay.setPosition(bottomLeft);
// set box size calculated from map extent size and overview map resolution
if (box) {
var boxWidth = Math.abs((bottomLeft[0] - topRight[0]) / ovresolution);
var boxHeight = Math.abs((topRight[1] - bottomLeft[1]) / ovresolution);
$(box).width(boxWidth).height(boxHeight);
}
};
ol.control.CustomOverviewMap.prototype.handleClick_ = function (event) {
event.preventDefault();
this.collapsed_ = !this.collapsed_;
$(this.element).toggleClass('ol-collapsed');
// change label
if (this.collapsed_) {
this.collapseLabel_.parentNode.replaceChild(this.label_, this.collapseLabel_);
} else {
this.label_.parentNode.replaceChild(this.collapseLabel_, this.label_);
}
// manage overview map if it had not been rendered before and control is expanded
if (!this.collapsed_ && this.needFirstRenderUpdate_) {
this.needFirstRenderUpdate_ = false;
this.ovmap_.updateSize();
this.ovmap_.once("postrender", function () {
this.render();
}.bind(this));
}
//trigger event
this.onCollapseOrExpand(this.collapsed_);
};

Simile Timeline - Events present but not displaying

I am working on a site that uses the Simile Timeline. I am using Kendo Core for the single page application components. I am loading the timeline from the results of an ajax request. I am manually adding the events. When I check the console the events are populated on the event source. However events do not display.
What do I need to change to get the events to display on the timeline?
Thanks in advance.
///////////////////////////////
// Timeline
///////////////////////////////
var timelineViewModel = kendo.observable({
InitUI: function (id) {
var self = this;
$.ajax({
url: "api/timelines/" + id,
type: "GET",
dataType: "json",
contentType: "application/json",
success: function (data) {
self.loadTimeLine(data);
}
});
},
loadTimeLine: function (data) {
SimileAjax.History.enabled = false;
$('#TimelineTitle').text(data.title);
var tl_el = document.getElementById("my-timeline");
var eventSource1 = new Timeline.DefaultEventSource();
for(var eIndex = 0; eIndex < data.events.length; eIndex ++)
{
var evt = new Timeline.DefaultEventSource.Event({
title: data.events[eIndex].title,
start: data.events[eIndex].start,
description: data.events[eIndex].description,
caption: data.events[eIndex].title,
color: '#FFCC33',
text: data.events[eIndex].title
});
eventSource1._events.add(evt);
}
var theme1 = Timeline.ClassicTheme.create();
theme1.event.bubble.width = 320;
theme1.event.bubble.height = 220;
var d = data.MinDate;
var bandInfos = [
Timeline.createBandInfo({
width: 100, // set to a minimum, autoWidth will then adjust
intervalUnit: Timeline.DateTime.YEAR,
intervalPixels: 200,
eventSource: eventSource1,
date: d,
theme: theme1,
layout: 'overview'
}),
Timeline.createBandInfo({
width: 100, // set to a minimum, autoWidth will then adjust
intervalUnit: Timeline.DateTime.MONTH,
intervalPixels: 200,
eventSource: eventSource1,
date: d,
theme: theme1,
layout: 'overview'
}),
Timeline.createBandInfo({
width: 350, // set to a minimum, autoWidth will then adjust
intervalUnit: Timeline.DateTime.WEEK,
intervalPixels: 200,
eventSource: eventSource1,
date: d,
theme: theme1,
layout: 'original'
})
];
bandInfos[1].syncWith = 2;
bandInfos[1].highlight = true;
bandInfos[0].syncWith = 2;
bandInfos[0].highlight = true;
tl = Timeline.create(tl_el, bandInfos, Timeline.VERTICAL);
tl.layout();
}
})
var timelineView = new kendo.View(
"timelineTemplate",
{
model: timelineViewModel
}
);
///////////////////////////////
// Layout
///////////////////////////////
var layout = new kendo.Layout("<div id='content'></div>");
///////////////////////////////
// DAS ROUTER
///////////////////////////////
var router = new kendo.Router();
router.route("(:viewName)/(:id)", function (viewName, id) {
layout.render("#maincontent");
if (viewName) {
switch (viewName.toLowerCase()) {
case "timeline":
if (id) {
if (id.toLowerCase() == "new") {
layout.showIn("#content", createTimelineView);
createTimelineViewModel.InitUI();
}
else {
layout.showIn("#content", timelineView);
timelineViewModel.InitUI(id);
}
}
break;
case "account":
if (id) {
layout.showIn("#content", accountView);
accountViewModel.InitUI(id);
}
break;
}
}
else {
layout.showIn("#content", indexView);
indexViewModel.InitUI();
}
});
$(function () {
router.start();
});

Vertical and horizontal scrollable ion-content with ion-infinite-scroll only vertically

Inside my ion-content I have a list which when scrolled to the bottom more items are loaded (provided by ion-infinite-scroll which calls 'LoadMore()').
The problem is that if I set direction = xy to ion-content, ion-infinite-scroll calls 'LoadMore()' if I scroll vertically and horizontally.
It is possible to my ion-infinite-scroll only call 'LoadMore()' when scrolled vertically?
Currently ionic version beta.13 does not support this feature.
I already have posted my suggested solution on ionic repository ( https://github.com/driftyco/ionic/issues/1073 )
I've created 'ion-infinite-scroll-fixed' directive wich differs only in last if block:
.directive('ionInfiniteScrollFixed', ['$timeout', function($timeout) {
function calculateMaxValue(distance, maximum, isPercent) {
return isPercent ?
maximum * (1 - parseFloat(distance,10) / 100) :
maximum - parseFloat(distance, 10);
}
return {
restrict: 'E',
require: ['^$ionicScroll', 'ionInfiniteScrollFixed'],
template: '<i class="icon {{icon()}} icon-refreshing"></i>',
scope: true,
controller: ['$scope', '$attrs', function($scope, $attrs) {
this.isLoading = false;
this.scrollView = null; //given by link function
this.getMaxScroll = function() {
var distance = ($attrs.distance || '2.5%').trim();
var isPercent = distance.indexOf('%') !== -1;
var maxValues = this.scrollView.getScrollMax();
return {
left: this.scrollView.options.scrollingX ?
calculateMaxValue(distance, maxValues.left, isPercent) :
-1,
top: this.scrollView.options.scrollingY ?
calculateMaxValue(distance, maxValues.top, isPercent) :
-1
};
};
}],
link: function($scope, $element, $attrs, ctrls) {
var scrollCtrl = ctrls[0];
var infiniteScrollCtrl = ctrls[1];
var scrollView = infiniteScrollCtrl.scrollView = scrollCtrl.scrollView;
$scope.icon = function() {
return angular.isDefined($attrs.icon) ? $attrs.icon : 'ion-loading-d';
};
var onInfinite = function() {
$element[0].classList.add('active');
infiniteScrollCtrl.isLoading = true;
$scope.$parent && $scope.$parent.$apply($attrs.onInfinite || '');
};
var finishInfiniteScroll = function() {
$element[0].classList.remove('active');
$timeout(function() {
scrollView.resize();
checkBounds();
}, 0, false);
infiniteScrollCtrl.isLoading = false;
};
$scope.$on('scroll.infiniteScrollComplete', function() {
finishInfiniteScroll();
});
$scope.$on('$destroy', function() {
void 0;
if(scrollCtrl && scrollCtrl.$element)scrollCtrl.$element.off('scroll', checkBounds);
});
var checkBounds = ionic.animationFrameThrottle(checkInfiniteBounds);
//Check bounds on start, after scrollView is fully rendered
setTimeout(checkBounds);
scrollCtrl.$element.on('scroll', checkBounds);
function checkInfiniteBounds() {
if (infiniteScrollCtrl.isLoading) return;
var scrollValues = scrollView.getValues();
var maxScroll = infiniteScrollCtrl.getMaxScroll();
if ((maxScroll.left !== -1 && scrollValues.left >= maxScroll.left && $attrs.notOnHorizontal !=="true") ||
(maxScroll.top !== -1 && scrollValues.top >= maxScroll.top && $attrs.notOnVertical !=="true")) {
onInfinite();
}
}
}
};
}]);
and in my HTML:
<ion-infinite-scroll-fixed
not-on-horizontal="true"
ng-if="infiniteScroll.canLoad"
on-infinite="infiniteScroll.loadMore();"
distance="1%">
</ion-infinite-scroll-fixed>
I hope this can help somebody :)

Resources