I would like to run a script that has event listeners on a feed of posts. When I add a new post to the feed I have a function that makes a fetch call to add the post to the server and then proceed to update the DOM asynchronously. While I'm updating the DOM I would like to refresh the feed div where all the post are. I'm using an update() function that makes an XMLHttpRequest and updates the div, but after the new post is updated to the DOM I lose the initial script that contains event listeners for the posts.
function post() {
content = document.querySelector('#exampleFormControlTextarea1').value
console.log(content)
fetch('/add', {
method: 'POST',
body: JSON.stringify({
content: content,
})
})
.then(response => response.json())
.then(result => {
// Print result
if (result.error) {
document.querySelector('#message').className = "alert alert-danger rounded width_1"
document.querySelector('#message').innerText = result.error
document.querySelector("#message").style.display = 'block';
} else {
document.querySelector("#message").style.display = 'block';
document.querySelector('#message').className = "alert alert-success rounded width_1"
document.querySelector('#message').innerText = result.message
setTimeout(function () {
document.querySelector('#message').style.display = "none"
}, 2500)
setTimeout(function () {
document.querySelector("#add").style.display = 'none';
}, 500)
update()
console.log(result);
}
});
return false;
}
function update() {
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (this.status >= 200 && this.status < 400 && request.readyState == 4) {
// Success!
var resp = this.response;
let div = document.createElement('div')
div.innerHTML = resp
let content = div.querySelector('#jqpost').innerHTML
let post = document.createElement('div')
post.innerHTML = content
let feed = document.querySelector('#feed')
feed.insertAdjacentElement('beforebegin', post)
//console.log(script_text)
} else {
// We reached our target server, but it returned an error
// console.error(request.statusText);
}
};
request.open('GET', '/', true);
request.send();
}
How can I keep the event listeners script after I reload the feed?
Related
I am making a simple website which consists of products (Laptop, CCTV). It has a single page. When I click on(Laptop tag, it should display Laptop items stored in JSON - and the same case For CCTV products.
Problem.
The first time I click on a link it does not show anything, when I click 2nd, 3rd times on link then it shows products. But preventdefault is not working.
Where should i apply preventDefault() event and how?
Html code for 2 links
<a
href="displayproducts.html" onloadeddata="fetchproducts('CCTV')";>
CCTV CAMERAS</a>
<a
href="displayproducts.html"
onloadeddata="fetchproducts('Laptop')">
Laptop and COMPUTERS</a>
JavaScript Code which handles that event and using AJAX AND JSON should return data (returning correctly).
function fetchproducts(product, event) {
console.log(product);
//your read json code
var xhr = new XMLHttpRequest();
xhr.open("get", "/jsondata/Products.json");
xhr.onload = function (event) {
console.log();
event.preventDefault();
var obj = JSON.parse(this.responseText);
try {
if (product === "CCTV") {
fillProducts(obj.CCTV);
} else if (product === "Laptop") {
fillProducts(obj.Laptop);
} else if (product == "Biometric") {
fillProducts(obj.Biometric);
}
} catch (error) {
console.log("some_error_occur");
}
};
xhr.send();
}
function fetchproducts(product, event) {
console.log(product);
var xhr = new XMLHttpRequest();
xhr.open("get", "/jsondata/Products.json", true);
xhr.onload = function () {
console.log();
try {
var obj = JSON.parse(xhr.responseText);
if (product === "CCTV") {
fillProducts(obj.CCTV);
} else if (product === "Laptop") {
fillProducts(obj.Laptop);
} else if (product == "Biometric") {
fillProducts(obj.Biometric);
}
} catch (error) {
console.log("some_error_occur: " + error);
}
};
xhr.send();
event.preventDefault();
}
I know how to load an entire page in Ajax, especially by getting the href to have something dynamic, but I would like to get a particular part of the loaded page.
I'm trying to create a modal window. In jQuery, I did it like this:
(function($)
{
$(".trigger").on("click", function(e)
{
var url = $(this).attr('href') + " #container #content"
e.preventDefault()
$(".modal, #overlay").toggleClass("show")
$(".modal .container").load(url, function()
{
$("#form").submit(function(event)
{
event.preventDefault();
})
})
})
$("#overlay").on("click", function()
{
$(".modal, #overlay").removeClass("show")
})
})(jQuery)
Pure JavaScript:
// Modal
var modal = document.querySelector(".modal")
var overlay = document.getElementById("overlay")
// Open Modal
var openModal = function(event)
{
event.preventDefault()
modal.classList.toggle("show")
overlay.addEventListener("click", closeModal)
// Ajax
var httpRequest = new XMLHttpRequest()
httpRequest.onreadystatechange = function()
{
if(httpRequest.readyState === 4)
{
document.querySelector(".modal .content").innerHTML = httpRequest.responseText
}
}
httpRequest.open("GET", this.getAttribute("href"), true)
httpRequest.send()
}
// Close Modal
var closeModal = function(event)
{
event.preventDefault()
modal.classList.remove("show")
overlay.removeEventListener("click", closeModal)
}
// Trigger
document.querySelectorAll(".trigger").forEach(a => {
a.addEventListener("click", openModal)
})
In this part:
httpRequest.open("GET", this.getAttribute("href"), true)
I would like to reproduce this in pure JavaScript:
var url = $(this).attr('href') + " #container #content"
I would use fetch() and DomParser API's
var openModal = function(event) {
event.preventDefault()
...
const url = event.currentTarget.href;
fetch(url)
.then(res => res.text())
.then(html => {
const doc = new DOMParser().parseFromString(html, 'text/html');
const content = doc.querySelector('#content').outerHTML;
document.querySelector(".modal .content").innerHTML = content;
});
}
Plunker demo
I've got an API that returns me {"html", "Css" and "JS"} that i'd ideally like to render on client side.
Issue:
Looks like something's failing for some reason and clicking on the button does not do anything. (I have accept button)
JavaScript:
function postAjax(success) {
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
xhr.open('GET', '/myaccount/profile/api/accept');
xhr.onreadystatechange = function() {
if (xhr.readyState > 3 && xhr.status == 200) {
success();
}
};
xhr.setRequestHeader('Accept', 'application/json', 'Content-Type', 'application/json');
xhr.send(null);
return xhr;
};
document.onreadystatechange = function() {
if (document.readyState == "interactive") {
// some logic
var cookieLanguage = document.getElementById("CookieContent_wrapper");
var cookieBanner = document.getElementById("CookieBanner");
var acceptAllButton = document.getElementById("acceptAllButton");
acceptAllButton.onclick = function() { // Does not get trigerred.
// Does not get trigerred.
// Do some logic.
};
}
};
However, acceptAllButton.onClick event is not triggerred.
This is my directive.js (angular)
populate() {
this.cookieBannerData = this.models.CookieData; // We are getting { "js", "html", "css"}
//CSS
$("head").prepend( this.cookieBannerData.css );
// HTML
let div = document.getElementById( 'cookie-banner-outerwrap' );
div.insertAdjacentHTML( 'beforeend', this.cookieBannerData.html );
//JS
$("head").append( this.cookieBannerData.js );
}
template.html
<div id="cookie-banner-outerwrap"></div>
When I click on the button, nothing happens. Is there anyway I can bind the onclick event with window so that I can get my
I have the following files: (inc.js is included in my html page)
inc.js
var field = new Worker('ajax.js');
field.addEventListener('message', function(e) {
var data = JSON.parse(e.data);
document.getElementById('fieldToUpdate').innerHTML = data[0];
}, false);
field.postMessage(0);
ajax.js
var xhr = new XMLHttpRequest();
function getData() {
xhr.open('get', 'field.php');
xhr.onreadystatechange = processData;
xhr.send(null);
}
function processData() {
if (xhr.readyState == 4) {
self.postMessage(xhr.responseText);
setTimeout(getData, 5000);
}
}
onmessage = function() {
setTimeout(getData, 5000);
}
My Problem is now, that this Script doesn't make one http request each 5 seconds but it starts as soon as one is finished.
I'm trying to use phantomJS (what an awesome tool btw!) to submit a form for a page that I have login credentials for, and then output the content of the destination page to stdout. I'm able to access the form and set its values successfully using phantom, but I'm not quite sure what the right syntax is to submit the form and output the content of the subsequent page. What I have so far is:
var page = new WebPage();
var url = phantom.args[0];
page.open(url, function (status) {
if (status !== 'success') {
console.log('Unable to access network');
} else {
console.log(page.evaluate(function () {
var arr = document.getElementsByClassName("login-form");
var i;
for (i=0; i < arr.length; i++) {
if (arr[i].getAttribute('method') == "POST") {
arr[i].elements["email"].value="mylogin#somedomain.example";
arr[i].elements["password"].value="mypassword";
// This part doesn't seem to work. It returns the content
// of the current page, not the content of the page after
// the submit has been executed. Am I correctly instrumenting
// the submit in Phantom?
arr[i].submit();
return document.querySelectorAll('html')[0].outerHTML;
}
}
return "failed :-(";
}));
}
phantom.exit();
}
I figured it out. Basically it's an async issue. You can't just submit and expect to render the subsequent page immediately. You have to wait until the onLoad event for the next page is triggered. My code is below:
var page = new WebPage(), testindex = 0, loadInProgress = false;
page.onConsoleMessage = function(msg) {
console.log(msg);
};
page.onLoadStarted = function() {
loadInProgress = true;
console.log("load started");
};
page.onLoadFinished = function() {
loadInProgress = false;
console.log("load finished");
};
var steps = [
function() {
//Load Login Page
page.open("https://website.example/theformpage/");
},
function() {
//Enter Credentials
page.evaluate(function() {
var arr = document.getElementsByClassName("login-form");
var i;
for (i=0; i < arr.length; i++) {
if (arr[i].getAttribute('method') == "POST") {
arr[i].elements["email"].value="mylogin";
arr[i].elements["password"].value="mypassword";
return;
}
}
});
},
function() {
//Login
page.evaluate(function() {
var arr = document.getElementsByClassName("login-form");
var i;
for (i=0; i < arr.length; i++) {
if (arr[i].getAttribute('method') == "POST") {
arr[i].submit();
return;
}
}
});
},
function() {
// Output content of page to stdout after form has been submitted
page.evaluate(function() {
console.log(document.querySelectorAll('html')[0].outerHTML);
});
}
];
interval = setInterval(function() {
if (!loadInProgress && typeof steps[testindex] == "function") {
console.log("step " + (testindex + 1));
steps[testindex]();
testindex++;
}
if (typeof steps[testindex] != "function") {
console.log("test complete!");
phantom.exit();
}
}, 50);
Also, CasperJS provides a nice high-level interface for navigation in PhantomJS, including clicking on links and filling out forms.
CasperJS
Updated to add July 28, 2015 article comparing PhantomJS and CasperJS.
(Thanks to commenter Mr. M!)
Sending raw POST requests can be sometimes more convenient. Below you can see post.js original example from PhantomJS
// Example using HTTP POST operation
var page = require('webpage').create(),
server = 'http://posttestserver.example/post.php?dump',
data = 'universe=expanding&answer=42';
page.open(server, 'post', data, function (status) {
if (status !== 'success') {
console.log('Unable to post!');
} else {
console.log(page.content);
}
phantom.exit();
});
As it was mentioned above CasperJS is the best tool to fill and send forms.
Simplest possible example of how to fill & submit form using fill() function:
casper.start("http://example.com/login", function() {
//searches and fills the form with id="loginForm"
this.fill('form#loginForm', {
'login': 'admin',
'password': '12345678'
}, true);
this.evaluate(function(){
//trigger click event on submit button
document.querySelector('input[type="submit"]').click();
});
});