unable to search for array items - javascript

In this program I am unable to search for items in an array. The db variable is already defined. I am unable to get into the search function and run it. Just curious why this might be happening. I am able to run the first validate function but then stops and will not perform the rest of the code.
// Create privatized scope using a self-executing function
(function() {
console.log("hello");
// Variable initialization (DO NOT FIX ANY OF THE BELOW VAR's)
var resultsDIV = document.getElementById("results"),
searchInput = document.forms[0].search,
currentSearch = '';
// Validates search query
var validate = function (query) {
console.log("validate");
// Trim whitespace from start and end of search query
query = query.trim();
// Check search length, must have 3 characters
if (query.length < 3) {
alert("Your search query is too small, try again.");
}else{
search(query);
// (DO NOT FIX THE LINE DIRECTLY BELOW)
searchInput.focus();
}
console.log("test");
};
console.log("outside search function");
// Finds search matches
var search = function (query) {
console.log("In search function");
// split the user's search query string into an array
var queryArray = query.split(" ");
// array to store matched results from database.js
var results = [];
// loop through each index of db array
for (var i = 0, j = db.length; i < j; i++) {
console.log(i);
// each db[i] is a single video item, each title ends with a pipe "|"
// save a lowercase variable of the video title
var dbTitleEnd = db[i].indexOf('|');
var dbItems = db[i].toLowerCase().substring(0, dbTitleEnd);
}
// loop through the user's search query words
// save a lowercase variable of the search keyword
for (var ii = 0, jj = queryArray.length; ii < jj; ii++) {
var qItem = queryArray[ii].toLowerCase();
}
// is the keyword anywhere in the video title?
// If a match is found, push full db[i] into results array
var compare = dbItems.indexOf(qItem);
if (compare !== -1) {
results = results.push(db[i]);
}
results.sort();
// Check that matches were found, and run output functions
if (results.length === 0) {
noMatch();
} else {
showMatches(results);
}
};
// Put "No Results" message into page (DO NOT FIX THE HTML VAR NOR THE innerHTML)
var noMatch = function() {
var html = '' +
'<p>No Results found.</p>' +
'<p style="font-size:10px;">Try searching for "JavaScript". Just an idea.</p>'
;
resultsDIV.innerHTML = html;
};
// Put matches into page as paragraphs with anchors
var showMatches = function (results) {
// THE NEXT 4 LINES ARE CORRECT.
var html = '<p>Results</p>',
title,
url
;
// loop through all the results search() function
for (var i = 0, j = results.length; i < j; i++) {
// title of video ends with pipe
// pull the title's string using index numbers
var titleEnd = results[i].indexOf('|');
title = results[i].subString(0, titleEnd);
// pull the video url after the title
url = results[i].substring(results[i].indexOf('|') + 1, results[i].length);
// make the video link - THE NEXT LINE IS CORRECT.
html += '<p><a href=' + url + '>' + title + '</a></p>';
resultsDIV.innerHTML = html; //THIS LINE IS CORRECT.
}
};
console.log("start of program");
/***** start of program *******/
// The onsubmit event will be reviewed in upcoming Course Material.
// THE LINE DIRECTLY BELOW IS CORRECT
document.forms[0].onsubmit = function(){
var query = searchInput.value;
validate(query);
// return false is needed for most events - this will be reviewed in upcoming course material
// THE LINE DIRECTLY BELOW IS CORRECT
return false;
};
})();

