Change client URL without requesting route to Node JS - javascript

My router.js, which is in public directory works the following way:
First, listens to the event of clicking an 'a' tag
Then, prevents following the link and passes the href value to this function
function loadPage(targetUrl) {
if (targetUrl == "/") {
loadHome(); //Loads Home Page
} else {
if (isSpanish()) {
var direction = "/pages/es" + targetUrl + ".html";
} else {
var direction = "/pages/en" + targetUrl + ".html";
}
var subDirections = direction.split("/");
$('#content').load(direction, function (response, status, xhr) { //Loads content
if (status == "error") {
$("#error-popup").slideDown();
$("#error-popup-wrapper").fadeIn();
document.title = "404" + titleAddon;
} else {
document.title = document.getElementById("title").innerHTML + titleAddon;
window.history.pushState({ url: "" + targetUrl + "" }, null, targetUrl);
}
});
window.scrollTo(0, 0);
}
};
But I believe is conflicting with my index.js which controlls the only route I have:
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, '/views/index.html'));
});
Everytime I click on a link, I believe the client is requesting the server for the route, and my router.js loads it correctly, but I don't want the page to reload.
How could I solve this?
P.D. Sometimes the page doesn't reload, generally when clicking the menu links. Not sure why.
The website I'm uploading this code to is: https://testing.fsupv2017.webs.upv.es

Related

How to enable history back button when using location.href = "site"?

