Load more button with ajax request trigger only once - javascript

I need an explanation about this code :
page2.php
<?php
if (isset($_POST['p'])) { echo $_POST['p'];}
page.php
<body>
<button name="bouton" id="bouton"> TEST </button>
<script>
document.getElementById('bouton').addEventListener("click", function() {
var xhr = new XMLHttpRequest();
xhr.open('POST', 'page2.php');
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send('p=2');
xhr.addEventListener('load', function() { /*document.body.innerHTML += xhr.response;*/ document.getElementById('bouton').insertAdjacentHTML('beforebegin',
xhr.response); });
});
</script>
</body>
It's a load more script for testing purpose. While this code works fine, if I replace
document.getElementById('bouton').insertAdjacentHTML('beforebegin',
xhr.response);
By the comment :
document.body.innerHTML += xhr.response;
The xhr.response file is adding only once. I can't understand why.
Thanks a lot !

Setting the innerHTML of the body is replacing the entire body of your document with a new one, the new button does not have a click handler attached to it like the old button so nothing will happen when you try to click it.
For insertAdjacentHTML nothing is replaced, you're just adding content before the button. The original button is still there and its click handler responds to your clicks with the ajax request.

Related

Running script after DOM is finished

I'm dynamically creating menu items to be placed on the menu bar, based on the headers of external files, imported with an XMLHttpRequest(). As I navigate through the different pages, this menu bar is dynamically updated.
This works fine.
I load each document into an individual div element, in a sort of stack of cards, and hide all but the setVisible() page.
window.onload = function(){
loadContent("personalinfo");
loadContent("academicalinfo");
loadContent("employmentinfo");
setVisible("academicalinfo");
/*setMenues("academicalinfo");*/
}
The last action of setVisible() is to call setMenues(), which is responsible for reading all of the headers of said main window. This also works fine-ish.
function loadMenues(file) {
var rightmenu = document.getElementById("right-menu");
while(rightmenu.firstChild){
rightmenu.removeChild(rightmenu.firstChild);
}
[].forEach.call(document.getElementById(file).children,
function(custompaddingchild) {
/* searching for h1 and adding menu items happens here */
}
);
The problem arises when the DOM elements are not loaded yet, as when the page loads. Since there are no ElementsById(file) in the document element until the page is completely rendered, it fails to add the menu items onload.
I have tried adding an EventListener on the "load" event of the window and on the document, I have tried executing the function on the end of the body of the main page, and on the on onload= argument of <body> (which runs even before the subpages are captured, leaving me with a blank page instead of the actual content), but as it seems, none of them seems to happen after the page is completely loaded.
Adding a 2 second delay before running the functions is not an effective solution. Besides, adding a delay to the onload function will not affect the result, and will only increase loading time by two seconds.
Clicking any of the menues which update the menues work as intended. The only problem is onload.
<div class="menu-item" onclick="setVisible('personalinfo');"><span>Personal information</span></div>
How can I make sure the page delays the setVisible() function until after the page is rendered? All the sources I've found claim the "load" event is triggered after the page is rendered, but it doesn't seem to be triggered in my case. The DOMContentLoaded event isn't triggered either, but I suspect I don't want this one. The click event, or a scroll event on the window, in contrast, do trigger correctly.
Mozilla, Window: load event
Javascript.info, Page: DOMContentLoaded, load, beforeunload, unload
Edit: As per request, here is loadContent():
function loadContent(file) {
var request = new XMLHttpRequest();
request.open("GET", file+".html?_=" + new Date().getTime());
request.onreadystatechange=function(){
var loadedcontent = request.responseText;
document.getElementById(file).innerHTML = loadedcontent;
}
request.send();
}
Edit 2:
Full code is available at https://github.com/mazunki/portfolioweb-stackoverflowquestion
You need to use promises: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
Try this
function loadContent(file) {
return new Promise(function (resolve, reject) {
var request = new XMLHttpRequest();
request.open("GET", file+".html?_=" + new Date().getTime());
request.onreadystatechange=function(){
var loadedcontent = request.responseText;
document.getElementById(file).innerHTML = loadedcontent;
resolve();
}
request.send();
});
}
window.onload = function(){
// when you finish all the content loading
Promise.all([
loadContent("personalinfo"),
loadContent("academicalinfo"),
loadContent("employmentinfo")
]).then(function() {
// Load menu
setVisible("academicalinfo");
/*setMenues("academicalinfo");*/
})
}
Sorry, but you tried to use the "library" https://github.com/ded/domready ? I think that is the simpliest solutuion for you.
Then you code would be:
function loadMenues(file) {
domready(function () {
var rightmenu = document.getElementById("right-menu");
while(rightmenu.firstChild){
rightmenu.removeChild(rightmenu.firstChild);
}
[].forEach.call(document.getElementById(file).children,
function(custompaddingchild) {/* searching for h1 and adding menu items happens here */ }
);
})
}
While this only stands as a fallback solution, and is not reliable over slow network connections, I solved it by placing the following inside the menuhandling.js file, called with <script src="menuhandling.js" type="text/javascript" defer></script>:
setTimeout(function(){
setVisible("personalinfo")
/*setMenues("personalinfo")*/
},500) // half a second
loadContent() is called for all files in stackhandling.js, with no delay, and not document.onload nor window.onload.

Chome extension prevents <select> elements from expanding

I have developed a very simple Chome extension that exposes a single toolbar button. When the button is clicked, the page content is POSTed to the server using XMLHttpRequest and then the innerHtml of the <html> element is replaced by the new content returned from the server.
For some reason this prevents <select> elements from expanding. I have verified this by disabling the extension which makes then work again.
Any ideas why this might be happening and how to fix it? The code is below for reference:
chrome.extension.onMessage.addListener(
function (request, sender, sendResponse) {
if (request.msg == "get_content") {
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
document.getElementsByTagName('html')[0].innerHTML =
xmlhttp.responseText;
} else {
alert('Cannot reach russiangram.com');
}
}
}
xmlhttp.open("POST", "https://russiangram.com/translate/Default.aspx", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send(document.getElementsByTagName('html')[0].innerHTML);
sendResponse({ data: 'success' });
}
});
At a guess I would say where you are replacing the contents of the documents HTML tag that you are possibly also replacing any associated JS/CSS references that were originally on that page as well.
Maybe as a test instead of replacing the contents of the HTML tag, add a new DIV element or something to the page and target that instead. That should hopefully allow you see whether or not the select functionality still works.

