Fast Search for Vue from Big Json Data - performance

I have a Buefy data table in Vue that loads with json data that is rendered through a php file.
I was looking for a search filter in my table that is fast, I already have this:
Template:
<b-field label="Search by Bid Price">
<b-input v-model="search_query.price"/>
</b-field>
Data: search_query: { price: "" },
Computed Function:
filter: function() {
if (this.search_query.price) {
let price_re = new RegExp(this.search_query.price, "i");
let data = [];
for (let i in this.posts) {
if (
this.posts[i].price &&
this.posts[i].price.toString().match(price_re)
) {
data.push(this.posts[i]);
}
}
return data;
}
return this.posts;
}
but this is not fast and is slow according to my data which is about 400 rows and more sometimes depending on the query.

So What I did was that i used vue-fuse to create a nice and customizable search setup. but I was experiencing a lag effect because I had a heavy json behind my table to search through so I used debounce from lodash to fix it. and it works like a charm right now.

Related

Force react-select to show all options using Elasticsearch

I'm trying to implement this with elasticsearch and it is working But how i can force this show results which can be different from the searched terms? For example i search ardino, The elasticsearch give me the word arduino but then react-select does not show that result because ardino does not contain arduino. I know the idea of this library is exactly that and it is working ok, but i have most of the things already implemented and it is only missing that part.
The handle is giving the right behavior and it is populating the options correctly.
Thank you
<Select
name= {this.state.selectedOption}
value={this.state.selectedOption}
isSearchable={true}
onChange = {(val) => {
this._handleSearch(val.value)
}}
onInputChange = {(val) => {
this._handleSearch(val)
}}
options={this.state.options}
/>
I would recommend using the Async component which can simplify your code. You will not need the onChange handler anymore.
isSearcheable is true by default, no need to specify.
In answer to your question: Make sure you are passing in label and value keys with each result option. If you want to customize any of the results, for example adding the search term in the results, you can manually manipulate the options array.
import React, {Component} from 'react';
import AsyncSelect from 'react-select/lib/Async';
class Search extends Component {
state = {inputValue: ""}
onInputChange = (inputValue) => {
this.setState({ inputValue });
};
getSearchResults = async (inputValue) => {
// elastic search results
let options = await fetch(`searchElastic/${inputValue}`);
// input value of drop-down
const inputValue = this.state.inputValue;
// manually add input field as an option in drop-down
if (inputValue.length > 0)
options.unshift({label: inputValue, value: inputValue})
// async handling of new props
return options.map(opt => {
return {label: opt.name, value: opt.value}
})
}
render() {
return <AsyncSelect
onInputChange={this.onInputChange}
loadOptions={this.getSearchResults}
/>
}
}
export default Search;

How to Load the database Table on scroll down in Mvc3

Hi all i have table which has a bulk data and a Screen for showing this data..i want o show data to the users like this
if a user goes to this screen i have to display only the first twenty of the records of my Database and when he wants to see more and scrolls down the data should be loaded on scroll down and i should show him again the Other 20 records of my DB..so as he scroll s down the page should load with that data should be populated to the page
i have been searching about this a lot but didn't get what i wanted...or how can i do this....can any one tell me how can i do this...
Rob Conery wrote a great blog post about this
He uses JQuery to make an ajax call to his controller to load more data. Here's the method he uses to load more:
<script type="text/javascript">
$(window).scroll(function() {
if ($(window).scrollTop() == $(document).height() - $(window).height()) {
loadMore();
}
});
var current=0;
function loadMore() {
if (current > -1) {
current++;
$('#loading').html("<img src='/content/images/bigloader.gif' />");
$.get("/archive/index/" + current,
function(data) {
if (data != '') {
$('#results').append(data);
$('#loading').empty();
} else {
current = -1;
$('#loading').html("<h3><i>-- No more results -- </i></h3>");
}
});
}
}
</script>

JQuery - Iterating JSON Response

