Open dimitriospafos opened 7 years ago
It would be beneficial for this SDK to have example of custom ifoWindowTemplate implementatation for Angular under ng-demo. Thanks a lot.
Is there anyone that can provide an example on how to implement the custom info windows for Angular2? It seems there was a pull request to fix some issues with the Angular implementation so I assume it is already possible but we just need an example. https://github.com/dapriett/nativescript-google-maps-sdk/pull/183
how can i use infoWindowTemplate in native script with angular 2 . Did anyone successfully implement infoWindowTemplate with angular 2?
Here is work around for Angular without example, it seems there is no way to directly set templates in Angular template (.html), for our purpose we directly created template in component code (.ts) and assigned it to MapView
const templates = `
</template>
<template key="pickupTemplate">
<StackLayout orientation="horizontal" verticalAlignment="center" margin="0 0 0 0" width="150" height="30" >
<StackLayout backgroundColor="black" verticalAlignment="center" width="50" height="30">
<Label text="${result.duration}" textAlignment="center" textWrap="true" style="color:white;font-size:12;"></Label>
</StackLayout>
<Label text="My Current Location" verticalAlignment="center" paddingLeft="10" style="color:black;font-size:15;"></Label>
</StackLayout>
</template>`;
this.mapView.infoWindowTemplates = templates
and then added following line while creating marker marker.infoWindowTemplate = 'pickupTemplate';
Works like charm.
when you are building app using web pack you need to add following code to main.aot.ts otherwise it will not work , reason is that what we have written above is XML template and somehow during build process with webpack it does not find list-view module, below code is copied from NativeScript JavaScript template if (global.TNS_WEBPACK) { //registers tns-core-modules UI framework modules require("bundle-entry-points"); }
it would be interesting to see how this can be achieved using Angular template like shown in Demo App with XML.
one more missing puzzle is how to keep multiple info window open, it appears that you can only open one marker window at time. trick could be to build custom icon with information embedded, see following stack flow discussion on that
https://stackoverflow.com/questions/32984118/show-info-window-on-every-marker-at-a-time
There is no property infoWindowTemplates exposed on the MapView class. How do you assign the template to it?
sorry for late reply
Actually MapView has infoWindowTemplates property, but it is not defined in typescript definition file (map-view.d.ts). Due to that typescript complains about it.
You have two options for it, Option 1 (Recommended) as type for your local variable , do following public mapView: MapView & {infoWindowTemplates: string }; This will make typescript accept infoWindowTemplates property and will not complain about it Option2 (Not Recommended) add in your node-modules infoWindowTemplates property into map-view.d.ts,
@milansar Thanks a lot. Works like charm!!!
@dimitriospafos Glad it worked :-)
@milansar Your solution works great! Is it possible to detect tap events on different elements inside the custom info window?
@racknoris , I tried but could not make it work. you can listen to click event on infoWindow but not elements inside.
@milansar is there way to put custom angular component inside infoWindowTemplate? I have tried but i am getting error:
System.err: com.tns.NativeScriptException:
System.err: Calling js method getInfoContents failed
System.err:
System.err: Error: Parsing XML at 3:7
System.err: > Module 'ui/offer-details' not found for element 'OfferDetails'.
System.err: > com.tns.NativeScriptException: Failed to find module: "ui/offer-details", relative to: app/tns_modules/
System.err: com.tns.Module.resolvePathHelper(Module.java:146)
System.err: com.tns.Module.resolvePath(Module.java:55)
System.err: com.tns.Runtime.callJSMethodNative(Native Method)
System.err: com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1088)
System.err: com.tns.Runtime.callJSMethodImpl(Runtime.java:970)
System.err: com.tns.Runtime.callJSMethod(Runtime.java:957)
System.err: com.tns.Runtime.callJSMethod(Runtime.java:941)
System.err: com.tns.Runtime.callJSMethod(Runtime.java:933)
System.err: com.tns.gen.com.google.android.gms.maps.GoogleMap_InfoWindowAdapter.getInfoContents(GoogleMap_InfoWindowAdapter.java:17)
System.err: com.google.android.gms.maps.zzg.zzi(Unknown Source)
System.err: com.google.android.gms.maps.internal.zzi.onTransact(Unknown Source)....
...
@bori87 , I have not tried it. I think problem is that InfoWindowTemplate content is parsed as Vanila NativeScript XML, not as Angular XML thus it is not able to find custom Angular Component you created.
I am not expert of Vanila NativeScript but it appears to me that you need to register your Angular component somewhere to make it available to Vanila NativeScript XML
@milansar , Is there a way to dynamically replace some of the content of the infoWindowTemplate? (angular) I have a template like this :
<template key="example">
<GridLayout rows="*" width="100" height="70">
<StackLayout row="0" orientation="horizontal">
<Label text="${PLACEHOLDER}">
</Label>
</StackLayout>
</GridLayout>
</template>;
I want to be able to replace the PLACEHOLDER each time I create a new marker. I tried replacing the PLACEHOLDER on the mapView.infoWindowTemplates before creating each marker but seems like it only keeps the last replaced template for all of them when they are rendered on the map.
The option of having multiple templates for each case is not viable since the value for the placeholder will be loaded dynamically from an api.
Any help would be appreciated.
Thanks
@dimitriospafos and @bori87
I figured there is way to have data binding on custom template. At time of creating info window, marker is used as binding context, It means property we set on marker is bound to template at rendering time. thus we can use userData property to provide custom data to template
your code need to be changed as following
`
;`
Then while creating marker
let marker = new Marker(); let icon = new Image(); icon.src = '~/assets/markers/round.png'; icon.imageSource = imageSource.fromFile('~/assets/markers/round.png'); marker.icon = icon; marker.position = Position.positionFromLatLng(latitude, longitude); marker.userData = {placeholder: "hello world"}; marker.infoWindowTemplate = "example";
I hope this help
@milansar
Thank you for all the help. It works!!! I really appreciate you putting the time into it to help.
While we have a "workaround", it would be really nice if the maintainer would just expose the capability through the MapView TS integraion
Send over a pull request @westlakem - I'll be glad to take a look when I get a chance.
I would but I got to warn you, it won't be immediate... this is a weekend project for me and I'm new to the ecosystem. Not trying to make excuses, just sayin it would take a while for me to get around to it
I hear ya @westlakem. I'm not doing any mobile development on my current projects, so you'll be waiting even longer for me. But I try to make time for pull requests when I can.
Idk how you people managed to get it working because as soon as I add a <template>
tag I get this:
Module 'ui/template' not found for element 'Template'.
Can someone explain how to solve this?
What is correct way to put button tap action on the info window? Because the element disappear when i put (tap) action
@dimitriospafos and @bori87
I figured there is way to have data binding on custom template. At time of creating info window, marker is used as binding context, It means property we set on marker is bound to template at rendering time. thus we can use userData property to provide custom data to template
your code need to be changed as following
<template key="example"> <GridLayout rows="*" width="100" height="70"> <StackLayout row="0" orientation="horizontal"> <Label text="{{userData.placeholder}}"> </Label> </StackLayout> </GridLayout> </template>;
Then while creating marker
let marker = new Marker(); let icon = new Image(); icon.src = '~/assets/markers/round.png'; icon.imageSource = imageSource.fromFile('~/assets/markers/round.png'); marker.icon = icon; marker.position = Position.positionFromLatLng(latitude, longitude); marker.userData = {placeholder: "hello world"}; marker.infoWindowTemplate = "example";
I hope this help
Do you know if it is possible in Angular? I tried using something like <Label [text]="userData.title" but it didn't work ... Thanks Marco
@dimitriospafos and @bori87 I figured there is way to have data binding on custom template. At time of creating info window, marker is used as binding context, It means property we set on marker is bound to template at rendering time. thus we can use userData property to provide custom data to template your code need to be changed as following
<template key="example"> <GridLayout rows="*" width="100" height="70"> <StackLayout row="0" orientation="horizontal"> <Label text="{{userData.placeholder}}"> </Label> </StackLayout> </GridLayout> </template>;
Then while creating markerlet marker = new Marker(); let icon = new Image(); icon.src = '~/assets/markers/round.png'; icon.imageSource = imageSource.fromFile('~/assets/markers/round.png'); marker.icon = icon; marker.position = Position.positionFromLatLng(latitude, longitude); marker.userData = {placeholder: "hello world"}; marker.infoWindowTemplate = "example";
I hope this helpDo you know if it is possible in Angular? I tried using something like <Label [text]="userData.title" but it didn't work ... Thanks Marco
Hey @mrzanirato did you set the userData for the specific marker
var marker = new Marker();
marker.position = Position.positionFromLatLng(this.latitude, this.longitude);
marker.userData = { title : "This is title" };
mapView.add(marker);
I'm trying to use the infoWindowTemplate with Angular2, but I can't see any example or documentation for it. My question is how can I define a template for a custom marker's window using Angular2 and nativescript?
Any help would be appreciated.