I checked your code and everything is there but somehow all wrongly connected. It seems that you have completely wrong concept about for loops. I did several minor changes:
query is trimmed on reading because we need it not just in validator
validator:
if query is too short set focus back
it validated but also allowed operation to continue in case of error - changed
changed to isValid() and checked in onsubmit handler
search:
wrong concept of for loops
you retrieve dbTitleEnd/dbItems and than overwrite them by the next one
there is no need to do results = results.push(db[i]); but just `results.push(db[i]);
subString() corrected to substring()
console.log() messages are left in
See Example in jsFiddle.

Related

Jquery - how to get & consider only 1 URL Parameter and ignore the others?

On my shop i have a filter. When a filter is selected it adds "filter.p.tag=xxx" parameter to the url. Since i have no other possibility to display current active filters, i need to grab them from the URL. And output them under the h1 and update in realtime when a new filter is selected.
For example the URL:
collections/all?filter.p.tag=animal&filter.p.tag=glitter&fbclid=2123&paramblabla=123123
-actually i only want everything after (filter.p.tag) - so in this example under the H1 Heading there should be following:
"Animal & Glitter"
I want to ignore every other parameter without "jquery remove or replace" them since this is unwanted.
THE QUESTION IS: How am i able to only consider the filter.p.tag param and ignore all others?
Now i have this code:
<script>
// Read a page's GET URL variables and return them as an associative array.
function getUrlVars()
{
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
function removeDuplicates(arr) {
return arr.filter((item,
index) => arr.indexOf(item) === index);
}
jQuery( document ).ready(function( $ ) {
jQuery(document.body).on('click', ".label_filter", function(){
setTimeout(function(){
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[1]);
// vars[hash[0]] = hash[1];
}
var unqvars = removeDuplicates(vars);
var result = '';
for(var i = 1; i <= unqvars.length; i++){
if(i == unqvars.length){
var sept = '';
}else{
var sept = ' & ';
}
result = unqvars+ sept;
}
var replaced = result.replaceAll(',', ' & ');
var replaced1 = replaced.replaceAll('+', ' ');
var replaced2 = replaced1.replaceAll('-', ' ');
var replaced3 = replaced2.replaceAll('& Page=', ' Seite ');
jQuery('#categoryfromfilter').text(replaced3);
}, 1000);
});
});
</script>
```
Less code, more robust
URLSearchParams().getAll() works well when there are multiple values for the same key name.
However, additional code is needed to make the function handle a wide range of input. For example, here we first parse the query string from the url. URLSearchParams would fail if the path were passed, e.g., /somepath?key=value. Query string values might also be encoded and so decodeURIComponent() is applied to each value.
const getParam = (url, key) =>
new URLSearchParams(url?.toString().split("?").pop())
.getAll(key).map(value => decodeURIComponent(value));
Example:
let url = "/collections/all?filter.p.tag=animals&filter.p.tag=glitter",
key = "filter.p.tag",
result = getParam(url, key);
// Output: "animals,glitter"
Update
OP asked for additional code to pull the filter values from window.location.href. We can use this href to create a URL and then modify the original solution to use URL.searchParams.
Additionally, OP wants to retrieve the filters whenever the page query string changes. This most likely happens when the user clicks a filter option that causes the page to reload with new data. For this we can use the DOMContentLoaded event to check for new filters when the page loads. While less likely, the page might also use History.pushState() to update the query string and for that we could use the popstate event.
function onQueryChange() {
let key = "filter.p.tag";
let url = new URL(window.location.href);
let filters = url.searchParams.getAll(key)
.map(value => decodeURIComponent(value))
.join("&");
// do something with the filters...
}
document.addEventListener("DOMContentLoaded", onQueryChange);
// document.addEventListener("popstate", onQueryChange);
Snippet
Code snippet that displays a range of test values.
const getParam = (url, key) =>
new URLSearchParams(url?.toString().split("?").pop())
.getAll(key).map(value => decodeURIComponent(value));
// Test Values
let name = "filter.p.tag";
["/collections/all?filter.p.tag=animals",
"/collections/all?filter.p.tag=animals&filter.p.tag=glitter",
"/collections/all?fbclid=IwAR2didTPblablabla&filter.p.tag=animals",
"/collections/all?filter.p.tag=animals&fbclid=IwAR2didTPblablabla&filter.p.tag=glitter",
"/collections/all?sort_by=apes&filter.p.tag=animals&fbclid=IwAR2didTPblablabla",
"fbclid=IwAR2didTPblablabla&filter.p.tag=animals",
"filter.p.tag=animals&filter.p.tag=glitter&fbclid=IwAR2didTPblablabla",
"/collections/all?fbclid=IwAR2didTPblablabla",
"filter.p.tag&fbclid=IwAR2didTPblablabla",
"/collections/all",
null,
undefined
].forEach(url => stdout.innerHTML += (`Returns "${getParam(url, name)}" for "${url}"\n`));
<xmp id="stdout"></xmp>

