How can i execute a function after a form submission causes a page refresh? - javascript

I am using shopify's built in customer create, login, reset form submissions which on submit, forces the page to refresh. My intention is to show a message that shows after the page has been refreshed via a button click function. This is what i have so far; The message shows until that page refreshes and then the active class is removed as you would expect.
$(document).ready(function () {
class Alert {
constructor() {
this.customerAlert = document.createElement('div');
}
init(){
this.customerAlert.classList.add('customer-alert');
document.querySelector('body').append(this.customerAlert);
}
show(message){
this.customerAlert.textContent = message;
this.customerAlert.classList.add('active');
setTimeout(() => {
this.customerAlert.classList.remove('active');
}, 8000);
}
}
//create snackbar and initiate
const alertMessage = new Alert();
alertMessage.init();
const createAccountButton = document.querySelector('input.account-trigger');
createAccountButton.addEventListener('click', () => {
alertMessage.show('Your account in now under review');
});
});

Set a boolean variable in session storage just prior to the submit to represent the two states, and then read it in after the refresh.
Something like this:
function HandleFlag(){
var F=sessionStorage.getItem('Flag');
if(F=='1'){
// display your message box here
sessionStorage.setItem('Flag','0');
} else {
// the state is "0" so toggle it just before submitting
sessionStorage.setItem('Flag','1');
}
}
I hope you get my drift.

Related

Firebase.auth.currentUser not available on load of page but available after a few seconds

My problem is that on load of my page, I need to access the information firebase.auth.currentUser, but this information is undefined if I call my function in the eventListener('load). But if I call it on click on a button, here the "add" button, (so a few seconds after page loaded), then it is working.
Here is what I tried in my code.
var FIREBASE_AUTH;
var FIREBASE_DATABASE;
const addButton = document.getElementById("add");
addButton.addEventListener("click", getEtablissemennts);
window.addEventListener('load', (event) => {
FIREBASE_AUTH = firebase.auth();
FIREBASE_DATABASE = firebase.database();
getEtablissemennts();
});
function getEtablissemennts(){
//works only if function is call on click on the button, doesn't work on load of the page
FIREBASE_DATABASE.ref('users').orderByChild('email').equalTo(FIREBASE_AUTH.currentUser.email).once("value", function(snapshot) {
...
}
}
You can't expect Firebase to authenticate the user and get their data on load. You should set up a listener:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is available now
} else {
// No user is signed in.
}
});
Source: https://firebase.google.com/docs/auth/web/manage-users#get_the_currently_signed-in_user

History API does not apply history changes until the user performs any actions on the page

