Can I request a route direction without rendering? - bing-maps

I will build my own style for the directions of a route, but only when I use the setRenderOptions Method with the itineraryContainer property I can access the DirectionSteps with a callback function (afterStepRender Event).
var directionsManager = new Microsoft.Maps.Directions.DirectionsManager(map);
// ...
directionsManager.setRenderOptions({ itineraryContainer: document.getElementById('itineraryDiv') });
Is there a possibility to get the Object with all DirectionSteps without rendering the steps in a hidden html element?

The solution is to use a url template from Bing Maps, see in documentation: http://msdn.microsoft.com/en-us/library/ff701717.aspx
http://dev.virtualearth.net/REST/v1/Routes?wayPoint.1=wayPoint1&viaWaypoint.2=viaWaypoint2&waypoint.3=wayPoint3&wayPoint.n=wayPointn&heading=heading&optimize=optimize&avoid=avoidOptions&distanceBeforeFirstTurn=distanceBeforeFirstTurn&maxSolutions=maxSolutions&routePathOutput=routePathOutput&tolerances=tolerance1,tolerance2,tolerancen&distanceUnit=distanceUnit&key=BingMapsKey

Related

Aurelia - Accessing ViewModel functions/binding from within Generated DOM elements

I have a section of my view (html) that is generated programmatically by a viewmodel/class. This uses the Aurelia DOM (Aurelia Docs - pal :: Dom) functionality to generate and add the raw HTML elements to the view.
However, I am unable to get events within the generated html to call back to the viewmodel. An example:
let deleteButton = this.dom.createElement("button");
deleteButton.setAttribute("onclick", "cancelCreditNote(`${ row.creditNoteId }`)");
A click on the generated button won't call back to the viewmodel, which does have a cancelCreditNote function. Various other things like deleteButton.setAttribute("click.delegate", "cancelCreditNote('${ row.creditNoteId }')"); do not work either.
Does anyone know how to access a viewmodel class from essentiall 'raw' html in aurelia?
Unfortunately in this instance I cannot use the standard aurelia templating to generate the HTML.
The DOM property on PAL is just an abstraction for the browser's DOM object, create element is likely just calling document.createElement which doesn't afford any Aurelia binding to the created element.
You could try using aurelia.enhance(context, element) which takes an existing DOM element and runs it through the templating engine.
With this method you can also pass a binding context to apply to the element.
In my HTML I use this:
<div id="collapsesidebar" click.delegate="toggleSidebar()">
In my view-model I have this method:
toggleSidebar(){
alert('hi');
}
You could also do this from your view-model with JQuery like this:
attached() {
$('main').on('click', ()=> alert('hi'));
}
The last option is ONLY available áfter the attached() method is triggered: before that the binding needs to do its job and only after that the elements are located inside of the dom.
In other words: this will not work:
activate(){
$('main').on('click', ()=> alert('hi'));
}
because the constructor and the activate method both get fired before the attached method.

Markercluster in Mapbox

