Clicked function on a MapView Marker-Label

Hey guys

I have a MapView in a NativeViewHost with a lot of MapMarkers in it.

Is there a way to apply something like a Clicked function on the labels so that they link to another page?

I know that there is no Clicked-function for MapMarkers but perhaps there is another way to do this.

Hi,

There is an event on MapView called MarkerTapped; here is an example from the MapMarker class reference showing how to use it:

<JavaScript>
    var Observable = require("FuseJS/Observable");

    exports.markers = Observable({latitude:30.282786, longitude:-97.741736, label:"Austin, Texas"});

    exports.onMarkerTapped = function(args)
    {
        console.log("Marker press: "+args.label);
    }
</JavaScript>

<NativeViewHost>
    <MapView MarkerTapped={onMarkerTapped} >
        <Each Items={markers}>
            <MapMarker Latitude="{latitude}" Longitude="{longitude}" Label="{label}" />
        </Each>
    </MapView>
</NativeViewHost>

Hope this helps :slight_smile:

Hey, thank you for your reply!

The function is what I was looking for.
But unfortunately, args is passing me my whole Array (and all my Observables), not only the item I was pressing on.

I guess its because the MarkerTapped is outside of the Each but I am not sure of how I could solve this problem.

Could you share the snippet of code where you set this up on your end? Lorents’ example is correct and I’d like to see what could cause the behavior you’re describing, because this sounds like a bug :slight_smile:

Also, please note what platform you are targeting, iOS or Android.

I am targeting both platforms but I am testing this on an Android (Galaxy S5).

This is my page with the MapView:

<Page ux:Class="Map">
	<NativeViewHost>
	    <MapView Latitude="{coordinates.lat}" Longitude="{coordinates.long}" Zoom="10" ShowMyLocation="true" ShowMyLocationButton="true" Style="Hybrid" MarkerTapped="{Marker}">
	       	<Each Items="{data.poiDatabase}">
				<MapMarker Latitude="{latitude}" Longitude="{longitude}" Label="{title}"/>
	       	</Each>
		</MapView>   	
	</NativeViewHost>
</Page>

And this is my module.exports of my JS-file:

module.exports = {
        //Navigation
        gotoIndex: function() {router.push("index");},
        gotoMap: function() {router.push("map");},
        gotoPoi: function() {router.push("poi");},
        gotoFavorites: function() {router.push("favorites");},
        gotoInformations: function() {router.push("informations");},
        gotoDetails: function(x) {
            poiArray.value = x.data;
            router.push("DetailView");},
        filterView: function() {
            if(filterVisible.value == true){filterVisible.value = false;}
            else{filterVisible.value = true;}
        },
        filter: function() { filter();},
        goBack: function() { router.goBack();},
        Marker: function(args) {
            console.log(JSON.stringify(args));
        },
        //DetailView
        phoneCall: function() { 
            if(poiArray.value.phone != "")
            {phone.call(poiArray.value.phone);}
         },
        openURL: function() {InterApp.launchUri(poiArray.value.url);},
        openFB: function() {InterApp.launchUri(poiArray.value.facebookURL);},
        //Other Stuff
        categoryButton: function(content) {filterByType(data.value, content.data.ID, "Category");
        },
        cityButton: function(content) {filterByType(data.value, content.data.City, "City")},
        filterVisible,
        categorys,
        citys,
        data,
        poiArray,
        mainActive,
        categoryActive,
        cityActive,
        categoryArray,
        cityArray,
        coordinates
};

I just logged the args value for testing and there is pretty much everything in it (filterVisible, categorys, citys and the whole poiDatabase, beginning at the very first entry).

Can you see any fault on my side here :)?

No this looks accurate. I’ll check this right now and see what we’ve got going on.

As a sanity check, are you getting everything AND the .label? What happens if you just console.log(args.label) as opposed to just the whole args object? The way data is gathered from the JS data context for JS callbacks is quite greedy.

I don’t think so.
I have to go for args.title (this is what I was trying to get and I have no label in my array) but for console.log(args.title) its just giving back a null.

What you are going to get (at least this is the intention) is an object with a ‘label’ field. What you are doing is binding your title field to the MapMarker Label, which is what gets passed through the args.

So console.log(args.label) gives you null? :confused:

I tested with this right now on iOS 8.1 and it behaves as expected:

  <JavaScript>
    var O = require("FuseJS/Observable")
    exports.markers = O({text:"Foo"})
    exports.tapped = function(args){
      console.log(args.label)
    }
  </JavaScript>
  <NativeViewHost>
    <MapView MarkerTapped="{tapped}">
      <Each Items="{markers}">
        <MapMarker Label="{text}"/>
      </Each>
    </MapView>
  </NativeViewHost>
</App>

Oh, I didn’t know its working that way.
args.label is working fine!

Thank you for your quick help :)!

Anytime! I’m glad to know I’m not insane :wink: I’ll look into why args is so full of data though.

Happy new year!