Simple book search app: how to replace search results on second search? - javascript

I have a simple app that searches the Google Books API and returns a list of public domain books. The user can then open the free book and read it.
The problem is, if you search more than once, it appends the next search results to the page.
Is there a way to have the results of the second search "replace" the first results?
fiddle: http://jsbin.com/welcome/52020
<form name="inputForm"
onsubmit="beginSearch(this.query.value); return false;"
method="get">
<input type="text" size="30" name="query" value="Romeo and Juliet" id="textfield"/>
<input type="submit">
</form>
<div id="lister">
</div>
//for list
function beginSearch(query) {
var script = document.createElement("script");
script.src = 'https://www.googleapis.com/books/v1/volumes?q='
+ encodeURIComponent(query) + '&filter=free-ebooks'
+ '&callback=handleResultsList';
script.type = "text/javascript";
document.getElementsByTagName("head")[0].appendChild(script);
}
//structure results
function handleResultsList(response) {
for (var i = 0; i < response.items.length; i++) {
var item = response.items[i];
var title = item.volumeInfo.title;
var thumb = item.volumeInfo.imageLinks.thumbnail;
link = item.accessInfo.webReaderLink + '&output=embed'; // cache value
var img = $("<img/>").attr("src", thumb);
var booklink = "booklink";
var bookframe = "bookframe";
$("<a/>").attr({class: booklink, href: link, title: title}).append(img).appendTo("#lister");
}
}

Since you're using jQuery, its should be as easy as doing something like this:
//structure results
function handleResultsList(response) {
$('#lister').find('a').remove(); // Remove all existing links before adding new
for (var i = 0; i < response.items.length; i++) {
var item = response.items[i];
var title = item.volumeInfo.title;
var thumb = item.volumeInfo.imageLinks.thumbnail;
link = item.accessInfo.webReaderLink + '&output=embed'; // cache value
var img = $("<img/>").attr("src", thumb);
var booklink = "booklink";
var bookframe = "bookframe";
$("<a/>").attr({class: booklink, href: link, title: title}).append(img).appendTo("#lister");
}
}

Change the onsubmit to
$("#lister").html(""); beginSearch(this.query.value); return false;

Related

Modifying URL with javascript

I have some simple code that allows you to enter Amazon isbns/asins and converts them to hyperlinks. These hyperlinks are Amazon.com searches for the said isbn/asin.
Example pic: http://imgur.com/a/rYgYt
Instead of the hyperlink being a search I would like the link to go directly to the products offer page.
The desired link would be as follows:
https://www.amazon.com/gp/offer-listing/ASIN/ref=dp_olp_used?ie=UTF8&condition=used
"ASIN" would be where the ASIN/ISBN would need to be populated to generate the link, for example:
Im asking if someone could help modify my existing code to create the change. My skills lack the ability to implement the change. The existing code is as follows:
<html>
<head>
</head>
<div><b>ISBN Hyperlinker</b></div> <textarea id=numbers placeholder="paste isbn numbers as csv here" style="width:100%" rows="8" >
</textarea> <div><b>Hyperlinked text:</b></div> <div id="output" style="white-space: pre"></div>
<input type="button" id="button" Value="Open All"/>
<script>
var input = document.getElementById('numbers');
var button = document.getElementById('button');
var output = document.getElementById('output')
var base =
'https://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords='
var urls = []
//adding an event listener for change on the input box
input.addEventListener('input', handler, false);
button.addEventListener('click', openAllUrls, false);
//function that runs when the change event is emitted
function handler () {
var items = input.value.split(/\b((?:[a-z0-9A-Z]\s*?){10,13})\b/gm);
urls=[];
// Build DOM for output
var container = document.createElement('span');
items.map(function (item, index) {
if (index % 2) { // it is the part that matches the split regex:
var link = document.createElement('a');
link.textContent = item.trim();
link.setAttribute('target', '_blank');
link.setAttribute('href', base + item);
container.appendChild(link);
urls.push(base + item);//add the url to our array of urls for button click
} else { // it is the text next to the matches
container.appendChild(document.createTextNode(item))
}
});
// Replace output
output.innerHTML = '';
output.appendChild(container);
}
function openAllUrls(){
for(var i=0; i< urls.length; i++){//loop through urls and open in new windows
window.open(urls[i]);
}
}
handler(); // run on load
</script>
</html>
to modify output URL, replace
var base = ".....';
with
var basePrefix = 'https://www.amazon.com/gp/offer-listing/';
var baseSuffix = '/ref=dp_olp_used?ie=UTF8&condition=used';
and replace
base + item
with
basePrefix + item + baseSuffix

How can I create a link based on this format: google->someword?