I am following markercluster examples from Mapbox library, but can't solve my problem. If you guys take a look at my working example here, you will notice this line of code:
L.mapbox.featureLayer(markerLayer).on('ready', function(e) {
What I initally thought was I could put markers inside of markercluster featureLayer, but I guess it was a wrong approach. Any solutions? Thanks.
Example following here
The mapbox example you refer to makes an AJAX call to retrieve the GeoJSON data, hence it needs to attach an on "ready" listener.
In your case your GeoJSON data is defined in your scripts, so the "ready" event will not be triggered (besides, you should use L.mapbox.featureLayer with your GeoJSON object directly, not a Feature Layer).
You can simply use the eachLayer method to iterate through all created markers within the Feature Layer, and add them into your Marker Cluster Group.
var clusterGroup = new L.MarkerClusterGroup();
var markerLayer = L.mapbox.featureLayer(markers).eachLayer(function(layer) {
clusterGroup.addLayer(layer);
});
map.addLayer(clusterGroup);
Updated Plunker: http://plnkr.co/edit/fN6xYcn1Lg532eLe39IS?p=preview

Angular JS update model from dom

I've seen heaps of questions about this, and all of them seem to be solved by either calling $scope.$apply(), $scope.$digest(), or by triggering the change() method on the input. But I can't seem to get it working with any of those methods. In this fiddle, I can type a name into the box and get the model value to update as I type. But when I click the link, to set the input name to a certain value, I want the model name to update. What do I need to do?
The reason I'm trying to do this is I want to be able to refresh my angular model when a user autofills the form, using the browser autofill or LastPass or similar. Surely there's some angular command to refresh the model from the DOM?
http://jsfiddle.net/PXCUq/
$(function () {
$('#setFirstName').click(function () {
$('input.firstname').val('Test Name');
angular.element($('input.firstname')[0]).scope().$apply();
// Model still not updated
});
});
Get the scope, then change the ng-model property:
$('#setFirstName').click(function() {
var scope = angular.element($('input').get(0)).scope()
scope.firstname = 'Test Name';
scope.$apply();
});
You can come up with a better jQuery selector. I was only focusing on the Angular part.
Fiddle.

How to reference dynamically added element after DOM loaded without a need to act on any events?

I know there is .on and .live (deprecated) available from JQuery, but those assume you want to attach event handlers to one ore more events of the dynamically added element which I don't. I just need to reference it so I can access some of the attributes of it.
And to be more specific, there are multiple dynamic elements like this all with class="cluster" set and each with a different value for the: title attribute, top attribute, and left attribute.
None of these jquery options work:
var allClusters = $('.cluster');
var allClusters2 = $('#map').children('.cluster');
var allClusters3 = $('#map').find('.cluster');
Again, I don't want to attach any event handlers so .on doesn't seem like the right solution even if I were to hijack it, add a bogus event, a doNothing handler, and then just reference my attributes.
There's got to be a better solution. Any ideas?
UPDATE:
I mis-stated the title as I meant to say that the elements were dynamically added to the DOM, but not through JQuery. Title updated.
I figured it out. The elements weren't showing up because the DOM hadn't been updated yet.
I'm working with Google Maps and MarkerClustererPlus to give some more context, and when I add the map markers using markerclustererplus, they weren't available in the javascript code following the add.
Adding a google maps event listener to my google map fixed the problem:
google.maps.event.addListener(myMarkerClusterer, 'clusteringend', function () {
// access newly added DOM elements here
});
Once I add that listener, all the above JQuery selectors and/or methods work just fine:
var allClusters = $('.cluster');
var allClusters3 = $('#map').find('.cluster');
Although this one didn't, but that's because it only finds direct decendants of parent:
var allClusters2 = $('#map').children('.cluster');
Do what you need to do in the ajax callback:
$.ajax(...).done(function (html) {
//append here
allClusters = $('.cluster');
});
If you want them to be separate, you can always bind handlers after the fact, or use $.when:
jqxhr = $.ajax(...).done(function (html) { /* append html */ });
jqxhr.done(function () { allClusters = $('.cluster') });
$.when(jqxhr).done(function () { /* you get it */ });
If these are being appended without ajax changes, then just move the cluster-finding code to wherever the DOM changes take place.
If that's not an option, then I guess you would just have to check on an interval.

In jQuery Mobile, how do you target the element created using loadPage?

I load a "page" into the DOM using $.mobile.loadPage(). I then want to target the element created, but I haven't figured out how to do this. This is what I thought would work:
var toc = $.mobile.loadPage('toc.html');
toc.trigger('customevent');
The above does not work in part because toc is a "deferred promise object" rather than a good ol' jQuery DOM reference. Additionally, it does not work because the second line is triggered before loadPage finishes. Is there a way to fire a callback after loadPage?
Thanks!
If you know the id of the page being loaded then you can bind the 'pagecreate' event to that object with .live() like so:
$('#blah').live('pagecreate', function () {alert('created');});
This will fire after the page has been loaded into the dom.
I just was just able to figure this out, even if you don't have the id, here's an example of how i am performing an action (fadeIn) on the the inserted element....
$(document).bind('pageload',function(evt,data){
$(document).unbind('pageload');
$(data.page).fadeIn();
});
$.mobile.loadPage('mypage.html',{'pageContainer':$('#my_item')});
You can use pageshow in order to fire a callback when the page is loaded. Please refer to the jQuery Mobile Events API for more detail.
An example would be something like:
$('div').live('pageshow',function(event, ui){
...
});