bing maps autocomplete get long and lat from address - jquery-ui

I want the user to search for an address and i want it to show som examples and when the user chooses one the examples i want it to find the coordinates. But for now i can't get autocomplete to work at all and it won't search for addresses.
$('[id$=PlaceOfDeparture]:not(.ui-autocomplete-input)').live('focus', function () {
$(this).autocomplete({
source: function (request, response) {
$.ajax({
url: "http://dev.virtualearth.net/REST/v1/Locations",
dataType: "jsonp",
data: {
key: 'AvmdDLtsmPpOQ9N21vLDEAlhnr-H-W-A9HmjXiIDn9cHBVp5ylLELdc_lmnuCcRB',
addressLine: request.term,
},
success: function (data) {
var result = data;
}
});
},
minLength: 2,
select: function (event, ui) {
event.preventDefault();
$(this).val(ui.item.label);
travel = $(this).closest('div').parent();
travel.find('[id$=PlaceOfDepartureCoordinates]').val(ui.item.value);
travel.find('[id$=PlaceOfDepartureContry]').val(ui.item.countryName);
$(this).change();
updateMap();
},
open: function () {
$(this).removeClass("ui-corner-all").addClass("ui-corner-top");
},
close: function () {
$(this).removeClass("ui-corner-top").addClass("ui-corner-all");
}
});
});

You can find a working code sample of how to do this here: http://www.vivienchevallier.com/Articles/use-bing-maps-rest-services-with-jquery-to-build-an-autocomplete-box-and-find-a-location-dynamically
However, I highly recommend against doing this. Autocomplete usually generates a high volume of transactions against your account. If you are using an enterprise account this will result in high costs. If you are using a non-enterprise account you will run into issues where the auto complete will not work all the time as your account with be rate limited due to the high frequency of requests.
A much better approach to create the type of functionality you are looking for is to create a user ranked auto suggest. This will drastically improve the suggestions to the user and will make for a much better user experience while minimizing the amount of wasteful calls made to the Bing Maps service. The idea behind the user ranked auto suggest is to create a database where you can store the locations selected by your users. Every time a user selects a location in the auto suggest a rank value is increased and the ordering of the suggestions is based on the rank value. If the user does not find any results in the auto suggest that match their query, that's when they press the search button and you call the Bing Maps service to return possible results. If they select any of the results you would then add that result to your database. I have a couple of customers who have done this and after a few months they were hardly generating any transactions against Bing Maps which meant lower costs over the long term. It also meant that they had a lot of insight into what their users are looking for and which locations were the most popular. This kind of insight can be very valuable.

This is an very old post. Bing Maps now offers autosuggest. Here are some resources:
http://bingmapsv8samples.azurewebsites.net/#Fill%20Address%20Form%20with%20Autosuggest
http://bingmapsv8samples.azurewebsites.net/#Custom%20Autosuggest%20Input%20with%20JQuery%20UI
https://msdn.microsoft.com/en-us/library/mt750287.aspx
You may also want to consider Azure Maps which provides autosuggest for addresses, POI, and POI categories:
https://azure.com/maps
https://learn.microsoft.com/en-us/rest/api/maps/search/getsearchaddress
Simply use the typeahead URL parameter.

Related

Search with Relay doesn't include new results due to local cache

I've implemented a search-as-you-type component in React and Relay. It's roughly the same setup as search functionality using relay
It works as intended with one exception. New results from the server never appear when I retype a search I've already performed on the client. I looks like Relay always goes to the local cache in this case.
So, for example, say I've searched for 'foo' and didn't find any results. Now, seconds later, another user on the website creates this 'foo', but Relay will never query the server since the cached response to the 'foo' search was an empty result.
Is there a pattern or best practice for this scenario?
The query is as follows. I call this.props.relay.setVariables to perform the search:
initialVariables: {
search: '',
hasSearch: false
},
fragments: {
me: () => Relay.QL`
fragment on Viewer {
relationSearch(search: $search) #include(if: $hasSearch) {
... on User {
username
}
}
}
`
}
The answer seems to be to use this.props.relay.forceFetch with the search variables instead.
See https://facebook.github.io/relay/docs/api-reference-relay-container.html#forcefetch
Someone correct me if this isn't best practice.

Counting clicks to external links with rails

I have Entry model with url field, which contains link to external site.
In view I list these links, and now I'd like to start counting when someone clicks it, and keep this info in database. What's the best way of doing it?
You can easily use google analytics to track outbound links: http://support.google.com/analytics/bin/answer.py?hl=en&answer=1136920
If that is not an option you will need to add some javascript to your links make an ajax request to the server to increment the count before transferring the user to the new url. Something similar to this jquery code:
$('a').click(function(){
var stored_ulr = $(this).attr('href');
$.ajax({
url: #your server url to increment count,
data: #data you need to send,
success: function() { window.location = stored_url; },
});
return false;
});
The above code is just a general outline. You will have to fill in the blanks and make it work for your needs.

Limiting requested field set of Kendo UI Grid bound to OData service

