Google Places Autocomplete issue on iOS7 (webview) - ios7

I currently have an issue implementing a simple Google Places Autocomplete input in a webview.
My issue seems to be related to a bug in ios7 where the blur event is triggered before the place_changed has been fired, thus the input field doesn't take the chosen value.
Here is the code (part of an AngularJS directive):
var newAutocomplete = function () {
scope.gPlace = new google.maps.places.Autocomplete(element[0], opts);
google.maps.event.addListener(scope.gPlace, 'place_changed', function () {
scope.$apply(function () {
var place = scope.gPlace.getPlace();
if (!place || !place.geometry) {
return;
}
scope.location = {
coords: {
lat: place.geometry.location.lat(),
lng: place.geometry.location.lng()
},
address: element.val()
};
});
});
};
Any idea how to handle this? Delaying the onBlur event?
Thanks in advance.
[SELF-ANSWERED]
I just found out the problem was related to the use of the FastClick library.
This is what needs to be added in the page to make it work:
$(document).on({
'DOMNodeInserted': function() {
$('.pac-item, .pac-item span', this).addClass('needsclick');
}
}, '.pac-container');
Thanks to can't tap on item in google autocomplete list on mobile for the solution!

Related

capture popup feature attribute in pop action

I've got an action function for my popup and I need to access the feature attributes from the pop up within the action function. In the code below I'd like to access {SAWID} -- I dont see it in the event parameter sent to the function.
var ContactsAction = {
title: "Get Contacts",
id: "contacts-this",
};
var template = {
// autocasts as new PopupTemplate()
title: "{Name}",
content: "{SAWID}",
actions: [ContactsAction]
};
// Event handler that fires each time an action is clicked.
view.popup.on("trigger-action", lang.hitch(this, this.Contacts));
// Executes when GetContacts is clicked in pop ups
Contacts: function (event) {
if (event.action.id === "contacts-this") {
//grab SAWID
}
}
Thanks
Pete
I found something that works, although its probably not the best way to do it:
there is an innerText property on the even.target object that includes all the text in the pop up. If I parse the innerText property I can get what I need: If anyone knows of a cleaner way please let me know. Thanks
// Executes when GetContacts is clicked in pop ups
Contacts: function (event) {
if (event.action.id === "contacts-this") {
var str = event.target.innerText;
var start = str.indexOf("Close") + 6;//"Close" always precedes my SAWID
var end = str.indexOf("Zoom") - 1;//"Zoom" is always after my SAWID
var SAWID = str.substring(start, end);
alert(SAWID);
}
}

Can I detect changes in a node's markup text using dojo?

I have a bunch of nodes that will contain markup in an unpredictable structure. I want to be able to watch these nodes and see if the html of the any of the child nodes or their descendants change, no matter how slightly. If they do, then I want to fire an event.
Can I do this through dojo? I'm using 1.10, the latest one.
Thanks.
It sounds like you're looking for dom mutations. As far as I'm aware dojo does not provide an api for this, but they're pretty simple to set up. The problem is different browsers have different ways of doing this.
var observeNode = document.getElementById('observeMe');
// Check for vendor-specific versions of MutationObserver.
MutationObserver = (function() {
var prefixes = ['WebKit', 'Moz', 'O', 'Ms', ''];
for (var i=0, il=prefixes.length; i<il; i++) {
if (prefixes[i] + 'MutationObserver' in window) {
return window[prefixes[i] + 'MutationObserver'];
}
}
}());
// Sniff for MutationObserver support
if (MutationObserver) {
var observer = new MutationObserver(function(mutations) {
alert('Something changed!');
});
observer.observe(observeNode, {attributes: true, childList: true, characterData: true});
} else {
// Fall back to mutation events
if (observeNode.addEventListener) {
observeNode.addEventListener('DOMSubtreeModified', function() {
alert('Something changed!');
});
}
// IE8 and below has its own little weird thing
else {
observeNode.onpropertychange = function() {
alert('Something Changed!');
}
}
}

jquery datatables scroll to top when pages clicked from bottom

