Maintain colllapse-state after refresh - javascript

In my Sidebar I included a collapse button to show/hide a form. Now I want to maintain the collapse-state when refreshing the page:
If the form was un-collapsed before refreshing the page, it must stay like this after the refresh.
I think I need to use the localStrorage in JavaScript, but I actually don't know how to use this.
This is my HTML:
<!-- Sidebar -->
<ul class="sidebar navbar-nav">
<li class="nav-item active">
<a class="nav-link" data-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample">
<i class="fa fa-filter"></i>
<span>Search Filter</span>
</a>
</li>
</ul>
<!-- Form -->
<div class="collapse" id="collapseExample">
<form>
......
</form>
I found some code only but it seems like it does not work for me..:
var shown = []
// On collapse
shown.remove($(this).attr('id'));
localStorage.setItem('shown', shown);
// On open
shown.push($(this).attr('id'));
localStorage.setItem('shown', shown);
// On page load
var shown = localStorage.getItem('shown');
for (var s in shown) {
$('#collapseExample' + s).show();
}
Thanks for your help!

Here's a Bootstrap 4 collapse example that works. The main difference from the starter template is that I moved the jQuery import to the top of the file so that I could use the document.load function. I've added comments to the code but if anything's still not clear, keep asking questions. Note that I left the vanilla javascript answer for historical comments and in case it helps you, too.
I used the starter page from here:
https://getbootstrap.com/docs/4.0/getting-started/introduction/
And the first collapse example from here:
https://getbootstrap.com/docs/4.0/components/collapse/
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<!-- Bootstrap CSS -->
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous"
/>
<title>Hello, world!</title>
<!-- jQuery -->
<script
src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"
></script>
<script>
$(function() {
// store a reference to the collapse div so that
// we don't have to keep looking it up in the dom
const collapseExample = $("#collapseExample");
// register a callback function to the collapse div that
// will be called every time the collapse is opened.
collapseExample.on("shown.bs.collapse", function() {
// since we know that that this function is called on
// open, we'll set the localStorage value to "show"
localStorage.setItem("collapseExample", "show");
});
// register a callback function to the collapse div that
// will be called every time the collapse is closed.
collapseExample.on("hidden.bs.collapse", function() {
// since we know that that this function is called on
// open, we'll set the localStorage value to "hide"
localStorage.setItem("collapseExample", "hide");
});
// Since this function runs on page load (meaning only once), we can
// check the value of localStorage from here and then call the
// bootstrap collapse methods ourselves:
// Check the value of the localStorage item
const showExampleCollapse = localStorage.getItem("collapseExample");
// Manipulate the collapse based on the value of the localStorage item.
// Note that the value is determined by lines 36 or 44. If you change those,
// then make sure to check that the comparison on the next line is still valid.
if (showExampleCollapse === "show") {
collapseExample.collapse("show");
} else {
collapseExample.collapse("hide");
}
});
</script>
</head>
<body>
<main>
<p>
<a
class="btn btn-primary"
data-toggle="collapse"
href="#collapseExample"
role="button"
aria-expanded="false"
aria-controls="collapseExample"
>
Link with href
</a>
<button
class="btn btn-primary"
type="button"
data-toggle="collapse"
data-target="#collapseExample"
aria-expanded="false"
aria-controls="collapseExample"
>
Button with data-target
</button>
</p>
<div class="collapse" id="collapseExample">
<div class="card card-body">
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus
terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer
labore wes anderson cred nesciunt sapiente ea proident.
</div>
</div>
</main>
<!-- Optional JavaScript -->
<!-- Popper.js, then Bootstrap JS -->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"
></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"
></script>
</body>
</html>
END BOOTSTRAP ANSWER
BEGIN VANILLA JAVASCRIPT ANSWER
Here's a basic, self-contained version of what you seem to be trying to do. It's not pretty, but hopefully, it's clear.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
function getCollapsed() {
const state = localStorage.getItem('collapsed');
if(state === 'collapsed'){
return true;
}
return false;
}
function getStatus(){
const resultDiv = document.getElementById('result');
const isCollapsed = getCollapsed();
if(isCollapsed){
resultDiv.innerHTML = "collapsed";
}else{
resultDiv.innerHTML = "un-collapsed";
}
}
function toggleCollapse(){
const isCollapsed = getCollapsed();
if(isCollapsed){
localStorage.setItem('collapsed', 'un-collapsed');
}else{
localStorage.setItem('collapsed', 'collapsed');
}
getStatus();
}
</script>
</head>
<body onload="getStatus()">
<div>
<button onclick="toggleCollapse()">Toggle Collapse</button>
</div>
<div id="result"></div>
</body>
</html>