How to configure the Kendo UI grid, so it would issue requests only for specific (displayed) fields?
In my instance, a Kendo UI grid is bound to a OData service. The service exposes a table with many (200+) fields. The app allows users to configure displayed field set of the Grid, set initial filters and sort parameters. The app configures the Grid, which then goes off and queries OData service.
The grid kendo.Data.DataSource is defined as:
var gridDataSource = new kendo.data.DataSource({
type: "odata",
transport: {
read: {
url: "#Url.Content(dynDataSource.Url)",
contentType: "application/json; charset=utf-8",
type: "GET",
dataType: "json"
}
},
pageSize: #Model.MaxPageSize,
serverPaging: true,
serverFiltering: true,
serverSorting: true,
filter: ...
}
Here's a sample request issued by the Grid (captured by Firebug):
http://localhost:22411/Data/Comp?%24inlinecount=allpages&%24top=1000&%24filter=DistrictCode+eq+%27460800%27
This returns all the fields of the table, which is a problem. The fields need to be limited by selecting only the required fields, the request for which would look like:
http://localhost:22411/Data/Comp?%24inlinecount=allpages&%24top=1000&%24filter=DistrictCode+eq+%27460800%27&%24select=DistrictCode,DistrictName,DistrictNumber
Again, how to configure the grid for this to happen?
I realize the source is available for Kendo UI, but I'm currently still on a trial version which doesn't include the source.
I think I've got a workable solution for this myself. I used an idea from this blog post:
http://community.dynamics.com/product/crm/crmtechnical/b/zhongchenzhoustipstricksandportaldevelopment/archive/2012/05/20/how-to-use-kendo-ui-datasource-kendo-ui-grid-with-dynamics-crm-2011-rest-endpoint.aspx
I attach an event handler the ajaxSend event, watch for my OData Service URL, and once such a request is detected, append the select column list to the URL. Here's the code:
$(document).ajaxSend(function (e, jqxhr, settings) {
if (settings.url.toLowerCase().indexOf("#Url.Content(dynDataSource.Url)".toLowerCase()) >= 0) {
settings.url += "&%24select=#requestColumnList";
}
});
Hope this helps. Still, if someone has got a better solution, I'd like to hear it.
I've also posted this question to Telerik forums: http://www.kendoui.com/forums/framework/data-source/configure-the-kendo-ui-datasource-so-it-would-issue-requests-only-for-specific-displayed-fields.aspx#2131604
I ran into a similar issue and implemented an approach that constructs an array of included columns in the transport's read data callback:
dataSource.transport.read.data = function(options) {
var data = {};
data["$select"] = columns.map(function(c) {
return c.field;
});
return data;
}
If you are using column menu and have hidden columns, you can also filter based on which columns are visible and force a grid refresh as columns are enabled.
columnShow: function (e) {
e.sender.dataSource.read();
}

Youtube-like like/dislike rating system code wanted?

I am trying to make a rating system, very similar to Youtube's thumbs Up/Down.
Actually, I was hoping to achieve exactly the same.
But from what I gather from here: http://code.google.com/apis/youtube/2.0/developers_guide_protocol.html#Ratings
Youtube uses an API to take care of all the Ratings.
So I am looking for info and help on how can I set up the same system YT has.
I basically want to have a Like/Dislike function for every page, which is liked to a specific object on that page - just like the like/dislike is linked to a video on every page. Preferrably also one for comments.
All help is very very welcomed. From source-codes for already done systems (I searched around google quite a bit, but never found a similar open-source rating system) to help and info on how I can set up the API-powered rating system.
For the database part, if you need to know which users liked which videos, then use
two tables, one for likes and one for dislikes:
TABLE likes {
user_id
video_id
}
TABLE dislikes {
user_id
video_id
}
Both tables associate a user with a video.
I would suggest having a database with all videos and comments, that has a field for likes and dislikes. you can then update the database with javascript click events to perform ajax calls to increment the count. you could use jquery and the code would be as simple as:
$('#up_button').click(function(){
var id = $(this).attr('thisid');
$.ajax({ type: 'POST',
url: 'AJAX/Handler/Upvote',
data: { video_id: id },
dataType: 'html',
success: function (data) { alert('success'); },
error: function (xhr, err) { alert('Error:\n\nreadyState: " + xhr.readyState + "\nstatus: " + xhr.status + "\nresponseText: " + xhr.responseText); }
});
});

jQuery UI AutoComplete Plugin - Questions

I have an ASP.NET MVC 3 Web Application (Razor), and a particular View with the jQuery UI AutoComplete plugin (v1.8).
Here's the setup i currently have:
$('#query').autocomplete({
source: function (request, response) {
$.ajax({
url: "/Search/FindLocations",
type: "POST",
dataType: "json",
data: { searchText: request.term },
success: function (data) {
response($.map(data, function (item) {
return { name: item.id, value: item.name, type: item.type }
}))
},
error: function (xmlHttpRequest, textStatus, errorThrown) {
// don't know what i should do here...
}
})
},
select: function (event, ui) {
$.get('/Search/RenderLocation', { id: ui.item.name }, function (data) {
$('#location-info').html(data);
});
},
delay: 300, minLength: 3
});
The AutoComplete returns locations in the world, basically identical to Google Maps auto complete.
Here are my questions:
1) What are the recommended settings for delay and minLength? Leave as default?
2) I thought about putting [OutputCache] on the Controller action, but i looks as though the plugin automatically does caching? How does this work? Does it store the results in a cookie? If so when does it expire? Is any additional caching recommended?
3) I've noticed if i type something, and whilst the AJAX request is fired off, if i type something else, the dialog shows the first result momentarily, then the second result. I can understand why, but it's confusing to the user (given the AJAX request can take 1-2 seconds) but i'm thinking about using async: false in the $.ajax options to prevent multiple requests - is this bad design/UX?
4) Can you recommend any other changes on my above settings for improving performance/usability?
1) It really depends on your usage and your data.
2) You should use [OutputCache]. If there's any caching happening on the plugin, it's only going to be for each user, if you use caching at the controller action level, it'll cache one for all users. (again, this might actually be bad depending on your usage, but usually this is good to do)
3) This questions kind of hard too because of the lack of context. If ajax requests are 1-2 seconds and there's no way to make this shorter, you really should be a pretty big delay in so that users aren't sending off many requests while typing out a long word (if they type slow).
4) sounds like you need to look at your /search/FindLocations method and see where you can do caching or pref improvements. Give us a look at your code in here and I can try to suggest more.

Resources