I am using a jQuery datatable with bottom pagination. When the pages are clicked from bottom , I want it to scroll it to top, so users do not have to manually do that for longer pages. I tried using dataTables_scrollBody, but it doesn't work properly
Here is my code:
oTable = $('#tTable').dataTable({
"fnDrawCallback": function(o) {
$('dataTables_scrollBody').scrollTop(0);
}
});
The page scrolls to top only when you click first/last (which I think is default behaviour), but not with every page click.
Update. The original answer was targeting 1.9.x. In dataTables 1.10.x it is much easier :
table.on('page.dt', function() {
$('html, body').animate({
scrollTop: $(".dataTables_wrapper").offset().top
}, 'slow');
});
demo -> http://jsfiddle.net/wq853akd/
Also, if you're using the bootstrap version of datatables, you may notice that when using the fix, the page actually scrolls back down after scrolling to the top. This is because it is focusing on the clicked button as per this datatables.net thread. You can fix this by simply focusing on the table header after the animate call, like so:
table.on('page.dt', function() {
$('html, body').animate({
scrollTop: $(".dataTables_wrapper").offset().top
}, 'slow');
$('thead tr th:first-child').focus().blur();
});
Original Answer
You should target .dataTables_wrapper and attach the event to .paginate_button instead. Here with a nice little animation :
function paginateScroll() {
$('html, body').animate({
scrollTop: $(".dataTables_wrapper").offset().top
}, 100);
console.log('pagination button clicked'); //remove after test
$(".paginate_button").unbind('click', paginateScroll);
$(".paginate_button").bind('click', paginateScroll);
}
paginateScroll();
see fiddle -> http://jsfiddle.net/EjbEJ/
Since Datatables 1.10 there is this page event
https://datatables.net/reference/event/page
So one can use
$('#example_table').on( 'page.dt', function () {
$('html, body').animate({
scrollTop: 0
}, 300);
} );
Demo: https://jsfiddle.net/mcyhqrdx/
This worked out for me.
$(document).ready(function() {
var oldStart = 0;
$('#example').dataTable({
"bJQueryUI": true,
"sPaginationType": "full_numbers",
"fnDrawCallback": function (o) {
if ( o._iDisplayStart != oldStart ) {
var targetOffset = $('#example').offset().top;
$('html,body').animate({scrollTop: targetOffset}, 500);
oldStart = o._iDisplayStart;
}
}
});
} );
I'm also using datatables and Allan's solution (found here) worked perfectly for me.
$(document).ready(function() {
var oldStart = 0;
$('#example').dataTable({
"bJQueryUI": true,
"sPaginationType": "full_numbers",
"fnDrawCallback": function (o) {
if ( o._iDisplayStart != oldStart ) {
var targetOffset = $('#example').offset().top;
$('html,body').animate({scrollTop: targetOffset}, 500);
oldStart = o._iDisplayStart;
}
}
});
} );
Thank's from davidkonrad. But when I used his code, after I clicked on paginate button, scroll of page went to top and then after load data, scroll backed to bottom.
I combined multiple posts in StackOverFlow and Datatables forum.
I defined a global variable :
var isScroll = false
When it's clicked on paginate button isScroll set to true:
$(document).on('click', '.paginate_button:not(.disabled)', function () {
isScroll = true;
});
And finally:
$(document).ready(function () {
$('#myDataTable').DataTable({
...
"fnDrawCallback": function () {
if (isScroll) {
$('html, body').animate({
scrollTop: $(".dataTables_wrapper").offset().top
}, 500);
isScroll = false;
}
},
...
});
});
Thanks from #0110
None of the above answers worked for me. Here's my solution.
$("#divContainingTheDataTable").click(function(event){
if ($(event.target).hasClass("paginate_button")) {
$('html, body').animate({
scrollTop: $("#divContainingTheDataTable").offset().top
}, 200);
}
});
I tried targetting .paginate_button but it never seemed to fire. My approach checks the div containing the datatable, if you click on the pagination buttons, the page scrolls up to the top of the container.
For those using the bootstrap version of Datatables:
You may notice that when using the fix from the accepted answer above, the page actually scrolls back down to the paging controls after scrolling to the top. This is because it is focusing on the clicked paging button as per this datatables.net thread. You can fix this by simply focusing on the table header after the animate call like so:
table.on('page.dt', function() {
$('html, body').animate({
scrollTop: $(".dataTables_wrapper").offset().top
}, 'slow');
$('thead tr th:first-child').focus().blur();
});
Note: the chained blur()'ing is done so that you the user doesn't see any focused styles on th:first-child.

