jQuery UI AutoComplete Plugin - Questions - asp.net-mvc

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.

Related

What do I do with low Scores in reCAPTCHA v3?

I have set up reCAPTCHA v3 on my ASP.NET MVC project. Everything is working fine and is passing back data properly.
So the code below depends on another dll I have, but basically, the response is returned in the form of an object that shows everything that the JSON request passes back, as documented by https://developers.google.com/recaptcha/docs/v3
It all works.
But now that I know the response was successful, and I have a score, what do I do? What happens if the score is .3 or below? Some people recommend having v2 also set up for secondary validation (i.e. the 'choose all the stop signs in this picture' or 'type the word you see'). Is that really the only 'good' option?
Obviously the code isn't perfect yet. I'll probably handle the solution in the AJAX call rather than the controller, but still. What should I do if the score is low?
I read this article
reCaptcha v3 handle score callback
and it helped a little bit, but I'm still struggling to understand. I don't necessarily need code (although it would never hurt) but just suggestions on what to do.
VIEW:
<script src="https://www.google.com/recaptcha/api.js?render=#Session["reCAPTCHA"]"></script>
grecaptcha.ready(function () {
grecaptcha.execute('#Session["reCAPTCHA"]', { action: 'homepage' }).then(function (token) {
$.ajax({
type: "POST",
url: "Home/Method",
data: JSON.stringify({token: token }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
console.log('Passed the token successfully');
},
failure: function (response) {
alert(response.d);
}
});
});
});
CONTROLLER:
[HttpPost]
public void ReCaptchaValidator(string token)
{
ReCaptcha reCaptcha = new ReCaptcha();
Models.ReCaptcha response = new Models.ReCaptcha();
response = reCaptcha.ValidateCaptcha(token);
//response returns JSON object including sucess and score
if (response.Success)
{
//WHAT DO I DO HERE????
}
}
Ended up getting the answer from another forum. Basically, the answer is "anything you want". There is no right or wrong when handing a successful response.
So what could be done, is if the response is successful and CAPTCHA doesn't throw a flag, do nothing. But if CAPTCHA is unhappy, you could display an alert or a banner that says 'could not process', or you could even add in CAPTCA version 2, which would make them do the picture test or the 'I am not a robot' checkbox, etc.

Preload page into turbolinks transition cache

I'm using turbolinks to simulate a "single-page" app. The app is acceptably quick once pages are cached, however the first clicks are too slow. Is there a way to pre-fill the transition cache by loading some pages in the background?
I'm going to be looking into hacking into the page cache, but wondering if anyone has done this before.
(If this seems unusual, well, just trust that I'm doing this for good reason. Turbolinks gets nearly the performance of a far more complex implementation and overall I'm quite happy with it.)
UPDATE: So it seems like this SHOULD be relatively easy by simply adding entries to the pageCache of Turbolinks, something like:
$.ajax({
url: url,
dataType: 'html',
success: function(data) {
var dom = $(data);
Turbolinks.pageCache[url] = {
...
}
}
});
however it doesn't seem possible to construct a body element in javascript, which is required. Without out that, it doesn't seem like I can't construct the object that is stored in the cache without the browser first rendering it.
Any ideas beyond hacking more into Turbolinks?
UPDATE 2: There was the further problem that pageCache is hidden by a closure, so hacking Turbolinks is necessary. I have a solution that I'm testing that leverages iFrames - seems to be working.
First Hack Turbolinks to allow access to pageCache, the end of your turbolinks.js.coffee should look like this.
#Turbolinks = {
visit,
pagesCached,
pageCache,
enableTransitionCache,
enableProgressBar,
allowLinkExtensions: Link.allowExtensions,
supported: browserSupportsTurbolinks,
EVENTS: clone(EVENTS)
}
Then implement a fetch function. This is what you were thinking about, we can use DOMParser to convert string into DOM object.
function preFetch(url) {
$.ajax({
url: url,
dataType: 'html'
}).done(function(data) {
var key = App.Helper.getCurrentDomain() + url;
var parser = new DOMParser();
var doc = parser.parseFromString(data, "text/html");
Turbolinks.pageCache[key] = {
url: url,
body: doc.body,
title: doc.title,
positionY: window.pageYOffset,
positionX: window.pageXOffset,
cachedAt: new Date().getTime(),
transitionCacheDisabled: doc.querySelector('[data-no-transition-cache]') != null
};
});
};
Usage:
$(function() {
preFetch('/link1'); // fetch link1 into transition cache
preFetch('/link2'); // fetch link2 into transition cache
});

