I am using this:
$(function() {
// initialize scrollable
window.api = $("div.scrollable").scrollable({
clickable: true,
activeClass: "active",
onSeek: function() {
alert("current position is: " + this.getIndex());
//remove highlighting from all images
$(".items img").removeClass("selected");
var position = this.getIndex().toString();
var thisItem = $(".items:nth-child(" + position + ")");
//var thisItem = allItems(this.getIndex);
alert("item is: " + $(this).attr('alt'));
changeimage($(".items:nth-child(2)"));
}
}).circular().autoscroll({
interval: 4000,
api: true,
autoplay: false,
steps: 1
});
});
(just testing) so that I can parse the current item to my changeimage() function
But all I get in my alerts are undefined.
WHat do I need to do here to get the current item
You can get the current item using the api by calling the following:
var currentItem = window.api.getItems().eq(window.api.getIndex());
The getIndex() function gets a numerical position of the element and getItems gets a jquery object with all the items within it. Using the eq() function asks for the item at the given position.
I've sometimes had bad luck with it, but within the onSeek callback, you should be able to use 'this' variable in place of the windows.api which would look like:
var currentItem = this.getItems().eq(this.getIndex());
Related
I'm trying to make a call to the searchManager.geocode function and return the location object to be stored in an array.
I'm a javascript novice, so I expect this is probably a question more fundamental to javacript than to bing maps, but...
I'm experimenting with the Bing Maps search using this demo as my template:
https://www.bing.com/api/maps/sdk/mapcontrol/isdk/searchbyaddress
Here is the example:
var map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
/* No need to set credentials if already passed in URL */
center: new Microsoft.Maps.Location(47.624527, -122.355255),
zoom: 8 });
Microsoft.Maps.loadModule('Microsoft.Maps.Search', function () {
var searchManager = new Microsoft.Maps.Search.SearchManager(map);
var requestOptions = {
bounds: map.getBounds(),
where: 'Seattle',
callback: function (answer, userData) {
map.setView({ bounds: answer.results[0].bestView });
map.entities.push(new Microsoft.Maps.Pushpin(answer.results[0].location));
}
};
searchManager.geocode(requestOptions);
});
What I would like to do is not actually do any work in the callback function, but simply return the location (`answer.results[0]') so that I can make a series of calls like this:
locations.push(geocodeAddress("address 1, city, state"));
locations.push(geocodeAddress("address 2, city, state"));
That locations array will be used for map bounds, adding pushpins, etc later.
Since the geocode function is an async one, you can't ask it to immediately return something for later use. However, what you could do is pushing the location to array directly in the callback function:
var map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
/* No need to set credentials if already passed in URL */
center: new Microsoft.Maps.Location(47.624527, -122.355255),
zoom: 8 });
var locations = [];
Microsoft.Maps.loadModule('Microsoft.Maps.Search', function () {
var searchManager = new Microsoft.Maps.Search.SearchManager(map);
var requestOptions = {
bounds: map.getBounds(),
where: 'Seattle',
callback: function (answer, userData) {
locations.push(answer.results[0].location);
}
};
searchManager.geocode(requestOptions);
});
And your later calls would just be below since pushing to array is already taken care of:
geocodeAddress("address 1, city, state");
geocodeAddress("address 2, city, state");
Of course, you would still need some mechanism to keep track that all geocode calls are finished before using the locations array (perhaps through a counter in each callback). Also you would only need to load the Microsoft.Maps.Search module once despite repetitive usage.
I have a global database of objects (points on a map) that I would like to show on a Leaflet map. Instead of loading all the database (simply too big) at once and creating the objects on a Leaflet LayerGroup, is there a more efficient way to go about querying data, perhaps as each map tile loads, or am I looking at creating a custom solution for this?
You could watch the 'moveend' event on map with map.on('moveend',loadstuff), make an ajax call inside loadstuff() to grab markers inside the current map.getBounds(), and then add/remove markers(I would assume you have some sort of global identifier for each of them) whether they are inside or outside the current view.
There's a standard and efficient way around doing what snkashis said. Create a tiled geoJSON service, and use the leaflet-tilelayer-geojson plugin.
Then all the code you would need browser-side is (from the Github page):
var geojsonURL = 'http://polymaps.appspot.com/state/{z}/{x}/{y}.json';
var geojsonTileLayer = new L.TileLayer.GeoJSON(geojsonURL, {
clipTiles: true,
unique: function (feature) {
return feature.id;
}
}, {
style: style,
onEachFeature: function (feature, layer) {
if (feature.properties) {
var popupString = '<div class="popup">';
for (var k in feature.properties) {
var v = feature.properties[k];
popupString += k + ': ' + v + '<br />';
}
popupString += '</div>';
layer.bindPopup(popupString);
}
if (!(layer instanceof L.Point)) {
layer.on('mouseover', function () {
layer.setStyle(hoverStyle);
});
layer.on('mouseout', function () {
layer.setStyle(style);
});
}
}
}
);
map.addLayer(geojsonTileLayer);
This question is similar to knockoutjs databind with jquery-ui datepicker, but instead of the jQueryUI datepicker, I would like to use one of the Bootstrap datepickers.
The API for the Bootstrap datepicker is different from jquery-ui, and I am having some trouble wrapping my head around making it work with knockout.js. I have created a jsFiddle to try it out.
It seems like the Bootstrap datepicker could be much simpler to use because it does not independently store the date. However, I would like to know how whether the jsFiddle is the appropriate way to use the Bootstrap datepicker widget with knockout.js i.e.
ko.bindingHandlers.datepicker = {
init: function(element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {};
$(element).datepicker(options);
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).datepicker("destroy");
});
},
update: function(element, valueAccessor) {
}
};
Here is a sample of how you could accomplish this with the datepicker that you are using:
ko.bindingHandlers.datepicker = {
init: function(element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {};
$(element).datepicker(options);
//when a user changes the date, update the view model
ko.utils.registerEventHandler(element, "changeDate", function(event) {
var value = valueAccessor();
if (ko.isObservable(value)) {
value(event.date);
}
});
},
update: function(element, valueAccessor) {
var widget = $(element).data("datepicker");
//when the view model is updated, update the widget
if (widget) {
widget.date = ko.utils.unwrapObservable(valueAccessor());
if (widget.date) {
widget.setValue();
}
}
}
};
It did not look like there was any destroy functionality, so I removed that piece. This handles the widgets changeDate event to update the view model, when a user changes the date. The update function handles when the view model is changed to update the widget.
If you want to bind the value to a non-observable, then it would take a little more code. Let me know if that is something that you need to support.
http://jsfiddle.net/rniemeyer/KLpq7/
my current version is a mix between the already shown solutions:
ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
var unwrap = ko.utils.unwrapObservable;
var dataSource = valueAccessor();
var binding = allBindingsAccessor();
//initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {};
$(element).datepicker(options);
$(element).datepicker('update', dataSource());
//when a user changes the date, update the view model
ko.utils.registerEventHandler(element, "changeDate", function (event) {
var value = valueAccessor();
if (ko.isObservable(value)) {
value(event.date);
}
});
},
update: function (element, valueAccessor) {
var widget = $(element).data("datepicker");
var value = ko.utils.unwrapObservable(valueAccessor());
//when the view model is updated, update the widget
if (widget) {
widget.date = value;
if (widget.date) {
widget.setValue();
$(element).datepicker('update', value)
}
}
}};
The accepted answer didn't work for me with the current version of the date picker. The input wasn't being initialized with the value of the observable. I made an updated binding, to which I added this:
$(element).datepicker('update', dataSource());
That seems to do the trick.
Here's an updated fiddle that uses the latest available date picker, Bootstrap, jQuery, and Knockout: http://jsfiddle.net/krainey/nxhqerxg/
Update:
I experienced some difficulty with the date picker not playing nicely with the observable when a user would edit the value in the text field manually. The tool would immediately parse the date, and plug the result into the input field.
If the user tried to edit 10/07/2014, for example, and used the backspace or delete to remove a number (10/0/2014), the resulting value would be parsed immediately and inserted into the text input. If the value was, for a moment, 10/0/2014, the picker would shift the calendar to 09/30/2014, and plug that value into the text field. If I tried to edit the month, and the value was, for a moment, 1/7/2014, the picker would shift to January 7, 2014, and plug that value in to the text field.
You can see that behavior in this fiddle:
http://jsfiddle.net/krainey/nxhqerxg/10/
I had to update my binding with a special handler to detect focus, and bind a one-time blur event to get it to handle manual edits correctly.
$(element).on("changeDate", function (ev) {
var observable = valueAccessor();
if ($(element).is(':focus')) {
// Don't update while the user is in the field...
// Instead, handle focus loss
$(element).one('blur', function(ev){
var dateVal = $(element).datepicker("getDate");
observable(dateVal);
});
}
else {
observable(ev.date);
}
});
The fiddle referenced in the original answer has been updated to reflect this:
http://jsfiddle.net/krainey/nxhqerxg/
Here is what I Ended up
ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = {
autoclose: true,
format: 'yyyy-mm-dd',
}
//var options = allBindingsAccessor().datepickerOptions || {};
$(element).datepicker(options);
//when a user changes the date, update the view model
ko.utils.registerEventHandler(element, "changeDate", function (event) {
var value = valueAccessor();
if (ko.isObservable(value)) {
var myDate = event.date;
var month = myDate.getMonth() + 1;
var monthText = month;
if (month < 10)
monthText = "0" + month;
var day1 = parseInt(myDate.getDate());
var dayText = day1;
if (day1 < 10)
dayText = '0' + day1;
value(myDate.getFullYear() + '-' + monthText + '-' + dayText);
}
});
},
update: function (element, valueAccessor) {
var widget = $(element).data("datepicker");
//when the view model is updated, update the widget
if (widget) {
widget.date = ko.utils.unwrapObservable(valueAccessor());
widget.setValue(widget.date);
}
}};
There is a much simpler way to get bootstrap-datepicker.js and knockout.js working together. Typically the initialization of the datepicker inputs is invoked during/after the page load. However when knockout.js updates the value binding, the datepicker is not updated correctly with the new value and so when you focus on the datepicker input it defaults to 01-Jan-2001.
All you have to do is to destroy and reinitialise the datepicker inputs after any knockout.js value bindings are updated as per the ViewModel method below, which sets up a mapped object to be edited.
self.showEditOrderForm = function (data) {
ko.mapping.fromJS(data, self.entity);
self.mode('edit');
$('#edit-dateordered').datepicker('destroy');
$('#edit-dateordered').datepicker({
format: 'dd-M-yyyy',
title: 'Select Date',
weekStart: 1,
todayHighlight: true,
autoClose: true,
endDate: '0d'
});
};
I have had some trouble with fetching json from a groups events on facebook and then put them in a tableview to be used in a Appcelerator mobile app.
The idea is to have this as a calendar to show events for a club in a simple way.
I want to show the name of the event. The picture for that event and the date for the event.
All in a tablerow.
I have gotten to the part where i can get the Name and date for the events with this code:
Ti.UI.backgroundColor = '#dddddd';
var access_token='AAACEdEose0cBAAICGa4tFTcZAqCOGm2w9qPYGZBwNtJ1oZAcwaMAP2DDHZCN58cvVBZCHZADZAZBTPC8tTnpfQ7uGKI5j3SbMYcRmWquZCdPzhwZDZD';
var url = "https://graph.facebook.com/64306617564/events?&access_token=" + access_token ;
var win = Ti.UI.createWindow();
var table = Ti.UI.createTableView();
var tableData = [];
var json, data, row, name, start_time, id;
var xhr = Ti.Network.createHTTPClient({
onload: function() {
// Ti.API.debug(this.responseText);
json = JSON.parse(this.responseText);
for (i = 0; i < json.data.length; i++) {
data = json.data[i];
row = Ti.UI.createTableViewRow({
height:'60dp'
});
var name = Ti.UI.createLabel({
text:data.name,
font:{
fontSize:'18dp',
fontWeight:'bold'
},
height:'auto',
left:'50dp',
top:'5dp',
color:'#000',
touchEnabled:true
});
var start_time = Ti.UI.createLabel({
text:'"' + data.start_time + '"',
font:{
fontSize:'13dp'
},
height:'auto',
left:'15dp',
bottom:'5dp',
color:'#000',
touchEnabled:true
});
row.add(name);
row.add(start_time);
tableData.push(row);
}
table.setData(tableData);
},
onerror: function(e) {
Ti.API.debug("STATUS: " + this.status);
Ti.API.debug("TEXT: " + this.responseText);
Ti.API.debug("ERROR: " + e.error);
alert('There was an error retrieving the remote data. Try again.');
},
timeout:5000
});
xhr.open("GET", url);
xhr.send();
But when i want the specific event to open in a new window when clicked i just get the event that lies last on the screen when i put this in a browser:
https://graph.facebook.com/64306617564/events?&access_token=AAACEdEose0cBAOLAFWMKPmvgqEwap1ldnl7DeZBDKJC6YTZC4Goh6K5NHsvpOFmFQaGp1IekVsCxZCZCz3lwGpRcQG9ZBkcMrZAnLk4As8kgZDZD
And the access token expires REALLY fast. Any ideas how to make an access token that lasts longer?
Well, the code i am using to open the window is:
table.addEventListener('click',function(e) {
// Create the new window with the link from the post
var blogWindow = Ti.UI.createWindow({
title : data.name,
modal : true,
barColor: '#050505',
backgroundColor: '#050505'
});
var webView = Ti.UI.createWebView({url:'http://www.facebook.com/events/' + data.id});
blogWindow.add(webView);
// Create the close button to go in the left area of the navbar popup
var close = Titanium.UI.createButton({
title: 'Close',
style: Titanium.UI.iPhone.SystemButtonStyle.PLAIN
});
blogWindow.setLeftNavButton(close);
// Handle the close event
close.addEventListener('click',function() {
blogWindow.close();
});
blogWindow.open();
});
win.add(table);
win.open();
in my opinion that should open the event that is clicked on by parsing the ID from the row and putting it after the link.
Am i retarded or what is wrong?
It doesnt matter on which event i click it just open the last one all of the times.
And how can i get a thumbnail for the events?
Pls help........
When you click on table to get value from data which is not available.You can achieve it using you custom variable try to put this line of code at your row creation where you add your row in array i.e.row.data = data; and on table click event get that object using this alert(e.source.data); and check it. Best luck
I am using Sencha Touch to develop a mobile version of a Bus Tracker for Boston University. The problem I a running into is that the method setPosition() for a google.maps.Marker is not rendering the position change in Safari or any Mobile browser.
The code set up is as follows:
I initialize an empty markers array
I initialize the map using Ext.Map() (sencha call)
I load data using a JSONP request every 5 seconds interval
Every time I get new data, I check if I have a marker for that bus id inside my markers array
If I don't I create a new marker and push it into my markers array
Otherwise I call setPosition with my new position on that marker in my markers array.
I then run a check to make sure the marker's position got updated to the position received from my JSON request
I have verified (I think) that the marker inside the markers array is getting the new position everytime. Also, in Chrome and Firefox, my buses move (as expected), but in safari and iPhone/Android browsers, nothing moves.
Here is the code snippet:
var markers = {};
var busesFunc = function()
{
Ext.util.JSONP.request({
url: 'http://m.cms-devl.bu.edu/rpc/bus/livebus.json.php',
callbackKey: 'callback',
params: {
},
callback: function(data) {
buses = data.ResultSet.Result;
for (var i = 0, ln = buses.length; i < ln; i++) {
var bus = buses[i];
var position = new google.maps.LatLng(bus.lat, bus.lng);
if(!markers[bus.id])
{
markers[bus.id] = new google.maps.Marker({
map: map.map,
title: 'hello',
clickable: true,
draggable: false,
position: position,
icon: "images/bg.png",
zIndex: 100
});
}
markers[bus.id].setPosition(position);
//markers[bus.id].setIcon("images/bg.png");
//markers[bus.id].setMap(map.map);
//markers[bus.id].setMap(map.map);
if(bus.lat != markers[bus.id].position.lat() || bus.lng != markers[bus.id].position.lng())
{
console.log(bus.id + " " + bus.lat + " " + bus.lng);
console.log(bus.id + " " + markers[bus.id].position.lat() + " " + markers[bus.id].position.lng());
}
}
}
});
}
setInterval(busesFunc, 5000);
You can view the sample here: http://www.bu.edu/nisdev/students/luiscarr/liveBusMobile/
And the whole javascript is called functions.js (I can't post more than one link)
[Sencha Person] markers not showing up is a known bug in the 0.93 beta release. The 0.94 release (current one) has this fixed.
Problem solved by making a unique request every interval. I figured it was a caching problem after some more debugging. So I added a timestamp parameter to the JSONP request and it was all fixed.