Related

How to trigger click event with enter button?

I am building a very basic magic 8 ball type 'game' using vanilla javascript. I have a text field (for a user question) and a submit button underneath. At present, I have it working fine with a event listener for the submit button but am trying to also get the same result if a user was to click enter.
I saw on w3s that you can trigger a button click upon enter, as below...
// Get the input field
var input = document.getElementById("myInput");
// Execute a function when the user presses a key on the keyboard
input.addEventListener("keypress", function(event) {
// If the user presses the "Enter" key on the keyboard
if (event.key === "Enter") {
// Cancel the default action, if needed
event.preventDefault();
// Trigger the button element with a click
document.getElementById("myBtn").click();
}
});
...but I can't seem to translate that into my own project. HTML and JS for my project below; I am trying not to use nested functions at the moment just to help with my understanding (as advised by my course mentor).
JavaScript
let question = document.querySelector('#userQuestion');
let button = document.querySelector('#shakeButton');
let answer = document.querySelector('#answer');
let options = [
'It is certain.',
'Signs point to yes.',
'Concentrate and ask again.',
'My sources say no.',
]
// Generate a random number
function generateAnswer() {
let index = Math.floor(Math.random() * 4);
let message = options[index];
answer.textContent = message;
answer.style.fontSize = '18px';
setTimeout(timeOut, 3000);
};
// Timeout function
function timeOut() {
answer.textContent = '8';
answer.style.fontSize = '120px';
};
// Enter button trigers click event
function enterButton (event) {
if (event.key === "Enter") {
event.preventDefault();
button.click();
}
};
//Event listener for button click
button.addEventListener('click', generateAnswer);
question.addEventListener("keypress", enterButton);
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Magic 8 Ball, ask it anything and it will answer.">
<!-- Stylesheet & Font Awesome Links -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Orbitron:wght#800&family=Press+Start+2P&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css">
<link rel="stylesheet" href="assets/css/style.css" type="text/css">
<!-- Stylesheet & Font Awesome Links End -->
<title>Magic 8 Ball</title>
</head>
<body>
<nav class="navbar">
<div class="container-fluid">
<a class="navbar-brand ms-auto" href="#">dc games</a>
</div>
</nav>
<!-- Header -->
<header class="heading">
<h1>The Magic 8 Ball</h1>
<p>Shake the Magic 8 Ball and it will answer your question.</p>
</header>
<!-- Header End-->
<!-- Magic 8 Ball -->
<div class="ball-black">
<div class="ball-white">
<p id="answer">8</p>
</div>
</div>
<!-- Magic 8 Ball End -->
<!-- User Question -->
<div class="user-input">
<input type="text" class="form-control mb-2 mr-sm-2" id="inlineFormInputName2 userQuestion" placeholder="What is your question?" required>
<button type="button" class="btn" id="shakeButton">Shake!</button>
</div>
<!-- User Question -->
<!-- Footer -->
<footer>
<div class="copyright fixed-bottom">
<p>Copyright © dc games 2022</p>
</div>
</footer>
<!-- Footer End -->
<!-- JavaScript Links -->
<script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
<script type="text/javascript" src="assets/js/script.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
<!-- JavaScript Links End -->
</body>
</html>
You cannot have multiple Ids on a single DOMElement. If you remove inlineFormInputName2 from the id of the user question, your code will work.
You can only have multiple identifiers for a class.
classes are used for formatting with css and Ids to specifically identify an element.

How to use Jquery Plugin with React js and react-router-dom

