Primefaces GMap addMarker (JavaScript) + selectMarker (overlaySelectEvent)

a 夏天 提交于 2020-01-25 01:12:06

问题


I have been struggling to combine both the GMap AddMarker and Selection examples from the Primefaces Showcase.

What I try to achieve here is to get the overlaySelectEvent fired when clicking on a marker that has been added to the map using JavaScript, having also those markers in the map model, correctly in sync.

JSF and JavaScript:

<p:growl id="messages" showDetail="true" />

<p:gmap id="gmap" center="36.890257,30.707417" zoom="13" type="HYBRID" style="width:600px;height:400px"
    model="#{mapBackingBean.emptyModel}" onPointClick="handlePointClick(event);" widgetVar="map" />

<p:ajax event="overlaySelect" listener="#{mapBackingBean.onMarkerSelect}" update="growl" />

<p:dialog widgetVar="dlg" showEffect="fade">
    <h:form prependId="false">
        <h:panelGrid columns="2">
            <h:outputLabel for="title" value="Title:" />
            <p:inputText id="title" value="#{mapBackingBean.title}" />

            <f:facet name="footer">
                <p:commandButton value="Add" actionListener="#{mapBackingBean.addMarker}" update=":messages" oncomplete="markerAddComplete()" />
                <p:commandButton value="Cancel" onclick="return cancel()" />
            </f:facet>
        </h:panelGrid>

        <h:inputHidden id="lat" value="#{mapBackingBean.lat}" />
        <h:inputHidden id="lng" value="#{mapBackingBean.lng}" />
    </h:form>
</p:dialog>

<script type="text/javascript">
    var currentMarker = null;

    function handlePointClick(event) {
        if(currentMarker === null) {
            document.getElementById('lat').value = event.latLng.lat();
            document.getElementById('lng').value = event.latLng.lng();

            currentMarker = new google.maps.Marker({
                position:new google.maps.LatLng(event.latLng.lat(), event.latLng.lng())
            });

            PF('map').addOverlay(currentMarker);

            PF('dlg').show();
        }   
    }

    function markerAddComplete() {
        var title = document.getElementById('title');
        currentMarker.setTitle(title.value);
        title.value = "";

        currentMarker = null;
        PF('dlg').hide();
    }

    function cancel() {
        PF('dlg').hide();
        currentMarker.setMap(null);
        currentMarker = null;

        return false;
    }

</script>

Backing bean:

@ManagedBean
@ViewScoped
public class MapBackingBean implements Serializable {

  private MapModel emptyModel;

  private Marker marker;

    private String title;

    private double lat;

    private double lng;

    @PostConstruct
    public void init() {
        emptyModel = new DefaultMapModel();
    }

    public MapModel getEmptyModel() {
        return emptyModel;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public double getLat() {
        return lat;
    }

    public void setLat(double lat) {
        this.lat = lat;
    }

    public double getLng() {
        return lng;
    }

    public void setLng(double lng) {
        this.lng = lng;
    }

    public void addMarker() {
        Marker marker = new Marker(new LatLng(lat, lng), title);
        emptyModel.addOverlay(marker);

        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Marker Added", "Lat:" + lat + ", Lng:" + lng));
    }

    public void onMarkerSelect(OverlaySelectEvent event) {
        marker = (Marker) event.getOverlay();

        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Marker Selected", marker.getTitle()));
    }

    public Marker getMarker() {
        return marker;
    }
}

So the question is: is there a way to trigger the ajax overlaySelectEvent when clicking on these markers added using JavaScript? Notice I do not want to 'update' the component, because it flashes when refreshing and I need it to be fast because this map will get some of its makers updated several times a minute.

I would appreciate any help. Thanks.


回答1:


I ended up doing it using just JavaScript and the Google Maps API as it doesn't seem to be a way for doing it in Primefaces as of the date of this answer.

What I have done is passing all the map data from the server to the client using a element. Then, from the client, I just extract the information and build the map accordingly. I don't make use of the Primefaces gmap model, as it is not required, and the information is already stored in the backing bean.

Although Primefaces offers functionality to make use of Google Maps from the server side, it is a small layer on top of Google Maps API, so Javascript is required for advanced map features. Something understandable.

EDIT: Please, go to https://forum.primefaces.org/viewtopic.php?t=41013&p=129363 for a solution that refreshes the map content without updating the gMap component and, thus, not flashing, by also keeping all the primefaces event listeners working.



来源:https://stackoverflow.com/questions/26129664/primefaces-gmap-addmarker-javascript-selectmarker-overlayselectevent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!