Pagination in infowindow of clusters in gmap3 - google-maps

How can i set pagination for google map cluster infowindow. Iam using gmap3.
$(this).gmap3(
{clear:"overlay"},
{
overlay:{
latLng: cluster.main.getPosition(),
options:{
content: eventlist,
offset: {
x:-46,
y:-73
}
}
}
});
iam having eventlist as
eventlist ='
<div class='infobubble infobulle drive'>
<div class='infobubble_wrap'>
<div class='infobubble_event_text'>
<div class='infobubble_event_names'>arts</div>
<div class='infobubble_date'>Feb 06</div>
<div class='infobubble_event_venue'>Bulldog</div>
</div>
<div class='infobubble_event_image'><img src=thumb.jpg></img></div>
<div class='clear'></div>
</div>
</div>
<div class='infobubble infobulle drive'>
<div class='infobubble_wrap'>
<div class='infobubble_event_text'>
<div class='infobubble_event_names'>Comedy</div>
<div class='infobubble_date'>Jun 13</div>
<div class='infobubble_event_venue'>Our Little Comedy Theater</div>
</div>
<div class='infobubble_event_image'><img src=eventdefault_thumb.jpg></img></div>
<div class='clear'></div>
</div>
</div>
';
How can i get my event 'arts' and 'comedy' in two pages of the infowindow of my gmap3.I am new to gmap3?

I solved it.I wrote a function to get the details of each marker individually and called the function to display the details in the infowindow.Initially i was set to zero.
function infowindowhtml(i)
{
context = global_context_menu;
var markernum = context.length;
var first = next = '';
if (i == 0) {
first = '';
} else {
var j = i - 1;
first = "<div class='prev_info' onclick='showinfodetails(" + j + ");'><<</div>";
}
if (i == (markernum - 1)) {
next = '';
} else {
var j = i + 1;
next = "<div class='next_info' onclick='showinfodetails(" + j + ");'>>></div>";
}
var pagination = '<div>' + first + '<div class="middle_section">' + (i + 1) + '</div>' + next + '</div>';
var datastring = context[i].data;
eventlist=" <div class='infobubble infobubble_cluster infobulle"+(datastring ? " drive" : "") + "'><div class='infobubble_wrap infobubble_wrap_cluster'><div class='infobubble_event_text'><div class='infobubble_event_names'>Comedy</div>" +"<div class='infobubble_date'>Jun 13</div>" +"<div class='infobubble_event_venue'>Our Little</div>" +"<div class='clear'></div>" + pagination + "</div></div>";
return eventlist;
}
in the function showinfodetails i wrote
function showinfodetails(i) {
eventlist = infowindowhtml(i);
$('.infobubble_content').html(eventlist);
}
so on each click on next j will get increased and for each click on prev j will get decreased.This will be passed to the showinfodetails function and the details of that marker will be displayed.
We get context from
mouseover: function(cluster, event, context) {
global_context_menu = context.data.markers;
}
global_context_menu globally declared.

It seems as if the infobubble constructor was treated differently than I remember. I'd do:
var arts_tab="
<div class='infobubble infobulle drive'>
<div class='infobubble_wrap'>
<div class='infobubble_event_text'>
<div class='infobubble_event_names'>arts</div>
<div class='infobubble_date'>Feb 06</div>
<div class='infobubble_event_venue'>Bulldog</div>
</div>
<div class='infobubble_event_image'>
<img src=thumb.jpg></img>
</div>
<div class='clear'></div>
</div>
</div>";
var comedy_tab="<div class='infobubble infobulle drive'>
<div class='infobubble_wrap'>
<div class='infobubble_event_text'>
<div class='infobubble_event_names'>Comedy</div>
<div class='infobubble_date'>Jun 13</div>
<div class='infobubble_event_venue'>Our Little Comedy Theater</div>
</div>
<div class='infobubble_event_image'>
<img src=eventdefault_thumb.jpg></img>
</div>
<div class='clear'></div>
</div>
</div>";
infoBubble = new InfoBubble({
maxWidth: 300
});
infoBubble.addTab('Arts', arts_tab);
infoBubble.addTab('Comedy', comedy_tab);
But if you're using gmaps's wrappers it might be called differently.

Related

how to make input elements symmetric size (equal width) in a bootstrap row