Google App Script to Break out Query Parameters in Google Sheets

I have a Google Sheet with 100 https request URLs with query parameters. The URLs look like this:
https://122.2o7.net/b/ss/ryan1/1/JS-2.0.0/s12345678?AQB=1&ndh=1&pf=1&t=6%2F9%2F2018%208%3A48%3A34%206%20360&ts=1538837314190&vid=test&fid=1w23232-erwwwre&ce=UTF-8&ns=ryan&pageName=ryan%3Atest%3Apage&g=https%3A%2F%2Fryanpraski.com%2F&cc=USD&ch=home&events=event1&c1=D%3Dv1&v1=evar1value&h1=hier1value&v20=evar20value&bh=8&AQE=1
I want to use Google App Script to break out the query parameters and put them neatly into the Google Sheet like this:
I got as far as the code below to break query string and split the query string parameters by the & delimiter, but I am not sure what to do next.
A couple cases that I need to consider as well.
There could be URLs with more or fewer parameters than my sample URL, but there will always be some overlay. I want to have the column headers automatically update.
There could be values like c1=D%3Dv1 where the decoded value is c1=D=v1
Any help would be greatly appreciated!
function test() {
var url = "https://122.2o7.net/b/ss/ryan1/1/JS-2.0.0/s12345678?AQB=1&ndh=1&pf=1&t=6%2F9%2F2018%208%3A48%3A34%206%20360&ts=1538837314190&vid=test&fid=1w23232-erwwwre&ce=UTF-8&ns=ryan&pageName=ryan%3Atest%3Apage&g=https%3A%2F%2Fryanpraski.com%2F&cc=USD&ch=home&events=event1&c1=D%3Dv1&v1=evar1value&h1=hier1value&v20=evar20value&bh=8&AQE=1";
var cleanUrl = decodeURIComponent(url);
var params = cleanUrl.split('?')[1];
var s = params;
var t = s.split('&');
var output = [];
t.forEach(function(q) {
output.push([q]);
});
Logger.log(output);
}
The following code breaks out the query parameters and puts them into a specific sheet. It also addresses a couple of possible scenarios:
1 There is no match for an existing code. In that case, a space is entered as a place holder.
2 The URL includes codes not included in the existing list. In that case, the "new" code(s) are added to the list, and their values are recorded also.
3 As the questioner pointed out, some URL parameters include multiple "Equals" signs ("="). Split can't be used in this case because though a parameter can be used to limit the number of split found, the left-over text is not returned in the new array. So I used indexOf (which returned the index of the first occurrence of searchValue) and subString to calculate the two parts of the URL component.
I assumed that the existing list of codes was in Row1, so I created a NamedRange to be able to manage them. If the code finds URL parameters that don't find a match with the codes in the Named Range, then the NamedRange is deleted and re-created to include the "new" codes.
The code outputs results to the "third sheet" (ss.getSheets()2;) in the spreadsheet; this is something that can be changed.
The last row containing data is determined, and the results of the analysis are set in the following row
Note: the url is hard coded.
function so_52825789() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var datasheet = ss.getSheets()[2];
// the codes are in Row1 in a Named Range called DataVariables
var urlvars = ss.getRangeByName('DataVariables').getValues();
// get the number of Columns for the Named Range
var datalen = urlvars[0].filter(String).length;
//Logger.log("Number of columns of codes = "+datalen); //DEBUG
//get the last row of containing data
var lastvals = ss.getRange("A1:A").getValues();
var lastrow = lastvals.filter(String).length;
//Logger.log("the last row is "+lastrow);// DEBUG
// Get the url
var url = "https://122.2o7.net/b/ss/ryan1/1/JS-2.0.0/s12345678?AQB=1&ndh=1&pf=1&t=6%2F9%2F2018%208%3A48%3A34%206%20360&ts=1538837314190&vid=test&fid=1w23232-erwwwre&ce=UTF-8&ns=ryan&pageName=ryan%3Atest%3Apage&g=https%3A%2F%2Fryanpraski.com%2F&cc=USD&ch=home&events=event1&c1=D%3Dv1&v1=evar1value&h1=hier1value&v20=evar20value&bh=8&AQE=1&ejb=1";
// Javascript function to remove the URL encoded charaters
var cleanUrl = decodeURIComponent(url);
// get the URL variables (the second half of the split)
var params = cleanUrl.split('?')[1];
var s = params;
// get the specific query variables by spliting on "&"
var t = s.split('&');
// get the number of query variables
var tlen = t.filter(String).length;
// setup some variables for use later
var output = [];
var mismatchcode = [];
var mismatchdata = [];
var tcount = [];
var nomatch = 0;
var ttest = 0;
var ztest = 0;
// Loop through the known codes from the Named Range
for (i = 0; i < datalen; i++) {
// set a variable value so that you can count how many named codes were found
ttest = 1;
// Start a loop though the query variables in the URL
for (z = 0; z < tlen; z++) {
// get the position of the Equals sign "="; there may be more than one but we only want the first one.
var n = t[z].indexOf("=");
if (n > 0) {
//var result="Equals appears at position = "+(n+1)+" (actual value = "+n+")";
//Logger.log(result);
//get the length of the element
var nstr = t[z].length;
//Logger.log("Length = "+nstr); //DEBUG
// break the element into two halves. The first half is the "Code" and the second half is the "value"
var code = t[z].substring(0, n);
var codevalue = t[z].substring((n + 1), nstr);
//Logger.log("z = "+z+", code is = "+code+", and the value is "+codevalue); // DEBUF
}
// test to whether there is a match between the Named Range Code and the URL
if (urlvars[0][i] == code) {
// set the variable to note a match was detected.
ttest = 0;
// push the code value into an array
output.push(codevalue);
// push the Named range code ID onto an array
tcount.push(z);
//Logger.log("Match "+urlvars[0][i]+" = "+code); //DEBUG
}
} // end of the URL variables loop
// having looped through the URL variables, test to see whether there was a match
// if not (ttest still equals One) then put an empty string in the output array, so ensure that every code has a value
// and keep count of the number of "nomatches"
if (ttest == 1) {
output.push(" ");
Logger.log("No match for " + urlvars[0][i]);
nomatch = nomatch + 1;
}
} // end of the Named Range loop
// create an array for 2d format
var outeroutput = [];
// put the loop array into the blank array. The result is a 2d array that can be read by the Google sheets script.
outeroutput.push(output);
// For the NamedRange analysis, we can now set the values from the loop
var targetrange = datasheet.getRange(lastrow + 1, 1, 1, datalen);
targetrange.setValues(outeroutput);
//Logger.log("targetrange = "+targetrange.getA1Notation()); //DEBUG
// count how matches were found for URL variables
var tcountlen = tcount.filter(String).length;
// compare the number of variables in the URL with the number of matches.
// If there is a difference, then we need to loop through the URL variables, find the ones that didn't match and do stuff with them.
if ((tlen - tcountlen) > 0) {
// starp loop for URL variables
for (z = 0; z < tlen; z++) {
// set the variable to detect whether or not a a match was made.
ztest = 1;
// Repeat the process of splitting the component code and value
var n = t[z].indexOf("=");
if (n > 0) {
// get the length of the variable
var nstr = t[z].length;
// get the componet parts
var code = t[z].substring(0, n);
var codevalue = t[z].substring((n + 1), nstr);
//Logger.log("z = "+z+", code is = "+code+", and the value is "+codevalue); //DEBUG
}
// start the loop for thecodes in the NamedRange
for (i = 0; i < datalen; i++) {
// If there's a match, chnage the value of the 'match testing' varuable
if (urlvars[0][i] == code) {
ztest = 0;
}
} // end of the loop for NamedRange codes
// if there hasn't been match, then
// push the url variable code and value onto some respective arrays
if (ztest == 1) {
mismatchcode.push(code);
mismatchdata.push(codevalue);
}
} // end of the URL variables loop
//Logger.log("Code fields = "+datalen+", data fields = "+tlen);// DEBUG
//Logger.log("Total no-matches for codes = "+nomatch); // DEBUG
// Logger.log("Total no-matches for URL fields = "+(tlen-tcountlen)); //DEBUG
// So, what shall we do if there the number of variables in the NAMED RANGE does equal the number of variables
// if((tlen-tcountlen) !=0){
// These rows are just for DEBUG assignstance.
// for (i=0;i<(tlen-tcountlen);i++){ //DEBUG
// Logger.log("URL field not found: code = "+mismatchcode[i]+", value = "+mismatchdata[i]); //DEBUG
// } //DEBUG
// create the arrays to act as 2d
var outermismatchcode = [];
var outermismatchdata = [];
// Push the mismatch arrays to the create the 2d arrays
outermismatchcode.push(mismatchcode);
outermismatchdata.push(mismatchdata);
// Identify the range for the addition URL Codes and values
// set the respective values
var extraurlcoderange = datasheet.getRange(1, datalen + 1, 1, (tlen - tcountlen));
extraurlcoderange.setValues(outermismatchcode);
var extraurldatarange = datasheet.getRange(lastrow + 1, datalen + 1, 1, (tlen - tcountlen));
extraurldatarange.setValues(outermismatchdata);
// We want to add the "new" codes found in the URL to the Named Range.
// Start by deletinging the existing NamedRange
ss.removeNamedRange("DataVariables");
// Define the parmeters for a new range.
// The main thing is that we need to add more columns
var newnamedrange = datasheet.getRange(1, 1, 1, (datalen + (tlen - tcountlen)))
// So, Create a new NamedRange using the same name as before.
ss.setNamedRange('DataVariables', newnamedrange);
// The following lines are just to check that everything worked OK
// var rangeCheck = ss.getRangeByName("DataVariables"); // DEBUG
// if (rangeCheck != null) { //DEBUG
// Logger.log("Columns in the new named range = "+rangeCheck.getNumColumns());//DEBUG
// } ,//DEBUG
// var rangeCheckName = rangeCheck.getA1Notation(); //DEBUG
// Logger.log("the new named range is = "+rangeCheckName);//DEBUG
} // end of the loop to identify URL variables that didn't match a code in the NamedRange
}
Note the addition value of the c1 code includes the relevant equals sign. Also the URL includes an additional parameter ("ejb=1") that is not in the existing list; this code and its value are added to the spreadsheet, and the NamedRange now includes the "new" code.

