jquery sqlite database text search engine - jquery-mobile

i am working on a search engine in jquery mobile I want to split words in an array for a database search the code I am using is:
var sear=$("#search").val();
var db = openDatabase("Database", "1.0", "PhoneGap Demo", 200000);
db.transaction(function (tx) {
tx.executeSql("SELECT * FROM DEMO WHERE (D_Indications LIKE ?);",
["%"+sear+"%"],
function (tx, results) {
$('#output').show();
var len = results.rows.length, i;
var row=results.rows.item(i);
for (i = 0; i < len; i++) {
$('#output2').append('<tr><td>'+ row.Cat_name +'</td><td>'+ row.Drug_Caty +'</td><td>'+ row.G_Name +'</td><td>'+ row.B_Name +'</td><td>'+ row.D_Indications +'</td></tr>').trigger('create');
}
});
});
I want it to split words after space and search each word individually in database.
For eg. if a user types "hello world" I want it to search "%hello%" & "%world%" separately in the database

You can define that by splitting it
text = "Hello World"
var SpaceCount = text.split(' ').length -1;
then you can define how many spaces you have by SpaceCount.
then have a condition:
if (SpaceCount==1){
var lines = text.split(' ')
$.each(lines, function(key, line) {
var db = openDatabase("Database", "1.0", "PhoneGap Demo", 200000);
db.transaction(function (tx) {
tx.executeSql("SELECT * FROM DEMO WHERE (D_Indications LIKE ?);",
["%"+ line +"%"],
function (tx, results) {
$('#output').show();
var len = results.rows.length, i;
var row=results.rows.item(i);
for (i = 0; i < len; i++) {
$('#output2').append('<tr><td>'+ row.Cat_name +'</td><td>'+ row.Drug_Caty +'</td><td>'+ row.G_Name +'</td><td>'+ row.B_Name +'</td><td>'+ row.D_Indications +'</td></tr>').trigger('create');
}
});
}
}

Related

More than 100 points and one polyline, Google Maps v3

I'm working with google maps api v3 and I'm trying to use snap to road with more than 100 points but in addition end up with just one polyline with the whole route that I can put a small animation. The view is a html.erb.
var apiKey = any_key;
var map = handler.getMap();
var drawingManager;
var placeIdArray = [];
var snappedCoordinates = [];
var path = <%= raw(#locations) %>
var markers = <%= raw(#markers) %>
var centerOn = path[0].split(',');
function breadCrumbsGrapher(path) {
handler.removeMarkers(Gmaps.store.markers);
for(var i = 0; i < polylines.length; i++) {
polylines[i].setMap(null);
}
var divided = handlePath(path);
if (typeof divided[0] == 'object') {
for(var i = 0; i < divided.length; i++) {
runSnapToRoad(divided[i]);
}
} else {
runSnapToRoad(path);
}
}
function waypointsLimiter(path) {
var path_loc_size = path.length;
var limited = [];
if(path_loc_size > 30) {
var stepper = Math.ceil(path_loc_size/30);
for(var i = stepper; i < path_loc_size; i += stepper) {
limited.push(path[i]);
}
if(limited.indexOf(path[path_loc_size-1]) == -1) {
limited.push(path[path_loc_size-1]);
}
} else {
limited = path;
}
return limited;
}
function handlePath(path) {
var i = 0;
var j = path.length;
if (j > 100) {
var newArray = [],
chunk = j/2;
if (j >= 200) {
chunk = j/3;
} else if (j >= 300) {
chunk = j/4;
} else if (j >= 400) {
chunk = j/5;
} else if (j >= 500 ) {
chunk = j/6;
} else if (j >= 600) {
chunk = j/7;
} else if (j >= 700 || j <= 799) {
chunk = j/8;
} else {
alert('La ruta no puede ser mostrada');
}
for (i, j; i < j; i+=chunk) {
newArray.push(path.slice(i,i+chunk+1));
}
return newArray;
} else {
return path;
}
}
// Snap a user-created polyline to roads and draw the snapped path
function runSnapToRoad(path) {
var path = path.join('|');
$.get('https://roads.googleapis.com/v1/snapToRoads', {
interpolate: true,
key: apiKey,
path: path,
}, function(data) {
processSnapToRoadResponse(data);
drawSnappedPolyline();
});
}
// Store snapped polyline returned by the snap-to-road service.
function processSnapToRoadResponse(data) {
snappedCoordinates = [];
placeIdArray = [];
for (var i = 0; i < data.snappedPoints.length; i++) {
var latlng = new google.maps.LatLng(
data.snappedPoints[i].location.latitude,
data.snappedPoints[i].location.longitude);
snappedCoordinates.push(latlng);
placeIdArray.push(data.snappedPoints[i].placeId);
}
}
// Draws the snapped polyline (after processing snap-to-road response).
function drawSnappedPolyline() {
var symbol = {
path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
scale: 3,
strokeColor: '#3B16B3'
};
var snappedPolyline = new google.maps.Polyline({
path: snappedCoordinates,
strokeColor: '#E51E25',
strokeWeight: 3,
icons: [{
icon: symbol,
offset: '0%'
}]
});
snappedPolyline.setMap(map);
animate(snappedPolyline);
zoomToObject(snappedPolyline);
polylines.push(snappedPolyline);
}
function zoomToObject(obj){
var bounds = new google.maps.LatLngBounds();
var points = obj.getPath().getArray();
for (var n = 0; n < points.length ; n++){
bounds.extend(points[n]);
}
map.fitBounds(bounds);
}
function animate(line) {
var count = 0;
window.setInterval(function() {
count = (count + 1) % 600;
var icons = line.get('icons');
icons[0].offset = (count / 6) + '%';
line.set('icons', icons);
}, 70);
}
breadCrumbsGrapher(path);
Also I've tried declaring a variable outside so I can concat all of the coordinates and generate a polyline with it but doesn't seem to work. Actualy that big array ends up being of 2000+ points.
The result that I have with the provided code
After all of that the issue is that I don't know how to merge the polylines to have just one line and being able to animate just that one line. If there's more than 100 coordinates I plot more polylines. In the image you can see that there's 3 icons (one for each polyline) and I need just to draw one line and have 1 icon.
To reproduce the issue just add a key and if you want use this set of coordinates:
https://drive.google.com/file/d/1jLb7Djv5DiSdR3k4QZRSatXBwrohlxcI/view?usp=sharing
function breadCrumbsGrapher(path) {
//mapMarkers();
snappedCoordinates = [];
handler.removeMarkers(Gmaps.store.markers);
for(var i = 0; i < polylines.length; i++) {
polylines[i].setMap(null);
}
var divided = handlePath(path);
if (typeof divided[0] == 'object') {
for(var i = 0; i < divided.length; i++) {
runSnapToRoad(divided[i]);
}
} else {
runSnapToRoad(path);
}
console.log(snappedCoordinates);
drawSnappedPolyline();
}
function runSnapToRoad(path) {
var path = path.join('|');
$.get('https://roads.googleapis.com/v1/snapToRoads', {
interpolate: true,
key: apiKey,
path: path,
}, function(data) {
processSnapToRoadResponse(data);
//drawSnappedPolyline();
});
}
I've changed the code but it doesn't work, even though I end up with a 2,557 coordinates array.
I've tried also tried this thinking that this could give me the time to have all coordinates:
async function breadCrumbsGrapher(path) {
//mapMarkers();
snappedCoordinates = [];
handler.removeMarkers(Gmaps.store.markers);
for(var i = 0; i < polylines.length; i++) {
polylines[i].setMap(null);
}
var divided = handlePath(path);
if (typeof divided[0] == 'object') {
for(var i = 0; i < divided.length; i++) {
await runSnapToRoad(divided[i]);
}
} else {
await runSnapToRoad(path);
}
console.log(snappedCoordinates);
drawSnappedPolyline();
}
and:
async function runSnapToRoad(path) {
var path = path.join('|');
await $.get('https://roads.googleapis.com/v1/snapToRoads', {
interpolate: true,
key: apiKey,
path: path,
}, function(data) {
processSnapToRoadResponse(data);
});
}
Thank you in advance.
You are using $.get() to query the Roads API which is an asynchronous call so when you call drawSnappedPolyline() from within your breadCrumbsGrapher function, you most probably don't (yet) have all coordinates in return from your AJAX call(s).
If you have 550 coordinates in your original path, you then know you must call the Roads API 6 times (5 times with 100 points + 1 time with 50 points). You should then be able to set a counter somewhere, to only draw your (complete) Polyline, once you got your 6 responses from the Roads API.
Or you could base that on the length of your final array (compared to the original path) although I don't know what would happen in case some points can't be "snapped".

Google Sheets - A pull data function doesn't want to play nice with a history storing function

I found a couple of functions that met my needs, but they don't want to play nice together. The goal is to pull data once a day, then add it to a new column. The history function is fine, and I've got a trigger setup to run it once a day, but it's erroring when attempting to run automatically, and sending me an email with the following.
6/18/18 5:29 PM loadRegionAggregates TypeError: Cannot find function
forEach in object [object Object]. (line 19, file
"Code") time-based 6/18/18 5:29 PM
here's the full code.gs (I bolded the section with line 19, first line of the function)
// Requires a list of typeids, so something like Types!A:A
// https://docs.google.com/spreadsheets/d/1IixV0eNqg19FE6cLzb83G1Ucb0Otl-Jnvm6csAlPKwo/edit?usp=sharing for an example
function loadRegionAggregates(priceIDs,regionID){
if (typeof regionID == 'undefined'){
regionID=10000002;
}
if (typeof priceIDs == 'undefined'){
throw 'Need a list of typeids';
}
var prices = new Array();
var dirtyTypeIds = new Array();
var cleanTypeIds = new Array();
var url="https://market.fuzzwork.co.uk/aggregates/?station=60003760&types=34,35,36,37,38,39,40"
**priceIDs.forEach(function (row) {
row.forEach(function (cell) {
if (typeof(cell) === 'number' ) {
dirtyTypeIds.push(cell);
}**
});
});
cleanTypeIds = dirtyTypeIds.filter(function(v,i,a) {
return a.indexOf(v)===i;
});
prices.push(['TypeID','Buy volume','Buy Weighted Average','Max Buy','Min Buy','Buy Std Dev','Median Buy','Percentile Buy Price','Sell volume','Sell Weighted Average','Max sell','Min Sell','Sell Std Dev','Median Sell','Percentile Sell Price'])
var parameters = {method : "get", payload : ""};
var o,j,temparray,chunk = 100;
for (o=0,j=cleanTypeIds.length; o < j; o+=chunk) {
temparray = cleanTypeIds.slice(o,o+chunk);
Utilities.sleep(100);
var types=temparray.join(",").replace(/,$/,'')
var jsonFeed = UrlFetchApp.fetch(url+types, parameters).getContentText();
var json = JSON.parse(jsonFeed);
if(json) {
for(i in json) {
var price=[parseInt(i),
parseInt(json[i].buy.volume),
parseInt(json[i].buy.weightedAverage),
parseFloat(json[i].buy.max),
parseFloat(json[i].buy.min),
parseFloat(json[i].buy.stddev),
parseFloat(json[i].buy.median),
parseFloat(json[i].buy.percentile),
parseInt(json[i].sell.volume),
parseFloat(json[i].sell.weightedAverage),
parseFloat(json[i].sell.max),
parseFloat(json[i].sell.min),
parseFloat(json[i].sell.stddev),
parseFloat(json[i].sell.median),
parseFloat(json[i].sell.percentile)];
prices.push(price);
}
}
}
return prices;
}
function storeData() {
var sheet = SpreadsheetApp.getActiveSheet();
var datarange = sheet.getDataRange();
var numRows = datarange.getNumRows();
var numColumns = datarange.getNumColumns();
sheet.getRange(1,numColumns + 1).setValue(new Date());
for (var i=2; i <= numRows; i++) {
var prices = sheet.getRange(i, 8).getValue();
sheet.getRange(i, numColumns + 1).setValue(prices);
}
}
I found this link:
TypeError: Cannot find function forEach in object
Which explains some of it, but when the code runs in debug mode, I don't have a range defined, and then the live sheet bugs with:
ReferenceError: "row" is not defined (line 21).
Note: My original code works fine when I run the script locally, just not when the daily timer goes off. I'm assuming the issues listed on the linked query regarding no forEach class on the nested object are applying to whatever runs the triggered .gs
Edit: Ok so i've been working on this all day. I've learned how to set an array var (since I didn't need to change the array, static works) and i've been trying to get the rest of the code adjusted ever since. Here's where I am so far:
// Requires a list of typeids, so something like Types!A:A
// https://docs.google.com/spreadsheets/d/1IixV0eNqg19FE6cLzb83G1Ucb0Otl-Jnvm6csAlPKwo/edit?usp=sharing for an example
function loadRegionAggregates(priceIDs,regionID){
if (typeof regionID == 'undefined'){
regionID=10000002;
}
if (typeof priceIDs == 'undefined'){
priceIDs = [34,35,36,37,38,39,40,11399];
}
var prices = new Array();
var dirtyTypeIds = new Array();
var cleanTypeIds = new Array();
var url="https://market.fuzzwork.co.uk/aggregates/?station=60003760&types=34,35,36,37,38,39,40"
// for (var priceIDs) {
// if (row.hasOwnProperty(column)) {
// var cell = row[column];
// if (typeof cell == "number") {
priceIDs.push(priceIDs);
// }
// }
// }
cleanTypeIds = dirtyTypeIds.filter(function(v,i,a) {
return a.indexOf(v)===i;
});
prices.push(['TypeID','Buy volume','Buy Weighted Average','Max Buy','Min Buy','Buy Std Dev','Median Buy','Percentile Buy Price','Sell volume','Sell Weighted Average','Max sell','Min Sell','Sell Std Dev','Median Sell','Percentile Sell Price'])
var parameters = {method : "get", payload : ""};
var o,j,temparray,chunk = 100;
for (o=0,j=cleanTypeIds.length; o < j; o+=chunk) {
temparray = cleanTypeIds.slice(o,o+chunk);
Utilities.sleep(100);
var types=temparray.join(",").replace(/,$/,'')
var jsonFeed = UrlFetchApp.fetch(url+types, parameters).getContentText();
var json = JSON.parse(jsonFeed);
if(json) {
for(i in json) {
var price=[parseInt(i),
parseInt(json[i].buy.volume),
parseInt(json[i].buy.weightedAverage),
parseFloat(json[i].buy.max),
parseFloat(json[i].buy.min),
parseFloat(json[i].buy.stddev),
parseFloat(json[i].buy.median),
parseFloat(json[i].buy.percentile),
parseInt(json[i].sell.volume),
parseFloat(json[i].sell.weightedAverage),
parseFloat(json[i].sell.max),
parseFloat(json[i].sell.min),
parseFloat(json[i].sell.stddev),
parseFloat(json[i].sell.median),
parseFloat(json[i].sell.percentile)];
prices.push(price);
}
}
}
return prices;
}
function storeData() {
var sheet = SpreadsheetApp.getActiveSheet();
var datarange = sheet.getDataRange();
var numRows = datarange.getNumRows();
var numColumns = datarange.getNumColumns();
sheet.getRange(1,numColumns + 1).setValue(new Date());
for (var i=2; i <= numRows; i++) {
var prices = sheet.getRange(i, 8).getValue();
sheet.getRange(i, numColumns + 1).setValue(prices);
}
}
So far, so good. It's not throwing any more errors on debug, and the column headers are coming in, but it's not bringing in the data anymore from the push.
Help!

Best way to filter on empty values with angular-ui-grid?

I'd like to offer my users the ability of showing only rows with empty values for a specific column. What would be the best approach?
I came up with this solution which feels hacky to me, reusing the filter input text field:
"onRegisterApi" : function(gridApi){
$scope.gridApi = gridApi;
$scope.gridApi.core.on.filterChanged( $scope, function() {
var grid = this.grid;
var term = grid.columns[7].filters[0].term; // the column I am interested in empty values
if( term == '_' ) {
$log.info("Setting filter to external mode");
$scope.grid.useExternalFiltering = true;
for(var i=0; i< grid.rows.length;i++){
var row = grid.rows[i];
if(row.entity.privileges==null || row.entity.privileges.trim().length==0){
$scope.gridApi.core.clearRowInvisible(row);
}
else{
$scope.gridApi.core.setRowInvisible(row);
}
}
}else if($scope.grid.useExternalFiltering==true){
$log.info("Resetting filter back to internal mode");
$scope.grid.useExternalFiltering = false;
for(var i=0; i< grid.rows.length;i++){
$scope.gridApi.core.clearRowInvisible(grid.rows[i]);
}
}
});
}

jquery-mobile , phonegap, dynamic data not displaying

Here is my code for dynamically creating a div and populating it from Phonegap database
But (a)it does not add the dynamic part from database. (b) the Rows: entry is printed in debugger console after the html content is dumped. ie. there seems to be lack of synchronisation:
var newPage;
var qry="SELECT literal,kunyomi from kanji where Unicode in(select b.Unicode from kanji_reading b where substr(b.kunyomi,1,1)='"+yomi+"')";
db.transaction(function (tx)
{
newPage = "<div data-role=page data-url=hi><div data-role=header><h1>" + yomi+ "</h1></div><div data-role=content>";
newPage +="<ul data-role='listview' id='details'>";
var temp="";
tx.executeSql(qry, [], function(tx,res)
{
var i;
var len = res.rows.length;
console.log("records"+len);
for (i=0; i<len; i++)
{
newPage+="<li><span class='tra-info-text'>"+res.rows.item(i).kunyomi+"</span></li>";
}
newPage+="</ul></div></div>";
},null);
var page=$(newPage);
console.log("page:"+page);
console.log("New Page:"+newPage);
console.log("page container:"+$.mobile.pageContainer);
page.appendTo($.mobile.pageContainer);
$.mobile.changePage( page );
});
The out put of console.log("New Page:"+newPage); only shows the static part i.e before the tx.executeSQL part. Whatever is added within the tx.executeSQL is not displayed.
Can anyone help?
The SQL query is asynchronous, meaning the end of your code (starting with var page = $(newPage)) will most likely be executed before your transaction is complete. You should make sure that the rest of your code is executed AFTER the transaction, the simplest being to have it in the callback of your SQL transaction.
db.transaction(function (tx)
{
newPage = "<div data-role=page data-url=hi><div data-role=header><h1>" + yomi+ "</h1></div><div data-role=content>";
newPage +="<ul data-role='listview' id='details'>";
var temp="";
tx.executeSql(qry, [], function(tx,res)
{
var i;
var len = res.rows.length;
console.log("records"+len);
for (i=0; i<len; i++)
{
newPage+="<li><span class='tra-info-text'>"+res.rows.item(i).kunyomi+"</span></li>";
}
newPage+="</ul></div></div>";
var page=$(newPage);
console.log("page:"+page);
console.log("New Page:"+newPage);
console.log("page container:"+$.mobile.pageContainer);
page.appendTo($.mobile.pageContainer);
$.mobile.changePage( page );
},null);
});

Javascript - getElementID from scratch using BFS?

I'm trying to learn javascript, and spent tonight writing a getElementByID() function using Breadth-First Search. In short: I'm lost.
Fiddle: http://jsfiddle.net/timdown/a2Fm6/
Code:
var nodes = [];
function getElementById(node, id) {
alert(nodes.length);
if (node.childNodes[i].id == id) {
return node.childNodes[i];
} else if (node.childNodes[i].length > 0) {
for (var i = 0, len = node.childNodes.length; i < len; ++i) {
nodes.push(node.childNodes[i]);
}
}
if (nodes.length > 0) {
getElementById(nodes[0], id);
}
}
var el = getElementById(document.body, 'id');
Any help?
You're missing a for loop in the top half of your code. Where is i defined?
Here's how I'd write it:
function getElementById(node, id) {
//An array of all the nodes at the same depth
var nodes = [node];
//While the array is not empty
while(nodes.length) {
var newNodes = [];
for(var i = 0; i < nodes.length; i++) {
var children = nodes[i].childNodes;
for(var j = 0; j < children.length; j++) {
var child = children[j];
if(child.id == id) {
return child
}
newNodes.push(child);
}
}
//Replace nodes with an array of the nodes the next level down
nodes = newNodes
}
}

Resources