Javascript - cycle through xml elements and display in turn - javascript

I am trying to create an application that will show, and periodically change, a paragraph of text (like a news article or similar).
I want the data to come from an xml file so other people can add stories/remove old stories etc.
I'm trying to get my JavaScript to populate a single html field with data from an xml file. Then after a given time, for now we'll say 4 seconds, it will change to the next piece of data.
Below is a very crude version of what I've been trying to do:
HMTL:
<head>
<script src="script.js"></script>
</head>
<body>
<div id="text"></div>
</body>
XML:
<document>
<text>one</text>
<text>two</text>
<text>three</text>
</document>
JavaScript:
var timer = setInterval(addText,4000);
var xhttp = new XMLHttpRequest();
xhttp.onreadystaechange = function() {
if(this.readyState == 4 && this.status == 200) {
addText(this);
}
};
function addText(xml) {
var xmlDoc = xml.responseXML;
var count = 0;
var max = xmlDoc.GetElementsByTagName("text");
document.getElementById("text").innerHTML =
xmlDoc.getElementByTagName("text")[count].childNodes[0].nodeValue;
if (count < max.length) {
count++;
} else {
count = 0;
}
}
xhttp.open("GET", "XMLFile.xml",true);
xhttp.send();
The current problem I am experiencing is that the first xml field populates successfully, but then I get an error saying "Unable to get property 'responseXML' of undefined or null reference".
Ideally what I'd also like is for the xml document to be opened everytime the function occurs, so the application doesn't have to be restarted if extra data is added to the xml file - if that makes sense (and is possible)

You can place addText in the scope of onreadystatechange handler. Something like this.
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if(this.readyState == 4 && this.status == 200) {
var xmlDoc = this.responseXML;
var count = 0;
var xText = xmlDoc.getElementsByTagName("text");
var max = xText.length;
var docText = document.getElementById("text");
function addText() {
//docText, xText and count are available from parent scope
docText.innerHTML =
xText[(count++) % max].childNodes[0].nodeValue;
}
var timer = setInterval(addText,4000);
}
};
xhttp.open("GET", "XMLFile.xml",true);
xhttp.send();

Related

Auto Link shorting via PHP&AJAX (bit.ly)

