Javascript/Ajax Request very erratic and random - javascript

I have been working on the following code and with help from #squint, I have got to a point where it appears to work, but very erratic and randomly.
Code Edited with #TomasZato suggestions
<%#LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<!--#include file="../Connections/DVerto.asp" -->
<%
Dim Recordset1
Dim Recordset1_cmd
Dim Recordset1_numRows
Set Recordset1_cmd = Server.CreateObject ("ADODB.Command")
Recordset1_cmd.ActiveConnection = MM_DVerto_STRING
Recordset1_cmd.CommandText = "SELECT Part_Number FROM dbo.Stock_Header WHERE Part_Number like '84%'"
Recordset1_cmd.Prepared = true
Set Recordset1 = Recordset1_cmd.Execute
Recordset1_numRows = 0
%>
<%
Dim Repeat1__numRows
Dim Repeat1__index
Repeat1__numRows = 10
Repeat1__index = 0
Recordset1_numRows = Recordset1_numRows + Repeat1__numRows
%>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head>
<body onLoad="loadDoc()">
<table width="50%" border="0" cellspacing="2" cellpadding="2">
<%
While ((Repeat1__numRows <> 0) AND (NOT Recordset1.EOF))
%>
<tr>
<td class="prodref"><%=(Recordset1.Fields.Item("Part_Number").Value)%></td>
<td class="demo"> </td>
</tr>
<%
Repeat1__index=Repeat1__index+1
Repeat1__numRows=Repeat1__numRows-1
Recordset1.MoveNext()
Wend
%>
</table>
<script>
// This creates array of elements with requested class name - eg. [HTMLElement, HTMLElement ...]
var elements = document.getElementsByClassName("prodref");
var outputElements = document.getElementsByClassName("demo");
// Allways check if there is correct number of demo elements to print loaded data in
if(elements.length != outputElements.length) {
console.error("The number of prodref and demo elements is not the same!");
}
// Loop through both arrays of elements and make AJAX request for every one of them
for (var i=0, length=elements.length; i < length; i++) {
loadDoc(elements[i], outputElements[i]);
}
function loadDoc(element, demoElement) {
console.log("creating loadDoc() call for element", element);
var xhttp = new XMLHttpRequest();
var url = "data.asp?prodref="+element.innerHTML;
// Onload calls if request was successful
xhttp.onload = function() {
console.log("loadDoc() call for element", element, "succeeded");
demoElement.innerHTML = xhttp.responseText;
};
// Error calls if there is an error
xhttp.onerror = function() {
console.error("There was some problem with the request for element",element," with url '", url, "', check the Net debug panel.");
}
// Do not make sync requests, that makes page lag. Just DON'T!!!
xhttp.open("GET", url, false);
xhttp.send();
}
</script>
</body>
</html>
<%
Recordset1.Close()
Set Recordset1 = Nothing
%>
Code (Data.asp)
<%#LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<!--#include file="../Connections/PSCRM.asp" -->
<%
Dim rs_proditem__MMColParam
rs_proditem__MMColParam = "1"
If (Request.QueryString("prodref") <> "") Then
rs_proditem__MMColParam = Request.QueryString("prodref")
End If
%>
<%
Dim rs_proditem
Dim rs_proditem_cmd
Dim rs_proditem_numRows
Set rs_proditem_cmd = Server.CreateObject ("ADODB.Command")
rs_proditem_cmd.ActiveConnection = MM_PSCRM_STRING
rs_proditem_cmd.CommandText = "SELECT * FROM dba.proditem as t1 LEFT JOIN dba.proditem_xtra as t2 ON t1.prodref=t2.prodref WHERE t1.prodref = ? and rber_mi_source = 'M'"
rs_proditem_cmd.Prepared = true
rs_proditem_cmd.Parameters.Append rs_proditem_cmd.CreateParameter("param1", 200, 1, 25, rs_proditem__MMColParam) ' adVarChar
Set rs_proditem = rs_proditem_cmd.Execute
rs_proditem_numRows = 0
%>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
</head>
<div class="demo"><%=(rs_proditem.Fields.Item("proddesc").Value)%></div>
<body>
</body>
</html>
<%
rs_proditem.Close()
Set rs_proditem = Nothing
%>
When the page loads, some results are seen, sometimes returns 2 results, then more. Sometimes it misses a row out.
I have also noticed that on load the data in the third column <td class='demo'></td> which is being pulled from data.asp seems to change while the page is still loading?
Any help would be greatly accepted.

