26

I use the google map tool from primefaces. I want my user to be able to place just one marker on a map. The values of the coordinates should be stored in a managed bean variables.

How can I do that? See what I did so far:

I created the map:

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

<p:dialog widgetVar="dlg" effect="FADE" effectDuration="0.5" close="false" fixedCenter="true">  
    <h:form prependId="false">  
        <h:panelGrid columns="2">  
            <h:outputLabel for="title" value="Title:" />  
            <p:inputText id="title" value="#{mapBean.title}" />  

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

        <h:inputHidden id="lat" value="#{newOfferSupportController.mapLocationX}" />  
        <h:inputHidden id="lng" value="#{newOfferSupportController.mapLocationY}" />  
    </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())  
            });  

            map.addOverlay(currentMarker);  

            dlg.show();  
        }     
    }  

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

        currentMarker = null;  
        dlg.hide();  
    }  

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

        return false;  
    }  
</script>

I also greated the variables that will hold the coordinates:

@ManagedBean
@RequestScoped
public class NewOfferSupportController {

private float mapLocationX;
private float mapLocationY;

//Get & set methods

It all works as in the primefaces page but I have 2 problems:

Problem 1: Once the marker is placed, it cannot be placed again.

Problem 2: In the same form where the map is there are some other elements such as text fields. I noticed that validation does not occur when I click on the submit button located in the form where the map is, Actually the form does not get submitted at all(This didn't occur before i added the map), why is the map disrupting the validation? enter image description here

Cœur
  • 37,241
  • 25
  • 195
  • 267
javing
  • 12,307
  • 35
  • 138
  • 211
  • Have you seen [this](http://www.primefaces.org/showcase/ui/gmapAddMarkers.jsf) ? – jmj Apr 30 '11 at 09:28
  • I did see that. And i partially implement it, but i don't see the add menu when i click somewhere on the map. What i did wrong? – javing Apr 30 '11 at 09:38
  • Can you please load the page in FireFox and check its error console, I think there might be some issue with javascript – jmj Apr 30 '11 at 09:45
  • It says: `Uncaught TypeError: Cannot set property 'value' of null` The error is in line 151, that is(Right click view source): `document.getElementById('lat').value = event.latLng.lat();` – javing Apr 30 '11 at 09:50
  • 2
    It seems `document.getElementById('lat')` returns `null` , can you see in the HTML source , is there any element with this id ? – jmj Apr 30 '11 at 09:53
  • The only thing i see with the id lat is: `` – javing Apr 30 '11 at 09:59
  • Oh.. yes just add `prependId="false"` in your like ` ` – jmj Apr 30 '11 at 10:02
  • I added that, now i see no error in the console, but the dialog for adding the marker still not appear when i click somewhere. If i double click the map just zooms in. – javing Apr 30 '11 at 10:06
  • I just tried to change the value of `p:dialog widgetVar="dlg"` to `p:dialog widgetVar="dlg2"` the inner dialog had the same value as the outer one. I thought that that might be making some conflict, so it does not get displayed when click on map, but still does not work. – javing Apr 30 '11 at 10:12
  • yes keep the both name different also I don't understand the need of nested dialogs . – jmj Apr 30 '11 at 10:16
  • I wanted to make the map as a popup dialog. I just made up my mind, i removed the popup dialog and it works correctly. But once i placed the marker i cannot place it again. How could i do that? – javing Apr 30 '11 at 10:19
  • again, can you see any error when you re attempt ? – jmj Apr 30 '11 at 10:23
  • Yes i see some errors. I just updated my question with a bit more details. – javing Apr 30 '11 at 10:31
  • Yes they just appeared. when i started to add the map. Oh no something is wrong i just removed all the code i added related to the map, and those errors are still there. Why is that? – javing Apr 30 '11 at 10:37
  • Probably the issue is because of these missing `.js` , can you please make it available to page – jmj Apr 30 '11 at 10:38
  • I will have to fix that before i continue with the map. I go try to fix it. – javing Apr 30 '11 at 10:53
  • I fixed that. Now i don't see those errors on the browser console. When i click on the map, the dialog for placing the marker pops. But when i place the marker i cannot submit the form. Also i cannot edit the marker position once placed. – javing Apr 30 '11 at 20:02
  • If the problem is still not solved it might be worth posting it at gis.stackexchange.com, which is specialized in geographical stuff. – steenhulthin Jun 07 '11 at 19:06
  • What JSF impl/version? What PF version? – BalusC Jun 13 '11 at 11:50
  • I use JSF 2.0 and my Primefaces version is 2.2.1 – javing Jun 13 '11 at 14:36
  • "JSF 2.0" is a spec version which tells nothing about the impl/version used. May I assume that you're using Mojarra 2.0.x? – BalusC Jun 13 '11 at 15:10
  • Yes i think that is what i use. – javing Jun 13 '11 at 15:30

1 Answers1

6

Problem 1: Once the marker is placed, it cannot be placed again.

This problem is caused by the following things:

  1. You've bound latitude and longitude to a different bean (NewOfferSupportController) than the bean which holds the map model (MapBean). You should be using MapBean example in the PrimeFaces showcase as design starting point for NewOfferSupportController bean. It namely stores the markers set. The hidden inputs must point to that bean because in the addMarker() method those values will be added. From the showcase example you just have to rename the MapBean class name and rename #{mapBean} references in the view by #{newOfferSupportController}.

  2. Your NewOfferSupportController bean is request scoped while it should be view scoped.

    @ManagedBean
    @ViewScoped
    public class NewOfferSupportController implements Serializable {}
    

    View scoped beans live as long as you're interacting with the same form by Ajax. But request scoped beans get recreated on every request (and thus also on every Ajax request!), hereby trashing the markers which are placed before in the map and inputs which are entered before adding markers.


Problem 2: In the same form where the map is there are some other elements such as text fields. Actually the form does not get submitted at all(This didn't occur before i added the map), why is the map disrupting the validation?

This works for me. This is likely caused because your NewOfferSupportController is been placed in the request scope instead of the view scope.

To recap, here is the code which I used in my test:

view:

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

<h:form>
    <p:gmap id="gmap" center="36.890257,30.707417" zoom="13" type="HYBRID" style="width:600px;height:400px"  
        model="#{mapBean.mapModel}" onPointClick="handlePointClick(event);" widgetVar="map" />
    <h:inputText value="#{mapBean.input}" required="true" />
    <p:commandButton value="submit" action="#{mapBean.submit}" update="messages" />
</h:form>

<p:dialog widgetVar="dlg" effect="FADE" effectDuration="0.5" close="false" fixedCenter="true">  
    <h:form prependId="false">  
        <h:panelGrid columns="2">  
            <h:outputLabel for="title" value="Title:" />  
            <p:inputText id="title" value="#{mapBean.title}" />  

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

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

(I didn't change the <script> code in the showcase example, just add it unchanged)

Bean:

@ManagedBean
@ViewScoped
public class MapBean implements Serializable {  

    private MapModel mapModel;  
    private String title;  
    private double lat;  
    private double lng;  
    private String input;

    public MapBean() {  
        mapModel = new DefaultMapModel();  
    }  

    public void addMarker(ActionEvent actionEvent) {  
        mapModel.addOverlay(new Marker(new LatLng(lat, lng), title));  
        addMessage(new FacesMessage(FacesMessage.SEVERITY_INFO, "Marker Added", "Lat:" + lat + ", Lng:" + lng));  
    }  

    public void submit() {
        addMessage(new FacesMessage(FacesMessage.SEVERITY_INFO, "Form submitted", "Amount markers: " + mapModel.getMarkers().size() + ", Input: " + input));
    }

    public void addMessage(FacesMessage message) {  
        FacesContext.getCurrentInstance().addMessage(null, message);  
    }  

    // Getters+setters.
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I understand. I will try try to fix it now. – javing Jun 13 '11 at 15:56
  • I just fixed it. It is fine now. Solved problem 1 and 2 after following your instructions and also refactoring unneeded stuff in my page. Its being more than a month since i did not know how to fix that.Thank you very much :) – javing Jun 13 '11 at 16:30
  • You're welcome. Say thanks to the bounty. I initially didn't answer because I've never used `` before (so I can't answer from top of head) and I didn't find it worth the effort to test it myself. – BalusC Jun 13 '11 at 16:37
  • Thanks to the guy that placed the bounty on my question :) Also it is the first time that i use `p:gmap` i was thinking in starting to find an alternative to it, but is great i solved the issue. Im happy that i finally made this primefaces tool to work as i wish :) – javing Jun 13 '11 at 17:07