I am new to js and html. I have a js code to redirect to a webpage in the same site, from https://example.com/html1.html to https://example.com/html2.html. I also want it so the back button can be enabled, but from what I have found from searching nothing provides an answer for what I am looking for.
Here is code:
location.href = "https://example.com/html2.html";
For some reason the back button to go to the previous page (https://example.com/html1.html) does not work.
location.href = "https://stackoverflow.com/";
//Firebase authstate changed listener here
//Timeout represents when the user signs in
setTimeout(() => {location.href = "https://example.com/";}, 500);
I have a hotfix which doesn't always work but it just puts a 1 sec delay and it works
firebase.auth().onAuthStateChanged(user => {
if (user) {
console.log("User: " + user.email + " Displayname: " + user.displayName);
console.log("Url: " + location.href);
console.log(location.href == "site1"); //Logging if we are in the site1 or not
if (location.href == "site1") {
setTimeout(() => {
location.href = "site2";
}, 1000);
console.log("Not in site2");
} else {
console.log("In site2");
}
console.log("Going to main blog");
}
});
Try
window.location('link')
should work

How do I load a page and immediately edit the DOM in electron?

I'm trying to create a markdown editor.
So far: I have loaded the index page. I'm using fs.readdir to get the titles of all the markdown files and display them in the sidebar. Then, on clicking on of these title #content get's the content.
module.exports = (win) => {
fs.readdir( './data', (err, data) =>{
data.map(title => {
if(title.split('.md').length==2){
el = document.createElement("li"); // get gave it the title ..
el.addEventListener('click', function(e){
fs.readFile(`./data/${title}`, (err, data) => {
document.getElementById('content').innerHTML = data;
});
})
document.getElementById('titles').appendChild(el) // title are on the page
The problem is when I introduce another page
I have a preferences page
win.loadURL(path.join('file://', __dirname, '../static/preferences.html'))
It has the same sidebar, hence I import the same code to get the titles. But now when I click one of the links, I don't want document.getElementById('content').innerHTML = data; but I want to load the index page and then inject the content
So far I tried this
const checkPageState = (pageName, callback) => {
if(pageName === "preferences"){
ipcRenderer.send(GO_TO_PAGE, 'index')
}
setTimeout(callback(), 1000);
}
...
el.addEventListener('click', function(e){
checkPageState(win, ()=>{
fs.readFile(`./data/${title}`, (err, data) => {
if (err) throw err;
fileDir = `./data/${title}`;
document.getElementById('content').innerHTML = data;
});
})
})
My thinking was ipcRenderer.send(GO_TO_PAGE, 'index') would load the index page (which it does) when wait for a bit and then inject the data into the index page. It doesn't!
How can I do this?
I recently tried to do this as well and it was kinda tricky but I found something that worked:
In electron when it tries to go to another page I stop it from going to it with:
win.webContents.on('will-navigate', function (evt, url) {
evt.preventDefault();
win.webContents.executeJavaScript('makeHiddenPageIframe("' + url + '");');
});
Then it calls the makeHiddenPageIframe function defined on the page.
Then in the page I define the makeHiddenPageIframe function:
function makeHiddenPageIframe (url) {
var hiddenPage = document.createElement("iframe");
hiddenPage.setAttribute("src", url);
hiddenPage.style.display = 'none';
document.body.appendChild(hiddenPage);
hiddenPage.onload = function () {
var frameDocument = hiddenPage.document;
if (hiddenPage.contentDocument) {
frameDocument = hiddenPage.contentDocument;
} else if (hiddenPage.contentWindow) {
frameDocument = hiddenPage.contentWindow.document;
}
document.open();
document.write(frameDocument.documentElement.innerHTML);
document.close();
window.history.pushState("", document.title, url.replace('https://' + window.location.hostname, ''));
}
}
This then makes a iframe and loads the page in there then once it has loaded copy all the html from the iframe to the parent window so it seems like the switch happened instantly.
Also the window.history.pushState thing at the bottom was when you overwrite the html the url stays the same so when you reload it goes back to the original page but the window.history.pushState changes the url without reloading the page.
Any form of navigation will do the iframe load so you would keep your win.loadURL( to go to another markdown page.
The 'will-navigate' event docs.
window.history.pushState ref.
I hope this helps :)

update current page number of pdf opened in new browser tab

I have a function I'm using to open PDF's in a new tab of the browser. The user may want to navigate to a different page than the one opened, so page can also be updated by the function:
openpdf: function(url, page, pageCount){
try {
console.log('the page count is ' + pageCount);
var page = new Number(page) + new Number(pageCount);
if (mobileAndTabletcheck()){
console.log('mobile detected');
return window.open(url + '#page' + page, 'somename');
}
console.log('no mobile detected')
return window.open(url + '#page=' + page, 'somename');
}
catch(e){
console.log(e)
}
},
The problem I'm having is that when the user clicks to navigate to the new page of the pdf, the URL is updated with the correct page number, but the viewer stays on the page originally opened.
Does anyone know how to make the current page update when the URL is updated?
You may use the local storage as a location to keep track of the open documents. I believe that the pdf viewer and the main page stays on the same domain. SO you may try something like this.
openpdf: function(url, page, pageCount){
try {
console.log('the page count is ' + pageCount);
var page = new Number(page) + new Number(pageCount);
if (mobileAndTabletcheck()){
console.log('mobile detected');
return window.open(url + '#page' + page, 'somename');
}
console.log('no mobile detected')
return window.open(url + '#page=' + page, 'somename');
}
catch(e){
console.log(e)
}
var openedLinks = JSON.parse(localStorage.getItem("links"));
openedLinks.push("Your URL here");
localStorage.setItem("links", JSON.stringify(names));
}
On the pdf viewer page, just update the local storage.
onpageChanged : function(){
var openedLinks = JSON.parse(localStorage.getItem("links"));
var index = items.indexOf("Your current Url");
if (index !== -1) {
openedLinks[index] = "Your updated URL";
}
localStorage.setItem("links", JSON.stringify(names));
}
And finally on the main page, use something like a timer to keep track of the opened links.
setInterval(function(){
var openedLinks = JSON.parse(localStorage.getItem("links"));
$("#someDiv").html(openedLinks.join(","));
},1000);
Hope this works for you. The code is not tested and may have errors.

OAuth Flow not working when using Promise

I am building a simple chrome extension which integrates with Twitter using OAuth. I have slightly modified the Chrome OAuth Tutorial to integrate with Twitter. The extension is build in Reactjs+Flux.
When the user clicks on "Sign in with Twitter" button, an Action signin is triggered, which is declared as follows:
signin: function(){
ChromeUtils.connecttotwitter().then(alert("Step After Then"));
AppDispatcher.dispatch({actionType:TweetSmartActions.SIGN_IN,signedInTwitterUserId: response.user_id});
},
The ChromeUtils.connecttotwitter() is defined as follows:
var ChromeUtils = {
connecttotwitter: function () {
return new Promise(function(fulfill,reject){
var request = {
type : "background.twitterRequestToken",
};
alert("Before sendMessage");
chrome.runtime.sendMessage(request, function(response) {
if (response)
{
fulfill(response);
}
else
{
reject(response);
}
});
});
},
And the event listener onMessage is defined in the background.js as:
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
console.log("background.js: " + JSON.stringify(request));
var type = request.type;
if (type == "background.twitterRequestToken")
{
oauth.authorize(function(token,secret,userId,screenname){
sendResponse({success:true,userId:userId,screenName:screenname});
});
alert("Alerting before returning true");
return true;
}
When I click on the "Sign In With Twitter" button, the authentication flow does start and a new page opens. However, after I introduced the Promise, the new page does not redirect to the twitter oauth page. In fact, to debug that I have put the following alert statements in chrome_ex_oauth.js:
ChromeExOAuth.prototype.initOAuthFlow = function(callback) {
if (!this.hasToken()) {
var params = ChromeExOAuth.getQueryStringParams();
if (params['chromeexoauthcallback'] == 'true') {
var oauth_token = params['oauth_token'];
var oauth_verifier = params['oauth_verifier']
this.getAccessToken(oauth_token, oauth_verifier, callback);
} else {
var request_params = {
'url_callback_param' : 'chromeexoauthcallback'
}
this.getRequestToken(function(url) {
alert("Url after get request token " + url);
window.location.href = url;
alert(window.location.href);
}, request_params);
}
Here, the url in the first alert is the twitter oauth url but the second alert gives the Chrome extension Url -
chrome-extension://kiekipigbdldhggmlohbnhofnjhcbmem/chrome_ex_oauth.html
Why did the url not get assigned to window.location.href?
Any ideas on what might be happening?
The issue was not because I was using a Promise, but because when using Flux, the Action was being Dispatched before the response from the Promise was received and this was causing the app to hang somehow
signin: function(){
ChromeUtils.connecttotwitter().then(alert("Step After Then"));
AppDispatcher.dispatch({actionType:TweetSmartActions.SIGN_IN,signedInTwitterUserId: response.user_id});
},
In the above, the AppDispatcher.dispatch should be called in the function which is invoked on then.

JQuery doesn't handle dynamic events with .load

On a webpage, when you click a link, the content of that page is fetched using the .load function. If nothing is found, then nothing happens.
The issue now is that if you go from one page to the next, and then back again, the code doesn't work.
Its a lot easier to go to my test site - http://joshblease.co.uk/JQuery/
Click on the orange link "Page"
Click on the header link "Index"
Now click on the orange "Page" link again
The page refreshes and I do not know why?
Edit: I am using Chrome to test this at the moment
Edit: My Code
function JLoad (url, elem, type) {
if(type != "ext"){
var $link = elem;
var uri = url + ' #content';
$("#content").load(uri, {'body_only': '1'}, function(response, status, xhr){
if (status != "error") {
if (window.history && window.history.pushState){
window.history.pushState({}, 'JoshBlease Test', url);
}else{
window.location.hash='!/'+url;
}
if(type == "menu"){
$("a").removeClass("active");
$link.addClass("active");
}
}else{
if(type == "menu"){
var linkText = $link.text();
$link.fadeOut(function(){$link.addClass("notFound").text("404 Error")}).fadeIn().delay(2000).fadeOut(function(){$link.removeClass("notFound").text(linkText)}).fadeIn();
}
}
});
}
};
This is in the header of the pages:
$(document).ready(function() {
$("a").on("click", function(event) {
console.log("Click");
event.preventDefault();
var url = $(this).attr("href").replace('./', '');
JLoad(url, $(this), $(this).attr("type"));
return false;
});
});
The Link being used:
Page
I am not sure why, but by using an old version of JQuery, I replaced the "on" event with "live". It now seems to work?

Categories