Showing matching lines from a search using jquery - javascript

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>");
}

Related

If-else statment not working after else is added

I am trying to write a search fnction for an address book which loops through the array of contacts and shows them in a popup. It first worked fine finding and showing the found contacts. After adding the else statement, only "none found" runs. I've tried switching the order and negating the first statement, but that does not work.
$(document).ready(function(){
newSearch.click(function(){
const inputValue = $('#searchcontacts').val();
for(let i = 0; i < contactList.length; i++){
if(inputValue.toUpperCase() === contactList[i].firstName.toUpperCase()){
resultsContent.text(contactList[i].firstName +
" " + contactList[i].lastName +
" " + contactList[i].phoneNumber +
" " + contactList[i].addressText);
} else {
}
};
resultsContent.text('None found')
});
});
You have always set the resultsContent.text('None found') after for loop is executed.
So even if a contact found and that contact is set to the resultsContent, it will be replaced by the resultsContent.text('None found') line
Following code snippet will do the job for you. But I have seen another issue with this code that only the last found contact will be shown in the resultsContent element since you have not accumulated the found results. If you need to show all the contacts you need to accumulate all of them and show
newSearch.click(function(){
const inputValue = $('#searchcontacts').val();
var hasContacts = false;
for(let i = 0; i < contactList.length; i++){
if(inputValue.toUpperCase() === contactList[i].firstName.toUpperCase()){
resultsContent.text(contactList[i].firstName +
" " + contactList[i].lastName +
" " + contactList[i].phoneNumber +
" " + contactList[i].addressText);
hasContacts = true;
} else {
}
};
if( !hasContacts) {
resultsContent.text('None found');
}
});

why my for loop is infinite here

below is the js code for wikipedia search project. I am getting infinite for loop even though it had condition to stop repeating the loop. I am stuck in this problem.
$(document).ready(function() {
$('.enter').click(function() {
var srcv = $('#search').val(); //variable get the input value
//statement to check empty input
if (srcv == "") {
alert("enter something to search");
}
else {
$.getJSON('https://en.wikipedia.org/w/api.php?action=opensearch&search=' + srcv + '&format=json&limit=20&callback=?', function(json) {
$('.content').html("<p> <a href ='" + json[3][0] + "'target='_blank'>" + json[1][0] + "</a><br>" + json[2][0] + "</p>");
/*for loop to display the content of the json object*/
for (i = 1; i < 20; i++) {
$('p').append("<p><a href ='" + json[3][i] + "'target='_blank'>" + json[1][i] + "</a>" + json[2][i] + "</p>");
}
});
}
});
});
You are appending to each and every one of <p> in page.
Since your for loop appends even more <p> (and you possibly have a high number of <p> elements in your page beforehand) you overflow your call stack.
You probably wanted to append to a specific <p>. Try giving an id to your selector.
from what i can see in the url you need to do the following:
loop over the terms found and select the link based on the index of the element, chose a single element .contentto append the data not a set of elements p, this will increase the number of duplicated results
$.getJSON('https://en.wikipedia.org/w/api.php?action=opensearch&search='+srcv+'&format=json&limit=20&callback=?', function(json){
$.each(json[1],function(i,v){
$('.content').append("<p><a href ='"+json[2][i]+"'target='_blank'>"+json[0]+"</a>"+v+"</p>");
});
});
see demo: https://jsfiddle.net/x79zzp5a/
Try this
$(document).ready(function() {
$('.enter').click(function() {
var srcv = $('#search').val(); //variable get the input value
//statement to check empty input
if (srcv == "") {
alert("enter something to search");
}
else {
$.getJSON('https://en.wikipedia.org/w/api.php?action=opensearch&search=' + srcv + '&format=json&limit=20&callback=?', function(json) {
$('.content').html("<p> <a href ='" + json[3][0] + "'target='_blank'>" + json[1][0] + "</a><br>" + json[2][0] + "</p>");
/*for loop to display the content of the json object*/
var i = 1;
for (i; i < 20; i++) {
$('p').append("<p><a href ='" + json[3][i] + "'target='_blank'>" + json[1][i] + "</a>" + json[2][i] + "</p>");
}
});
}
});
});

toMatch Not Working

Does anyone know why this isn't passing?
function correctColorDisplay(message, player_turn, selector) {
if ((message > 0) && (player_turn != 0)) {
return $(selector).append("<li>" + message + " " + "color(s) are present but not in the correct position in Round " + player_turn + ".</li>");
}
}
Jasmine:
describe('#correctColorDisplay', function(){
it('returns a message to the user displaying if a correct color (not positions) was chosen', function(){
var message = 2
var playerTurn = 2
var selector = $('<li></li>')
correctColorDisplay(message,playerTurn, selector)
expect(selector).toMatch("<li>" + message + " " + "color(s) are present but not in the correct position in Round " + playerTurn + ".</li>")
});
});
The error I keep getting is this giant message: Expected { 0 : HTMLNode, length : 1, jquery : '1.11.0', constructor : Function, selector : '', toArray : Function, get : Function, pushStack : Function, each, etc (it goes on much longer)
You are trying to match a newly created HTMLNode with a regular expression (that is basically just a string in this case).
The toMatch function of Jasmine is for regular expressions.
I'm not entirely familiar with Jasmine, but I'm guessing you're looking for something like:
describe('#correctColorDisplay', function(){
it('returns a message to the user displaying if a correct color (not positions) was chosen', function() {
var message = 2;
var playerTurn = 2;
var selector = $('<li></li>');
selector = correctColorDisplay(message, playerTurn, selector);
expect(selector).toEqual( $("<li><li>" + message + " " + "color(s) are present but not in the correct position in Round " + playerTurn + ".</li></li>") );
});
});
If that doesn't work, I suggest you look into jasmine-jquery.

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.

AJAX search - no results returns last line

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')

Categories