I am learning react js and trying to create a website with react js from a Html template. The template is using Jquery Isotope image filter plugin and my react code using react-router-dom for navigating page. when starting the app, in the home page the filter is working properly but when navigating to another page using the menu bar, the isotope filter does not work. It again works when i hard reload the page again. I have tried some way but that didn't work. So what is the way to use Jquery Plugin in a react js app ??
My Code is below:
Index.html page. Here i am declaring the Scripts:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Favicons -->
<link href="assets/img/favicon.png" rel="icon">
<link href="assets/img/apple-touch-icon.png" rel="apple-touch-icon">
<!-- Google Fonts -->
<link
href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i|Raleway:300,300i,400,400i,500,500i,600,600i,700,700i|Poppins:300,300i,400,400i,500,500i,600,600i,700,700i"
rel="stylesheet">
<link rel="stylesheet" href="css/app.css">
<!-- Vendor CSS Files -->
<link href="assets/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="assets/vendor/icofont/icofont.min.css" rel="stylesheet">
<link href="assets/vendor/boxicons/css/boxicons.min.css" rel="stylesheet">
<link href="assets/vendor/owl.carousel/assets/owl.carousel.min.css" rel="stylesheet">
<link href="assets/vendor/remixicon/remixicon.css" rel="stylesheet">
<link href="assets/vendor/venobox/venobox.css" rel="stylesheet">
<link href="assets/vendor/aos/aos.css" rel="stylesheet">
<!-- Template Main CSS File -->
<link href="assets/css/style.css" rel="stylesheet">
<title>Laravel</title>
</head>
<body class="antialiased">
<div id="root"></div>
<script src="js/app.js"></script>
<!-- Vendor JS Files -->
<script src="assets/vendor/jquery/jquery.min.js"></script>
<script src="assets/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="assets/vendor/jquery.easing/jquery.easing.min.js"></script>
<script src="assets/vendor/php-email-form/validate.js"></script>
<script src="assets/vendor/owl.carousel/owl.carousel.min.js"></script>
<script src="assets/vendor/waypoints/jquery.waypoints.min.js"></script>
<script src="assets/vendor/counterup/counterup.min.js"></script>
<script src="assets/vendor/isotope-layout/isotope.pkgd.min.js"></script>
<script src="assets/vendor/venobox/venobox.min.js"></script>
<script src="assets/vendor/aos/aos.js"></script>
<!-- Template Main JS File -->
<script src="assets/js/main.js"></script>
</body>
</html>
Home.js component. Here i am using the isotope filter plugin:
import React from 'react';'
export default function Home() {
return (
<>
{/* <!-- ======= Portfolio Section ======= --> */}
<section id="portfolio" className="portfolio" style={{ marginTop: "50px" }}>
<div className="container" data-aos="fade-up">
<div className="section-title">
<h2>View Our Image Store</h2>
<p>Magnam dolores commodi suscipit. Necessitatibus eius consequatur ex aliquid fuga eum quidem. Sit sint consectetur velit. Quisquam quos quisquam cupiditate. Et nemo qui impedit suscipit alias ea.</p>
</div>
<div className="row" data-aos="fade-up" data-aos-delay="100">
<div className="col-lg-12 d-flex justify-content-center">
<ul id="portfolio-flters">
<li data-filter="*" className="filter-active">All</li>
<li data-filter=".filter-app">App</li>
<li data-filter=".filter-card">Card</li>
<li data-filter=".filter-web">Web</li>
</ul>
</div>
</div>
<div className="row portfolio-container" data-aos="fade-up" data-aos-delay="200">
<div className="col-lg-4 col-md-6 portfolio-item filter-app">
<div className="portfolio-wrap">
<img src="assets/img/portfolio/portfolio-1.jpg" className="img-fluid" alt="portfolio-1" />
<div className="portfolio-info">
<h4>App 1</h4>
<p>App</p>
<div className="portfolio-links">
<i className="bx bx-plus"></i>
<i className="bx bx-link"></i>
</div>
</div>
</div>
</div>
<div className="col-lg-4 col-md-6 portfolio-item filter-web">
<div className="portfolio-wrap">
<img src="assets/img/portfolio/portfolio-2.jpg" className="img-fluid" alt="portfolio-2" />
<div className="portfolio-info">
<h4>Web 3</h4>
<p>Web</p>
<div className="portfolio-links">
<i className="bx bx-plus"></i>
<i className="bx bx-link"></i>
</div>
</div>
</div>
</div>
</div>
</section>
And the isotope plugin is initialized in main.js script file that is integrated in the index.html page above.
So when i start the app, this page Home component works fine but when i go to another menu and come again to this menu then the filter doesn't work. What is the way to do this correctly?
Also i created below hooks to load the scripts in this Home component but doesn't work.
Hooks code:
import React, { useEffect } from 'react'
export default function loadScript(url) {
useEffect(() => {
const script = document.createElement('script');
script.src = url;
script.async = true;
document.body.appendChild(script);
return () => {
document.body.removeChild(script);
}
}, [url]);
}
and called it from Home component like below:
import loadScript from '../hooks/loadScript'
export default function Home() {
loadScript("assets/vendor/jquery/jquery.min.js");
loadScript("assets/vendor/bootstrap/js/bootstrap.bundle.min.js");
loadScript("assets/vendor/jquery.easing/jquery.easing.min.js");
loadScript("assets/vendor/php-email-form/validate.js");
loadScript("assets/vendor/owl.carousel/owl.carousel.min.js");
loadScript("assets/vendor/waypoints/jquery.waypoints.min.js");
loadScript("assets/vendor/counterup/counterup.min.js");
loadScript("assets/vendor/isotope-layout/isotope.pkgd.min.js");
loadScript("assets/vendor/venobox/venobox.min.js");
loadScript("assets/vendor/aos/aos.js");
loadScript("assets/js/main.js");
But is doesn't work. What is the right way to do this?
You may be having trouble loading jquery in. I would install it as an npm package:
npm i jquery
And then load jquery into your app like so:
import $ from 'jquery'
However, I'm not sure if it's failing for a different reason. You can load jquery as an npm package which might take some pain out of things, but I doubt that the jquery plugin you want to use exists as an npm package. I should mention that it is a little bit of an anti-pattern to use jquery within a React app. Not that you can't or shouldn't, but the challenge comes in trying to build a data model that is tracked within React's state management. When relying heavily on other libraries like jquery it can start to become a lot of work to stitch the two together.
That said, sometimes it still can be worth it to make use of a jquery plugin if it accomplishes something which cannot easily be done in a React plugin. You'll have to make the decision as to which is best in your case.

Smooth scroll Javascript works but messes up flask app

Im working on a flask app and in my index.html I have a js file that has a smooth scrolling script in it. The smooth scroll works as far as clicking on links and the page goes to that section nice and smooth, but I have a web form that Im trying to process with flask. When I run the app.py and then go to the url it gives my sites loads, but if I fill out the form and submit nothing happens. I get an error in dev console:
uncaught TypeError: Cannot read property 'top' of undefined
at HTMLInputElement.<anonymous> (main.js:33)
at HTMLInputElement.dispatch (jquery-3.4.1.min.js:2)
at HTMLInputElement.v.handle (jquery-3.4.1.min.js:2)
When I comment out the smooth scroll code and run the app, the form works correctly when I click submit. App.py prints out my data and the success page is loaded. The problem is the smooth scroll but I dont know why, because again it actually does smooth scroll but when the code is active but it wont let the submit work.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://kit.fontawesome.com/b015121141.js"></script>
<link rel="stylesheet" href="../static/css/style.css">
<link rel="stylesheet" media="screen and (max-width: 768px)" href="../static/css/mobile.css">
<link rel="stylesheet" media="screen and (min-width: 1100px)" href="../static/css/widescreen.css">
<title>System Services</title>
</head>
<body id="home">
<nav id="navbar">
<h1 class="logo">
<span class="text-primary">
<i class="fas fa-robot"></i>
</span>Systems
</h1>
<ul>
<li>Home</li>
<li>What</li>
<li>Who</li>
<li>Contact</li>
</ul>
</nav>
<!-- header: Showcase -->
<header id="showcase">
<div class="showcase-content">
<h1 class="l-heading">
Take me to your leader
</h1>
<p class="lead">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptates alias quasi eligendi. Itaque, repudiandae
obcaecati accusamus harum nesciunt possimus magni?
</p>
Read More
</div>
</header>
<!-- Section: Contact-->
<section id="contact">
<div class="contact-form bg-primary p-2">
<h2 class="m-heading">Contact Us</h2>
<p>Please Use the form below to contact us</p>
<form action="/submit" method="POST">
<div class="form-group">
<label for="name">Name</label>
<input type="text" name="name" id="name" placeholder="Enter Name">
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" name="email" id="email" placeholder="Enter Email">
</div>
<div class="form-group">
<label for="phone">Phone</label>
<input type="text" name="phone" id="phone" placeholder="Enter Phone">
</div>
<div class="form-group">
<label for="message">Message</label>
<textarea name="message" id="" placeholder="Enter Message"></textarea>
</div>
<input type="submit" value="Submit" class="btn btn-dark">
</form>
</div>
<div class="map"></div>
</section>
<!-- Footer -->
<footer id="main-footer" class="bg-dark text-center py-1">
<div class="container">
<p>Copyright © 2019, All Rights Reserved</p>
</div>
</footer>
<!-- JQuery CDN -->
<script src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<!-- Local Js file -->
<script src="../static/js/main.js"></script>
<!-- Google Maps -->
<script src="https://maps.googleapis.com/maps/api/js?key=[api]&callback=initMap"
async defer></script>
</body>
</html>
success.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Success</title>
</head>
<body>
<H1>Success!!</H1>
</body>
</html>
app.py
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/submit', methods=['POST'])
def submit():
if request.method == 'POST':
name = request.form['name']
email = request.form['email']
phone = request.form['phone']
message = request.form['message']
print(name, email, phone, message)
return render_template('success.html')
if __name__ == '__main__':
app.debug = True
app.run()
main.js
//init and add the map
function initMap() {
// your location
const loc = { lat: 42.964890, lng: -88.183040 };
// centered map on location
const map = new google.maps.Map(document.querySelector('.map')
, {
zoom: 10,
center: loc
});
// the marker, positioned at location
const marker = new google.maps.Marker({ position: loc, map: map });
}
// Sticky menu background
window.addEventListener('scroll', function () {
if (window.scrollY > 150) {
document.querySelector('#navbar').style.opacity = 0.88;
} else {
document.querySelector('#navbar').style.opacity = 1;
}
})
// Smooth Scrolling
$('#navbar a, .btn').on('click', function (event) {
if (this.hash !== '') {
event.preventDefault();
const hash = this.hash;
$('html, body').animate({
scrollTop: $(hash).offset().top - 100
},
800
);
}
});
The problem is really related on jquery forum and don't came from flask. Nevertheless, they are solutions :
Solution #1:
Use the native css smooth scroll (works fine in your case in my opinion) --> Smooth scroll
Solution #2 :
Try to call animate() in console of your website and paste it belowthe result to see where the problem came from :)
I hope this will help you I tried on my computer and I can figure any other solutions !
You have the line this.hash inside your click event which will always return "" and that is the reason you are getting the error because you have the hash/id in the href attribute of the links and buttons where you are binding the click event
<ul>
<li>Home</li>
<li>What</li>
<li>Who</li>
<li>Contact</li>
</ul>
<input type="submit" value="Submit" class="btn btn-dark">
Read More
and you just need to change the
this.hash
to
$(this).attr('href')
OR
this.href
your click event should look like this
// Smooth Scrolling
$('#navbar a, .btn').on('click', function (event) {
if (this.href !== '') {
event.preventDefault();
const hash = this.href;
$('html, body').animate({
scrollTop: $(hash).offset().top - 100
},
800
);
}
});

How to reload javascript without refreshing the page?

I have a webpage that links some javascript via tags. The script is amazon-localiser.js which will change an amazon link to one appropriate for the visitor. e.g. an Amazon.com link will swap to amazon.co.uk for a UK visitor or Amazon.de for a german visitor.It also appends to the link the relevant amazon affiliate link.
When the user lands on the page they click through some options (javascript) however by the time you reach an amazon link the page must be refreshed for the amazon-localiser.js script to work. I have tried using a page refresh in HTML but this sends me back to the very beginning of the questions. How do I reload the javascript without affecting the users location on the site?
The site is www.wfbsir.com, if you select "Scifi" then "Maybe" you will get to an amazon.com link, if you hover over it you will see it links to amazon.com if you refresh the page it will show you the link to your local store with an affiliate link appended.
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>What book should I read?</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="manifest" href="/manifest.json">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<link rel="stylesheet" href="app.css" />
</head>
<body>
<div class="wrapper">
<div class="container">
<div class="row">
<div class="col-xs-12 text-right">
<button class="btn btn-default btn-corner" type="submit" data-bind="click: startOver, visible: queryData().id > 0">Start over</button>
</div>
</div>
</div>
<div class="container main">
<div class="row">
<div class="c12 text-center">
<h1 data-bind="text: queryData().text"></h1>
<h3 data-bind="text: queryData().subhead"></h3>
<h3><a data-bind="text: queryData().link, attr: {href: url}"></a></h3>
<div class="option-group" data-bind="foreach: queryData().answers">
<button class="btn btn-default btn-lg" type="submit" data-bind="click: $parent.goToTarget, text: text"></button>
</div>
<button class="btn btn-default" type="submit" data-bind="click: stepBack, visible: navHistory().length > 1">Previous Step</button>
<button class="btn btn-default" type="submit" data-bind="click: buyBook, visible: navHistory().length > 1">Buy the book</button>
</div>
</div>
</div>
<div class="push"></div>
</div>
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"></script>
<script src="app.js?v=0.4.0"></script>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript" src="amazon-localiser.js"></script>
<script>
</script>
I have tried using jQuery getScript and also window.location.reload(); but neither reload just the javascript, the only thing that I can find to work is F5/Refresh.
I noticed that the amazon-localiser.js invokes the function findLocation onload of the page, as you can see below.
if (window.addEventListener) {
window.addEventListener("load", findLocation, false)
} else {
window.attachEvent("onload", findLocation)
}
So, a possible solution to your problem, could be to invoke this function again when you need to update your amazon link.
I tried invoking it from the console and it works, so try to invoke findLocation() manually when needed and see if it serves your scope.
Simone
You can add dynamically script on the page with some condition, for example:
var script = document.createElement('script');
var src;
if (true) {
src = 'amazon.co.uk';
} else {
src = 'amazon.com';
}
script.src = src;
document.head.appendChild(script);
As gnllucena told, you can view the question or there is the solution.
Build the loader function:
Put the following code in the document
<script type="text/javascript">
function LoadMyJs(scriptName) {
var docHeadObj = document.getElementsByTagName("head")[0];
var newScript= document.createElement("script");
newScript.type = "text/javascript";
newScript.src = scriptName;
docHeadObj.appendChild(newScript);
}
</script>
// place a button for reloading script.
<input type="button" name="reloadNewJs" value="Reload JavaScript" onClick="LoadMyJs('needed_script.js')">

What am I doing wrong with this JavaScript parsing code?

I am trying to make a simplistic HTML editor for part of my website without things like Ace or TinyMCE. The problem is that when I'm using local storage, the save function appears to work, but the view function is not changing the notes to the saved notes.
I made a JSFiddle for all of you, at this URL.
Here is my HTML code:
<html>
<head>
<!-- Begin Section 1: Metas -->
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="UTF-8">
<!-- End Section 1: Metas -->
<!-- Begin Section 2: Scripts -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.1.3/nprogress.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js" type="text/javascript"></script>
<script src="https://cdn.mxpnl.com/libs/mixpanel-2.2.min.js" type="text/javascript"></script>
<script src="https://secure.quantserve.com/quant.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.2.0/js/bootstrap.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ladda-bootstrap/0.1.0/ladda.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ladda-bootstrap/0.1.0/spin.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.2/modernizr.min.js" type="text/javascript"></script>
<script src="scripts/app/app.js" type="text/javascript"></script>
<!-- End Section 2: Scripts -->
<!-- Begin Section 3: Stylesheets and Links -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" rel="stylesheet" type="text/css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.1.3/nprogress.min.css" rel="stylesheet" type="text/css">
<link href="http://fonts.googleapis.com/css?family=Pacifico|Open+Sans|Roboto|Roboto+Slab" rel="stylesheet" type="text/css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/ladda-bootstrap/0.1.0/ladda.min.css" rel="stylesheet" type="text/css">
<link href="stylesheets/app/app.css" rel="stylesheet" type="text/css">
<!-- End Section 3: Stylesheets and Links -->
<!-- Start Section 4: Required Elements -->
<title>Superpad Editor</title>
<!-- End Section 4: Required Elements -->
</head>
<body>
<div class="container animated bounce">
<div class="errors"></div>
<nav class="navbar navbar-default" role="navigation">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-brand-centered">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<div class="navbar-brand navbar-brand-centered"><span class="brand-logo">Superpad</span></div>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="navbar-brand-centered">
<ul class="nav navbar-nav">
</ul>
<ul class="nav navbar-nav navbar-right">
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="btn-group">
<button type="button" class="btn btn-primary" id="save">Save Notes</button>
<button type="button" class="btn btn-success" id="view">View Saved Notes</button>
</div>
<div contenteditable class="content-editable normal editor"></div>
</div>
</body>
</html>
Here is my JavaScript (it uses jQuery):
NProgress.start();
mixpanel.init("<CENSORED FOR SECURITY>");
mixpanel.track("Page Loads");
NProgress.done();
$(document).ready(function(){
if (Modernizr.localstorage) {
console.log("L.S.W.");
} else {
$(".errors").append("<div class="alert alert-danger alert-dismissible" role="alert"><button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×<\/span><span class="sr-only">Close<\/span><\/button><strong>Oh snap!<\/strong> Local Storage doesn't work on your browser. Saving won't work, so you might want to keep this open if you want to keep your notes.<\/div>");
NProgress.done();
};
$("#save").click(function() {
localStorage["note"] = JSON.stringify($(".editor").html());
});
$("#view").click(function() {
if (localStorage["note"] != null) {
var contentsOfOldDiv = JSON.parse(localStorage["note"]);
$(".editor").
$("div.fifth").replaceWith(contentsOfOldDiv);
} else {
$(".errors").append("<div class=alert alert-info alert-dismissible> role="alert"><button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×<\/span><span class="sr-only">Close<\/span><\/button><strong>Heads up!<\/strong> No save was detected. Did you save before?<\/div>");
};
});
});
So what am I doing wrong (I got the JSON parsing idea from another Stack Overflow subject!)?
You have several syntax issues. For example the lines below:
$(".errors").append("<div class="alert alert-danger alert-dismissible" role="alert"><button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×<\/span><span class="sr-only">Close<\/span><\/button><strong>Oh snap!<\/strong> Local Storage doesn't work on your browser. Saving won't work, so you might want to keep this open if you want to keep your notes.<\/div>");
and
$(".errors").append("<div class=alert alert-info alert-dismissible> role="alert"><button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×<\/span><span class="sr-only">Close<\/span><\/button><strong>Heads up!<\/strong> No save was detected. Did you save before?<\/div>");
You need to escape the " character or use a single quote. That might not solve your issue, but it's a start. Your code is failing when execution reaches that line, and it can't continue, which might explain why you aren't getting the expected result.
Try using your browser developer tools to find any errors in your code. This page has some information on finding and using the dev tools in your browser. The error in the JSFiddle is shown as:
Uncaught SyntaxError: Unexpected identifier
If you fix the quotation issues, you then get the error:
Uncaught ReferenceError: mixpanel is not defined
Keep going through the errors in your console and see if you can narrow down the issue that way.

Categories

Resources