There is a site page on which you need to implement routing using the history of API.
This page can be accessed as follows:
transition from a blank page,
transition from another page (external / internal),
return using the browser button Back,
routing the page inside using the open / close buttons.
Routing example:
site.com/typical-page/routing-page-level1/routing-page-level2/routing-page-level3/other-typical-page
typical-page, other-typical-page - pages without routing
routing-page-level1, routing-page-level2, routing-page-level3 - a page with routing.
Inside the page it works fine I go to the page with routing:
site.com/typical-page/routing-page-level1/
I click on the button level2, go to:
site.com/typical-page/routing-page-level1/routing-page-level2/
level3, go to:
site.com/typical-page/routing-page-level1/routing-page-level2/routing-page-level3
I click Close on the page or the BACK button in the browser I go
site.com/typical-page/routing-page-level1/routing-page-level2/
I click Close again on the page or the BACK button in the browser I go
site.com/typical-page/routing-page-level1/
If I immediately go to site.com/typical-page/routing-page-level1/routing-page-level2/routing-page-level3 from a blank page, and then click BACK in the browser, I return to a blank page.
But, if from a blank page I immediately go to site.com/typical-page/routing-page-level1/routing-page-level2/routing-page-level3, then I click anywhere on the page and then click BACK in the browser , then I’m going to site.com/typical-page/routing-page-level1/routing-page-level2, if again, then
at site.com/typical-page/routing-page-level1.
I understand that the browser does not apply history changes until the user performs any actions on the page. For example, click.
How can this be avoided?
This article was used as a sample JS - window.history - Delete a state
This is pseudo code.
let guideHistory = ['init'];
let flag;
history.pushState({state: '/guide'}, '', '/guide');
// User came from blank page
if (!history.state) {
setTimeout(() => {
flag = true;
history.replaceState({state: '/routing-page-level1'}, '', '/routing-page-level1');
level2.trigger('click');
}, 20);
}
// User came from other page
if (history.state) {
flag = true;
level2Click(level2);
}
level2.on('click', level2Click);
level3.on('click', level3Click);
function level2Click() {
addHistory(level2.attr("data-path"));
if (flag)) {
setTimeout(() => {
level3.trigger('click');
}, 30) ;
}
function addHistory(historyState, historyPath) {
if (guideHistory[0] === 'init'){
guideHistory.pop();
}
if (historyPath) {
guideHistory.push('/routing-page-level1' + '/' + historyPath);
}
else {
guideHistory.push('/routing-page-level1');
}
history.replaceState({state: historyState}, '', '/routing-page-level1/' + historyState);
}
}
function level3Click(event) {
setTimeout(() => {
addHistory(level3, level2));
}, 0);
}
window.onpopstate = function() {
if (guideHistory[0] !== 'init') {
if (!guideHistory.length) {
history.go(-1);
}
else {
pushHistory(guideHistory);
function pushHistory(guideHistory) {
let pop = guideHistory.pop();
history.pushState({state: pop}, '', pop);
}
}
}
};
Thanks!

beforeinstallprompt triggers on every load

Beforeinstallprompt triggers on every load.
I have used the code here: https://developers.google.com/web/fundamentals/app-install-banners/
I am not using the The mini-info bar which i have dissabled by calling e.preventDefault();
The problem is that the showAddToHomeScreen(); is called on every load if the user does not click addToHomeScreen.
I want the showAddToHomeScreen(); function to be called only every month or so by storing information about the last "canceled" click in sessions or something similar. Isn't google suppose to do this on it's own?
This i found on the following link:
https://developers.google.com/web/updates/2018/06/a2hs-updates
You can only call prompt() on the deferred event once, if the user clicks cancel on the dialog, you'll need to wait until the beforeinstallprompt event is fired on the next page navigation. Unlike traditional permission requests, clicking cancel will not block future calls to prompt() because it call must be called within a user gesture.
window.addEventListener('beforeinstallprompt', function (e) {
// Prevent Chrome 67 and earlier from automatically showing the prompt
e.preventDefault();
// Stash the event so it can be triggered later.
deferredPrompt = e;
showAddToHomeScreen();
});
function showAddToHomeScreen() {
var prompt = document.querySelector(".a2hs-prompt");
prompt.style.display = "flex";
var open = document.querySelector(".a2hsBtn");
open.addEventListener("click", addToHomeScreen);
var close = document.querySelector(".a2hsBtn-close");
close.addEventListener("click", function() {
prompt.style.display = "none";
});
}
function addToHomeScreen() {
var prompt = document.querySelector(".a2hs-prompt");
// hide our user interface that shows our A2HS button
prompt.style.display = 'none';
if (deferredPrompt) {
// Show the prompt
deferredPrompt.prompt();
// Wait for the user to respond to the prompt
deferredPrompt.userChoice.then(
function (choiceResult) {
if (choiceResult.outcome === 'accepted') {
show_ad2hs_success_message();
}
deferredPrompt = null;
});
}
}
You have to define your own session and add expire date. This is simple with ajax. This is how i did:
Javascript:
$(document).ready(function() {
$.ajax({
url: '/update_session_addtohomescreen',
success: function (session_expired) {
if(session_expired=='True'){
showAddToHomeScreen();
}
},
error: function () {
alert("it didn't work");
}
});
});
This is wrapping the showAddToHomeScreen(); function
View
#csrf_exempt
def update_session_addtohomescreen(request):
if request.is_ajax():
number_of_days_till_expire = 1
now_in_secs = time.time()
if not 'last_session_coockie' in request.session or now_in_secs > request.session['last_session_coockie']+60:#number_of_days_till_expire*86400:
session_expired = True
request.session['last_session_coockie'] = now_in_secs
else:
session_expired = False
return HttpResponse(session_expired)
return None
You should though include csrf token in your request and also add the url to urls.py