Function to return a list - issue with filtering the output

I am trying to output only articles if authorsId = authorId.
Beside that the whole function works exactly as I want, here it is:
The general idea is to limit access to only own articles.
So, my question is: how do I limit the results to show only articles written by the owner of the page we are on (authorsId = authorId).
function ArticlesListReturn(returned) {
xml = returned.documentElement;
var rel = document.getElementById('related_category_articles');
rel.options.length = 0;
var status = getXMLData('status');
var title = '';
var id = '';
var authorid = '';
if (status == 0) {
alert("%%LNG_jsArticleListError%%" + errormsg);
} else {
var authorid = document.getElementById("authorid").value; // Serge
// authorsid = getNextXMLData('authors',x);
for (var x = 0; x < xml.getElementsByTagName('titles').length; x++) {
title = getNextXMLData('titles', x);
id = getNextXMLData('ids', x);
authorsid = getNextXMLData('authors', x);
alert(authorsid) // authors of each article - it returns the proper values
alert(authorid) // author of the page we are on - it returns the proper value
var count = 0;
rel.options[x] = new Option(title, id, authorid); // lign that returns results
title = '';
id = '';
authorid = '';
}
}
I suspect the problem is when you try performing a conditional statement (if/then/else) that you are comparing a number to a string (or a string to a number). This is like comparing if (1 == "1" ) for example (note the double quotes is only on one side because the left would be numeric, the right side of the equation would be a string).
I added a test which should force both values to be strings, then compares them. If it still gives you problems, make sure there are no spaces/tabs added to one variable, but missing in the other variable.
Also, I changed your "alert" to output to the console (CTRL+SHIFT+J if you are using firefox). The problem using alert is sometimes remote data is not available when needed but your alert button creates a pause while the data is being read. So... if you use alert, your code works, then you remove alert, your code could reveal new errors (since remote data was not served on time). It may not be an issue now, but could be an issue for you going forward.
Best of luck!
function ArticlesListReturn(returned) {
xml = returned.documentElement;
var rel = document.getElementById('related_category_articles');
rel.options.length = 0;
var status = getXMLData('status');
var title = '';
var id = '';
var authorid = '';
if (status == 0) {
alert("%%LNG_jsArticleListError%%" + errormsg);
} else {
var authorid = document.getElementById("authorid").value; // Serge
// authorsid = getNextXMLData('authors',x);
for (var x = 0; x < xml.getElementsByTagName('titles').length; x++) {
title = getNextXMLData('titles', x);
id = getNextXMLData('ids', x);
authorsid = getNextXMLData('authors', x);
console.log("authorsid = "+authorsid); // authors of each article - it returns the proper values
console.log("authorid = "+authorid); // author of the page we are on - it returns the proper value
if( authorsid.toString() == authorid.toString() )
{
rel.options
var count = 0;
console.log( authorsid.toString()+" equals "+authorid.toString() );
rel.options[rel.options.length] = new Option(title, id, authorid); // lign that returns results
}
else
{
console.log( authorsid.toString()+" NOT equals "+authorid.toString() );
}
title = '';
id = '';
authorid = '';
}
Did you check the console for messages? Did it correctly show authorid and authorsid?
I have edited the script and made a couple of additions...
The console will tell you if the conditional check worked or not (meaning you will get a message for each record). See the "if/else" and the extra "console.log" parts I added?
rel.options[x] changed to equal rel.options[rel.options.length]. I am curious on why you set rel.options.length=0 when I would instead have done rel.options=new Array();

Do a query for every loop item and wait for result

I am making a CloudCode function that returns all users that are matching to my settings. In this function I am looping through a list of users and I need to get their settings in order to see if I should return them. The only problem is that the loop doesn't wait for the query to finish.
How can I get the Settings object for every user in the loop, check if the settings are correct and then push them in an array and return the array when the loop has finished?
The code I am using now:
for (var i = 0; i < connectResults.length; i++) {
var connect = connectResults[i];
for (var j = 0; j < matchResults.length; j++) {
var match = matchResults[j];
if (connect.get("sendBy").id == match.id) {
var indexOf = matchResults.indexOf(match);
matchResults.splice(indexOf, 1);
} else if (connect.get("receivedBy").id == match.id) {
var indexOf = matchResults.indexOf(match);
matchResults.splice(indexOf, 1);
}
if(typeof match.get("settings") != 'undefined') {
var settingsQuery = new Parse.Query("Settings");
settingsQuery.equalsTo("objectId",match.get("settings").id);
settingsQuery.find({
success: function(setting) {
console.log(match.get("username") + " " + setting.get("radius"));
}
});
}
}
}
response.success(matchResults);
Instead of querying all users and attempting to match their settings, I would instead query all users using the setting as a query constraint. In other words, tell the database that you want it to return all the users with the right settings.
var usersQuery = new Parse.Query("Users");
//Below, "settings" is the column name in your Users table
usersQuery.equalTo("settings", /* Settings value you are matching */);
usersQuery.find({
//...
});
You might need a containedIn query if there are multiple setting possibilities. See the docs for an example: https://parse.com/docs/js/guide#queries-query-constraints
Good luck! :)

Cant figure out search error

working on this, too. I've fixed the spelling and (i think) the bracket errors. Also fixed a couple errors I saw that stood out, but didn't get too far. I'm still stumped as to where to go with it next.
(function(){
// Variable initialization (DO NOT FIX ANY OF THE BELOW VAR's)
var resultsDIV = document.getElementById("results"),
searchInput = document.forms[0].search,
currentSearch = ''
;
// Validates search query
var validate = function(query){
// Trim whitespace from start and end of search query
while (query.charAt[0] === " "){
query = query.substring(1, query.length);
};
while (query.charAt(query.length-1) === ""){
query = query.substring(0, query.length - 1);
};
// Check search length, must have 3 characters
if (query.length < 3){
alert ("Your search query is too small, try again.");
// (DO NOT FIX THE LINE DIRECTLY BELOW)
searchInput.focus();
return;
};
search (query);
};
// Finds search matches
var search = function (query){
// split the user's search query string into an array
var queryArray = query.join(" ");
// array to store matched results from database.js
var results = [];
// loop through each index of db array
for(var i=0, j=db.length; i<j; i++){
// each db[i] is a single video item, each title ends with a pipe "|"
// save a lowercase variable of the video title
var dbTitleEnd = db[i].indexOf('|');
var dbitem = db[i].tolowercase().substring(0, dbTitleEnd);
// loop through the user's search query words
// save a lowercase variable of the search keyword
for(var ii=0, jj=queryArray.length; ii<jj; ii++){
var qitem = queryArray[ii].tolowercase();
// is the keyword anywhere in the video title?
// If a match is found, push full db[i] into results array
var compare = dbitem.indexOf(qitem);
if(compare !== -1){
results.push(db[i]);
};
};
};
};
results.sort();
// Check that matches were found, and run output functions
if(results.length = );{
noMatch();
}else{
showMatches(results);
};
// Put "No Results" message into page (DO NOT FIX THE HTML VAR NOR THE innerHTML)
var noMatch = function(){
var html = ''+
'<p>No Results found.</p>'+
'<p style="font-size:10px;">Try searching for "JavaScript". Just an idea.</p>'
;
resultsDIV.innerHTML = html;
};
// Put matches into page as paragraphs with anchors
var showMatches = function(results){
// THE NEXT 4 LINES ARE CORRECT.
var html = '<p>Results</p>',
title,
url
;
// loop through all the results search() function
for(var i=0, j=results.length; i<j; i++){
// title of video ends with pipe
// pull the title's string using index numbers
titleEnd = results[i].indexOf('|');
title = results[i].subString(0, titleEnd);
// pull the video url after the title
url = results[i].substring(results[i].indexOf('|')+1, results[i].length);
// make the video link - THE NEXT LINE IS CORRECT.
html += '<p><a href=' + url + '>' + title + '</a></p>';
};
resultsDIV.innerHTML = html; //THIS LINE IS CORRECT.
};
// The onsubmit event will be reviewed in upcoming Course Material.
// THE LINE DIRECTLY BELOW IS CORRECT
document.forms[0].onsubmit = function(){
var query = searchInput.value;
validqte(query);
// return false is needed for most events - this will be reviewed in upcoming course material
// THE LINE DIRECTLY BELOW IS CORRECT
return false;
;
})();
There are a few syntax errors which should prevent this from running at all.
// syntax error
var results = ();
// should be
var results = [];
Also it appears that the definition of showMatches ends with an unmatched right parenthesis.
Given that somehow the code is running with these syntax errors (and possibly others I didn't notice), the (a) glaring issue is:
if (results.length = 0) {
Yeah, that's an assignment, not a comparison. You just set the array's length to zero, which effectively clears it. This both fails the length test here (returning 0), then hands the now empty array off to be displayed as results, but of course it's now an array of length 0.
On another note, probably not an actual problem but I can't help it. The while loop business to trim the string? Yeah, don't do that. Use trim. If you need a polyfill there's always:
if (!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^\s+|\s+$/g, '');
};
}

Categories

Resources