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>");
}
});
}
});
});
Related
I am creating a search engine of sorts, using the Wikipedia API to query content. As it currently stands, the user can make a search input and the page returns the top 10 results with links and snippets. I run into difficulty when the user makes another search, in which case the page simply appends the original search results again. I have tried using replaceWith() and html(), but they either prevent the search results from coming through at all (if I put them within the event handler), or they don't get triggered (if they are outside the event handler). I am hoping to achieve a result where the user can make another input and the page will replace the current content with the new search results.
Here is what I have currently:
JS:
var results = [];
$("#search").on("keydown", "#searchinput", function(event) {
if (event.key === "Enter") {
var searchParameter = encodeURIComponent(this.value);
var link = "https://en.wikipedia.org/w/api.php?action=opensearch&search=" + searchParameter + "&limit=10&namespace=0&format=json&origin=*";
$.getJSON(link, function(data) {
for (var key in data) {
results.push(data[key]);
}
for (var i = 0; i < 10; i++) {
$("#results").append("<div class=\"resultContent\">" + "<h2>" + "" + results[1][i] + "" + "</h2>" + "<p>" + results[2][i] + "<br/>" + "</p>")
}
})
}
})
HTML:
Feeling Bold? Click Here for a Random Article
<div id="search">
<span>Search:</span>
<input type="text" id="searchinput" autocomplete="off"></input>
</div>
<div id="results"></div>
Thanks for the help!
You can remove the current results just before your loop:
$("#results").empty();
for (var i = 0; i < 10; i++) {
$("#results").append("<div class=\"resultContent\">" + "<h2>" + "" + results[1][i] + "" + "</h2>" + "<p>" + results[2][i] + "<br/>" + "</p>")
}
if (!mileage) {
valid = 0;
plateErrors = "Please tell us the Vehicle Mileage";
}
if (!price) {
valid = 0;
plateErrors = "We can't generate the report with out Price ";
}
if (valid == 1) {
window.open('https://www.carreport.ae/Home/VehicleInformationByPlate?siteID=1004' +
'&plateSource=' + plate_source + '&plateCode=' + plate_code + '&plateNumber=' + plate_number + '&mileage=' + mileage + '&price=' + price, '_blank');
} else {
var i;
alert(plateErrors);
$('#plateNumberError').removeClass('hidden');
//plateErrors.toString();
$.each(plateErrors, function(key, element) {
$("#plateNumberError").html("<p class='alert alert-danger' role='alert'>" + key + "</p>");
});
}
Above is my sample code:
what i need is I am having an array with error texts .I need to display each text in a P tag and insert all these P tags with error msg to a div.
When I use a for loop i am getting only the characters , not the whole string as one
make it
var plateErrors = [];
if (!mileage)
{
valid = 0;
plateErrors.push( "Please tell us the Vehicle Mileage" );
}
if (!price)
{
valid = 0; plateErrors.push( "We can't generate the report with out Price " );
}
if (valid == 1)
{
window.open('https://www.carreport.ae/Home/VehicleInformationByPlate?siteID=1004'
+ '&plateSource=' + plate_source + '&plateCode=' + plate_code + '&plateNumber=' + plate_number + '&mileage=' + mileage + '&price=' + price, '_blank');
}
else
{
var i;
alert(plateErrors);
$('#plateNumberError').removeClass('hidden'); //plateErrors.toString();
$.each(plateErrors ,function(key,element){
$("#plateNumberError").append( "<p class='alert alert-danger' role='alert'>" + element + "</p>"); });
}
You need to reaplace .html()by .append() :
$.each(plateErrors ,function(key,element){
$("#plateNumberError").append("<p class='alert alert-danger' role='alert'>" + key + "</p>");
});
It should works
you need to create an array first:
var plateErrors = [];
if (!mileage)
{
valid = 0;
plateErrors.push("Please tell us the Vehicle Mileage");
}
if (!price)
{
valid = 0;
plateErrors.push("We can't generate the report with out Price);
}
Use .html() instead of .append() to append HTML elements. This is the fastest way to append elements to DOM.
plateErrorsHtml = [];
$.each(plateErrors ,function(key,element){
plateErrorsHtml.push("<p class='alert alert-danger' role='alert'>" + element + "</p>");
});
$("#plateNumberError").html(plateErrorsHtml.join(''));
Here is the detailed discussion on this topic jquery .html() vs .append()
I am showing number counter in one of my section. When I add new betslips to the container the numbers are displaying correctly. However, when I delete any of the row the counter is not getting updated. For example if there are 3 rows numbered 1, 2 and 3 and if I delete row number 2 the updated values are 1 and 3. Infact the counter should reset to 1 and 2.
Here is my JS code
Adding the betslip rows
function createSingleBetDiv(betInfo) {
var id = betInfo['betType'] + '_' + betInfo['productId'] + '_' + betInfo['mpid'],
div = createDiv(id + '_div', 'singleBet', 'bet gray2'),
a = createA(null, null, null, null, 'right orange'),
leftDiv = createDiv(null, null, 'left'),
closeDiv = createDiv(null, null, 'icon_shut_bet'),
singleBetNumber = ++document.getElementsByName('singleBet').length;
// Info abt the bet
$(leftDiv).append('<p class="title"><b>' + singleBetNumber + '. ' + betInfo['horseName'] + '</b></p>');
var raceInfo = "";
$("#raceInfo").contents().filter(function () {
if (this.nodeType === 3) raceInfo = $(this).text() + ', ' + betInfo['betTypeName'] + ' (' + betInfo['value'] + ')';
});
$(leftDiv).append('<p class="title">' + raceInfo + '</p>');
// Closing btn
(function(id) {
a.onclick=function() {
removeSingleBet(id + '_div');
};
})(id);
$(a).append(closeDiv);
// Creating input field
$(leftDiv).append('<p class="supermid"><input id="' + id + '_input\" type="text"></p>');
// Creating WIN / PLACE checkbox selection
$(leftDiv).append('<p><input id="' + id + '_checkbox\" type="checkbox"><b>' + winPlace + '</b></p>');
// Append left part
$(div).append(leftDiv);
// Append right part
$(div).append(a);
// Appending div with data
$.data(div, 'mapForBet', betInfo);
return div;
}
Function to remove betslip
function removeSingleBet(id) {
// Remove the div
removeElement(id);
// Decrease the betslip counter
decreaseBetSlipCount();
// Decrease bet singles counter
updateBetSinglesCounter();
}
function decreaseBetSlipCount() {
var length = $("#racingBetSlipCount").text().length,
count = $("#racingBetSlipCount").text().substring(1, length-1),
text;
count = parseInt(count);
if (!isNaN(count)) count--;
if (count == 0) text = noSelections;
else text = count;
$("#racingBetSlipCount").text('(' + text + ')');
}
This could be done using only CSS, e.g:
DEMO jsFiddle
HTML:
<div id="bets">
<div class="bet"> some content</div>
<div class="bet"> some content</div>
<div class="bet"> some content</div>
</div>
CSS:
#bets {
counter-reset: rowNumber;
}
#bets .bet {
counter-increment: rowNumber;
}
#bets .bet::before {
content: counter(rowNumber);
min-width: 1em;
margin-right: 0.5em;
}
All row number will be updated automatically when adding/removing any row.
You can manage to do that with following steps;
Enclose bet no with span,
$(leftDiv).append('<p class="title"><b><span class="bet_no">' + singleBetNumber + '<span>. ' + betInfo['horseName'] + '</b></p>');
and I assume you have aouter div called "your_div"
Call below function after every increase and decrease event
function updateBetNo() {
var counter = 1;
$("#your_div .bet_no").each(function(i, val) {
$(this).text(counter);
counter++;
});
}
Make the betNumber findable:
$(leftDiv).append('<p class="title"><b><span class="singleBetNumber">' + singleBetNumber + '</span>. ' + betInfo['horseName'] + '</b></p>');
After an insert or delete renumber:
$('.singleBedNumber').each(function(idx, el) {
$(el).html('' + (idx + 1));
});
The first problem I see is that $("#racingBetSlipCount") is likely not selecting what you think it is. Since #racingBetSlipCount is an id selector it will only select one item.
To me you need to wrap the betnumber in something accessible so you can update it without having to parse through the title.
So first you would update the creation of the betTitle:
$(leftDiv).append('<p class="title"><b><span class=\'betNum\'>' + singleBetNumber + '</span>. ' + betInfo['horseName'] + '</b></p>');
Then you can loop through each and update the number appropriately.
var count = 1;
$.each($(".betNum"), function(){
$(this).html(count++);
});
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>");
}
var intFields = 0;
var maxFields = 10;
function addElement() {
"use strict";
var i, intVal, contentID, newTBDiv, message = null;
intVal = document.getElementById('add').value;
contentID = document.getElementById('content');
message = document.getElementById('message');
if (intFields !== 0) {
for (i = 1; i <= intFields; i++) {
contentID.removeChild(document.getElementById('strText' + i));
}
intFields = 0;
}
if (intVal <= maxFields) {
for (i = 1; i <= intVal; i++) {
intFields = i;
newTBDiv = document.createElement('div');
newTBDiv.setAttribute('id', 'strText' + intFields);
newTBDiv.innerHTML = "<input placeholder='recipient" + intFields + "#email.com' type='text' name='" + intFields + "'/><a href='javascript:removeElement();'><img id='strImg + " + intFields + "' src='images/minus.png' alt='Add A Field'/></a><input type='text' value='" + newTBDiv.id + "'/>";
contentID.appendChild(newTBDiv);
message.innerHTML = "Successfully added " + intFields + " fields.";
}
} else {
for (i = 1; i <= maxFields; i++) {
intFields = i;
newTBDiv = document.createElement('div');
newTBDiv.setAttribute('id', 'strText' + intFields);
newTBDiv.innerHTML = "<input placeholder='recipient" + intFields + "#email.com' type='text' name='" + intFields + "'/><a href='javascript:removeElement();'><img id='strImg + " + intFields + "' src='images/minus.png' alt='Add A Field'/></a><input type='text' value='" + newTBDiv.id + "'/>";
contentID.appendChild(newTBDiv);
message.innerHTML = "Unable to create more than 10 receipient fields!";
}
}
}
My script here dynamically adds up to 10 fields where users will be able to enter an email address and to the right of the text box i add an image of a minus sign that calls another script. I'm having trouble working out how to assign and keep track of the minus signs. I need to be able to have the minus sign script's recognize the text box it is by and remove it. I can write the remove script easily enough but I'm unsure of how to tell the image which text box to remove. Any help, suggestions, or comments are greatly appreciated.
Thanks,
Nick S.
You can add a class to the field called minus and then check through like that. I would suggest using jquery for this.
To add the class
$("#element").addClass("minus");
To remove all elements with that class
$("body input").each(function (i) {
if($(this).attr("class") == "minus"){
$(this).remove();
}
});
The two best options, imo, would be 1) DOM-traversal, or 2) manipulating ID fragments.
Under the first way, you would pass a reference to the element where the event takes place (the minus sign) and then navigate the DOM from there to the get the appropriate text box (in jQuery you could use $(this).prev(), for example).
Under the second way, you would assign a prefix or a suffix to the ID of the triggering element (the minus sign), and the same prefix or suffix to the target element (the text box). You can then (again) generate the appropriate ID for your target element by simple string manipulation of the ID from the triggering element.
Is that sufficient to get you started?
Try adding a class to the field and the same class to the minus sign.
So add this right after the setAttribute id,
newTBDiv.setAttribute('class', 'field' + intFields);
then just remove any elements that have that class.