Jquery autocomplete on large array - javascript

I am using Jquery autocomplete with local array of size ~5000, every word is ~10 chars.
I am initializing the object like this:
.autocomplete({matchContains: true, minLength: 3, delay: 700, source: array1, max: 10, highlight: true })
The problem is, that when I start to type, it takes a lot of time (sometime crashes the browser) until the result is displayed.
What can I do?
Thanks

You could use AJAX to fetch the array instead of putting it into the HTML, increase the delay and the required minLength before querying the server in order to reduce the matches.

I would do like Darin Dimitrov said, but I would also do a .Take(10) (or some arbitrary number that sounds good to you) in a quick linq statement on the server side. This would lessen the result set and would still become more accurate as the user continues to type.

Are you using the standard jQuery autocomplete plugin? If so, I'm unfamiliar with the option parameter "source" that you used.
The proper syntax for that plugin is: autocomplete( url or data, [options] ). It sounds like your version works with the 'source' option parameter,(although while crashing the browser) so I'm confused. If the browser is crashing, I'd expect the problem to be related to the javascript.
I recommend trying:
$('whatever').autocomplete(array1,{
matchContains: true,
minLength: 3,
delay: 700,
max: 10,
highlight: true
});

Related

Understanding how this javascript slideshow works with key value pairs