The problem is that you produced totally obscure code and you forgot what it's doing. First to the cause - I actually don't understand how come it ever works. First you do this:
a[i] = document.getElementsByClassName("prodref").innerHTML;
This is wrong because
a is HTMLElementCollection and is not supposed to be changed
document.getElementsByClassName("prodref") is an also HTMLElementCollection and has no property innerHTML
a[i] should now contain undefined, but since HTMLElementCollection array is immutable this code just doesn't do anything.
After this, you try to do this - technically it should work, because your wrong code above didn't do anything:
xhttp.open("GET", "data.asp?prodref="+a[i].innerHTML, true);
But it fails, which indicates there's an error you're hiding from me (eg. problem in the VBS script).
Fixed code with remarks
I decided to clean up and comment your code:
// This creates array of elements with requested class name - eg. [HTMLElement, HTMLElement ...]
var elements = document.getElementsByClassName("prodref");
var outputElements = document.getElementsByClassName("demo");
// Allways check if there is correct number of demo elements to print loaded data in
if(elements.length != outputElements.length) {
console.error("The number of prodref and demo elements is not the same!");
}
// Loop through both arrays of elements and make AJAX request for every one of them
for (var i=0, length=elements.length; i < length; i++) {
loadDoc(elements[i], outputElements[i]);
}
function loadDoc(element, demoElement) {
console.log("creating loadDoc() call for element", element);
var xhttp = new XMLHttpRequest();
var url = "data.asp?prodref="+element.innerHTML;
// Onload calls if request was successful
xhttp.onload = function() {
console.log("loadDoc() call for element", element, "succeeded");
demoElement.innerHTML = xhttp.responseText;
};
// Error calls if there is an error
xhttp.onerror = function() {
console.error("There was some problem with the request for element",element," with url '", url, "', check the Net debug panel.");
}
// Do not make sync requests, that makes page lag. Just DON'T!!!
xhttp.open("GET", url, false);
xhttp.send();
}
Of course, since you decided not to provide a good test page, I couldn't test this code.

Related

how to make an Ajax request to a URL and append the url with query string in order to run the url program

I am trying to get information from a form without using a submit button. First I need to build a query string and then I need to make an ajax request to a URL that contains a program that will take the information from the forms to calculate the mileage from one city to the other. here is my http file:
<!DOCTYPE html>
<html>
<head>
<title>Mileage Calculator</title>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
</head>
<body>
<h1>Mileage Calculator</h1>
<form>
Start City<input type="text" id="startCity" name="startCity"></input><br><br>
Start State<input type="text" id="startState" name="startState"></input><br><br>
End City<input type="text" id="endCity" name="endCity"></input><br><br>
End State<input type="text" id="endState" name="endState"></input><br><br>
<input type="button" onclick="buildQuery()" value="Submit"></input>
</form>
<p id="justTry">Let's see if we can change this guy</p>
<script src="assign12.js"></script>
</body>
</html>
I am using an onclick event to call a javascript function that collects all the form info and arranges it into a query string. Here is that function "buildQuery()" :
function buildQuery() {
startcity = document.getElementById("startCity").value;
startstate = document.getElementById("startState").value;
endcity = document.getElementById("endCity").value;
endstate = document.getElementById("endState").value;
var params = {
startcity,
startstate,
endcity,
endstate
};
var esc = encodeURIComponent;
var query = Object.keys(params)
.map(k => esc(k) + '=' + esc(params[k]))
.join('&');
loadSite(query);
}
the buildQuery() function then calls the loadQuery(query) function which makes an ajax request. This is were I am having trouble. the query string must be appended to the URL so it can take the form info and calculate the mileage, but I'm not sure how to get that to happen. here is what I have so far:
function loadSite(query) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
appendQuery(this.responseText);
//document.getElementById("justTry").innerHTML = url;
}
};
var url = "/cgi-bin/ercanbracks/mileage/mileageAjaxJSON" + query;
xhttp.open("POST", "/cgi-bin/ercanbracks/mileage/mileageAjaxJSON", true)
xhttp.send();
}
what is the best way to accomplish this task?
thanks, Megan
First thing first, you should not manually select all the inputs with ids. Instead I would recommend selecting the inputs using querySelectorAll as below
function getFormPayload(formId){
const payload = {};
for(const input of document.querySelectorAll(`form#${formId} *[name]`)){
payload[input.getAttribute('name')] = input.value;
}
return payload;
}
With the function above you can then iterate through the value and create the query as you initially did.
p/s: Note that some elements like select doesn't have value attribute so you would need to wrap the value assign in an if statement. Good luck!