I want to create links, based on a specific format.
When I type this:
google->apple
I want get get this link:
https://www.google.hu/search?q=apple
I tried this way, but unfortunately it is not working:
//Intelligent actions start
function replace(){
var str = $('.smile').html();
var re = /google->([^ \n$]+)/g;
var url = "https://www.google.hu/search?q=" + re.exec(str)[1];
}
//Intelligent actions end
Update
Based #vinayakj answer, I start create a solution for this:
//Intelligent actions start
function googleSearch(val){
var url = "https://www.google.hu/search?q=" + val.split('->')[1];
alert(url)
//location.href = url;
}
$( document ).ready(function() {
googleSearch($('.comment-content p').text())
$( ".comment-content p" ).replaceWith( "<a href='url'>url</a>" );
});
//Intelligent actions end
And looks like replacewith function reaplce all content in
.comment-content p
with:
url
And this function it has some problem:
Reaplce all text even if dosen't find this sting in div:
google-->some word
The link is absolute incorrect becouse I get back this value everywhere:
url
What am I doing wrong?
function googleSearch(val){
var url = "https://www.google.hu/search?q=" + val.split('->')[1];
alert(url)
location.href = url;
}
<input onchange="googleSearch(this.value)" type=text>
Here is the final solution after all your comments
var urls = {
"google":"https://google.com/search?q=#",
"bing":"https://....q=#&bla=bla"};
function getUrl(str) {
var parts = str.split("->");
var url = urls[parts[0]].replace("#",encodeURI(parts[1]));
return = $("<a/>",{href: url, class:parts[0]+"-search"}).text("Keresés ..."+parts[1]);
}
$(function() {
$("div.comment-content > p.smile").each(function() {
var $link = getLink($(this).text());
$(this).html($link);
});
});
Old answer
var urls = {
"google":"https://google.com/search?q=#",
"bing":"https://....q=#&bla=bla"};
function getUrl(str) {
var parts = str.split("->");
return urls[parts[0]].replace("#",parts[1]);
}
window.onload=function() {
document.getElementById("myForm").onsubmit=function() {
var str = document.getElementById("q").value;
var url = getUrl(str);
if (url) alert(url); // location.href=url;
return false; // cancel the submit
}
}
<form id="myForm">
<input id="q" type="text">
</form>
I found the solution, but thanks for everybody:
$("div.comment-content > p.smile").each(function(){
var original = $(this).text();
var replaced = original.replace(/google->([^.\n$]+)/gi, '<a class="google-search" href="https://www.google.hu/search?q=$1" target="_blank">Keresés a googleben erre: $1</a>' );
$(this).html(replaced);
console.log("replaced: "+replaced);
});
$("a.google-search").each( function() {
this.href = this.href.replace(/\s/g,"%20");
});

Passing array -- scope