Load Div Content from Another Page

I am trying to load a div content from another page(this page is in another project which is running in tomcat all together) with javascript ajax.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:8080/prob-services/clogin#login_page');
xhr.onload = function() {
alert(xhr.status);
console.log(xhr);
if (xhr.status === 200) {
var modal = document.getElementById("modal_dialog");
modal.innerHTML = xhr.responseText;
}
};
xhr.send();
The problem is when I log xhr I see that responseURL is until #, so ajax takes only http://localhost:8080/prob-services/clogin instead of http://localhost:8080/prob-services/clogin#login_page. That's why it loads whole page.
Is there any way to get only div content without JQuery?
Solution to filter the whole page:
Create a dummy hidden DOM element like
<div style='display: none' id="loadedHTML"></div>
then put the HTML of the whole page you received from the server into it:
document.getElementById('loadedHTML').innerHTML = xhr.responseText;
now you can search the html inside this component. Say the part you want to is in a div called "MyDiv" inside the page:
var modal = document.getElementById("modal_dialog");
modal.innerHTML = document.getElementById('MyDiv').innerHTML;
fell free to ask more if it's not clear enough.
Use this jQuery load() function
$('#modal_dialog').css('opacity','1').load('http://localhost:8080/prob-services/clogin',function() {
alert():
} );

PHP/JS/AJAX/HTML: Dynamically creating a webpages

This is my first time using AJAX i have been reading up on it, and it is also my first time doing this with js. I think i have confused myself along the way.
I am trying to dynamically create a new restaurant page, so every time a administrator clicks the onclick button a new webpage is created, with the content from the new restaurant page, which i have already created.
At the moment i have gotten as far as on pressing a button, a new webpage is created succesfully, however, i have no idea how to access the new webpage i also wanted to display a link to the newly created webpage as it is created, like for example using before. in js to show the dynamic feature before my o'clock button for example.
HTML
<html>
<body>
<button onclick="makePage()">click</button>
<script src="makePage.js">
</script>
</body>
</html>
JS
function makePage(){
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState==4 && xmlhttp.status==200)
alert("webpage " + xmlhttp.responseText + " was successfully created!");
}
var content = "<html><head><meta charset=\"utf-8\" /> </head><body>new website<script>alert(\"test\")</script></body></html>";
xmlhttp.open("GET","makePage.php?content=" + content,true);
xmlhttp.send();
}
PHP
<?php
$content = $_GET["content"];
$file = uniqid() . ".html";
file_put_contents($file, $content);
echo $file;
?>
Any suggestions? guidance or related pages i can read up on. Anything will be extremely appreciated.
In your js do something like this instead of alert:
if(xmlhttp.readyState==4 && xmlhttp.status==200){
var createA = document.createElement('a');
var createAText = document.createTextNode(xmlhttp.responseText); // or whatever name you need
createA.setAttribute('href', xmlhttp.responseText);
createA.appendChild(createAText);
document.body.appendChild(createA); // or you can create some <div> or whatever and append it to that
}
This is plain javascript, but using jquery you can do it easier with ajax or get functions.

Automatic refresh using AJAX not working?

I've got a chat function in my website for two users to chat with each other, and I'm using JavaScript, AJAX, and PHP for it.
At the moment, it won't refresh the chat area automatically unless I submit a reply to the chat or refresh the page. I can't figure out why.
JavaScript Function
function checkReply(threadid) {
// XMLHttpRequest
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("chatwrap").innerHTML = xmlhttp.responseText;
setInterval(checkReply(threadid), 10000);
}
}
xmlhttp.open("GET","inc/chatreply.php?chatid="+ threadid,true);
xmlhttp.send();
}
The event handler is on the <div> the responseText will end up in:
<div id="chatwrap" onload="checkReply('.$threadid.')"></div>
$threadid is a GET variable set at the top of the page:
$threadid = (int)$_GET['chatid'];
UPDATE
Seeing that you were in a PHP state already, the syntax was correct.
The problem is that the div doesn't possess an onload event. You'll have to attach it to the body tag, or include a script in the head or below the div, as it will only execute after the div has been rendered.
You're not including the PHP variable correctly. At the moment you are passing the string .$threadid. to the checkReply function. You will have to drop into PHP mode again before using this syntax by using the delimiters <?php & ?>.
<div id="chatwrap" onload="checkReply(<?php echo $threadid; ?>)"></div>
This should work better.

Categories

Resources