How to make a for in a tag script?

1

Well, I'm trying to create a page on my site that shows me the title, description, and location of the log of some occurrences. When I access the page, I load through%% all occurrences with their proper parameters. The occurrences are sent within a list via servlet to a JSP, which shows them.

My problem is that to load the map with the location of the instance, I need to execute a <c:forEach> tag that has no body. The tag loads the files and, at the end of loading, calls a javascript function, present on the page, using <script> .

Because I'm using this tag to load and call the function that shows my map with the location of the instance, I need it to run on callback="function()" , forEach or anything else to help me loop. I thought about doing with scriptlet or JSTL, but I could not get it right away. Can someone help me? I'm using the javascript Google Maps API.

JSP that performs location loading:

    <%@page pageEncoding="ISO-8859-1"%>
            <%@include file="includes/cabecalho.html"%>
            <%@include file="includes/navmenu.jsp"%>
            <div class="centralizado jumbotron">
                <div class="card-deck">
                    <!--Panel-->
                    <div class="row">
                        <c:forEach var="ocorrencia" items="${ocorrencias}">
                            <div class="col-md-4">
                                <div style="padding: 10px;" class="card">
                                    <div style="padding: 10px;" class="card-body">
                                        <h5 class="card-title">${ocorrencia.tituloOcorrencia}</h5>
                                        <p class="card-text">${ocorrencia.descricaoOcorrencia}</p>
                                        <div style="position: relative; width: 100%;height: 300px" id="map"></div>
                                        <input type="number" id="lat" value="${ocorrencia.latitudeOcorrencia}" hidden/>
                                        <input type="number" id="lng" value="${ocorrencia.longitudeOcorrencia}" hidden/>
                                        <br>
                                    </div>
                                    <div class="card-footer">
                                        <small class="text-muted">${ocorrencia.usuario_fk_ocorrencia.nomeUsuario} em ${ocorrencia.dataOcorrencia}</small>
                                    </div>
                                </div>
                            </div>
                        </c:forEach>
                    </div>
                </div>
            </div>
            <script>
                // Initialize and add the map
                function initMap() {

                    //Attribuition for lat and lng to var
                    var lat = parseFloat(document.getElementById('lat').value);
                    var lng = parseFloat(document.getElementById('lng').value);
                    // The location of Uluru
                    var uluru = {lat: parseFloat(lat), lng: parseFloat(lng)};
                    // The map, centered at Uluru
                    var map = new google.maps.Map(
                        document.getElementById('map'), {zoom: 15, center: uluru});
                    // The marker, positioned at Uluru
                    var marker = new google.maps.Marker({position: uluru, map: map});
                }
            </script>
            <!--Load the API from the specified URL
            * The async attribute allows the browser to render the page while the API loads
            * The key parameter will contain your own API key (which is not needed for this tutorial)
            * The callback parameter executes the initMap() function
            -->
            <!--Preciso do loop nesta tag-->
            <script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAUWfu8L-5YIKUDXV812EM3tBZhrK0uDY4&callback=initMap"></script><%@includefile="includes/footer.jsp"%>

Some information that might be useful to help me: link

    
asked by anonymous 01.07.2018 / 03:43

1 answer

1

See this field with id s lat , lng and map within forEach ? So, that means you're going to generate multiple elements with the same% s of% s. However, the value of the id field should be unique.

The solution to make% s of% s unique is to concatenate a number after them. And then, you can use those numbers in the id function.

To get a unique number at each iteration, you can use the id field of initMap .

Your code should look like this:

<%@ page pageEncoding="UTF-8" %>
<%@ include file="includes/cabecalho.html" %>
<%@ include file="includes/navmenu.jsp" %>
<script type="text/javascript">
    // Initialize and add the map
    function initMap(n) {
        // Attribuition for lat and lng to var
        var lat = parseFloat(document.getElementById('lat-' + n).value);
        var lng = parseFloat(document.getElementById('lng-' + n).value);
        var mapElement = document.getElementById('map-' + n);

        // The location of Uluru
        var uluru = {lat: parseFloat(lat), lng: parseFloat(lng)};
        // The map, centered at Uluru
        var map = new google.maps.Map(mapElement, {zoom: 15, center: uluru});
        // The marker, positioned at Uluru
        var marker = new google.maps.Marker({position: uluru, map: map});
    }
</script>
<div class="centralizado jumbotron">
    <div class="card-deck">
        <!--Panel-->
        <div class="row">
            <c:forEach var="ocorrencia" items="${ocorrencias}" varStatus="loop">
                <div class="col-md-4">
                    <div style="padding: 10px;" class="card">
                        <div style="padding: 10px;" class="card-body">
                            <h5 class="card-title">${ocorrencia.tituloOcorrencia}</h5>
                            <p class="card-text">${ocorrencia.descricaoOcorrencia}</p>
                            <div style="position: relative; width: 100%; height: 300px" id="map-${loop.index}"></div>
                            <input type="number" id="lat-${loop.index}" value="${ocorrencia.latitudeOcorrencia}" hidden/>
                            <input type="number" id="lng-${loop.index}" value="${ocorrencia.longitudeOcorrencia}" hidden/>
                            <br>
                        </div>
                        <div class="card-footer">
                            <small class="text-muted">${ocorrencia.usuario_fk_ocorrencia.nomeUsuario} em ${ocorrencia.dataOcorrencia}</small>
                        </div>
                    </div>
                </div>
                <script type="text/javascript">
                    function initMap${loop.index}() {
                        initMap(${loop.index});
                    }
                </script>
                <script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAUWfu8L-5YIKUDXV812EM3tBZhrK0uDY4&callback=initMap${loop.index}"></script></c:forEach></div></div></div><%@includefile="includes/footer.jsp" %>

Note that varStatus will become an iteration counter, and with it, you can load this Google Maps script once for each iteration.

The forEach is a variable of type ${loop.index} , an object type that serves to provide data about the iteration of loop . one of its methods is javax.servlet.jsp.jstl.core.LoopTagStatus , which is the result of the call to forEach . You can see more about this object here and this question in SOen .

Another detail: I recommend using UTF-8 instead of ISO-8859-1. The ISO-8859-1 format is outdated and obsolete and will give you problems when someone tries to put Chinese or emoji text on your page. Better to prevent and change everything to UTF-8 now than to fix it later when problems start to appear.

    
01.07.2018 / 04:17