I want to pass an array from one external .js file to another.
Each of these files works fine by themselves, but I am having a problem passing the array from pickClass.js to displayStudent.js, and getting the names and "remaining" value to display in the html file. I know it has something to do with how the arrays are declared, but I can't seem to get it to work properly.
The first file declares the array choice:
(masterStudentList.js):
var class1 = ['Brown, Abe','Drifter, Charlie','Freed, Eve'];
var class2 = ['Vole, Ug','Xylo, William','Zyzzyx, Yakob'];
The second picks which array to use based on the radio buttons (pickClass.js):
var classPicked = array(1);
function randomize(){
return (Math.round(Math.random())-0.5); }
function radioResult(){
var chooseClass = document.getElementsByName("chooseClass");
for (i = 0; i < chooseClass.length; i++){currentButton = chooseClass[i];
if (currentButton.checked){
var selectedButton = currentButton.value;
} // end if
} // end for
var output = document.getElementById("output");
var response = "You chose ";
response += selectedButton + "\n";
output.innerHTML = response;
chosenClass = new Array();
if (selectedButton == "class1")
{chosenClass = class1;}
else
{chosenClass = class2;}
var text = "";
var nametext = "";
var i;
for (i = 0; i < chosenClass.length; i++) {
text += chosenClass[i]+ ' / ';
}
var showText = "";
l = chosenClass.length;
classPicked = Array(l);
for (var i = 0; i < l; ++i) {
classPicked[i] = chosenClass[i].split(', ').reverse().join(' ');
showText += classPicked[i]+ '<br>';
}
//return = classPicked;
document.getElementById("classList").innerHTML = classPicked;
} // end function
This works properly.
I then want to pass "classPicked" to another .js file (displayStudent.js) which will randomize the student list, loop and display the students for a few seconds, and then end with one student name.
basket = classPicked; //This is where the array should be passed
function randOrd(){
return (Math.round(Math.random())-0.5); }
function showBasket(){
mixedBasket = basket.sort( randOrd ); //randomize the array
var i = 0; // the index of the current item to show
document.getElementById("remaining").innerHTML = basket.length;
fruitDisplay = setInterval(function() {
document.getElementById('showStud')
.innerHTML = mixedBasket[i++]; // get the item and increment
if (i == mixedBasket.length) i = 0; // reset to first element if you've reached the end
}, 100); //speed to display items
var endFruitDisplay = setTimeout(function()
{ clearInterval(fruitDisplay);
var index = mixedBasket.indexOf(document.getElementById('showStud').innerHTML);
mixedBasket.splice(index,1);
}, 3500); //stop display after x milliseconds
}
Here is the html (master.html). It's just rough -- I'll be working on the layout later:
<html>
<head>
<script src="masterStudentList.js" type="text/javascript"></script>
<script src="pickClass.js" type="text/javascript"></script>
<script src="displayStudent.js" type="text/javascript"></script>
</head>
<body>
<h2>Choose Class</h2>
<form action = "">
<fieldset>
<input type = "radio"
name = "chooseClass"
id = "radSpoon"
value = "class1"
checked = "checked" />
<label for = "radSpoon">Class 1</label>
<input type = "radio"
name = "chooseClass"
id = "radFlower"
value = "class2" />
<label for = "radFlower">Class 2</label>
<button type = "button"
onclick = "radioResult()"> Choose Class
</button>
<div id = "output">
</fieldset>
</form>
</div>
<center>
<h1> <span id="chooseStud"></span><p></h1>
<script> var fruitSound = new Audio();
fruitSound.src = "boardfill.mp3";
function showFruitwithSound()
{
fruitSound.play(); // Play button sound now
showBasket()
}
</script>
Remaining: <span id = "remaining" ></span>
<p>
<button onclick="showFruitwithSound()">Choose Student</button>
</center>
pickedClassList = <p id = classList> </p>
</body>
</html>
You shouldn't use global variable like this (I encourage you to read more on this theme) and I'm not sure I understand what you're trying to do... but the solution of your issue should be to move the basket = classPicked; line into your showBasket method :
basket = classPicked; //This is where the array should be passed
function randOrd(){
return (Math.round(Math.random())-0.5);
}
function showBasket(){
// whatever
}
should be :
function randOrd(){
return (Math.round(Math.random())-0.5);
}
function showBasket(){
basket = classPicked; //This is where the array should be passed
// whatever
}
This way, each time you call showBasket, this method will use the last value of classPicked.
Otherwise, basket will always keep the reference on the first value of classPicked.
Why ? because each time you assign a new Array to the basket variable (classPicked = Array(l);) instead of changing directly it's content by :
emptying it : while (classPicked.length > 0) { classPicked.pop(); }
and then adding new data : classPicked.concat(chosenClass)
You can't pass things to files; you could call a function defined in displayStudent.js, pass it classPicked, and have it assign it to basket.
I noticed this at the end of your second chunk of code ...
} // end function
This could indicate the classPicked is declared inside a function (I don't see one on the code). Because it is inside function scope, your set of code that is trying to use it cannot.
Push the declaraction of classPicked outside of the function.
var classPicked = Array(1);
function thisusesclasspicked() {
...
Also, please start indenting your code properly, it will become much easier to maintain and read.
UPDATE FROM COMMENTS:
I see the declaration now ...
classPicked = Array(l);
for (var i = 0; i < l; ++i) {
classPicked[i] = chosenClass[i].split(', ').reverse().join(' ');
showText += classPicked[i]+ '<br>';
}
... however, you are re-assigning the array with an element of one just before you attempt to make modifications to it ... You are emptying it there: classPicked = Array(l);

Draw an information table in JS

I have this code using Harvard API that thakes all the CS courses and load them to a dropdownlist.
after picking a course I want to draw an table with all the information of the course, but for some reason I get this to work, the function just not fire (I think it's the issue).
can some one see the problem in the function i wrote?
<script type="text/javascript">
function loadXMLDoc() {
document.getElementById("span").style.visibility = "visible";
document.getElementById("button").style.visibility = "hidden";
$.ajax({
type: "GET",
url: "http://courses.cs50.net/api/1.0/courses?field=COMPSCI&output=xml",
success: function (data) {
var courses = data.documentElement.getElementsByTagName("course");
var options = document.createElement("select");
$(options).change(function () {
ShowCourseDetails(this);
});
for (var i = 0; i < courses.length; i++) {
var option = document.createElement("option");
option.value = $(courses[i]).find("cat_num").text();
option.text = $(courses[i]).find("title").text();
options.add(option, null);
}
document.getElementById("selectDiv").appendChild(options);
document.getElementById("span").style.visibility = "hidden";
}
});
}
//Get the Course information
function ShowCourseDetails(event) {
// get the index of the selected option
var idx = event.selectedIndex;
// get the value of the selected option
var cat_num = event.options[idx].value;
$.ajax({
type: "GET",
url: "http://courses.cs50.net/api/1.0/courses?output=xml&&cat_num=" + cat_num,
success: function (data) {
$("#TableDiv").html(ConvertToTable(data.documentElement));
}
});
}
//Draw The Table
function ConvertToTable(targetNode) {
targetNode = targetNode.childNodes[0];
// first we need to create headers
var columnCount = 2;
var rowCount = targetNode.childNodes.length
// name for the table
var myTable = document.createElement("table");
for (var i = 0; i < rowCount; i++) {
var newRow = myTable.insertRow();
var firstCell = newRow.insertCell();
firstCell.innerHTML = targetNode.childNodes[i].nodeName;
var secondCell = newRow.insertCell();
secondCell.innerHTML = targetNode.childNodes[i].text;
}
// i prefer to send it as string instead of a table object
return myTable.outerHTML;
}
</script>
the Markup:
<div class="left">
<input id="button" type="button" onclick="loadXMLDoc()" value="Get all Coputer Science Courses From Harvard"/>
<br />
<span id="span" style="visibility: hidden">Downloading Courses From Harvard.. Please Wait.. </span>
<div id="selectDiv"></div>
<div id="TableDiv"></div>
</div>
10x alot in advance.
To get it to call ShowCourseDetails I changed this code:
$(options).change(function () {
ShowCourseDetails(this);
});
To this:
$('select').change(function () {
ShowCourseDetails(this);
});
And moved it to the bottom of your callback function, under this:
document.getElementById("span").style.visibility = "hidden";
So that the event gets hooked up to the DOM element after it's been added. I then had to change this code:
$("#TableDiv").html(ConvertToTable(data.documentElement));
To this, since documentElement didn't seem to be defined:
$("#TableDiv").html(ConvertToTable(data.childNodes[0]));
Which then allowed me to just remove this line in your ConvertToTable function:
targetNode = targetNode.childNodes[0];
It still doesn't quite work since you are not navigating through the returned XML correctly. But I'll leave fixing that up to you.

Javascript: Problem regarding creating a dropdown list using javascript?

I'm trying to create a dropdown list from an array on my overlay (div element) using javascript.
In this example,
spcodelist = [u'CA125', u'HCM112', u'HCM147', u'HCM97', u'HKI128', u'HKI158', u'HKS161', u'HKS231', u'TKA230']
Here are related lines of code:
var pcode_form = document.createElement('form');
div.appendChild(pcode_form);
var pcode_select = document.createElement('select');
pcode_form.appendChild(pcode_select);
var i = 0;
var spcodelist = document.getElementById('spcodelist').value;
spcodelist = spcodelist.replace("[","");
spcodelist = spcodelist.replace("]","");
var spcodearr = new Array();
spcodearr = spcodelist.split(', ');
for (i=0;i<=spcodearr.length;i++){
spcodearr[i] = spcodearr[i].replace(/u'/g,"");
spcodearr[i] = spcodearr[i].replace(/'/g,"");
var pcode_option = document.createElement('option');
pcode_option.text = spcodearr[i];
pcode_option.value = spcodearr[i];
pcode_select.appendChild(pcode_option);
}
With this code, the dropdown list works fine but code after it will not work any more. I don't know what's the problem? How can I solve it? Or is there any better solution? Thank you very much.
I don't know what you are doing wrong, but the following works fine and should work in any browser. I've added a remove button so you can add and remove the select as often as you like.
<script type="text/javascript">
function addSelect(id) {
var div = document.getElementById(id);
var pcode_form = document.createElement('form');
pcode_form.id = 'f0';
div.appendChild(pcode_form);
var pcode_select = document.createElement('select');
pcode_form.appendChild(pcode_select);
var spcodelist = document.getElementById('spcodelist').value;
// Do replaces in one go
spcodelist = spcodelist.replace(/[\[\]\'u ]/g,'');
var spcodearr = spcodelist.split(',');
for (var i=0, iLen=spcodearr.length; i<iLen; i++) {
pcode_select.options[i] = new Option(spcodearr[i],spcodearr[i]);
}
}
</script>
<button onclick="addSelect('d0');">Add select</button>
<button onclick="
var el = document.getElementById('f0');
el.parentNode.removeChild(el);
">Remove form</button>
<div id="d0"></div>
<textarea id="spcodelist" style="display:none">[u'CA125', u'HCM112', u'HCM147', u'HCM97', u'HKI128', u'HKI158', u'HKS161', u'HKS231', u'TKA230']</textarea>

Categories

Resources