I would like to build a form (VIA POST METHOD) with just one field (url - link shortening). Now the question is how and if is it possible to build a form that detects the value of the URL field is a link and automatically shortens it rather than waiting you click Send (for exmaple like the web of Bit.ly).
The main idea is once the field is an identifier that value is a proper Hyperlink is directly sends and shortens (And the field is replaced by a shortened link) it without waiting for the click on the SEND.
index.html
<html>
<head>
<script>
function showHint(str) {
if (str.length == 0) {
document.getElementById("txtHint").innerHTML = "";
return;
} else {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("txtHint").innerHTML = this.responseText;
}
};
xmlhttp.open("GET", "gethint.php?q=" + str, true);
xmlhttp.send();
}
}
</script>
</head>
<body>
<p><b>Start typing a url in the input field below:</b></p>
<form>
Url: <input type="text" onkeyup="showHint(this.value)">
</form>
<p><span id="txtHint"></span></p>
</body>
</html>
gethint.php
<?php
// get the q parameter from URL
$q = $_REQUEST["q"];
$hint = "";
if (!filter_var($q, FILTER_VALIDATE_URL) === FALSE) {
// short the link
$rand = rand(1,1000);
$hint = 'http://domain.com/'.$rand; }
echo $hint === "" ? "Not a valid URL" : $hint; ?>
I'd use jQuery for the event triggering/AJAX and https://gist.github.com/dperini/729294 for weburl regex.
I'm not that at home on pure JavaScript AJAX calls, but is
xmlhttp.open("GET")
the right way to go at it if you want to make a POST?
Anyway the main thing you're missing is
function isUrl(url){
var regex = /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?#)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i;
if(regex.test(url)){
return regex.test(url);
}else{
return regex.test("http://"+url);
}
}
So this should be your new index.html
<html>
<head>
<script>
var extensions = [".aero",".biz",".cat",".com",".coop",".edu",".gov",".info",".int",".jobs",".mil",".mobi",".museum",".name",".net",".org",".travel",".ac",".ad",".ae",".af",".ag",".ai",".al",".am",".an",".ao",".aq",".ar",".as",".at",".au",".aw",".az",".ba",".bb",".bd",".be",".bf",".bg",".bh",".bi",".bj",".bm",".bn",".bo",".br",".bs",".bt",".bv",".bw",".by",".bz",".ca",".cc",".cd",".cf",".cg",".ch",".ci",".ck",".cl",".cm",".cn",".co",".cr",".cs",".cu",".cv",".cx",".cy",".cz",".de",".dj",".dk",".dm",".do",".dz",".ec",".ee",".eg",".eh",".er",".es",".et",".eu",".fi",".fj",".fk",".fm",".fo",".fr",".ga",".gb",".gd",".ge",".gf",".gg",".gh",".gi",".gl",".gm",".gn",".gp",".gq",".gr",".gs",".gt",".gu",".gw",".gy",".hk",".hm",".hn",".hr",".ht",".hu",".id",".ie",".il",".im",".in",".io",".iq",".ir",".is",".it",".je",".jm",".jo",".jp",".ke",".kg",".kh",".ki",".km",".kn",".kp",".kr",".kw",".ky",".kz",".la",".lb",".lc",".li",".lk",".lr",".ls",".lt",".lu",".lv",".ly",".ma",".mc",".md",".mg",".mh",".mk",".ml",".mm",".mn",".mo",".mp",".mq",".mr",".ms",".mt",".mu",".mv",".mw",".mx",".my",".mz",".na",".nc",".ne",".nf",".ng",".ni",".nl",".no",".np",".nr",".nu",".nz",".om",".pa",".pe",".pf",".pg",".ph",".pk",".pl",".pm",".pn",".pr",".ps",".pt",".pw",".py",".qa",".re",".ro",".ru",".rw",".sa",".sb",".sc",".sd",".se",".sg",".sh",".si",".sj",".sk",".sl",".sm",".sn",".so",".sr",".st",".su",".sv",".sy",".sz",".tc",".td",".tf",".tg",".th",".tj",".tk",".tm",".tn",".to",".tp",".tr",".tt",".tv",".tw",".tz",".ua",".ug",".uk",".um",".us",".uy",".uz", ".va",".vc",".ve",".vg",".vi",".vn",".vu",".wf",".ws",".ye",".yt",".yu",".za",".zm",".zr",".zw"];
var delay = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
function isUrl(url){
var regex = /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?#)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i;
if(regex.test(url)){
return regex.test(url);
}else{
return regex.test("http://"+url);
}
}
function showHint(str) {
delay(function(){
str = str.toLowerCase();
var dot = str.lastIndexOf(".");
var extension = str.substr(dot);
extension = extension.split('/')[0];
var found = $.inArray(extension, extensions) > -1;
if (!isUrl(str)||!found) {
document.getElementById("txtHint").innerHTML = "";
return;
} else {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("txtHint").innerHTML = this.responseText;
}
};
xmlhttp.open("GET", "gethint.php?q=" + str, true);
xmlhttp.send();
}
}, 500)
}
</script>
</head>
<body>
<p><b>Start typing a url in the input field below:</b></p>
<form>
Url: <input type="text" onkeyup="showHint(this.value)">
</form>
<p><span id="txtHint"></span></p>
</body>
</html>
edit: Say you will start typing in http://www.example.net.. The AJAX will trigger on "http://www.example.ne" and then again when you add the last letter. To avoid that, you might try "change" instead of "keyup" event.
edit2: Now checks against list of valid domain extensions
edit3: Now waits half a second before posting the result.
edit4: Small oversight while checking for extensions, fixed with
extension = extension.split('/')[0];
Also if you want to enable users to write URL's without "http://" and similar, you'll need an edited regex or write a small hack that adds that to your string before you send it into "isUrl()".

How to show php file output on Page where from it is called?

I have webpage on which i run a php file by javascript as given below
<script type="text/javascript">
var bhs = document.createElement('script');
var bhs_id = "yvw3lwc1tnvqfh4k4k4hisossew";
bhs.src = "//example.com/insert.php?site=" + bhs_id + "";
document.head.appendChild(bhs);
document.write("<span id='calc'></span>");
</script>
This JavaScript successfully insert data into insert.php file and then send to database. Besides i want to show one variable value generated in insert.php file in span id calc on a webpage where from above JavaScript is executed. How to do this? Thanks in advance.
It´s better use AJAX:
function loadDoc() {
var xhttp = new XMLHttpRequest();
var bhs_id = "yvw3lwc1tnvqfh4k4k4hisossew";
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
alert('OK!');
}
};
xhttp.open("GET", "//example.com/insert.php?site=" + bhs_id, true);
xhttp.send();
}
Reference:
http://www.w3schools.com/xml/ajax_intro.asp

Load text from local .txt file into html textarea using JavaScript

