Google Maps Store Locator Click Jumps to Top of Page - javascript

I have a Store Locator and every time I click on an anchor (such as Zoom Here, Directions, or Street View), the hash in the href takes me to the top of the page. How can I prevent this from happening? I tried looking through the Store Locator source, but it's minified and hard to figure out what is what. I also tried adding event delegation to anchors with class "action" but this didn't work either.
Main function
google.maps.event.addDomListener(window, 'load', function() {
var map = new google.maps.Map(document.getElementById('mappanel'), {
center: new google.maps.LatLng(56.102683, 10.452576),
zoom: 7,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var panelDiv = document.getElementById('searchpanel');
var data = new storeSource;
var view = new storeLocator.View(map, data, {
geolocation: false
});
new storeLocator.Panel(panelDiv, {
view: view
});
});
storeLocator class
/** #extends storeLocator.StaticDataFeed */
function storeSource() {
jQuery.extend(this, new storeLocator.StaticDataFeed);
var that = this;
jQuery.get('/components/com_maps/storeSource.csv', function(data) {
that.setStores(that.parse_(data));
});
}
/** #private */
storeSource.prototype.parse_ = function(csv) {
var stores = [];
var rows = csv.split('\r');
var headings = this.parseRow_(rows[0]);
for (var i = 1, row; row = rows[i]; i++) {
row = this.toObject_(headings, this.parseRow_(row));
if(row.adresse.length > 3) {
row.lat = row.lat.replace(",", ".");
row.lng = row.lng.replace(",", ".");
var position = new google.maps.LatLng(row.lat, row.lng);
var locality = this.join_([row.postnr, row.by], ', ');
var store = new storeLocator.Store(row.uid, position, null, {
title: row.navn,
address: this.join_([row.adresse, locality, row.land], '<br>'),
phone: row.tlfnr
});
stores.push(store);
}
}
return stores;
};
/** Joins elements of an array that are non-empty and non-null. */
storeSource.prototype.join_ = function(arr, sep) {
var parts = [];
for (var i = 0, ii = arr.length; i < ii; i++) {
arr[i] && parts.push(arr[i]);
}
return parts.join(sep);
};
/*** CSV parsing */
storeSource.prototype.parseRow_ = function(row) {
// Each row in the CSV file only has ; as delimiter
row = row.split(';');
return row;
};
/** Creates an object mapping headings to row elements. */
storeSource.prototype.toObject_ = function(headings, row) {
var result = {};
for (var i = 0, ii = row.length; i < ii; i++) {
result[headings[i]] = row[i];
}
return result;
};
Here's a link to the Store Locator library: http://storelocator.googlecode.com/git/index.html

That is the default behaviour in the browser for clicking on an <a> tag that has an href value of #. The # is reserved for jumping to sections on the page. As an easy example, if you have an <a> tag with an href of #movies, and a section on your page that has a name attribute that is also movies, then clicking on <a href="#movies"> will bring the user directly to the movies section of your page. If you simply have #, then the browser skips to the very top of the page, because you didn't specify a section name.
To prevent this behaviour, you need to do at least this:
$(".my-links").on( 'click', function( evt ) {
evt.preventDefault();
});
And you may also need to include another line like this (depending on your selector/setup):
$(".my-links").on( 'click', function( evt ) {
evt.preventDefault();
evt.stopPropagation();
});
preventDefault() will stop the default behaviour for a click on any element that matches the selector. See here.
stopPropagation() will stop the default event from bubbling up the DOM, so it doesn't get caught by any parent elements. See here.
Hope this helps

Related

Selectize.js can't get dropdown to pop-down

I have a Selectized select which is not showing a popup with the options, even though I can see in the debugger that the selectized control contains the desired options. When I click on the dropdown button, the arrow points upwards as it would when displaying the list, but that is all that its doing and no popup containing the options list is displayed. Also this dropdown is inside a bootstrap modal dialog. The following code snippet shows the Selectize dropdown initialization and selectization. The first part initializes the control.
the following loads the options array:
This is where the selectization occurs. First we call the initialization method to load the options, and then use the resulting instantiated control to create the selectized Control:
By the way, I have the same exact code working on another page, but I just don't see why it wouldn't work in this page. The code is identical in both cases.
Code in text format:
var sgAllSelectize = [];
var pplicationId = null;
function bindAllSGContainer(appId, option) {
/* ok, so we loaded the SG select element, time to selectize it */
var handler;
var pageType = $("#hdnPageType").val();
if (pageType == 'clone') {
handler = onChangeSGidForAllServer;
}
if (pageType == 'migration') {
handler = onChangeMigrationSGidForAllServer;
}
if (pageType == 'failover') {
handler = onChangeFailoverSGidForAllServer;
}
var element = "#allServerSGselect_" + appId;
applicationId = appId;
var $vs = $(element).selectize({
create: true,
sortField: 'text',
placeHolder: 'Example: sg-00000000',
persist: false,
options: option,
createOnBlur: true,
allowEmptyOption: false,
closeAfterSelect: true,
onChange: function (input) {
var aid = appId;
var sgValid = input.search(/^sg-[a-zA-Z0-9]{8}$/i);
var sg_selection = $("option", element);
var sg_selection_stripped = sg_selection.val().slice(0, 11);
if (sgValid == 0) {
sg_selection.val(sg_selection_stripped);
handler(input, aid);
} else {
console.log("sg " + input + " is not valid");
this.removeOption(input, "silent");
this.setValue("");
/* sending an empty sg id will disable the sg elements */
handler("", aid);
}
}
});
sgAllSelectize[appId] = $vs;
}
var allOptsArray = [];
//load up the options into an object array
for (var h = 0; h < str1.length; h++) {
optAllSgObject = new Object();
optAllSgObject.text = str1[h];
optAllSgObject.value = str1[h];
allOptsArray.push(optAllSgObject);
}
bindAllSGContainer(appId, allOptsArray);
var o = sgAllSelectize[appId];
selectizeAll = o[0].selectize;
The answer is hidden in a comment.
The surrounding cell or table had an overflow: hidden. Ensure this is set to overflow: visible.

How to get Tooltipster to access data in a js array

Using Tooltipster, I want to populate tooltips with words selected from a English/Thai glossary set up as a js 2D array. The intention is that as an English word is tooltipped it will be used to access and display the paired Thai word(s). All of this is in a modal dialog. Here is the html:
<div id="modal_text">
<p id="modal_text01">The <span class="tooltip">boy</span> is <span class="tooltip">walking</span><span> </span><span class="tooltip" >home</span></p>
here is the js code (the array is set as a global variable)
var eng_thai_glossary=[["the","คำนำหน้านามเจาะจง"], ["and","และ"], ... ["dependent","ซึ่งพึ่งพา ผู้อาศัย"]];
jQuery(document).ready(function () {
"use strict";
var modalIndex = "";
var ws_dlog = jQuery("div#ws_dialog").dialog({
... /* dialog setup */
jQuery("span.ws_dialog_icon").on("click",function(evnt) {
evnt.stopPropagation();
ws_dlog.dialog("open");
jQuery("#ui-dialog-title-dialog").hide();
jQuery(".ui-dialog-titlebar").removeClass('ui-widget-header');
var elementId = evnt.target.id;
modalIndex = elementId.substr(7);
var modalId = "modal_text" + modalIndex,
modalText = document.getElementById(modalId).innerHTML;
var ws_modal_html = '<div class = "ws_dialog_box"><p class = "ws_dialog_text">Here is the word in a sentence</p><p class="ws_dialog_thai">คำในประโยค</p><p class = "ws_dialog_sentence"></p><p><span class="fa fa-volume-up fa_volume_ws"></span></p></div>';
ws_dlog.html(ws_modal_html);
jQuery("div.ws_dialog_box p.ws_dialog_sentence").append(modalText);
jQuery('span.tooltip').tooltipster({
functionAfter: function(evnt) {
var eng_word = jQuery(this).evnt.innerHTML,
thai_word = "";
for( var i=0; i<eng_thai_glossary.length; i++) {
if(eng_thai_glossary[i][0] === eng_word) {
thai_word = eng_thai_glossary[i][1];
return thai_word;
}
}
}
});
});
... /* audio code */
});
Firebug shows the class "tooltipstered" is being added to the html indicating Tooltipster is being initialized. I'm a bit lost beyond this point. I'm not sure whether functionAfter is the right way to go here, or any of the other code for that matter. Any advice would be most welcome
OK, this is the solution I arrived at for the above issue. Pretty standard stuff, I guess. The toLowerCase method covers the English convention of capitalizing the first character of a sentence.
jQuery('span.tooltip').tooltipster({
functionBefore: function(origin, continueTooltip) {
var eng_word = jQuery(origin).text().toLowerCase(),
thai_word = "",
gloss_length = eng_thai_glossary.length;
for(var i=0; i<gloss_length; i++){
if(eng_thai_glossary[i][0] === eng_word) {
thai_word = eng_thai_glossary[i][1];
break;
}
}
origin.tooltipster( "content", thai_word);
continueTooltip();
}
});

Auto highlighting part of word

I'm trying to build a "search in the shown elements" function with jquery and css.
Here's what I got so far:
http://jsfiddle.net/jonigiuro/wTjzc/
Now I need to add a little feature and I don't know where to start. Basically, when you write something in the search field, the corresponding letters should be highlighted in the list (see screenshot, the blue highlighted part)
Here's the script so far:
var FilterParticipants = function(options) {
this.options = options;
this.participantList = [];
this.init = function() {
var self = this;
//GENERATE PARTICIPANTS OPBJECT
for(var i = 0; i < this.options.participantBox.length ; i++) {
this.participantList.push({
element: this.options.participantBox.eq(i),
name: this.options.participantBox.eq(i).find('.name').text().toLowerCase()
})
}
//ADD EVENT LISTENER
this.options.searchField.on('keyup', function() {
self.filter($(this).val());
})
}
this.filter = function( string ) {
var list = this.participantList;
for(var i = 0 ; i < this.participantList.length; i++) {
var currentItem = list[i];
//COMPARE THE INPUT WITH THE PARTICIPANTS OBJECT (NAME)
if( currentItem.name.indexOf(string.toLowerCase()) == -1) {
currentItem.element.addClass('hidden');
} else {
currentItem.element.removeClass('hidden');
}
}
}
this.init();
}
var filterParticipants = new FilterParticipants({
searchField: $('#participants-field'),
participantBox: $('.single_participant'),
nameClass: 'name'
});
I think you're just complicating things too much... You can do this easily in a few lines. Hope this helps:
var $search = $('#participants-field');
var $names = $('.single_participant p');
$search.keyup(function(){
var match = RegExp(this.value, 'gi'); // case-insensitive
$names
.hide()
.filter(function(){ return match.test($(this).text()) })
.show()
.html(function(){
if (!$search.val()) return $(this).text();
return $(this).text().replace(match, '<span class="highlight">$&</span>');
});
});
I used hide and show because it feels snappier but you can use CSS3 animations and classes like you were doing.
Demo: http://jsfiddle.net/elclanrs/wTjzc/8/
Here`s the way to do it with jQuery autocomplete so question
If you want to build it on your own you can do the following:
1. Get the data of every item.
2. Make render function in which you will substitute say "Fir" in Fire word to Fire
3. Every time you change the text in the input you can go through the items and perform substitution.

Google Fusion Map - Dynamic Menu queried from the google fusion table

I am pretty sure that I know what the problem is with my code, but I am unsure how to fix it.
I have a google fusion table that i am querying to generate a menu that has radio buttons in it. A map that is a google fusion table visualized like a google map is also on the page.
When i hard code a couple radio buttons and click them it makes the items light up on the map based on the ID of the element. I using google.maps.event.addDomListener to make this magic work. So that works great.
Now i want to take it one step further and actually pull the data from a google fusion table so it shows the most up to date list of items i have in my table. So, I'm using jQuery and a $.get command to get the feed in jsonp. I'm outputting 2 columns of data and dynamically building radio buttons by attaching them with a innerHTML line -- attaching it to a div.
So, I'm thinking the problem has to do with the DOM, but i am not sure how to get the radio buttons to load in first and then load in the map so all is available to the maps events so clikcing the radio actually does something.
The question is what modifications do i need to make so my dynamic generated radio buttons will work with my google fusion map?
Here is my javascript code:
function initialize() {
var table = ########;
var map = new google.maps.Map(document.getElementById('map-canvas'), {
center: new google.maps.LatLng(30.6, -108.1),
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var layer = new google.maps.FusionTablesLayer();
filterMap(layer, table, map);
getData(table);
google.maps.event.addDomListener(document.getElementById('num1'),
'click', function() {
filterMap(layer, table, map);
});
google.maps.event.addDomListener(document.getElementById('num2'),
'click', function() {
filterMap(layer, table, map);
});
}
// Filter the map based on checkbox selection.
function filterMap(layer, table, map) {
var where = generateWhere();
if (where) {
if (!layer.getMap()) {
layer.setMap(map);
}
layer.setOptions({
query: {
select: "State",
from: table,
where: where
}
});
} else {
layer.setMap(null);
}
}
// Generate a where clause from the checkboxes. If no boxes
// are checked, return an empty string.
function generateWhere() {
var filter = [];
var bugs = document.getElementsByName('bug');
for (var i = 0, bug; bug = bugs[i]; i++) {
if (bug.checked) {
var BugName = bug.value.replace(/'/g, '\\\'');
filter.push("'" + BugName + "'");
}
}
var where = '';
if (filter.length) {
where = "'BugName' IN (" + filter.join(',') + ')';
}
return where;
}
// build the menu
function getData(table) {
var queryUrlHead = 'http://www.google.com/fusiontables/api/query?sql=';
var queryUrlTail = '&jsonCallback=?'; // ? could be a function name
// write your SQL as normal, then encode it
var query = "SELECT BugName, bugAbbr FROM " + table + " LIMIT 1";
var queryurl = encodeURI(queryUrlHead + query + queryUrlTail);
var jqxhr = $.get(queryurl, dataHandler, "jsonp");
}
function dataHandler(d) {
// get the actual data out of the JSON object
var data = d.table.rows;
var ftdata = ['<div>'];
for (var i = 0; i < data.length; i++) {
ftdata.push('<input type="radio" id="'+data[i][1]+'" value="'+data[i][0]+'" name="bug">'+data[i][0]+'');
}
ftdata.push('</div>');
document.getElementById('ft-data').innerHTML = ftdata.join('');
}
google.maps.event.addDomListener(window, 'load', getData);
google.maps.event.addDomListener(window, 'load', initialize);
This site had a bunch of example code.
http://csessig.wordpress.com/category/fusion-tables/

obj is null, javascript

function init()
{
alert("init()");
/**
* Adds an event listener to onclick event on the start button.
*/
xbEvent.addEventListener(document.getElementById("viewInvitation"), "click", function()
{
new Ajax().sendRequest("31260xml/invitations.xml", null, new PageMaster());
xbEvent.addEventListener(document.getElementById("declinebutton"), "click", function ()
{
declineInvitation();
});
});
ok so what I have here is a event listerner function, the case is when viewInvitation is clicked , the program will fetch my xml file and run page master function where I created my decline button with id="declinebutton", however this does not work, the error message that i get is obj=null or the program could not find id = declinebutton, why is it so? I have created it when I called page master using dom. any help will be appreciated.
function PageMaster()
{
this.contentDiv = document.getElementById("content");
}
/**
* Builds the main part of the web page based on the given XML document object
*
* #param {Object} xmlDoc the given XML document object
*/
var subjectList;
var i;
PageMaster.prototype.doIt = function(xmlDoc)
{
alert("PageMaster()");
alert("Clear page...");
this.contentDiv.innerHTML = "";
if (null != xmlDoc)
{
alert("Build page...");
//create div Post
var divPost = document.createElement("div");
divPost.className = "post";
//create h1 element
var h1Element = document.createElement("h1");
var headingText = document.createTextNode("Invitations");
h1Element.appendChild(headingText);
//insert h1 element into div post
divPost.appendChild(h1Element);
subjectList = xmlDoc.getElementsByTagName("subject");
var groupList = xmlDoc.getElementsByTagName("group");
for (i = 0; i < subjectList.length; i++) //for each subject
{
var divEntry = document.createElement("div");
divEntry.className = "entry";
var subjectNum = subjectList[i].attributes[0].nodeValue;
var subjectName = subjectList[i].attributes[1].nodeValue;
var groupId = groupList[i].attributes[0].nodeValue;
var groupName = groupList[i].attributes[1].nodeValue;
var ownerId = groupList[i].attributes[2].nodeValue;
//set up the invitation table attributes
var table=document.createElement("table");
table.width = 411;
table.border = 3;
table.borderColor = "#990000"
var input=document.createElement("p");
var inputText=document.createTextNode("You are invited to join " + groupName + "(groupId : " + groupId +")");
input.className="style11";
var blank=document.createElement("nbps");
input.appendChild(inputText);
var acceptButton=document.createElement("input");
acceptButton.type="button";
acceptButton.id="acceptbutton";
acceptButton.value="accept";
var declineButton=document.createElement("input");
declineButton.type="button";
declineButton.id="declinebutton";
declineButton.value="decline";
table.appendChild(input);
table.appendChild(acceptButton);
table.appendChild(declineButton);
divEntry.appendChild(table);
var blankSpace = document.createElement("p");
divEntry.appendChild(blankSpace);
divPost.appendChild(divEntry);
}
//insert div post into div content
this.contentDiv.appendChild(divPost);
}
};
/**function getValueOf()
{
return i;
}**/
function declineInvitation()
{
alert("decline");
}
function acceptInvitation()
{
alert("hello");
/**var pos=getValueOf();
alert(subjectList[pos].attributes[0].nodeValue);**/
}
That's my page master function, and I definitely have created the button. but it does not work.
Try calling your function like this:
window.onload=init;
The javascript runs as the page loads. At that point, the element does not yet exist in the DOM tree. You'll need to delay the script until the page has loaded.
The example you gave doesn't create the "Decline" button, as your question suggests it should. If it should, you might want to look at that.
Of course, if the button already exists, please disregard this answer.
You have a listener inside a listener. Is that right?
What about this?:
function init(){
alert("init()");
/** * Adds an event listener to onclick event on the start button. */
xbEvent.addEventListener(document.getElementById("viewInvitation"), "click", function()
{
new Ajax().sendRequest("31260xml/invitations.xml", null, new PageMaster());
}
xbEvent.addEventListener(document.getElementById("declinebutton"), "click", function ()
{
declineInvitation();
});
As far as I understand, you create button with id="declinebutton" for each entry from xml, is that right?
If yes, I'd suggest you to generate different id's for each button (for example, append line index to 'declinebutton', so you have buttons 'declinebutton0', 'declinebutton1' an so on), and assign event listener to buttons separately in the loop.

Categories