Load the part of a page in Ajax, not the entire page - javascript

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

Related

Reload / insert script after inserting div via XMLHttpRequest

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?

content in <script> tag to ReactJS component

Here is my code in HTML, in this I need to take out the script part and modify it to ReactJS and use as script source in html again. Since, I started it as html itself and new to React.
<script>
function idbOK() {
return "indexedDB" in window; //check whether indexeddb is supported in the browser
}
var db;
var key = 100;
$(document).ready(function() {
if(!idbOK()) return;
var DBopenRequest = indexedDB.open("ora_idb3",1);
DBopenRequest.onupgradeneeded = function(e) {
var thisDB = e.target.result;
console.log("running onupgradeneeded");
if(!thisDB.objectStoreNames.contains("notes")) {
var notesOS = thisDB.createObjectStore("notes", {autoIncrement: true})
console.log("makng a new object store notes");
notesOS.createIndex("title","title",{unique: false});
}
}
DBopenRequest.onsuccess = function(e) {
console.log("running onsuccess");
db = e.target.result;
getNote();
$('#note').on('input propertychange change', function(){
addNote();
})
}
DBopenRequest.onerror = function(e) {
console.log("onerror!");
console.dir(e);
}
});
</script>
I want to change the code to ReactJS. Am new to ReactJS and found this complex to move.
You can do so by the following approach:
const dbSetupScript = `function idbOK() {
return "indexedDB" in window; //check whether indexeddb is supported in the browser
}
var db;
var key = 100;
$(document).ready(function() {
if(!idbOK()) return;
var DBopenRequest = indexedDB.open("ora_idb3",1);
DBopenRequest.onupgradeneeded = function(e) {
var thisDB = e.target.result;
console.log("running onupgradeneeded");
if(!thisDB.objectStoreNames.contains("notes")) {
var notesOS = thisDB.createObjectStore("notes", {autoIncrement: true})
console.log("makng a new object store notes");
notesOS.createIndex("title","title",{unique: false});
}
}
DBopenRequest.onsuccess = function(e) {
console.log("running onsuccess");
db = e.target.result;
getNote();
$('#note').on('input propertychange change', function(){
addNote();
})
}
DBopenRequest.onerror = function(e) {
console.log("onerror!");
console.dir(e);
}
});`;
Note: If you want some variable value then, can use ${variable_name} syntax inside dbSetupScript string.
Then from React component's render method you can do the following
<script dangerouslySetInnerHTML={{__html: dbSetupScript}} />

How can I trigger modal boxes using the following javascript code?

Hey guys I need just a little bit of help with this.
So I have modal boxes hiding on my page and when I click on them using the video platform VERSE they work perfectly.
My questions is: How can I call the same modal boxes if I wan to call them from a regular link or button on the page.
Here is the sample:
http://digitalfeast.com/clients/nccv/ncc-verse.html
Here is my Javascript code:
(function() {
(function() {
window.onload = function() {
var frame = document.getElementsByName("verse-iframe")[0].contentWindow;
// Variables below (i.e. "menu-1") reference div id from your markup
function receiveMessage(event) {
var data = (typeof event.data === "String") ? JSON.parse(event.data) : event
var modalWindow1 = document.getElementById("ruben-1");
var modalWindow2 = document.getElementById("ruben-2");
var modalWindow3 = document.getElementById("menu-3");
var modalWindow4 = document.getElementById("menu-4");
// Variables below (i.e. "menu-1") reference the unique callback names entered for your hotspots in the Verse editor
if (data.data["identifier"] === "ruben-1") {
modalWindow1.style.display = "block";
}
if (data.data["identifier"] === "ruben-2") {
modalWindow2.style.display = "block";
}
if (data.data["identifier"] === "menu-3") {
modalWindow3.style.display = "block";
}
if (data.data["identifier"] === "menu-4") {
modalWindow4.style.display = "block";
}
}
var closeBtns = document.getElementsByClassName("modal-close");
for (var i = 0; i < closeBtns.length; i++) {
var btn = closeBtns[i];
btn.onclick = function (event) {
event.target.parentNode.parentNode.style.display = "none";
frame.postMessage({action: "play"}, "*");
};
}
window.addEventListener('message', receiveMessage);
var frame = document.getElementsByName("verse-iframe")[0].contentWindow;
};
}());
}());
Given your code, all you need to do is send the window a message using the Messaging API inside your button click handler.
Your event listener will then execute the receiveMessage function and open your model for ruben-1.
window.onload = () => {
document.querySelector('[data-modal="ruben-1"]').addEventListener("click", (e) => {
let postData = {
identifier: e.target.dataset.modal
};
window.postMessage(postData, "*");
});
window.addEventListener('message', m => {
alert(m.data.identifier);
});
}
<button data-modal="ruben-1">Ruben-1 Video</button>

