I am trying to create an IE11 compatible webpage which will sit on a few users desktops, which will grab some data from a JSON API and display it.
The user will type in their individual API key before pressing a button, revealing the API data.
Could you please help where my code has gone wrong? The error message I get from the console is: "Unable to get property 'addEventListener' of undefined or null reference. " So it looks like it is not even making the call to the API.
<script>
var btn = document.getElementById("btn");
var apikey = document.getElementById("apikey").value
btn.addEventListener("click", function() {
var ourRequest = new XMLHttpRequest();
ourRequest.open('GET', 'http://example.example?&apikey=' + document.getElementById("apikey").value);
ourRequest.onload = function() {
if (ourRequest.status >= 200 && ourRequest.status < 400) {
var ourData = JSON.parse(ourRequest.responseText);
document.getElementById("title").textContent = ourData.data[0]["name"];
}}}
);
</script>
.
<body>
Enter API key: <input type="text" id="apikey">
<button id="btn">Click me</button>
<p id="title"></p>
</body>
The API data which I am trying to just extract the name from, looks something like this:
{"data":[{"name":"This is the first name"},{"name":"This is the second name"}]}
It's likely that you're including the Javascript in the page before the HTML. As Javascript is executed as soon as the browser reaches it, it will be looking for the #btn element which will not have been rendered yet. There are two ways to fix this:
Move the Javascript to the bottom of the <body> tag, making it run after the HTML has been output to the page.
Wrap the Javascript in a DOMContentLoaded event, which will defer the script until the page has finished loading. An example is as follows:
window.addEventListener('DOMContentLoaded', function() {
var btn = document.getElementById('btn');
var apikey = document.getElementById("apikey").value;
[...]
});
Related
I want a link "Run this in " just below each PRE-CODE block.
The link should popup a new tab with any online compiler/interpreter and the code of the block.
I don't know if there is a solution already done. Like highlight.js but do this. So I tried my own approach unsuccessfully. I want to keep the HTML simple and clean.
Picked jdoodle as starting point, but the idea is to have options.
The HTML form, works! Either by redirecting or by changing the target to a new tab.
Now I want this working without the HTML FORM (to keep the HTML simple and clean) and do this in a javascript function call.
With XMLHttpRequest to perform the POST call, I get errors on CORS policy.
Access to XMLHttpRequest at 'https://www.jdoodle.com/api/redirect-to-post/execute-lua-online/' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource
I believe that this doesn't happens with HTML-FORM because it redirects and origin gets to be the same.
So I tried unsuccessfully to either use XMLHttpRequest to redirect or popup into jdoodle but I cant get to transfer the POST data containing the code.
My non-working-javascript-example
<pre><code class="language-lua">
print("hello jdoodle")
</code></pre>
Run this on jDoodle.
<form id="inputform" method="post" action=
"https://www.jdoodle.com/api/redirect-to-post/execute-lua-online/" target="_blank">
<textarea name="initScript"
rows="4" cols="20">
print("Either redirecting or in a tab, it works!")
</textarea>
<br/><br/>
<input type="submit" value="Test">
</form>
<script>
function runthis(caller) {
prev_el = caller.previousElementSibling;
code_el = prev_el.getElementsByTagName("CODE")[0];
code_str = code_el.innerText;
alert(code_str);
var handle=window.open("https://www.jdoodle.com/api/redirect-to-post/execute-lua-online/");
const http = new XMLHttpRequest();
http.open('POST', 'https://www.jdoodle.com/api/redirect-to-post/execute-lua-online/', true);
http.onload = function () {
console.log(this.responseText);
};
FD = new FormData();
FD.append('initScript', code_str);
FD.append('submit', 'Test');
alert(JSON.stringify(FD)); // it shows empty ¿why?
http.send(FD);
}
</script>
Answering my own question, but I would always appreciate better alternatives.
As the HTML Form was working, the first step is to reproduce this in javascript, and this is not done with XMLHttpRequest.
function runthis_on_external_site(pre_elem, url, textareaname="initScript" ) {
code_el = pre_elem.getElementsByTagName("CODE")[0];
code_str = code_el.innerText;
var form_elem = document.createElement("FORM");
form_elem.method = "POST";
form_elem.action = url;
form_elem.target = "_blank";
var element1 = document.createElement("TEXTAREA");
element1.name=textareaname;
element1.innerHTML = code_str;
form_elem.appendChild(element1);
document.body.appendChild(form_elem);
form_elem.submit();
form_elem.remove();
}
Then a link must be added below each <PRE><CODE> block after the page is loaded.
function insert_A_tag_after_( pre_elem, inner, url, textareaname) {
A = document.createElement("A");
A.className = 'ref';
A.href = '#';
A.innerHTML = inner;
A.onclick = function() {
runthis_on_external_site( pre_elem, url, textareaname);
};
pre_elem.parentNode.insertBefore(A, pre_elem.nextSibling);
}
//========================================================
window.addEventListener('DOMContentLoaded', function() {
console.log('Adding external Compilers/Interpreters');
document.querySelectorAll( 'code' ).forEach((e) => {
if( e.classList.contains( 'language-lua' ) ){
url = "https://www.jdoodle.com/api/redirect-to-post/execute-lua-online/";
insert_A_tag_after_( e.parentNode, "jDoodle", url, "initScript" );
url = "https://www.lua.org/cgi-bin/demo";
insert_A_tag_after_( e.parentNode, "lua.org", url, "input" );
}
})
});
NOTE: that, I have only found jDoodle and lua.org/cgi-bin/demo so far to be able to get the code from a POST variable. Others online compilers would be appreciated.
NOTE2: I picked the class name as 'language-lua' for compatibility with highlight.js
NOTE3: As far as I could research, I couldn't found any other popular alternative solution for this. Most solutions are to embed a compiler/editor from only one site.
I'm trying to get a image file from a input field in my form, transform it to a base64 string, and then send it to my backend using AJAX, but it's returning undefined. Weird thing is that I managed to do it in a JSFiddle, but am not achieving this in the server.
P.S.: I'm not gonna write the AJAX call and server interactions, as they are not relevant for this issue. I'm sending more data, and it's getting sent just right.
<form method="post">
<input type="file" id="documento" accept="image/*"/><br>
<button type="submit" id="continuar">Continuar</button>
</form>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script type="text/javascript">
$("#continuar").click(function (){
var fileInputDoc = document.getElementById('documento');
var readerDoc = new FileReader();
readerDoc.readAsDataURL(fileInputDoc.files[0]);
readerDoc.onload = function () {
var docb64 = readerDoc.result; //This is the point where everything goes wrong. Here I get the following error: "Cannot read property 'indexOf' of null".
var doc_aux = docb64.indexOf('base64,');
doc_aux += 7;
var doc = docb64.slice(doc_aux);
}
}
</script>
It might also be important to say that I've tested separate parts of the code, such as:
document.getElementById('documento'); (doesn't return null, meaning it found the actual element)
readerDoc.readAsDataURL(fileInputDoc.files[0]); (returns [object FileReader])
Functional JSFiddle
My sources:
https://www.codegrepper.com/code-examples/javascript/convert+input+image+to+base64+javascript
https://developer.mozilla.org/pt-BR/docs/Web/API/FileReader/readAsDataURL
I have add a page widget (the formerly "likebox") on my page.
It's something like:
<div class="fb-page"
data-href="https://www.facebook.com/imdb"
data-width="340"
data-hide-cover="false"
data-show-facepile="true"></div>
On the page. Everything works fine now.
However, I want to dynamically add extra widgets on my page after the page is loaded (including the FB js-sdk and the first widget). For example. I want to add a new Page-widget after I click a button:
$('button').click(function(){
$('body').append(`
<div class="fb-page"
data-href="https://www.facebook.com/imdb"
data-width="340"
data-hide-cover="false"
data-show-facepile="true"></div>
`);
})
But after doing so, the div wouldn't turn into the box.
I tried many ways like reloading the js file or removing the FB object. But all failed.
Is there any function like:
FB.refillFBHTMLElements() so that I can turn dynamically-created elements into Facebook widgets?
Try using FB.XFBML.parse(). I just tried it with this example, and it successfully parsed a dynamically created widget:
HTML:
<div id="fb-root"></div>
<script async defer crossorigin="anonymous"
src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v6.0&appId=2730175443872266&autoLogAppEvents=1"></script>
<h4>Dynamically Load Facebook Widget</h4>
<button onclick="loadWidget()" class="mb-2">Load Widget</button>
<div id="widget"></div>
JavaScript:
function loadWidget() {
const fbPage = document.createElement('div');
fbPage.className = "fb-page";
fbPage.dataset.href = "https://www.facebook.com/facebook";
fbPage.dataset.tabs = "timeline";
fbPage.dataset.width = "";
fbPage.dataset.height = "";
fbPage.dataset.smallHeader = "false";
fbPage.dataset.adaptContainerWidth = "true";
fbPage.dataset.showFacepile = "true";
const bq = document.createElement('blockquote');
bq.cite = "https://www.facebook.com/facebook";
bq.className = "fb-xfbml-parse-ignore";
const anchor = document.createElement('a');
anchor.href = "https://www.facebook.com/facebook";
anchor.innerHTML = 'Facebook';
bq.appendChild(anchor);
fbPage.appendChild(bq);
const widget = document.getElementById('widget');
widget.appendChild(fbPage);
// parse the widget
FB.XFBML.parse(widget);
}
Reference:
FB.XFBML.parse()
I am using tokbox trial for video chatting on my website. But the problem i am facing is that ::: User 1 can see and hear User 2 clearly. User 2 can see User 1 clearly, but user 2 couldnt here user 1. And code i am using
<html>
<head>
<title>Monkvyasa | Test</title>
<script src='http://static.opentok.com/webrtc/v2.2/js/opentok.min.js'></script>
<script type="text/javascript">
// Initialize API key, session, and token...
// Think of a session as a room, and a token as the key to get in to the room
// Sessions and tokens are generated on your server and passed down to the client
var apiKey = "xxxxxxx";
var API_KEY=apiKey;
var sessionId = "2_MX40NTAyMDgxMn5-xxxxxxxxxxxxxxxxxxxxHBXZEZoWHN-fg";
var token = "T1==cGFydG5lcl9pZD00NTAyMDgxMiZzaWc9ZDNiYjYyZGE2NTBkYmUzMTUyNGNjNDZjYzAzY2NjZWRhZGY3NTEyZjpyb2xlPW1vZGVyYXRvciZzZXNzaW9uX2lkPTJfTVg0xxxxxxxxxxxxxxxxxxxxxxxxBNM1JsYlRCUFdXWkhSSEJYWkVab1dITi1mZyZjcmVhdGVfdGltZT0xNDEzMjAwMjIxJm5vbmNlPTAuMTk1MzEwNTU0MzY1MjEwNSZleHBpcmVfdGltZT0xNDEzMjg0MzY5";
// Initialize session, set up event listeners, and connect
var session;
var connectionCount = 0;
function connect() {
session = TB.initSession(sessionId);
session.addEventListener("sessionConnected", sessionConnectHandler);
session.addEventListener('streamCreated', function(event){
e=event;
console.log(e);
for (var i = 0; i < event.streams.length; i++) {
streams = event.streams;
// Make sure we don't subscribe to ourself
alert("new user connected :)");
if (streams[i].connection.connectionId == session.connection.connectionId) {
return;
}
// Create the div to put the subscriber element in to
var div = document.createElement('div');
div.setAttribute('id', 'stream' + streams[i].streamId);
document.body.appendChild(div);
session.subscribe(streams[i], div.id);
}
});
session.connect(API_KEY, token);
}
function sessionConnectHandler(event) {
var div = document.createElement('div');
div.setAttribute('id', 'publisher');
var publisherContainer = document.getElementById('publisherContainer');
// This example assumes that a publisherContainer div exists
publisherContainer.appendChild(div);
var publisherProperties = {width: 500, height:450};
publisher = TB.initPublisher(API_KEY, 'publisher', publisherProperties);
session.publish(publisher);
}
function disconnect() {
session.disconnect();
}
connect();
</script>
</head>
<body>
<h1>Monkvysa videofeed test!</h1>
<input style="display:block" type="button" id="disconnectBtn" value="Disconnect" onClick="disconnect()">
<table>
<tr>
<td> <div id="publisherContainer"></div></td> <td><div id="myPublisherDiv"></div></td>
</tr>
</table>
</body>
</html>
Thanks in advance
The code looks mostly correct, except you're using an older form of the 'streamCreated' event handler. In the latest version of the API, you no longer need to iterate through the event.streams array, you actually get one invocation of the event handler per stream.
In order to further dig into the problem, would you be able to add a link to a gist containing all the console logs? To make sure the logs are being outputted, you can call OT.setLogLevel(OT.DEBUG); at the beginning of the script.
Lastly, the newer API is greatly simplified and you could save yourself the effort of DOM element creation and iteration. What you have implemented is basically identical to our Hello World sample applications, which you can find in any of our server SDKs, for example here: https://github.com/opentok/opentok-node/blob/61fb4db35334cd30248362e9b10c0bbf5476c802/sample/HelloWorld/public/js/helloworld.js
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');
}