AJAX search - no results returns last line - javascript

I am trying to implement a search box that will search a particular play (AJAX file) for any instances of the word, if the word is found it then outputs that line. My problem is that if no results are found of the word instead of continuing to show the entire play it outputs the last line of the play only.
My function:
function searchResults(query) {
var temp = "\\b" + query + "\\b";
var regex_query = new RegExp(temp, "gi");
var currentLine;
var num_matching_lines = 0;
$("#mainOutput").empty();
$("LINE", current_play_dom).each(function () {
var line = this;
currentLine = $(this).text();
matchesLine = currentLine.replace(regex_query, '<span class="query_match">' + query + '</span>');
if ( currentLine.search(regex_query) > 0 ) {
num_matching_lines++
$("#mainOutput").append("<br /><p class='speaker_match'>"+ $(line).parent().find('SPEAKER').text() +"</p>");
$("#mainOutput").append("<p class='act_match'>"+ $(line).parent().parent().parent().children(':first-child').text()+"</p>");
$("#mainOutput").append("<p class='scene_match'>"+ $(line).parent().parent().children(':first-child').text() +"</p>");
$("#mainOutput").append("<p>" + matchesLine + "</p>");
$("#mainOutput").append("<br>");
}
});
$("#mainOutput").append("<p>" + matchesLine + "</p>");
$("#sideInfo").append("<p>Found " + query + " in " + num_matching_lines + " lines</p>");
}
Also as a side question is there a neater way to do this:
$(line).parent().parent().parent().children(':first-child')

Related

JavaScript: Code says "cannot read property 'indexOf' of undefined" but I can't fix the problem

The code is used in a HTML document, where when you press a button the first word in every sentence gets marked in bold
This is my code:
var i = 0;
while(i < restOftext.length) {
if (text[i] === ".") {
var space = text.indexOf(" ", i + 2);
var tekststykke = text.slice(i + 2, space);
var text = text.slice(0, i) + "<b>" + tekststykke + "</b>" + text.slice(i + (tekststykke.length + 2));
var period = text.replace(/<b>/g, ". <b>");
var text2 = "<b>" + firstWord + "</b>" + period.slice(space1);
i++
}
}
document.getElementById("firstWordBold").innerHTML = text2;
}
It's in the first part of the code under function firstWordBold(); where it says there is an error with
var space1 = text.indexOf(" ");
Looks like you're missing a closing quote on your string, at least in the example you provided in the question.
Your problem is the scope of the text variable. In firstWordBold change every text to this.text, except the last two where you re-define text
Also, if you want to apply bold to the first word this is easier...
document.getElementById('test-div-2').innerHTML = '<b>' + firstWord + '</b>' + restOftext;
It now works for me, with no errors and it applies bold to the first word.
Here's how the function ended up,
function firstWordBold() {
console.log('bolding!');
var space1 = this.text.indexOf(' ');
var firstWord = this.text.slice(0, space1);
var restOftext = this.text.slice(space1);
document.getElementById('test-div-2').innerHTML = '<b>' + firstWord + '</b>' + restOftext;
}
To make every first word bold, try this...
function firstWordBold() {
let newHTML = '';
const sentences = this.text.split('.');
for (let sentence of sentences) {
sentence = sentence.trim();
var space1 = sentence.indexOf(' ');
var firstWord = sentence.slice(0, space1);
var restOftext = sentence.slice(space1);
newHTML += '<b>' + firstWord + '</b>' + restOftext + ' ';
}
document.getElementById('test-div-2').innerHTML = newHTML;
}
One last edit, I didn't notice you had sentences ending with anything other that a period before. To split on multiple delimiters use a regex, like so,
const sentences = this.text.split(/(?<=[.?!])\s/);

How to keep the next line \n from getting removed inside the email text?

All the \n are removed from the string when the text is put inside mail body .
var valuess = Object.entries(feedBackText);
valuess.forEach(function (key) {
responseText = responseText.concat(' ' + key[0] + ':' + key[1] + '\n');
});
var parsedString = responseText.toString();
window.location = "mailto:myid#gmail.com"+"?subject="+subjectmail+"&body=" +
parsedString;
The following demonstrates how you can solve this using the built-in encodeURIComponent function:
var parsedString = "text on the" + "\n" + "next line";
var link = "mailto:myid#gmail.com" + "?subject=Example&body=" +
encodeURIComponent(parsedString);
console.log(link);

How do I hyperlink JSON API return values with variable URL addresses?