The Story So far....
Trying to learn JS and JQuery and i thought i would start with the basics and try alittle AJAX "search as you type" magic. Firstly i just wanted to get the AJAX part right and iterating through the return JSON object and appending it to a unordered list. Im doing no validation on the inputted value vs. the returned JSON results at this time, i just want a controlled way of when to do the AJAX getJSON call. Later i will do the validation once i get this right.
Anyways im having trouble displaying the Account Numbers in in the ul. At the moment the only thing that is being displayed is AccountNumber in the li and not my ACCOUNT NUMBERS
My JS Code is here:
http://jsfiddle.net/garfbradaz/HBYvq/54/
but for ease its here as well:
$(document).ready(function() {
$("#livesearchinput").keydown(function(key) {
$.ajaxSetup({
cache: false
});
$.getJSON(" /gh/get/response.json//garfbradaz/MvcLiveSearch/tree/master/JSFiddleAjaxReponses/", function(JSONData) {
$('<ul>').attr({
id: "live-list"
}).appendTo('div#livesearchesults');
$.each(JSONData, function(i, item) {
var li = $('<li>').append(i).appendTo('ul#live-list');
//debugger;
});
});
});
});​
My JSON file is hosted on github, but again for ease, here it is:
https://github.com/garfbradaz/MvcLiveSearch/blob/master/JSFiddleAjaxReponses/demo.response.json
{
"AccountNumber": [
1000014,
1015454,
1000013,
1000012,
12
]
}
Also here is my Fiddler results proving my JSON object is being returned.
EDIT:
There were so queries about what i was trying to achieve, so here it goes:
Learn JQuery
To build a "Search as you Type" input box. Firstly i wanted to get the AJAX part right first, then i was going to build an MVC3 (ASP.NET) Application that utilises this functionality, plus tidy up the JQuery code which includes validation for the input vs. the returned JSON.
Cheesos answer below worked for me and the JSFiddle can be found here:
http://jsfiddle.net/garfbradaz/JYdTU/
First, I think keydown is probably the wrong time to do the json call, or at least... it's wrong to do a json call with every keydown. That's too many calls. If I type "hello" in the input box, within about .8 seconds, then there are 5 json requests and responses.
But you could make it so that it retrieves the json only the first time through, using a flag.
Something like this:
$(document).ready(function() {
var $input = $("#livesearchinput"), filled = false;
$.ajaxSetup({ cache: false });
$input.keydown(function(key) {
if (!filled) {
filled = true;
$.getJSON("json101.js", function(JSONData) {
var $ul =
$('<ul>')
.attr({id: "live-list"})
.appendTo('div#livesearchesults');
$.each(JSONData, function(i, item) {
$.each(item, function(j, val) {
$('<li>').append(val).appendTo($ul);
});
});
});
}
});
});
The key thing there is I've used an inner $.each().
The outer $.each() is probably unnecessary. The JSON you receive has exactly one element in the object - "AccountNumber", which is an array. So you don't need to iterate over all the items in the object.
That might look like this:
$.each(JSONData.AccountNumber, function(i, item) {
$('<li>').append(item).appendTo($ul);
});
What you probably want is this:
$.each(JSONData.AccountNumber, function(i, item) {
var li = $('<li>').append(item).appendTo('ul#live-list');
});
Your code:
$.each(JSONData, function(i, item) {
var li = $('<li>').append(i).appendTo('ul#live-list');
});
Says "iterate over the keys and values of the outer JSON structure, and print the keys". The first key is "AccountNumber", so you end up printing that.
What you want to do is iterate over the array stored at JSONData.AccountNumber, and print the values:
$.each(JSONData.AccountNumber, function() {
var li = $('<li>').append(this).appendTo('ul#live-list');
});

Ajax / JSON Redrawing google chart