Ajax call works only first time

This is my code, to modify the content of a table cell, clicking a link "Open/Close" of the sibling cell.
The link works good the first time but on the second click, the execution start again from
$("a[href*='close']").click(function (event)
even if the new link contains "open" and not the word "close" anymore.
Why have I this behaviour?
Which is the problem? How can I solve it?
Thanks in advance!
$(document).ready(function()
{
$("a[href*='close']").click(function (event)
{
event.preventDefault();
var click = $(this);
console.log(click);
var url = click.attr("href");
console.log(url);
var nid = url.split("/")[1];
console.log(nid);
// var url = "close/" + nid;
// console.log(url);
$.get(url, function(data, status)
{
if (data.status == 1)
{
console.log(data.res);
click.text("Open");
var new_url = url.replace("close", "open");
console.log("New Url = " + new_url);
click.attr("href", new_url);
click.parent().prev().text(data.res);
}
else
{
console.log("Error");
}
});
}); // CHIUDE FUNZIONE
$("a[href*='open']").click(function (event)
{
event.preventDefault();
var click2 = $(this);
console.log(click2);
var url = click2.attr("href");
console.log(url);
var nid = url.split("/")[1];
console.log(nid);
// var url = "open/" + nid;
// console.log(url);
$.get(url, function(data, status)
{
if (data.status == 1)
{
console.log(data.res);
click2.text("Close");
var new_url = url.replace("open", "close");
console.log("New Url = " + new_url);
click2.attr("href", new_url);
click2.parent().prev().text(data.res);
}
else
{
console.log("Error");
}
});
}); // CHIUDE FUNZIONE
As I stated in my comment to the question, you can use a delegate event binding, rather than juggling event bindings, to allow events to only be processed by the logic that you want them to be processed by.
$(document).on('click', 'a[href*="close"]', function (event) {
event.preventDefault();
console.log('close');
event.target.href = '#open';
});
$(document).on('click', 'a[href*="open"]', function (event) {
event.preventDefault();
console.log('open');
event.target.href = '#close';
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Toggle

Debounce click on an AJAX link

Is it possible to debounce the click of a link? If a user clicks too many times too fast on a pjax link it'll break the load of new content.
$(document).on('click', 'a[data-pjax]', loadNewContent);
var $target = $('main.content section.context'),
$fake = $('main.fake'),
$fakeContext = $('main.fake section.context');
function loadNewContent() {
event.preventDefault();
var $this = $(this),
url = $this.attr('href');
$fake.addClass('is--loading');
$.pjax({
url: url,
fragment: 'body',
container: $fakeContext
});
$fake.one(transitionEnd, function() {
$target.html($fake.find('section.context').html());
$fake.removeClass('is--loading');
$fake.off(transitionEnd);
});
}
Any thoughts? I tried this, but it stopped the loadNewContent from firing. (https://github.com/cowboy/jquery-throttle-debounce)
$(document).on('click', 'a[data-pjax]', $.debounce(1000, true, function() {
loadNewContent();
}));
Something like this would work :
var callWaiting = false;
callAjax() {
if(!callWaiting) {
callWaiting = true;
makeHttpCall(url, data, function(response) {callWaiting = false;});
callWaiting = false;
}
}

Categories