Get Azure Cosmos Table values to HTML

My goal is to change a text in my Html to a value from Azure Cosmos DB Table. How can I do that?
This is what I tried so far:
I'm using Azure Cosmos DB with the Table API. In this DB I have created a Table MyTable. In this Table I have one example entity:
Example Entity -> MyColumn: MyValue || MyColumn2: MyValue2 || ...
PartitionKey: 0 || RowKey: 0 || Text: MyText
I want MyText to be in an HTML. For this I created a WebApplication in VS2019 with this .html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link href="MyJS.js" />
<script type="text/javascript" src="MyJS.js"></script>
</head>
<body>
<button onclick="MyFunc()">whaddup</button>
<p id="MyId">text</p>
</body>
</html>
And this .js:
function MyFunc() {
var azure = require('azure-storage');
var tableSvc = azure.createTableService('myAccountName', 'myPrimaryKey', 'myEndpoint');
var query = new azure.TableQuery()
.where('PartitionKey eq ?', '0');
tableSvc.queryEntities('MyTable', query, null, function (error, result, response) {
if (!error) {
for (var key in result.entries) {
var value = result.entries[key];
for (var colName in value) {
var colVal = value[colName];
if (colName != ".metadata") {
var x = document.getElementById("MyId");
x.innerHTML = colVal._;
console.log(colName + ": " + colVal._);
}
}
}
}
});
}
The Html is just a button and a text. When clicking the button the text should change via the javascript.
The first error I encountered with this was 'require' is not defined when clicking the button. To fix this I used Browserify.
Then the next problem was that my function could not be found. I fixed this by changing function MyFunc() {...} to window.MyFunc = function() {...}.
And I ran into the next problem. When clicking the button I got this error:
Access to XMLHttpRequest at
'https://myAccountName.table.cosmos.azure.com/MyTable?%24filter=PartitionKey...'
from origin 'null' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Well I tried to fix this. I've seen something about using a proxy so I changed:
var tableSvc = azure.createTableService('myAccountName', 'myPrimaryKey', 'myEndpoint');
to this:
var tableSvc = azure.createTableService('myAccountName', 'myPrimaryKey', 'https://cors-anywhere.herokuapp.com/' + 'myEndpoint');
And now I got to this error when clicking the button:
GET
https://cors-anywhere.herokuapp.com/https://myAccountName.table.cosmos.azure.com/MyTable?%24filter=PartitionKey...
401 (Unauthorized)
And now last but not least two error messages that might be important to mention:
When going on this URL:
https://myAccountName.table.cosmos.azure.com/MyTable?%24filter=PartitionKey...
I get to see this:
{"odata.error":{"code":"MediaTypeNotSupported","message":{"lang":"en-us","value":"None of the provided media types are supported\r\nActivityId: someActivityIdHere, documentdb-dotnet-sdk/2.4.0 Host/64-bit MicrosoftWindowsNT/6.2.9200.0\nRequestID:someRequestIDhere\n"}}}
When visiting this URL:
https://cors-anywhere.herokuapp.com/https://myAccountName.table.cosmos.azure.com/MyTable?%24filter=PartitionKey...
I get to see this:
Missing required request header. Must specify one of: origin,x-requested-with

Having trouble understanding ajax calls