I have a <textarea> element and a button that calls a loadFile() JavaScript function. I want this function to allow me to load the text from a .txt file on my local machine into the textarea. Any help with this would be greatly appreciated!
You can use the File and FileReader objects to read local files.
You can use an input element with type="file" to allow the user to select a file.
<input id="myFile" type="file"/>
<textarea id="myTextArea" rows="4" columns="20"></textArea>
After the user has selected a file, you can get the File object from the input element. For example...
var file = document.getElementById("myFile").files[0];
You can then use a FileReader object to read the file into the text area. For example...
var reader = new FileReader();
reader.onload = function (e) {
var textArea = document.getElementById("myTextArea");
textArea.value = e.target.result;
};
reader.readAsText(file);
I found a old topic about this:
How do I load the contents of a text file into a javascript variable?
Have you read the last answer already? This works with a div instead of a textbox, but you could adapt the code a bit.
In the last piece of the last commenters post you could change this line:
document.getElementById("id01").innerHTML = out;
to:
document.getElementById("textbox01").innerHTML = out;
And in your HTML:
<textarea name="textbox01">Enter text here...</textarea>
Result:
function loadFile() {
var xmlhttp = new XMLHttpRequest();
var url = "file.txt";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myArr = JSON.parse(xmlhttp.responseText);
myFunction(myArr);
console.log("xmlhttp Request Asepted");
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
function myFunction(arr) {
var out = "";
var i;
var row = 0;
for(i = 0; i < arr.length; i++) {
// console.log( arr[1].data); change data to what every you have in your file
// out += arr[i].data + '<br>' + arr[i].data2 ;
document.getElementById("textbox01").innerHTML = out;
}
}
}

Multiple XMLHttpRequests not working

I am puzzled about this. I have two XMLHttpRequests that operate on Select elements of my HTML file (each one operates on a different Select element right when the HTML file is loaded). I am using a callback function as was recommended on W3CSchools. If my variable xmlHttp is defined outside of my callback function, only the second request works, and the first one gets deleted before it has a chance to finish. If I put 'var' in front of it the same thing happens. However, if my variable is inside the function with 'var' in front of it, then absolutely nothing happens. I have narrowed it down to where to the line that says "HERE!!!!!" is where the program seems to hang. I know the loadXMLDoc function does not actually finish because when I put an alert outside of it, nothing happens. I am supposing it has something to do with the 'if' part and the program not being able to recognize xmlHTTP, even though it was locally defined. I am still pretty new to JavaScript and just want to be able to run multiple XMLHttpRequest objects at once without them getting in each other's way but also without the page hanging. Any ideas why this does not work?
HTML:
<form>
<select id="stateSelectCities">
<!-- Will be populated with MySQL -->
</select>
<select id="citySelect">
<option>Select a State</option>
</select>
<br />
<br />
<select id="stateSelectCounties">
<!-- Will be populated with MySQL -->
</select>
<select id="countySelect">
<option>Select a State</option>
</select>
<p id="xmltest"></p>
<p id="currentState"></p>
<p id="sc"></p>
<p id="rs"></p>
<p id="st"></p>
</form>
JavaScript:
<script type="text/javascript">
function loadXMLDoc(method, data, url, cfunc) {
var xmlHTTP = new XMLHttpRequest();
xmlHTTP.onreadystatechange = cfunc;
xmlHTTP.open(method, url, true);
if (data) {
xmlHTTP.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlHTTP.send(data);
} else {
xmlHTTP.send();
}
}
function returnStateListForCounties() {
loadXMLDoc('GET', null, "stateslist.xml", function() {
document.getElementById('countySelect').disabled = true;
if (xmlHTTP.readyState == 4 && xmlHTTP.status == 200) {
// Read the XML Data and Populate Counties States Menu
var response = xmlHTTP.responseXML;
var states = response.getElementsByTagName('state');
for (i = 0; i < states.length; i++) {
var option = document.createElement('option');
option.innerHTML = states[i].childNodes[0].nodeValue;
option.setAttribute('onmouseup', 'returnCounties(this.innerHTML)');
document.getElementById("stateSelectCounties").add(option);
}
}
//document.getElementById("sc").innerHTML = 'statusCode: ' + xmlHTTP.status;
//document.getElementById("rs").innerHTML = 'readyState: ' + xmlHTTP.readyState;
//document.getElementById("st").innerHTML = 'statusText: ' + xmlHTTP.statusText;
})
}
function returnStateListForCities() {
loadXMLDoc('GET', null, 'stateslist.xml', function() {
document.getElementById('citySelect').disabled = true;
// HERE!!!!!
if (xmlHTTP.readyState == 4 && xmlHTTP.status == 200) {
// Read the XML Data and Populate Cities States Menu
var response = xmlHTTP.responseXML;
var states = response.getElementsByTagName('state');
for (i = 0; i < states.length; i++) {
var option = document.createElement('option');
option.innerHTML = states[i].childNodes[0].nodeValue;
option.setAttribute('onmouseup', 'returnCities(this.innerHTML)');
document.getElementById("stateSelectCities").add(option);
}
}
document.getElementById("sc").innerHTML = 'statusCode: ' + xmlHTTP.status;
document.getElementById("rs").innerHTML = 'readyState: ' + xmlHTTP.readyState;
document.getElementById("st").innerHTML = 'statusText: ' + xmlHTTP.statusText;
})
}
//returnStateListForCounties();
returnStateListForCities();
</script>
The problem here is xmlHTTP variable which is defined inside loadXMLDoc function and try to use again inside returnStateListForCounties function, I'll do it like this:
function loadXMLDoc(method, data, url, cfunc) {
var xmlHTTP = new XMLHttpRequest();
xmlHTTP.onreadystatechange = function() {
if (xmlHTTP.readyState == 4 && xmlHTTP.status == 200)
{
cfunc(xmlHTTP.responseXML); //Call passed func with the resulting XML
}
};
xmlHTTP.open(method, url, true);
if (data) {
xmlHTTP.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlHTTP.send(data);
} else {
xmlHTTP.send();
}
}
This way you encapsulate the data recovery.