This may seem like a bit of a newbie question, but I’ve just started a new job and am trying to understand more about and roughly how the following javascript code works:
app.placementOptions["cycleslideshow"] = {
".cycle-slideshow" : {
speed: 500
, timeout: 8000
, fx: "fade"
, pager: ".decoration-right"
},
".regen-slideshow .cycle-slideshow" : {
speed: 800
, timeout: 12000
, fx: "scrollHorz"
, pager: ".decoration-right"
}
};
Note that this above code apparently styles the slideshow buttons to be the small circles at the bottom right of the area above the fold on this site: https://www.ccht.org.uk
And the full JS for that is here: https://www.ccht.org.uk/js/plugins.js
Can someone explain what the snippet code roughly does? What is it? Is it JavaScript OOP with key value pairs? Can someone link to an article to help me read up about it? My employer may use BX Slider: https://bxslider.com
I was told that this part of the code is key: pager: ".decoration-right" - the company uses the LESS CSS preprocessor if that makes a difference.
And is Stack Overflow the right place to put this kind of question that has no actual solution (not that I won't accept any answer)? Hopefully it won't get closed as being broad. Thanks for any advice here.
I haven't looked at your full code yet, but this code is essentially just setting the cycleslideshow property of the placementOptions object (which is itself a property of the app object) to be equal to everything to the right of the = sign.
So basically, you have an object app which could be intialized like this:
const app = {
placementOptions: {}
}
Then with the snippet above, you're creating a new key on the placementOptions object, which could have also just been written as app.placementOptions.cycleslideshow in this case (in other words, the bracket notation wasn't needed).
The cycle slideshow object has two keys, which are both JavaScript objects representing collections of CSS rules, so this object is likely referenced when styling some DOM element, as you said, and can easily be accessed by the class names. In this case, wrapping the property names in quotes is required, because valid property names can't begin with . or have spaces in them unless they're wrapped as strings like this.
The pager line may have particular significance to the CSS, but has no particular JavaScript significance. Each of these CSS properties are just keys on their respective objects.
The following code is equivalent to your original snippet (not taking into account any additional keys/values that app or placementOptions may have:
const app = {
placementOptions: {
cylceslideshow: {}
}
}
app.placementOptions.cycleslideshow['.cycle-slideshow'] = {
speed: 500
, timeout: 8000
, fx: "fade"
, pager: ".decoration-right"
};
app.placementOptions.cycleslideshow['.regen-slideshow .cycle-slideshow'] = {
speed: 800
, timeout: 12000
, fx: "scrollHorz"
, pager: ".decoration-right"
};
Note that in this case, where bracket notation is used, it is required, for the same reason I mentioned above. You wouldn't neccessarily write the code this way, the way it is written is already fine, but this is just breaking it down into smaller parts for you and showing you they're the same.
In either case, you could access the object like this:
console.log(app.placementOptions.cycleslideshow['.cycle-slideshow']);
// logs:
/*
{
speed: 500,
timeout: 8000,
fx: "fade",
pager: ".decoration-right"
}
*/
Or access part of the object:
console.log(app.placementOptions.cycleslideshow['.cycle-slideshow'].speed);
// logs: 500
Overall the question is a bit broad, but hopefully this helps.
EDIT: not sure how beginner or basic you're looking for, but here's an article that goes over some of the basics about working with JS Objects: https://medium.freecodecamp.org/lets-explore-objects-in-javascript-4a4ad76af798.
freeCodeCamp itself has plenty of beginner resources (articles, challenges, videos, etc.) for learning JS.
The snippet you have provided seems to be simply specifying the configurations for the classes in the HTML, such as ".cycle-slideshow" and ".regen-slideshow .cycle-slideshow".
I'm not sure what the plugin code is doing exactly behind the scenes, but those configuration values specified in the snippet will be read by the plugin by the key "cycleslideshow". The value is the collection of settings specified. This is using the JavaScript object format, similar to JSON.
To find out exactly what each entry from the configuration mean and what the expected values are, you can search their github page since it seems to be open source.

Object has no method 'charAt' in jQuery plugin

I am attempting to use the autoNumeric jQuery plug-in which helps with the conversion of various currencies in jQuery.
The plug-in itself works when I use it in a jsFiddle example.
$(function () {
$('.money').autoNumeric('init', {
aSign: '$',
vMin: '-999999999.99',
nBracket: '(,)'
});
});
However, as soon as I integrate it into a big, legacy project, I start receiving the above error on line 194. I know why I'm getting the error - a string is not being passed into the negativeBracket function (negativeBracket(s, nBracket, oEvent) is the signature). Instead, it seems to be a jQuery object - e.fn.init1. I'm confused on how this might be happening. I realize the community may not be able to give a direct answer, but I would love (and will accept as an answer) being pointed in the right direction as nothing has jumped out at me so far.
Update
So, have some additional info that may be of help. It still has me stumped how it's happening (unfortunately, the answers below didn't help to provide any additional insight). When I link in autoNumeric, I key it off of any text field with the class money. It does work as I am typing in the box. I can see see formatting. However, when I tab into a new box, the box I just finished typing in clears itself completely after hitting line 152 in autoNumeric with the same exact error.
#Carlos487 was correct in his answer when he said I have an object that is not a string. I instead have an object that, I believe, is a function. Here's what I'm seeing in Chrome debugger tools:
e.fn.init[1]
> 0: input#price.money required
> context: input#price.money required
length: 1
selector: ""
> __proto__: Object[0]
The "arrowed" items can be further expanded out. I don't know if this provides any more clues, but it's at least something a bit different.
The errors like
no method XXXXX in Object
are produced because you are trying to call obj.XXXX() and obj is not of the desired type, in your particular case a string.
Have you tried in another browser because older or IE can be a little troublesome. I would recomend using chrome developer tools with your legacy app to see if anything else is conflicting or producing the error
I will bet money that you are using a second library which is interfering with jQuery. It has probably overridden $ with its own function.
Try using jQuery instead of $:
jQuery(function () {
jQuery('.money').autoNumeric('init', {
aSign: '$',
vMin: '-999999999.99',
nBracket: '(,)'
});
});
It turns out that the issue was a myriad of issue compounding into the error I saw. A couple things that was happening:
The validator plug-in was wrapping the jQuery object in its own structure (hence the charAt issue).
Once I fixed that, I also learned that some homegrown code was also wiping and rewriting data into the field to provide formatting (which is what autoNumeric is also doing), so autoNumeric would bomb out because it would get a null value and attempt to format it.
There was some other random craziness that also needed cleaned up. So...issue resolved! Still more to work on, but at least this hurdle is past. Thanks all for your help.

Working with very large Javascript array or objects