basically what I want to do is grab 5 images from the RSS feed and display them afterwards. Unfortunately the RSS items don't have links to images so what I do is grab the article URL from the RSS feed and then I use YQL to scan through the article to see if there is an image. The articles may or may not have an image and there can be 10 or more articles so I have to have a counter to determine when I get 5 images. That's where I'm having the problem, I can't figure out how to update the counter in the success part of the ajax call (I have also tried using an array but it didn't work).
I have seen other examples and I've been trying to do this since yesterday but I have had no luck. Maybe there are other easier ways to do this but I have no clue. Any help would be greatly appreciated.
Please see my code below.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>La Retama</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
$(document).bind('mobileinit',function(){
$.mobile.changePage.defaults.changeHash = false;
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
});
</script>
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<link rel="stylesheet" href="./my_style.css">
</head>
<body>
<div id="home" data-role="page" >
<div id="my_header" data-role="header">
<h1>Insert Page Title Here</h1>
</div>
<div data-role="main" class="ui-content">
</div>
<div id="my_footer" data-role="footer" data-position="fixed">
<h1>Insert Footer Text Here</h1>
</div>
</div>
</body>
<script>
var pagina7Arr = [];
var pagina7SSPArr = [];
/*Getting the RSS feed*/
$.ajax({
url: 'http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=10&callback=?&q=' + encodeURIComponent('http://web.paginasiete.bo/rss/feed.html?r=77'),
dataType : 'jsonp',
success : function (data) {
var myObject = data.responseData.feed.entries;
var how_many = 0;
for (var i=0; i < myObject.length;i++){
var article_url = myObject[i].link;
var YQL_link = checkPagina7URL(article_url)
var YQL = "https://query.yahooapis.com/v1/public/yql?q=SELECT%20*%20FROM%20data.html.cssselect%20WHERE%20url%3D'"+YQL_link+"'%20AND%20(css%3D'.fotoNota-ext%20'%20OR%20css%3D'.fotoNota')&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";
pagina7Arr.push(YQL)
}
pageImages(pagina7Arr)
}
});
/* Here is where I want to store the 5 images */
function pageImages(input){
var module = 0;
var testarr=[];
for (var i=0; i<input.length; i++){
$.ajax({
url: input[i],
dataType : 'jsonp',
success : function (data) {
/*I would like to update a counter here or insert images to an array I can use later on*/
try{
testarr.push(data.query.results.results[0].div.img.src);
}catch(err){
try{
testarr.push(data.query.results.results[1].div.img.src);
}catch(err){
}
}
}
});
console.log("array: "+testarr.length)
}
}
/*Formatting the page URL to insert into YQL call*/
function checkPagina7URL (data){
data = data.substr(data.indexOf('.bo')+4,data.length);
var section = data.substr(0, data.indexOf('/'));
data = data.substr(data.indexOf('/')+1,data.length)
var year = data.substr(0,data.indexOf('/'))
data = data.substr(data.indexOf('/')+1,data.length);
var month = data.substr(0,2);
if(month.indexOf('/') != -1){
month = data.substr(0,1);
}else{
month = data.substr(0,2);
}
data = data.substr(data.indexOf('/')+1,data.length);
var day = data.substr(0,2);
if(day.indexOf('/') != -1){
day = data.substr(0,1);
}else{
day = data.substr(0,2);
}
data = data.substr(data.indexOf('/')+1,data.length);
var page_link = data.substr(data.indexOf('/')+1,data.length);
var result = "http%3A%2F%2Fwww.paginasiete.bo%2F"+section+"%2F"+year+"%2F"+month+"%2F"+day+"%2F"+page_link;
return result;
}
</script>
</html>
When you make $.ajax({}) call, the success is called asynchronously. So when you are calling this line:
console.log("array: "+testarr.length)
It is too early to count the images, so what is happening here is that you are calling ALL the pages, and fetching the images for all of them. You can certainly do that, but then you have to stop calling testarr.push after your counter becomes >=5. (The counter check should be just before you make such push call)
A more efficient way, would be to fetch only what you need (though will be slower due to syncronousity) and that is by only making subsequent url calls from within the success function of previous call. The above should be easy to do.
You can also do more fancy work (though trickier to code), doing hybrid, fetching 5 urls async, then see in the success callback if you got 5 images you stop, if not, make (5-counter) async requests of the remaining page urls.

Javascript not rendering - Blank head

There's something wrong with my script, it doesn't render the JS correctly. I tried to pinpoint the problem but cannot find any typo. If i load the page, the tag is blank, making all css & other JS disabled. But suprisingly the data is loader correctly. If i remove the script, everything went to normal.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="jquery-1.9.1.js"></script>
<script src="jquery-ui.js"></script>
<script>
// Create a connection to the file.
var Connect = new XMLHttpRequest();
// Define which file to open and
// send the request.
Connect.open("GET", "Customers.xml", false);
Connect.setRequestHeader("Content-Type", "text/xml");
Connect.send(null);
// Place the response in an XML document.
var TheDocument = Connect.responseXML;
// Place the root node in an element.
var Customers = TheDocument.childNodes[0];
// Retrieve each customer in turn.
$("#middle").ready( function () {
document.write("<ul class='product'>");
for (var i = 0; i < Customers.children.length; i++)
{
var dul = "wawa"+[i];
//document.getElementById(dul).addEventListener('click', storeData, false);
var Customer = Customers.children[i];
// Access each of the data values.
var Pic = Customer.getElementsByTagName("pic");
var Name = Customer.getElementsByTagName("name");
var Age = Customer.getElementsByTagName("tipe");
var sex = Customer.getElementsByTagName("country");
var checked = window.localStorage.getItem("selected"+i);
// Write the data to the page.
document.write("<li><img href='./pic/");
document.write(Pic[0].textContent.toString());
document.write(".jpg'><a href='display.html?id="+i+"'>");
document.write(Name[0].textContent.toString());
document.write("</a><div class='age'>");
document.write(Age[0].textContent.toString());
document.write("</div><div class='sex'>");
document.write(sex[0].textContent.toString());
document.write("</div><div class='cex'>");
document.write("<input name='checkbox' type='checkbox' id='wawa_"+i+"'");
if (!checked) {
document.write(" onClick='cbChanged(this, "+i+")'");
} else {
document.write("checked onClick='cbChanged(this, "+i+")'");
}
document.write("></div></li>");
}
document.write("</ul>");
});
function cbChanged(checkboxElem, x) {
if (checkboxElem.checked) {
window.localStorage.setItem("selected"+x, x);
alert("That box was checked.");
} else {
window.localStorage.removeItem("selected"+x);
alert("That box was unchecked.");
}
}
</script>
</head>
<body>
<div class="container">
<div class="content" id="middle">
</div>
<div class="content" id="footer">
</div>
</div>
</body>
</html>
Ok here's the full source.
You don't close the HTML img tag right
Change
document.write("<li><img href='./pic/");
document.write(Pic[0].textContent.toString());
document.write("'.jpg><a href='display.html?id="+i+"'>");
// ^ this quote
To
document.write("<li><img href='./pic/");
document.write(Pic[0].textContent.toString());
document.write(".jpg'><a href='display.html?id="+i+"'>");
// ^ should be here
If you open the developer console you can usually see where errors like this take place. It will also output and javascript errors that you come across so it will make that part a whole lot easier. Do you have any errors in your console?
The dev consoles are:
Chrome: It is built it.
Firefox: Firebug
Safari: It's built it
EDIT:
Don't do var functionName = function() {..} unless you know about how hoisting works. This is contributing to you problem so change
cbChanged = function(checkboxElem, x) {
if (checkboxElem.checked) {
window.localStorage.setItem("selected"+x, x);
alert("That box was checked.");
} else {
window.localStorage.removeItem("selected"+x);
alert("That box was unchecked.");
}
}
To
function cbChanged(checkboxElem, x) {
if (checkboxElem.checked) {
window.localStorage.setItem("selected"+x, x);
alert("That box was checked.");
} else {
window.localStorage.removeItem("selected"+x);
alert("That box was unchecked.");
}
}
Without the above changes the function cbChanged is not hoisted. So if you call it before it is reached you will get an error.
There are several other things that stand out to me on this. You might want to spend some more time on your javascript fundamentals. Read up on why document.write is a bad thing. Try removing parts of the script to narrow down what is causing the problem. It would have made this easier to fix if you had made a fiddle.

How to grab text from URL and place in JS array?

I've stated previously that I am very new to JavaScript and HTML. I'm creating a small search tool and I'm very confused as to how to get text from a URL and put it in my JS array.
For example, let's say the URL is: http://www.somethingrandom.com/poop
In that URL, there's a couple of words: "something", "everything", "nothing"
Literally just that. It's in a pre tag in HTML, and that's it.
Now, my JS code, I want it to open up that URL, and take those words and place them in a string/list/array, whatever, it could be anything as long as it can happen, I can manipulate it further later.
I have this so far:
<html>
<head>
<script type = "text/javascript">
function getWords(){
var url = "http://www.somethingrandom.com/poop"
var win = window.open( url );
window.onload = function(){
var list = document.getElementsByTagName("pre")[0].innerHTML;
var listLength = list.length;
alert( listLength);
}
}
</script>
</head>
<body>
<button id="1" onClick="getWords();">Click Here</button>
</body>
</html>
It doesn't work however.. And I'm not sure why. :( Please help.
Make an AJAX request and you will have access to the returned content.
Using jQuery:
function getWords(){
var url = "http://www.somethingrandom.com/poop"
$.get(url, function(data) {
var list = $('pre:eq(0)', data).html;
var listLength = list.length;
alert( listLength);
}, 'html');
}

Categories

Resources