Load a JavaScript event the last in CRM form

I have one image saved in Notes with every form in my CRM Online 2013 custom entity. I am using the following code to query the image and show it in an Image tag in a Web Resource on the form. For debugging purposes I was calling the following code through a button, but I want this process of querying the Notes and displaying the image in the web resource to be automatic when the form load. Here is my code:
<html><head><meta charset="utf-8"></head>
<body>
<img id="image" src="nothing.jpg" style="width: 25%; height: auto;" />
<script type="text/javascript">
$(windows).load(function()
{
var recordId = window.parent.Xrm.Page.data.entity.getId();
var serverUrl = Xrm.Page.context.getServerUrl().toString();
var ODATA_ENDPOINT = "XRMServices/2011/OrganizationData.svc";
var objAnnotation = new Object();
ODataPath= serverUrl+ODATA_ENDPOINT;
var temp= "/AnnotationSet?$select=DocumentBody,FileName,MimeType,ObjectId&$filter=ObjectId/Id eq guid'" + recordId + "'";
var result =serverUrl + ODATA_ENDPOINT + temp;
var retrieveRecordsReq = new XMLHttpRequest();
retrieveRecordsReq.open('GET', ODataPath + temp, false);
retrieveRecordsReq.setRequestHeader("Accept", "application/json");
retrieveRecordsReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
retrieveRecordsReq.onreadystatechange = function ()
{
if (this.readyState == 4 /* complete */)
{
if (this.status == 200)
{
this.onreadystatechange = null; //avoids memory leaks
var data = JSON.parse(this.responseText, SDK.REST._dateReviver);
if (data && data.d && data.d.results)
{
SuccessFunc(JSON.parse(this.responseText, SDK.REST._dateReviver).d.results);
}
}
else
{
alert(SDK.REST._errorHandler(this));
}
}
};
var x = new XMLHttpRequest();
x.open("GET", result, true);
x.onreadystatechange = function ()
{
if (x.readyState == 4 && x.status == 200)
{
var doc = x.responseXML;
var title = doc.getElementsByTagName("feed")[0].getElementsByTagName("entry")[0].getElementsByTagName("content")[0].getElementsByTagName("m:properties")[0].getElementsByTagName("d:DocumentBody")[0].textContent;
document.getElementById('image').src ="data:image/png;base64,"+title;
}
};
x.send(null);
});
</script>
</body></html>
I have removed the button tag..now I want this the query to happen on page Load, but nothing happens when I refresh the form. In my opinion the function loads before the annotation loads. Is there a way to make it wait and load the last?
If you want to wait for the parent window to load I think $(windows).load(myFunction); should do the trick.
Maybe $ is undefined because you did not add jQuery to your webressource.
There are also a few little mistakes and unattractive things:
First:
You will get a wrong server url.
If you want to access the Xrm-object in a webresource you always have to use window.parent.Xrm or you put it in a variable var Xrm = window.parent.Xrm;
For example:
var Xrm = window.parent.Xrm;
var recordId = Xrm.Page.data.entity.getId();
var serverUrl = Xrm.Page.context.getServerUrl().toString();
Second:
The ODataPath variable is not declared. Use var ODataPath= serverUrl+ODATA_ENDPOINT; instead. By the way the value of the ODataPath has nothing to do with OData. It is more the REST-Endpoint of Dynamics CRM.
My script would look like this:
var Xrm, recordId, serverUrl, restEndpointUrl, odataQuery, fullRequestUrl, xmlRequest;
Xrm = window.parent.Xrm;
recordId = Xrm.Page.data.entity.getId();
serverUrl = Xrm.Page.context.getServerUrl().toString();
restEndpointUrl = serverUrl + "/XRMServices/2011/OrganizationData.svc";
^ I think a '/' was missing there
odataQuery = "/AnnotationSet?$select=DocumentBody,FileName,MimeType,ObjectId&$filter=ObjectId/Id eq guid'" + recordId + "'";
fullRequestUrl = restEndpointUrl + odataQuery;
I also dont understand why you use the second HttpRequest.
All of this code is not tested.

Categories