I am trying to create multiple input boxes in two columns. However, I cannot make the size of the boxes equal in each bootstrap row. Because I am not a web developer, any advice on how to resolve this problem would be greatly appreciated!
The reproducible example can be accessed from this link
/* create single select box */
function createSingleSelectBox(id, header_arr) {
var selectBox = document.createElement("select");
selectBox.setAttribute("id", id);
selectBox.multiple = false;
selectBox.className = "input-small w-50";
for (var i = 0; i < header_arr.length; i++) {
var op = new Option();
op.value = header_arr[i];
op.text = header_arr[i];
selectBox.options.add(op);
}
return selectBox;
}
/* create input number box */
function createInputNumberBox(id, min, step, type, my_class, default_val) {
var inputNumBox = document.createElement("input");
inputNumBox.id = id;
inputNumBox.className = my_class;
inputNumBox.type = type;
inputNumBox.step = step;
inputNumBox.min = min;
inputNumBox.value = default_val;
return inputNumBox;
}
/* create heading with icon*/
function createHeadingWithIcon(
head_type,
head_text,
icon_id,
bottom_margin_px
) {
var h = document.createElement(head_type);
h.innerHTML =
head_text +
" " +
"<i class='far fa-question-circle' " +
icon_id +
" style='color:grey'></i>";
// <i class="far fa-question-circle" id="go_tooltip" style="color:grey"></i>
h.style.marginBottom = bottom_margin_px;
return h;
}
//#######################################################################################################################
var h4 = createHeadingWithIcon("h6", "R1_C1", "id='exclusive_tooltip'", "5px");
document.getElementById("id_R1_C1").appendChild(h4);
var exclusive_all = ["YES", "NO"];
var single_selectbox = createSingleSelectBox("R1_C1_select", exclusive_all);
document.getElementById("id_R1_C1").appendChild(single_selectbox);
var h4 = createHeadingWithIcon("h6", "R1_C2", "id='k_out_N_tooltip'", "5px");
document.getElementById("id_R1_C2").appendChild(h4);
var inputNumBox = createInputNumberBox(
"id_R1_C2_input",
1,
1,
"number",
"input-xs w-50 h-50",
"2"
);
document.getElementById("id_R1_C2").appendChild(inputNumBox);
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<div class="col-lg-4">
<div class="card pl-2 py-2">
<div class="card-block">
<div class="row pl-2">
<div class="col-md-7" id="id_R1_C1"></div>
<div class="col-md-5" id="id_R1_C2"></div>
</div>
</div>
</div>
</div>
Two obvious problems here:
You've linked to Bootstrap v3.3.5, but you're using Bootstrap v5 classes. In particular, the w-50 class wasn't available in v3.
You're specifying that the inputs should be 50% of the width of their parent. But the parents are different widths - one is seven columns (~58% of the container), and the other is five columns (~42% of the container).
If you're able to update to Bootstrap v5, then you can make your inputs the same size with:
/* create single select box */
function createSingleSelectBox(id, header_arr) {
var selectBox = document.createElement("select");
selectBox.setAttribute("id", id);
selectBox.multiple = false;
selectBox.className = "input-small w-50";
for (var i = 0; i < header_arr.length; i++) {
var op = new Option();
op.value = header_arr[i];
op.text = header_arr[i];
selectBox.options.add(op);
}
return selectBox;
}
/* create input number box */
function createInputNumberBox(id, min, step, type, my_class, default_val) {
var inputNumBox = document.createElement("input");
inputNumBox.id = id;
inputNumBox.className = my_class;
inputNumBox.type = type;
inputNumBox.step = step;
inputNumBox.min = min;
inputNumBox.value = default_val;
return inputNumBox;
}
/* create heading with icon*/
function createHeadingWithIcon(
head_type,
head_text,
icon_id,
bottom_margin_px
) {
var h = document.createElement(head_type);
h.innerHTML =
head_text +
" " +
"<i class='far fa-question-circle' " +
icon_id +
" style='color:grey'></i>";
// <i class="far fa-question-circle" id="go_tooltip" style="color:grey"></i>
h.style.marginBottom = bottom_margin_px;
return h;
}
//#######################################################################################################################
var h4 = createHeadingWithIcon("h6", "R1_C1", "id='exclusive_tooltip'", "5px");
document.getElementById("id_R1_C1").appendChild(h4);
var exclusive_all = ["YES", "NO"];
var single_selectbox = createSingleSelectBox("R1_C1_select", exclusive_all);
document.getElementById("id_R1_C1").appendChild(single_selectbox);
var h4 = createHeadingWithIcon("h6", "R1_C2", "id='k_out_N_tooltip'", "5px");
document.getElementById("id_R1_C2").appendChild(h4);
var inputNumBox = createInputNumberBox(
"id_R1_C2_input",
1,
1,
"number",
"input-xs w-50 h-50",
"2"
);
document.getElementById("id_R1_C2").appendChild(inputNumBox);
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="col-lg-4">
<div class="card pl-2 py-2">
<div class="card-block">
<div class="row pl-2">
<div class="col-md-6" id="id_R1_C1"></div>
<div class="col-md-6" id="id_R1_C2"></div>
</div>
</div>
</div>
</div>
NB: There are a lot of changes between v3 and v5. If you're working with an existing site, changing Bootstrap versions is not a trivial task.

