Leaflet sidebar within a while loop - php

I have a dataset with several points (latitude, longitude and some text for each), which I would like to show on a map, using Leaflet.
Instead of using Leaflet built-in popups, I am trying to use leaflet-sidebar, which allows to open a sidebar when a marker is clicked.
If you are interested, you can see an example (with one single marker) here:
https://github.com/Turbo87/leaflet-sidebar/blob/master/examples/index.html
As you can see, I correctly open a sidebar for each marker, but the content of each <div> is shown also below the map.
This is due to the fact that I have the <div> within a PHP while loop, as follows:
<?php
$i = 0;
while($result = mysql_fetch_array($objQuery)){
$i++;
$lat = $result['lat'];
$lon = $result['lon'];
$text = $result['some_text'];
?>
<div id="sidebar_<?=$i;?>" align="left">
<b>text</b>: <?=$some_text;?>
</div>
<script>
var sidebar_<?=$i;?> = L.control.sidebar('sidebar_<?=$i;?>', {
closeButton: true,
position: 'left'
});
map.addControl(sidebar_<?=$i;?>);
setTimeout(function () {
sidebar_<?=$i;?>.hide();
}, 500);
var marker = L.marker([<?php echo $lat;?>, <?php echo $lon;?>]).addTo(map).on('click', function () {
sidebar_<?=$i;?>.toggle();
});
</script>
<?php
}
?>
If I place the <div id="sidebar_<?=$i;?>"> outside the while loop, I can't collect each single marker lat/lon/text reference.
Do you have any tips on how to avoid this repetition below the map?

I found a workaround!
On the plugin webpage there is a note to add contents to <div> dynamically.
Basically, you need to leave the <div> empty in the html, and add content in the script part, using setContent:
<script>
var sidebar_<?=$i;?> = L.control.sidebar('sidebar_<?=$i;?>', {
closeButton: true,
position: 'left'
});
//HERE IT IS:
sidebar_<?=$i;?>.setContent('<b>categoria</b>: <?=$categoria;?><br><br><b>problema</b>: <?=$descrizione;?><br><br><b>proposta</b>: <?=$soluzione;?><br><br><div class="smaller">data segnalazione: <?=$giorno."/".$mese."/".$anno;?></div>');
map.addControl(sidebar_<?=$i;?>);
setTimeout(function () {
sidebar_<?=$i;?>.hide();
}, 500);
var marker = L.marker([<?php echo $lat;?>, <?php echo $lon;?>], {icon: iconarossa}).addTo(map).on('click', function () {
sidebar_<?=$i;?>.toggle();
});
</script>
Now it looks as I wished.

You need to add display: none to the style of the sidebar <div> -
<div id="sidebar_<?=$i;?>" align="left" style="display:none">
<b>text</b>: <?=$some_text;?>
</div>
You can probably do it a neater way with classes, but this should get you going.

Related

display mutiple google maps on a single page with data from MySQL and using loop

I want to display multiple google maps with my latitude and longitude from MySQL and I use looping. Here is my code:
<style>
.my_map {
height: 400px;
width: 100%;
}
</style>
<div>
<?php
foreach($clinics AS $clinic) {
?>
<div class="my_map" id="map_<?php print($clinic->id); ?>" >
<script>
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map_<?php print($clinic->id); ?>'), {
center: {lat: <?php print($clinic->latitude); ?>, lng: <?php print($clinic->longitude); ?>},
zoom: 16
});
}
</script>
</div>
<?php
}
?>
</div>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=MY_KEY_HERE&callback=initMap">
</script>
My problem is only the last map is displayed while the others before do not render the maps. Should I not write the script inside the loop? Thanks.
Whilst not tested I'd suggest an approach similar to this perhaps. Create a javascript variable with all the original data from the php variable $clinics - in this case json - and use the initMap function to iterate through that variable/data, creating a map object on each iteration.
<style>
.my_map {
height: 400px;
width: 100%;
}
</style>
<script async defer src="//maps.googleapis.com/maps/api/js?key=MY_KEY_HERE&callback=initMap"></script>
<script>
var obj,map;
<?php
/*
assuming that `$clinics` is an array and that each member is also an array
with constituent keys id,latitude,longitude which is how it appears to be
from the original question
encode as json data
*/
$json=json_encode( $clinics );
/* create javascript variable with data */
echo "
var json={$json};
";
?>
function initMap(){
/* iterate through json data */
for( var n in json ){
obj=json[n];
map=new google.maps.Map( document.querySelector('div[ data-id="'+n+'" ]'),{
center:{ lat:parseFloat( obj.latitude ), lng:parseFloat( obj.longitude ) },
zoom:16
});
}
}
</script>
<?php
/*
generate containers to hold each map based upon original array
*/
foreach( $clinics as $index => $clinic ){
echo "<div class='my_map' data-id='{$index}'></div>";
}
?>
you should use foreach .. : end foreach eg:
<div>
<?php foreach($clinics AS $clinic) : ?>
<div class="my_map" id="map_<?php print($clinic->id); ?>" >
<script>
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map_<?php print($clinic->id); ?>'), {
center: {lat: <?php print($clinic->latitude); ?>, lng: <?php print($clinic->longitude); ?>},
zoom: 16
});
}
</script>
</div>
<?php endforeach; ?>
</div>
We tried the code suggested by RamRaider however we were unable to get the maps showing. To get it working we had to attach the initialise script call to end of the page. The code therefore becomes:
<style>
.my_map {
height: 400px;
width: 100%;
}
</style>
<script>
jQuery(function() {
// Asynchronously Load the map API
var script = document.createElement('script');
script.src = "//maps.googleapis.com/maps/api/js?key=MY_KEY_HERE&callback=initMap";
document.body.appendChild(script);
});
var obj,map;
<?php
/*
assuming that `$clinics` is an array and that each member is also an array
with constituent keys id,latitude,longitude which is how it appears to be
from the original question
encode as json data
*/
$json=json_encode( $clinics );
/* create javascript variable with data */
echo "
var json={$json};
";
?>
function initMap(){
/* iterate through json data */
for( var n in json ){
obj=json[n];
map=new google.maps.Map( document.querySelector('div[ data-id="'+n+'" ]'),{
center:{ lat:parseFloat( obj.latitude ), lng:parseFloat( obj.longitude ) },
zoom:16
});
}
}
</script>
<?php
/*
generate containers to hold each map based upon original array
*/
foreach( $clinics as $index => $clinic ){
echo "<div class='my_map' data-id='{$index}'></div>";
}
?>