reset webpage to its initial state

I have written a clear function which is supposed to clear map and combo box. But I want to reset the webpage to its initial state. I have tried APP.restart()
App.restart = function() {
var child,
child_process = require("child_process"),
gui = require('nw.gui'),
win = gui.Window.get();
if (process.platform == "darwin") {
child = child_process.spawn("open", ["-n", "-a", process.execPath.match(/^([^\0]+?\.app)\//)[1]], {detached:true});
} else {
child = child_process.spawn(process.execPath, [], {detached: true});
}
child.unref();
win.hide();
gui.App.quit();
}
But nothing works.
I do not need to reload function. Can anyone tell how to reset the webpage to its initial state?
Follow any one of this:
1.Prevent page from caching (with response headers from server);
2.Clear all fields each time page is loaded with Javascript.
Example with jQuery:
<script>
$(document).ready(function(){
$('your_form_input_fields_id').val('');
});
</script>
See this link: reset webpage

Commit settings instantly Windows 8 app

I'm trying to make a test app for Windows 8 that has two input boxes and one button (lets call it "Calculate" button). When the user presses the button he gets a result. He can enter his details in either metric or imperial units by choosing which units he wants to use in the settings flyout. Now what I'm trying to do is to commit the changes instantly. When the user selects for example the imperial units the input boxes and the result automatically change to imperial. Right now when I change the units from metric to imperial I must press the "Calculate" button again to see the results in imperial.
How can I do that?
Below is some of my code.
In the default .js file I created a button handler:
var test = document.getElementById("button");
test.addEventListener("click", doDemo, false);
In the main .js file where all the calculations are done it looks like this:
function doDemo(eventInfo) {
var applicationData = Windows.Storage.ApplicationData.current;
var roamingSettings = applicationData.roamingSettings;
if (roamingSettings.values["cmorft"] == 'imperial') {
var greetingString3 = "Imperial";
document.getElementById("units").innerText = greetingString3;
} else {
var greetingString4 = "metric";
document.getElementById("units").innerText = greetingString4;
}
I used the following to save the user's choice:
var applicationData = Windows.Storage.ApplicationData.current;
var roamingSettings = applicationData.roamingSettings;
WinJS.UI.Pages.define("/html/settings.html", {
// This function is called whenever a user navigates to this page. It
// populates the page elements with the app's data.
ready: function (element, options) {
var imperialRadio = document.getElementById("imperial"),
metricRadio = document.getElementById("metric");
// Set settings to existing values
if (roamingSettings.values.size > 0) {
if (roamingSettings.values["cmorft"]) {
setMIValue();
}
}
// Wire up on change events for settings controls
imperialRadio.onchange = function () {
roamingSettings.values["cmorft"] = getMIValue();
};
metricRadio.onchange = function () {
roamingSettings.values["cmorft"] = getMIValue();
};
},
unload: function () {
// Respond to navigations away from this page.
},
updateLayout: function (element, viewState, lastViewState) {
// Respond to changes in viewState.
}
If I understand you correctly, you simply need to set the innerText properties of your HTML elements when you change the units, not just when you click the button. In your demo it can be as simple as calling doDemo from within the onchange handlers for your radiobuttons, as that will read the updated setting and set the text.

Categories

Resources