Splitting up results of knockout data into 2 columns

Was curious if there was an easy way to split up the following code into 2 columns via Knockout and HTML. I know how to do it in the CSS but really it's just to split results 1-5 and 6-9. Here's my code. Screenshot attached as well. Thank you
<div class="item summary">
<h3> <?=l(479)?> </h3>
<div data-bind="foreach:$data.summary">
<div>
<span data-bind="text:$data.sequence + '.'"></span>
<span data-bind="text:$data.label + ':'"></span>
<span data-bind="text:$data.value"></span>
</div>
</div>
</div>
If the length isn't going to change you can duplicate the markup for each block and add a slice(). It's not the most elegant but it's probably the easiest.
<!-- ko if: summary && summary.length > 0 -->
<div data-bind="foreach: $data.summary.slice(0,5)">
...
<div data-bind="foreach: $data.summary.slice(5)">
...
<!-- /ko -->
If you want something a little more dynamic you can create a computed function that splits your array into multiple pieces and use a nested foreach instead:
function viewModel(){
var self = this;
this.summary = [
new Summary(1),
new Summary(2),
new Summary(3),
new Summary(4),
new Summary(5),
];
this.summaryBlocks = ko.computed(function(){
if(self.summary && self.summary.length > 0){
var size = self.summary.length / 2;
return [
self.summary.slice(0,size),
self.summary.slice(size)
];
}else{
return [];
}
});
}
function Summary(val){
this.sequence = 'sequence';
this.label = 'label';
this.value = val;
}
ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="item summary">
<h3> <?=l(479)?> </h3>
<div data-bind="foreach: summaryBlocks">
<div style="display:inline-block; vertical-align:top;" data-bind="foreach:$data">
<div>
<span data-bind="text:$data.sequence + '.'"></span>
<span data-bind="text:$data.label + ':'"></span>
<span data-bind="text:$data.value"></span>
</div>
</div>
</div>
</div>
EDIT: Another snippet for dealing with a variable number of columns
function viewModel() {
var self = this;
this.columns = ko.observable(1);
this.summary = [new Summary(1), new Summary(2), new Summary(3), new Summary(4), new Summary(5), new Summary(6), new Summary(7), new Summary(8), new Summary(9)];
this.summaryBlocks = ko.pureComputed(function() {
var result = [];
for (var i = 0; i < self.columns(); i++) result.push([]);
if (self.summary && self.summary.length > 0) {
for (var i = 0; i < self.summary.length; i++) {
var col = i % self.columns();
result[col].push(self.summary[i]);
}
}
return result;
});
}
function Summary(val) {
this.sequence = 'sequence';
this.label = 'label';
this.value = val;
}
ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
columns: <span data-bind="text: columns"></span>
<br/><input type="range" min=1 max=5 data-bind="value: columns" />
<div class="item summary">
<div data-bind="foreach: summaryBlocks">
<div style="display:inline-block; vertical-align:top;" data-bind="foreach:$data">
<div style="border: 1px dashed blue;">
<span data-bind="text:'item ' + value"></span>
</div>
</div>
</div>
</div>

Displaying 3 columns of data using bootstrap? Data shows as a row instead