jquery mobile 1.4 not updating content on page transition

From the index page, a user clicks a navigation link, the data attribute is passed via ajax, the data is retrieved from the server but the content is not being updated on the new page.
Been stuck for hours, really appreciate any help!
js
$('a.navLink').on('click', function() {
var cat = $(this).data("cat");
console.log(cat);
$.ajax({
url: 'scripts/categoryGet.php',
type: 'POST',
dataType: "json",
data: {'cat': cat},
success: function(data) {
var title = data[0][0],
description = data[0][1];
console.log(title);
$('#categoryTitle').html(title);
$('#categoryTitle').trigger("refresh");
$('#categoryDescription').html(description);
$('#categoryDescription').trigger("refresh");
}
});
});
Im getting the correct responses back on both console logs, so I know the works, but neither divs categoryTitle or categoryDescription are being updated. I've tried .trigger('refresh'), .trigger('updatelayout') but no luck!
This was not intended to be an answer (but I can't comment yet.. (weird SO rules)
You should specify in the question description that the above code IS working, that your problem occurs WHEN your playing back and forth on that page/code aka, using the JQM ajax navigation.
From what I understood in the above comment, you're probably "stacking" the ajax function every time you return to the page, thus getting weird results, if nothing at all.
Is your example code wrapped into something ? If not, (assuming you use JQM v1.4) you should consider wrapping it into $( 'body' ).on( 'pagecontainercreate', function( event, ui ) {... which I'm trying to figure out myself how to best play with..
Simple solution to prevent stacking the ajax definition would be to create/use a control var, here is a way to do so:
var navLinkCatchClick = {
loaded: false,
launchAjax: function(){
if ( !this.loaded ){
this.ajaxCall();
}
},
ajaxCall: function(){
// paste you example code here..
this.loaded = true;
}
}
navLinkCatchClick.launchAjax();

IE memory leak and eval with jQuery

I've created a page which needs to have its elements updated according what's happening with the data in our database. I'd like to know what do you think about this approach using eval, I know it's risky but in my case it was the fastest way.
$('.updatable').each(function () {
var data;
data = 'ViewObjectId=' + $(this).attr('objectid');
$.ajax({
async: true,
url: '/Ajax/GetUpdatedViewObjectDataHandler.ashx',
data: data,
type: 'POST',
timeout: 10000,
success: function (data) {
$.each(data, function (index, value) {
eval(value);
});
}
});
Now the issue I have is when the page is loaded, for each 10 seconds the page is updated, until here it's perfect.
After each round of updates, my Internet Explorer steal some memory, and it gets the whole machine memory after some hours, terrific.
What would you do in this case? Some other update approach is recommended? Or even, is there something you think I could do to avoid this memory leak?
Found the answer here: Simple jQuery Ajax call leaks memory in Internet Explorer
THE SOLUTION:
var request = $.ajax({ .... });
request.onreadystatechange = null;
request.abort = null;
request = null;
JQuery doesn't do that and the memory never releases.
jQuery version 1.4.2.
Now it's working like a charm.

jQuery UI Autocomplete - IE6 lockup

Before you say it, I know, IE6 is dead and it smells like it's dead. However my client has a closed network, all their machines are run only IE6, so that 100% of my user base :/
I'm using jQuery UI and the autocomplete widget, it performs well in Firefox however on IE6, even for a small list of items (here 5, returned by json with an item and a description) it's locking up the browser when I mouse over them. Applying the css seems like it may be the cause.
$( "#searchTest" ).autocomplete({
source: function( request, response ) {
$.ajax({
url: "index.pl",
dataType: "json",
data: {
term: request.term
},
success: function( data ) {
response( $.map( data.items, function( item ) {
return {
label: item.id + ' - ' + item.label,
value: item.id
}
}));
}
});
},
minLength: 2
});
I can even kind of replicate the problems in IE6 using the online demos, albeit to a much lesser extent, it's just slow it doesn't hang up the browser.
If anyone can make any suggestions for improving performance in IE6 I'd be very happy to hear them. I'm using the default style sheet from the Themeroller. Thanks
Doh! I was using a plugin to add round corners to IE6: http://dillerdesign.com/experiment/DD_roundies/
I commented this out and it's working way better! The plugin in question is now EOL (my bad for not checking this). The client will have to live with a functional system, but no round corners till they change browser versions.

Resources