How to load dynamic content (jquery) inside ajax call?

My homepage loads pages with jquery ajax call. In the Pictures subpage there is 3 div, and each loads a php with ajax, too. I would like to include a gallery js to every sub-subpage. However, the js does not loads. Here is my code in the index.php for the subpages:
<script type="text/javascript">
$(function()
{
var actualmenu = 'fooldal.html';
$('#tartalom').load('fooldal.html');
$('.fooldal').click(function()
{
$('#tartalom').load('fooldal.html');
actualmenu = 'fooldal.html';
}
);
$('.kepek').click(function(){
$('#tartalom').load('kepek.php', function(){
$(document.body).on('click', 'a[rel=gallery_view]' ,function(){
$(this).KeViewer('gallery', {'percent' : 70});
return false;
});
});
actualmenu = 'kepek.php';
});
});
</script>
And there is my kepek.php page:
<script type="text/javascript">
$(function()
{
$('#galeria').load('kepek_csenge.php');
$('#csenge').click(function()
{
$('#galeria').load('kepek_csenge.php');
}
);
);
</script>
<div id="albums">
<div class="album" id="csenge">
Csenge
<br/>
<img src="albumok/csenge/01.jpg" alt="csenge"/>
</div>
</div>
<div style="clear:both;"></div>
<div id="galeria" width="500"></div>
Inside kepek_csenge.php there are rows like this, which should trigger the gallery:
<a class="thumb_wrapper" href="albumok/csenge/01.jpg" title="Első" rel="gallery_view"><img alt="" class="thumb" src="albumok/csenge/thumbs/01.jpg" /></a>
Unfortunately it just loads a new page with the selected picture. How can i use the galleryviewer js in this page?
It is important to understand that the document you are loading into was ready long before you load anything with ajax
This means that the code wrapped in $(function() in your ajax pages will fire as soon as it is encountered. If that code precedes the html it references then it won't find those elements since they don't exist yet.
Try moving all the script tags in the ajax loaded content to after the html.
It is generally easier to put all the scripts into one and wrap different parts in functions and then just call those functions in the success callback of load();
function loadPage(page){
var url = '...' +page;
$('#selector').load(url, function(){
initViewer();
});
}

Codeigniter scrollpagination

I am using jquery plugin scrollpagination in codeigniter i am facing problem that my loop does not terminate and alos not giving accurate result.
this is my html code
<div id="main">
<div id='friend_display'>
<?php if($list->num_rows() > 0 ){
foreach($list->result() as $show)
{ ?>
<div class="image-box" style="margin-left:30px" id='image-holder' >
<div class="photo-cover">
<img width="160px" height="117px" src="<?=base_url()?>uploads/user_images/friends/<?php echo $show->user_image;?>" alt="" />
</div>
<p class="photo-name"><b><?php echo $show->user_name;?></b></p>
</div>
<?php } } else { echo '<div align="center" style="color:#FF0000; font-size:17px; font-weight:bold">You have no Friends yet</div>';}?>
<div class="cl"> </div>
</div></div>
this is script
<script type="text/javascript">
var page_num = 1;
$(function(){
$('#friend_display').scrollPagination({
'contentPage': '<?=base_url()?>friends/load_more', // the url you are fetching the results
'contentData': {page_num:$('.image-box').size()}, // these are the variables you can pass to the request, for example: children().size() to know which page you are
'scrollTarget': $(window), // who gonna scroll? in this example, the full window
'heightOffset': 10, // it gonna request when scroll is 10 pixels before the page ends
'beforeLoad': function(){ // before load function, you can display a preloader div
$('#loading1').fadeIn();
},
'afterLoad': function(elementsLoaded){ // after loading content, you can use this function to animate your new elements
$('#loading1').fadeOut();
var i = 0;
$(elementsLoaded).fadeInWithDelay();
page_num:$('.image-box').size();
}
});
// code for fade in element by element
$.fn.fadeInWithDelay = function(){
var delay = 0;
return this.each(function(){
$(this).delay(delay).animate({opacity:1}, 200);
delay += 100;
});
};
});
</script>
and this is my php function
function load_more()
{
$offset = $this->input->post('page_num');
$list = $this->friends_model->show_friends($offset);
if($list->num_rows()>0)
{
foreach($list->result() as $show)
{?>
<div class="image-box" style="margin-left:30px" id='image-holder'>
<div class="photo-cover">
<img width="160px" height="117px" src="<?=base_url()?>uploads/user_images/friends/<?php echo $show->user_image;?>" alt="" />
</div>
<p class="photo-name"><b><?php echo $show->user_name;?></b></p>
</div>
<?php } ?>
<div class="cl"> </div>
<?php
}
else
{
//echo(333);
}
}
in db i jst shoing main query
$this->db->limit(12,$offset);
can someone tell me what i am missing?
Open this Link to wathch complete code.Scroll Pagination
I belive that the way you are fetching offset isn't correct. (Thought I'm not sure because I don't know what is in your POST['page_num'])
$offset = $this->input->post('page_num');
It looks like you fetch the page number, but the offset in limit function should be how much row has to be skipped. So if you are showing 12 results per "tick" offset should be 12*page_number
$this->db->limit(12,$offset*12);
If you leave offset to page number, you will get wrong results:
limit(12,[0,1,2,...]) // items 1-12, 2-13, 3-14 etc...
limit(12,[0,12,24....] //items 1-12, 13-24, 25-32 etc...
Here i solve this problem in my own way you can try this.In your script remove this line
'contentData': {page_num:$('.image-box').size()},
and add this line
'childClass' : '.image-box',
After open scrollpagination.js file then replace this line data: opts.contentData, with this data: {page_num : $(obj).children(opts.childClass).size()},. Again replace 'contentData' : {}, this line with 'childClass' : '.datalist',.
In your function display_friends() please replace exit; function with this line echo '<input type="hidden" id="nodata" value="1" />'; . After that write your script look like this :
$(function(){
$('#nomoreresult').hide();
$('#loading1').hide();
$('#friend_display').scrollPagination({
'contentPage': 'Your_Url', // the url you are fetching the results
// these are the variables you can pass to the request, for example: children().size() to know which page you are
'childClass' : '.image-box',
'scrollTarget': $(window), // who gonna scroll? in this example, the full window
'heightOffset': 10, // it gonna request when scroll is 10 pixels before the page ends
'beforeLoad': function(){ // before load function, you can display a preloader div
$('#loading1').show().fadeIn();
},
'afterLoad': function(elementsLoaded){
// after loading content, you can use this function to animate your new elements
$('#loading1').hide().fadeOut();
$(elementsLoaded).fadeInWithDelay();
if($('#nodata').val() == '1'){
$('#friend_display').stopScrollPagination();
$('#loading1').hide();
$('#nomoreresult').show().fadeIn();
}
}
});
// code for fade in element by element
$.fn.fadeInWithDelay = function(){
var delay = 0;
return this.each(function(){
$(this).delay(delay).animate({opacity:1}, 200);
delay += 1000;
});
};
Did you try jQuery.noConflict()?
<script type="text/javascript">
var page_num = 1;
jQuery.noConflict();
$(function(){...
Edit2:
It seems your offset works wrong. According to http://pastebin.com/MC1KZm8y
Find:
$offset = $this->input->post('page_num');
$list = $this->friends_model->find($offset);
Replace:
$page_line = 6; //for example
$page_num = $this->input->post('page_num');
$offset = ($page_num -1) * $page_line;
$list = $this->friends_model->find($offset);
Add this missing code inside the afterLoad:function(){.. code also this should stop looping your pagination make sure to add exactly same id that you entered for the scrollpagination id <div id='friend_display'>
if ($('#friend_display').children().size() > 100){ //set the condition to where to stop
// if more than 100 results already loaded, then stop pagination (only for testing)
$('#nomoreresults').fadeIn(); //if you want to show message like "No more result!" use this
$('#friend_display').stopScrollPagination();// this is the most important function call
}
inside .scrollPagination({.. change 'contentPage': '<?php echo base_url();?>controller/action' inside this action(){ $this->load->view('that_you_want_to_display'); it means your display_friends() method only should contain the view file that want to load and parse and the data that you want to display and inside that view echo your data using the foreach

trigger click jquery for all elements

I have the following information in my html
<div idd="8327" id="like" class="geen">Like</div>
<div idd="8329" id="like" class="geen">Like</div>
<div idd="8330" id="like" class="geen">Like</div>
<div idd="8331" id="like" class="geen">Like</div>
I want to send the ID to a specific php page to execute with .get.
it works. but it only works for the first div. The script is only executed when clicking the div with id 8327. When clicking another div, nothing happens :
What can be wrong ?
<script type="text/javascript">
$(document).ready(function() {
$("#like").click(function(event){
var code = $(this).attr("idd");
$.get("like.php", { code1: code, code2: "Kim" } );
alert("Thanks for clicking!");
});
});
</script>
when you use the id selector in Jquery you only select the first element so to get all elements use a class selector instead. So change:
$("#like").click(
To
$(".geen").click(
Switch your selector to use the class. jQuery assumes that # (id) is unique and will use the built in browser function document.getElementById().
$(".geen").click(function(event){
var code = $(this).attr("idd");
$.get("like.php", { code1: code, code2: "Kim" } );
alert("Thanks for clicking!");
});
use your class as selector because id can not be duplicate( which is in your case)
So through this
$(".geen").click(function(event){
var code = $(this).attr("idd");
$.get("like.php", { code1: code, code2: "Kim" } );
alert("Thanks for clicking!");
});

Reading latitude/longitude from DB and putting markers on the map

Below is given my sample code. In index.php I define jquery tabs. One of the tabs should open a map (openlayers) and put markers on this map. Latitude and longitude of each marker is taken from MySQL DB. The problem is that I don't know how and where to execute the function put_marker reading data from DB. I know it should be a basic question.
index.php
<script type="text/javascript">
$(document).ready(function() {
$("#tabs").tabs({
ajaxOptions: {
success: function( html ) {
$("#content").html(html);
page_init();
}
}
});
});
</script>
<div id="tabs">
<ul>
<li><span>Administration</span></li>
<li><span>Map</span></li>
</ul>
</div>
map.php
<?php
include_once 'include/DatabaseConnector.php';
$query4="SELECT r.resLatitude, r.resLongitude FROM resources r;";
$result4=DatabaseConnector::ExecuteQueryArray($query4);
foreach ($result4 as $row):
// HERE I HAVE A PROBLEM
//putMarker($row['resLatitude'],$row['resLongitude']);
endforeach;
?>
<script src="http://www.openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript">
var map, layer;
function page_init(){
map = new OpenLayers.Map("basicMap");
var mapnik = new OpenLayers.Layer.OSM();
var fromProjection = new OpenLayers.Projection("EPSG:4326"); // Transform from WGS 1984
var toProjection = new OpenLayers.Projection("EPSG:900913"); // to Spherical Mercator Projection
var position = new OpenLayers.LonLat(2.07833,41.2969).transform( fromProjection, toProjection);
var zoom = 15;
map.addLayer(mapnik);
map.setCenter(position, zoom );
}
function putMarker(latMarca, lonMarca)
{
var lonLat = new OpenLayers.LonLat(lonMarca ,latMarca ).transform(new OpenLayers.Projection("EPSG:4326"),map.getProjectionObject());
var zoom=16;
var markers = new OpenLayers.Layer.Markers( "Markers" );
map.addLayer(markers);
markers.addMarker(new OpenLayers.Marker(lonLat));
map.setCenter (lonLat, zoom);
}
</script>
<div id="basicMap" style="width: 100%; height: 100%;">
</div>
Well, you're getting your markers in PHP on the server side. And you're passing them to Javascript on the client side. Two different places.
Actually, there's no need even in JSON manipulations in the simplest case.
In your map.php you can do:
..
echo '<script type="text/javascript">';
echo '$(document).ready(function() {';
foreach ($result4 as $row){
echo 'putMarker('.$row['resLatitude'].','.$row['resLongitude'].');';
}
echo '});';
echo '</script>';
...
These code would be interpreted on the client side as pure JS, but with values being taken from the PHP.
By the way, it's not a good approach to write your code the same way.
Look toward MVC frameworks, where the code and look are separated from each other.

Categories