Im using the google visualization chart api here: https://developers.google.com/chart/interactive to make a server uptime graph which seems to be working nicely.
However I want the users to be able to select a date range and then redraw the graph without having to refresh the browser. And I have a small problem with this.
I first draw the graph with the initial data, and then if a user changes the date range this graph should be redrawn. I tried redrawing with some sample data and this works fine. However I cant seem to get it to work with the updated data.
Now in the php file where i fetch the data from the DB i return both the average uptime for this period as well as the total uptime for the period as such:
/*mysql query striped*/
$uptime_result = mysql_query($query, $connection) or die(mysql_error());
$uptime_data = "['Day', 'Uptime'],";
while ($items = mysql_fetch_array($uptime_result)){
$uptime_data.="['{$items['date']}',{$items['uptime']}], ";
}
// get average uptime
/*mysql query striped*/
$uptime_result = mysql_query($query, $connection) or die(mysql_error());
$result_array = mysql_fetch_array($uptime_result);
$avg_uptime = round($result_array['AVG(uptime)'],2);
echo "{\"data\":\"{$uptime_data}\",\"average\":$avg_uptime}";
Which outputs something like:
{"data":"['Day', 'Uptime'],['2012-05-31',100.00], ['2012-06-01',100.00], ['2012-05- 22',99.65], ['2012-05-21',99.65], ['2012-05-20',100.00], ['2012-05-31',100.00], ['2012-05-30',100.00], ['2012-05-29',100.00], ['2012-05-28',100.00], ['2012-05-27',100.00], ['2012-05-26',100.00], ['2012-05-25',100.00], ['2012-05-24',100.00], ['2012-05-23',100.00], ['2012-05-19',100.00], ['2012-05-18',100.00], ['2012-05-17',100.00], ['2012-05-16',100.00], ['2012-05-15',100.00], ['2012-05-14',100.00], ['2012-05-13',100.00], ['2012-05-12',100.00], ['2012-05-11',100.00], ['2012-05-10',100.00], ['2012-05-09',100.00], ['2012-05-08',100.00], ['2012-05-07',100.00], ['2012-06-02',100.00], ['2012-06-03',100.00], ['2012-06-04',100.00], ","average":99.98}
I.e a JSON array with two variables data and average. I am able to fetch the two independently as such:
$(function(){
$('#from,#to').focusout(function(){
var start=$('#from').val();
var end=$('#to').val();
$.ajax({
type: 'POST',
data: ({from : start, to : end, id : <?php echo $id; ?>}),
url: 'fetchuptime.php',
success: function(data) {
//7 reulst goes here
//var json = data;
var obj = jQuery.parseJSON(data);
$('#uptime_span').html(obj.average +" %");
$('#test').html(data);
chart_data = google.visualization.arrayToDataTable([
obj.data
]);
var ac = new google.visualization.AreaChart(document.getElementById('visualization'));
ac.draw(chart_data, {
colors : ['#00DB00'],
title : '',
isStacked: false,
width: 570,
height: 400,
'chartArea': {'width': '88%', 'height': '90%'},
hAxis: {minValue: 0,showTextEvery: 6, slantedText: false},
vAxis: {
viewWindowMode:'explicit',
viewWindow:{
max:100,
min:90.65
}
},
pointSize: 3,
legend: {position: 'none'}
});
}
});
});
});
eg. obj.average and obj.data gives me the two string. However this does not seem to work, i guess the data doesn't get passed along correctly.
I have tested the actual output data (eg obj.data) is formatted correct as I've tried inserting it statically.
So I'm obviously doing something wrong here, and I assume it's because I'm passing an string while google chart needs an array, tried to fix it in various ways but haven't found anything working yet.
Can anyone help me with this one?
The format of your JSON is valid, but probably not what you're wanting:
{"data":"['Day', 'Uptime'],['2012-05-31',100.00] ... ['2012-06-04',100.00], ", "average":99.98}
That represents an object with a field named data whose value is a string (like you said). What you probably want to do is make it an array on the server side. Instead of double quotes, use square brackets. There is also a trailing comma which must be removed.
{"data":[['Day', 'Uptime'],['2012-05-31',100.00] ... ['2012-06-04',100.00]], "average":99.98}

MVC: Set value in autocomplete on Edit

In our MVC application we use jQuery autocomplete control on several pages. This works fine on Create, but I can't make it work on Edit.
Effectively, I don't know how to make the autocomplete controls preload the data from model and still behave as an autocomplete in case the user wants to change the value.
Also how can I make sure that the value is displayed in the same format that is used in Create calls?
All our autocomplete controls have corresponding controllers and all parse Json results.
Let's Try this! Alright Do this:
Suppose you had a list of countries you needed to filter
Auto Complete knows how to some default things by default but suppose you really wanted CountryName and also you know every keypress does an ajax call to the URL you specify.
Create an action method like so:
public ActionResult LookupCountry(string q, int limit)
{
var list = GetListOfCountries(q, 0, limit);
var data = from s in list select new {s.CountryName};
return Json(data);
}
Here is the Jquery:
$(document).ready( function() {
$('#txtCountryName').autocomplete('<%=Url.Action("LookupCountry", "MyController") %>', {
dataType: 'json',
parse: function(data) {
var rows = new Array();
for(var i=0; i<data.length; i++){
rows[i] = { data:data[i], value:data[i].CountryName, result:data[i].CountryName};
}
return rows;
},
formatItem: function(row, i, n) {
return row.CountryName;
},
width: 300,
mustMatch: true,
});
});
Here is the Html
<html><head></head><body>#Html.TextBox("txtCountryName",Model.CountryName)</body></html>
Basically, The magic is in the call to LookUpCountry
The GetCountriesList(string query, int startindex, int limit)
Returns MyCountries.Where(c => c.CountryName.SubString(startindex, limit).Contains(query)).ToList();
So you are making your own trimming function because JQuery has no idea what CountryName is or how to trim it. How ever if it was a javascript object I am not quite sure but do
var jsonString = #Html.GetListOfCountries() //Or Model.Countries.ToJSONString()
var json = JSON.stringify(jsonString); //also JSON.Parse(jsonString) if stringify won't work
which would return the necessary countries as a Html Helper Extension method. And perhaps as a list of javascript objects it would be smart enough to handle it that way in it's native language. However the first approach works for me.

Resources