Currently I'm working on a script where I've got to store more than 1,250,000 objects. I'm using the push() function in a jQuery each() loop like this:
words.push({
"page": pagenumber,
"content": word,
"hpos": $(this).attr("HPOS"),
"vpos": $(this).attr("VPOS"),
"width": $(this).attr("WIDTH"),
"height": $(this).attr("HEIGHT")
});
In Chrome it goes quit fast, between 30 and 40 seconds, but in Internet Explorer it can take up to 360 seconds.
It's for a project where old newspapers are loaded and you can search the text from those newspapers. The newspapers are in a directory and are loaded dynamically. In this test I'm doing I'm using newspapers from october 1926, containing 308 pages and over 1.250.000 words.
Is there a better/faster way to achieve this?
Is there a better/faster way to achieve this?
Yes: Do it on a server, not in the browser. This also has the advantage that you can do it once and reuse the information.
But assuming for some reason that's not possible:
The first thing you can do is stop making several million unnecessary function calls by only doing $(this) once per loop:
.....each(function () {
var $this = $(this);
words.push({
"page": pagenumber,
"content": word,
"hpos": $this.attr("HPOS"),
"vpos": $this.attr("VPOS"),
"width": $this.attr("WIDTH"),
"height": $this.attr("HEIGHT")
});
});
Normally repeatedly doing that isn't a big deal (though I'd avoid it anyway), but if you're doing this one and a quarter million times...
And if all of those attributes really are attributes, you can avoid the call entirely by cutting jQuery out of the middle:
.....each(function () {
words.push({
"page": pagenumber,
"content": word,
"hpos": this.getAttribute("HPOS"),
"vpos": this.getAttribute("VPOS"),
"width": this.getAttribute("WIDTH"),
"height": this.getAttribute("HEIGHT")
});
});
jQuery's attr function is great and smooths over all sorts of cross-browser hassles with certain attributes, but I don't think any of those four needs special handling, not even on IE, so you can just use DOM's getAttribute directly.
The next thing is that some JavaScript engines execute push more slowly than assigning to the end of the array. These two statements do the same thing:
myarray.push(entry);
// and
myarray[myarray.length] = entry;
But other engines process push as fast or faster than the assignment (it is, after all, a ripe target for optimization). So you might look at whether IE does push more slowly and, if so, switch to using assignment instead.

jQuery duration method

Currently I am working on an plugin for jQuery. In some jQuery functions you can pass an duration (e.g. '500ms', '1s', 'fast') parameter in.
I suppose there is a function within jQuery which pares that value and returns a value in ms? (so 1s would return 1000 or something).
Which method would this be, and is it possible to use this in my own plugin? So I can fire an callback after '1s' or 'fast' like some other methods as animate currently does.
You can always have a look at the source code. There you can see that .animate() calls a method jQuery.speed which uses jQuery.fx.speeds:
speeds: {
slow: 600,
fast: 200,
// Default speed
_default: 400
},
jQuery.speed seems to be useful in this regard, though I don't see any code which converts '1s' into 1000. Are you sure jQuery is doing this?
let's take a look at jquery source :
speeds: {
slow: 600,
fast: 200,
// Default speed
_default: 400
},
So, how about slow fadeOut ? let's take a peek into the source again. It looks like 'fadeOut' is just a shortcut for custom animation. There is a nice generic block of logic that jQuery re-uses for that purpose. There's no point in pasting the whole source in here :) you can easily go to your project a see for your self.
You could implement this very easily on your own
function ms(s){
return parseInt(s) *1000;
}
alert(ms("20s")); #=> 20000
Aside from that, using 1000 compared to '1s' is hardly an inconvenience. The integer has additional benefits as it's easier to modify in a programmatic way using simple arithmetic.

setting jquery auto-complete plugin to auto-submit

Two things I'm trying to adjust in my usage of JQuery autocomplete in PHP.
1. I would like that when I chose an option it will auto-submit the form (currently it requires two enters)
2. When I continue to write and no new options exist is still shows me the old options. I would rather it not suggest un-relevant options even if none exist.
Thanks
UPDATE:
I've resolved num. 2, for future readers the problem was I sent null instead of an empty json from the source url.
Regarding num. 1, I've done as suggested and now my JQuery js code looks like this:
$( "#searchid" ).autocomplete({
source: "/autocomplete_url.php?more=1",
});
$("#searchid").result(function (event, data, formatted)
{
alert("o"); // just to check if got here
$('#formid').submit();
});
However, The result function is never invoked (I've added a simple alert to verify that). Any idea why?
For 1.) you can simply submit the form through jquery from within the result(handler). Look at this - http://docs.jquery.com/Plugins/autocomplete if you look at the last code sample on the page, instead of redirecting, you can simply submit the form instead within the result call.
Regarding the 2.) point, well jquery autocompletes works just like that, perhaps you're doing something wrong or expecting something wrong, please give more information regarding the same.

Categories

Resources