Why are the class="col" classes not causing the data to show as a row containing 3 columns?
https://jsfiddle.net/bobbyrne01/b63g4kpe/1/
Html:
https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js
https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css
<div id="results"></div>
Js:
document.getElementById('results').innerHTML += '<div class="container">';
document.getElementById('results').innerHTML += '<div class="row">';
for (var i = 0; i < 3; i++) {
document.getElementById('results').innerHTML += '<div class="col">';
document.getElementById('results').innerHTML += i + ' Col';
}
document.getElementById('results').innerHTML += '</div>';
document.getElementById('results').innerHTML += '</div><br/>';
document.getElementById('results').innerHTML += 'After container';
Your js is not rendering properly as mentioned by others. I have shown a way to achieve this in the following example. Here I have created divs and appended them as children one after another.
Example Snippet
$(document).ready(function() {
var res = document.getElementById('results');
var con = document.createElement('div');
con.className = 'container-fluid';
var newdiv = document.createElement('div');
newdiv.className = 'row';
res.appendChild(con);
con.appendChild(newdiv);
for (var i = 0; i < 3; i++) {
var con1 = document.createElement('div');
con1.className = 'col-md-4 col-xs-4';
newdiv.appendChild(con1);
var text = document.createTextNode(i + ' Col');
con1.appendChild(text);
}
document.getElementById('results').innerHTML += 'After container';
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div id="results">
</div>
Because the syntax is (for example) col-md-4 also you are closing your row div too early. UPDATE: In fact it's somewhat worse than that, your output renders as:
<div id="results">
<div class="container">
</div>
<div class="row"></div>
<div class="col"></div>0 Col
<div class="col"></div>1 Col
<div class="col"></div>2 Col<br>
After container
</div>
You forgot to include the GRID column correctly. You wrote <div class="col">. You should write class like col-lg-* or col-md-* or col-sm* inside div tag. Replace these * with number from 1-12. Hope this answer your question and i have provided you the code below.
document.getElementById('results').innerHTML += '<div class="container">';
document.getElementById('results').innerHTML += '<div class="row">';
document.getElementById('results').innerHTML += '<div class="col-xs-12 col-lg-12">';
for (var i = 0; i < 3; i++) {
document.getElementById('results').innerHTML += '<div class="col-xs-4 col-lg-4"> Column ' + (i + 1) + '</div>';
}
document.getElementById('results').innerHTML += '</div>';
document.getElementById('results').innerHTML += '</div>';
document.getElementById('results').innerHTML += '</div><br/>';
document.getElementById('results').innerHTML += 'After container';
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<head>
<body>
<div id="results"></div>
</body>

Autodividers in listview in JQM using filter

I am using autodividers in listview in JQM and populating new "pages" which works fine when all the list is displayed but when user filters the list, the corresponding page does not display. I'm sure I'm missing something obvious so would appreciate any help.
js
$(document).ready (function() {
$.getJSON("eur_countries_array.json", function (data) {
var countries = [];
for (var obj in data){
countries.push({
title: data[obj].title,
flag: data[obj].flag,
population: data[obj].population,
avg_annual_growth: data[obj].avg_annual_growth,
date: data[obj].date
});
}
// call sort function
countries.sort(compare);
// read through array
var listHTML = "";
for (var i=0; i < countries.length; i++) {
// for each country add flag and title to list
listHTML += '<li><img class="ui-li-icon ui-corner-none alt="'+ countries[i].flag + 's flag" src="flags/16/' + countries[i].flag +'.png" >' + countries[i].title + '</li>';
// Append new "pages" after "home" page for each country
var pHTML = '<div data-role="page" id="' + countries[i].flag + '">';
pHTML += '<div data-role="header"><h1>' + countries[i].title + '</h1><a data-rel="back">Back</a></div>';
pHTML += '<div role="main" class="ui-content" class="country_details">';
pHTML += '<div class="center"><img class="flag_display" alt="'+ countries[i].flag + 's flag" src="flags/64/' + countries[i].flag +'.png" ></div></div>';
pHTML += '<div><p class="center">Population of ' + countries[i].title + ' is ' + countries[i].population + '</p></div>';
pHTML += '<div><p class="center">Average annual growth: ' + countries[i].avg_annual_growth + '</p></div>';
pHTML += '<div><p class="center">Statistics correct as of: ' + countries[i].date + '</p></div>';
pHTML += '</div>';
console.log(pHTML);
$("body").append(pHTML);
}
// Display countries list
// call the refresh method to update the visual styling after adding new elements
$("#countryList").empty().append(listHTML).listview("refresh");
});
});
html
<div data-role="page" id="home">
<div data-role="header">
<h2>European Countries</h2>
</div>
<div role="main">
<ul id="countryList" data-role="listview" data-autodividers="true" data-filter="true" data-inset="true">
<li></li>
</ul>
</div>
<div data-role="footer">
</div>
</div><!-- page -->

Result list is not being displayed (google-fusion-tables template derek)

I am trying to make a searchable map with the great template Derek made.
I have tried everything but somehow I do not manage to get my result list to display. Div is visible but no results. Hope someone can help me. I followed these instructions:
This is part of the index
<a class='btn btn-primary' id='search' href='#'>
<i class='glyphicon glyphicon-search'></i>
Zoeken
</a>
<a class='btn btn-default' id='reset' href='#'>
<i class='glyphicon glyphicon-repeat'></i>
Reset
</a>
</div>
<div class='alert alert-info' id='result_box' ><strong id='result_count'></strong></div>
<div class='well'> <div id='results_list'></div> </div>
</div>
<div class='col-md-8'>
<noscript>
<div class='alert alert-info'>
<h4>Your JavaScript is disabled</h4>
<p>Please enable JavaScript to view the map.</p>
</div>
</noscript>
<div id='map_canvas'></div>
And this the maps_lib.js
submitSearch: function(whereClause, map, location) {
//get using all filters
//NOTE: styleId and templateId are recently added attributes to load custom marker styles and info windows
//you can find your Ids inside the link generated by the 'Publish' option in Fusion Tables
//for more details, see https://developers.google.com/fusiontables/docs/v1/using#WorkingStyles
MapsLib.searchrecords = new google.maps.FusionTablesLayer({
query: {
from: MapsLib.fusionTableId,
select: MapsLib.locationColumn,
where: whereClause
},
styleId: 2,
templateId: 2
});
MapsLib.searchrecords.setMap(map);
MapsLib.getCount(whereClause);
MapsLib.getList(whereClause);},
And this:
getCount: function(whereClause) {
var selectColumns = "Count()";
MapsLib.query(selectColumns, whereClause, "", "", "MapsLib.displaySearchCount");
},
displaySearchCount: function(json) {
MapsLib.handleError(json);
var numRows = 0;
if (json["rows"] != null)
numRows = json["rows"][0];
var name = MapsLib.recordNamePlural;
if (numRows == 1)
name = MapsLib.recordName;
$( "#result_box" ).fadeOut(function() {
$( "#result_count" ).html(MapsLib.addCommas(numRows) + " " + name + " gevonden");
});
$( "#result_box" ).fadeIn();
},
getList: function(whereClause) {
var selectColumns = "Achternaam, Adres, Postcode, Woonplaats";
MapsLib.query(selectColumns, whereClause, "MapsLib.displayList");
},
displayList: function(json) {
MapsLib.handleError(json);
var data = json["rows"];
var template = "";
var results = $("#results_list");
results.hide().empty(); //hide the existing list and empty it out first
if (data == null) {
//clear results list
results.append("<li><span class='lead'>No results found</span></li>");
}
else {
for (var row in data) {
template = "\
<div class='row-fluid item-list'>\
<div class='span12'>\
<strong>" + data[row][0] + "</strong>\
<br />\
" + data[row][1] + "\
<br />\
" + data[row][2] + "\
<br />\
" + data[row][3] + "\
</div>\
</div>"
results.append(template);
}
}
results.fadeIn();
},
The problem seems to be in this function:
getList: function(whereClause) {
var selectColumns = "Achternaam, Adres, Postcode, Woonplaats";
MapsLib.query(selectColumns, whereClause, "MapsLib.displayList");
},
I think it should be represented like this:
getList: function(whereClause) {
var selectColumns = "Achternaam, Adres, Postcode, Woonplaats ";
MapsLib.query(selectColumns, whereClause, "", "", "MapsLib.displayList");
},
I don’t know if you are still looking for an answer to this question but maybe somebody else is as they browse these topics.
Using Derek’s awesome template –
Here is the code I used to create the container box on the main (index) page.
<div class='well'>
<div class="scrollr" id='results_list'></div>
</div>
Note: I added the “scrollr” reference and created the code for it in the “custom.css” file.
This simply puts a border around the result list box and makes it scrollable. Here is style code I added to the custom.css file:
.scrollr {
height: 400px;
overflow: scroll;
border-style: solid;
border-color: darkgray;
background-color: lightgray;
}
Finally, here is the code I added to the “maps_lib.js” file after the “displaySearchCount” function.
//DISPLAY RESULTS FUNCIION----------------------------------------------------------------------------------------
MapsLib.prototype.getList = function(whereClause) {
var self = this;
var selectColumns = 'Column1, Column2, Column3, Column4, Column5';
self.query({
select: selectColumns,
where: whereClause
}, function(response) {
self.displayList(response);
});
},
MapsLib.prototype.displayList = function(json) {
var self = this;
var data = json['rows'];
var template = '';
var results = $('#results_list');
results.hide().empty(); //hide the existing list and empty it out first
if (data == null) {
//clear results list
results.append("<li><span class='lead'>No results found</span></li>");
}
else {
for (var row in data) {
template = "\
<div class='row-fluid item-list'>\
<div class='span12'>\
<strong>" + data[row][0] + "</strong>\
<br />\
" + data[row][1] + "\
<br />\
" + data[row][2] + "\
<br />\
" + data[row][3] + "\
<br />\
" + data[row][4] + "<br>\
</div>\
</div>";
results.append(template);
}
}
results.fadeIn();
},
Hope this helps someone.