I have an HTML/CSS search bar where people can type a keyword and, on click, my Open States JSON API code returns New Jersey state bills that match that keyword.
Search Bar Screenshot
Screenshot of a Result
I want the bill titles that are returned to be hyperlinked to their page on the New Jersey state legislature site, but I can only find instructions for how to hyperlink a return with a static site.
Here is my JavaScript code so far (with API key removed):
e.preventDefault();
// console.log($("#billID").val());
var billSearchValue = $("#billID").val();
if(billSearchValue=='')
{
alert("Enter Desired Query Parameters");
} else{
// console.log(billSearchValue);
}
var searchQuery = "&q=" + billSearchValue;
var baseUrl = "http://openstates.org/api/v1/bills/?state=nj";
var apiKey = "";
var apiKeyParam = "&apikey=";
var apiKeyParams = apiKeyParam + apiKey;
var urlJSON = baseUrl + searchQuery + apiKeyParam + apiKey;
// console.log(urlJSON);
$.getJSON(urlJSON, function (data) {
var billsVar = [];
$.each(data, function(key, val) {
billsVar.push(val);
});
for (var i = 0; i < billsVar.length; i++) {
var billList = "<li>Bill <ul class=\"ul-sub\">"
var billTitle = "<li><strong>Bill Title</strong>: " + billsVar[i]['title'] + "</li>";
var billCreatedAt = "<li><strong>Bill Created</strong>: " + billsVar[i]['created_at'] + "</li>";
var billUpdatedAt = "<li><strong>Bill Updated</strong>: " + billsVar[i]['updated_at'] + "</li>";
var billID = "<li><strong>ID</strong>: " + billsVar[i]['id'] + "</li>";
var billChamber = "<li><strong>Bill Chamber</strong>: " + billsVar[i]['chamber'] + "</li>";
var billState = "<li><strong>Bill State (Probably Don't Want/Need This)</strong>: " + billsVar[i]['state'] + "</li>";
var billSession = "<li><strong>Bill Session</strong>: " + billsVar[i]['session'] + "</li>";
var billType = "<li><strong>Bill Type</strong>: " + billsVar[i]['type'] + "</li>";
var billSubjects = "<li><strong>Subjects</strong>: " + billsVar[i]['subjects'] + "</li>";
var billBillID = "<li><strong>Bill ID</strong>: " + billsVar[i]['bill_id'] + "</li>";
var billOutput = billList + billTitle + billCreatedAt + billUpdatedAt + billID + billChamber + billState + billSession + billType + billSubjects + billBillID + "</ul></li>";
$("#jsonlist").append(billOutput);
}
});
})
});
After a bit of research I see that a bill hyperlink is like this:
http://openstates.org/nj/bills/{Bill Session}/{Bill ID}/
I can't test my code because I have no API key, but the solution could be something like:
var billTitle = '<li><strong>Bill Title</strong>: '
+ '<a href="http://openstates.org/nj/bills/' +
billsVar[i]['session'] + '/' + billsVar[i]['bill_id'].split(' ').join('') + '/">'
+ billsVar[i]['title'] + '</a></li>';

Search XML for word - jQuery

I am looking to search an XML document to match whatever word the user has entered. The problem I'm having is at best I can only get the number of the lines it occurs in, so if it occurs twice in one line it's only be counted as one instance.
I'm passing the search term in from an input box to this function:
function searchResults(query) {
var temp = "\\b" + query + "\\b";
var regex_query = new RegExp(temp, "gi");
var currentLine;
var num_matching_lines = 0;
$("#mainOutput").empty();
$("LINE", current_play_dom).each(function () {
var line = this;
currentLine = $(this).text();
matchesLine = currentLine.replace(regex_query, '<span class="query_match">' + query + '</span>');
if (currentLine.search(regex_query) > 0) {
$('#sideInfo>ul').empty();
num_matching_lines++
$("#mainOutput").append("<br /><p class='speaker_match'>"+ $(line).parent().find('SPEAKER').text() +"</p>");
$("#mainOutput").append("<p class='act_match'>"+ $(line).parent().parent().parent().children(':first-child').text()+"</p>");
$("#mainOutput").append("<p class='scene_match'>"+ $(line).parent().parent().children(':first-child').text() +"</p>");
$("#mainOutput").append("<p>" + matchesLine + "</p>");
$("#mainOutput").append("<br>");
}
});
$("#mainOutput").append("<p>" + matchesLine + "</p>");
$("#sideInfo").append("<p>Found " + query + " " + num_matching_lines + " times</p>");
}
This is outputting the line count fine but I want to be able to output the amount of times the word actually occurs in the XML.

Showing matching lines from a search using jquery

I have a bit of code that searches the current information shown on the page from a input source, which is an XML loaded in. This then shows how many times the word has been found, it should then display the lines where the word was found although currently it is showing all the lines. The code is
function searchResults(query) {
var temp = "\\b" + query + "\\b";
var regex_query = new RegExp(temp, "gi");
var currentLine;
var num_matching_lines = 0;
$("#mainOutput").empty();
$("LINE", g_playDOM).each(
function() {
currentLine = $(this).text();
matchesLine = currentLine.replace(regex_query,
'<span class="query_match">' + query + '</span>');
if (currentLine.search(regex_query) > 0)
num_matching_lines++;
$("#mainOutput").append("<p>" + matchesLine + "</p>");
});
$("#sideInfo").append(
"<p>Found " + query + " in " + num_matching_lines + " lines</p>");
}
$(document).ready(function() {
loadPlay();
$("#term_search").focus(function(event) {
$(this).val("");
});
$("#term_search").keypress(function(event) {
if (event.keyCode == 13)
searchResults($("#term_search").val());
});
$('#term-search-btn').click(function() {
searchResults($("#term_search").val());
});
});
</script>
Currently the number of lines the word is on is being shown correctly.
If you want a line of code to be executed within a conditional, then you need to place curly braces around it. Otherwise, only the very next action item will be executed. In your case, increase the count of the number of lines that match.
Your subsequent action item, appending the found line into the DOM is executed on every branch because the if statement has already done its job. Offending lines below:
if ( currentLine.search(regex_query) > 0 ) num_matching_lines++;
$("#mainOutput").append("<p>" + matchesLine + "</p>");
Fixed:
if ( currentLine.search(regex_query) > 0 ) {
num_matching_lines++;
$("#mainOutput").append("<p>" + matchesLine + "</p>");
}

Categories