Google Maps KML Layer won't Zoom

I have an embedded Google Map using API V3 but I cannot get it default Zoom to anything other than 1.
My JS in the head is:
var map1;
var src1 = 'https://latitude.google.com/latitude/apps/badge/api?user=8963899225283336226&type=kml';
function initialize1() {
map1 = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 7,
mapTypeId: google.maps.MapTypeId.TERRAIN
});
loadKmlLayer1(src1, map1);
}
google.maps.event.addDomListener(window, 'load', initialize1);
function loadKmlLayer1(src1, map1) {
var kmlLayer1 = new google.maps.KmlLayer(src1, {
suppressInfoWindows: false,
clickable: true,
preserveViewport: false,
map: map1
});
}
The HTML is just the map-canvas div, nothing else. Looking at some of the threads on here it look like its something to do with detecting the viewport and resetting the bounds.
I found a thread that suggested adding something like:
google.maps.event.addListener(kmlLayer1, 'defaultviewport_changed', function() {
var bounds = kmlLayer1.getDefaultViewport();
map.setCenter(bounds.getCenter());
})
but it made no difference. I'm by no means a JS expert and whilst I mostly understand what is going on in most of the code above, I'm not advanced enough to improvise or even understand where it should be placed.
Thanks Molle.
I enhanced to this and it works:
google.maps.event.addListener(kmlLayer, 'status_changed', function () {
console.log('kml loaded:');
google.maps.event.addListenerOnce(map, 'zoom_changed', function () {
console.log('zoom_changed:');
map.setZoom(7);
map.setCenter(new google.maps.LatLng(0, 0));
});
});
The API will set the viewport to contain all KML-features, what will override the zoom-settings.
Reset the zoom once the zoom has changed(as it does when the KML-Layer has been loaded)
google.maps.event.addListenerOnce(map1, 'zoom_changed', function() {
this.setZoom(7);
})

Header and Footer keep showing up with modal pop up window

I just want to show basic HTML without the header and footer of my main page when using a modal window.
How can one do that in MVC3/4?
Here is an example of what is happening...
Not sure why it is doing that.
This is a basic jquery modal window call
$(function () {
//$('a.tempDlg').live("click", function (event) { loadDialog(this, event, '#edit-set'); });
//$('a.AddPatDlg').live("click", function(event) {loadDialog(this, event, '#addPat');});
//debugger;
$('a.addEncounter').live("click", function (event) { loadDialog(this, event, '#DisplayUniqueEncounters'); });
$('a.SearchEncounter').live("click", function (event) { loadDialog(this, event, '#searchEncounter'); });
//$("#sID").click(function (event) { loadDialogByClick(this, event, '#searchEncounter'); });
});
function loadDialog(tag, event, target) {
//debugger;
event.preventDefault();
var $loading = $('<img src="<%=Url.Content("~/Images/ajax-loader.gif")%>" alt="loading" class="ui-loading-icon">');
var $url = $(tag).attr('href');
var $title = $(tag).attr('title');
var $dialog = $('<div></div>');
$dialog.empty();
$dialog
.append($loading)
.load($url)
.dialog({
autoOpen: false
, title: $title
, width: 1200
, modal: true
, minHeight: 550
, show: 'fade'
, hide: 'fade'
});
$dialog.dialog('open');
};
I have done this before without including the header and footer, and I forget how it was done? I must be missing a step.
You can also set the Layout = null at the top of the page
That is correct... I want to give nemesv credit for this answer, but he didn't answer the question. So I will just say that he was right. You need to return a partialView(), not just a regular view... Returning a regular view always gets all of the other MVC markup. Thanks...