Simple ajaxify, without hash or hashbang urls - javascript

I'm taking a course in webdesign. I and a lot of the other students are really interested in ajaxifying our work. Our teacher is only into design and HTML - so he can't help.
I hope I use the right term - otherwise please correct me. By ajaxifying, I mean having my webpage only update certain parts when navigating.
For example, let's say I have a webpage consisting of 3 subpages:
1: index.html
<!DOCTYPE html><html><head><title> Welcome! </title></head>
<body>
<div id="Content"> Welcome, dear visitor... take a look around! </div>
<div id="Menu">
<ul>
<li><b> Home </b></li>
<li> Projects </li>
<li> Contact </li>
</ul>
</div>
<div id="Footer"> Email and mediaplayer </div>
</body></html>
2: projects.html
<!DOCTYPE html><html><head><title> Projects </title></head>
<body>
<div id="Content"> All my projects are shown here! </div>
<div id="Menu">
<ul>
<li> Home </li>
<li><b> Projects </b></li>
<li> Contact </li>
</ul>
</div>
<div id="Footer"> Email and mediaplayer </div>
</body></html>
3: contact.html
<!DOCTYPE html><html><head><title> Contact </title></head>
<body>
<div id="Content"> Contact info! </div>
<div id="Menu">
<ul>
<li> Home </li>
<li> Projects </li>
<li><b> Contact </b></li>
</ul>
</div>
<div id="Footer"> Email and mediaplayer </div>
</body></html>
When using the links:
Only the Content-div should be reloaded.
The Menu should update which menu-point is active (here shown with bold-tags). If that's too complex a reload of the menu could work.
The Footer should not be reloaded at all.
The title should be updated.
The url should be updated.
I would really like the urls to be clean. That is: NOT /#projects.html or /#/projects.html, but just straight-up /projects.html or /projects
Working bookmarking and back-button are crucial.
Is this possible at all? I would be forever insanely thankful to anyone helping me here! :-D
I've tried out (and hacked around with) jQuery Address and History plugins, the History.js and a 'gist' to it. Couldn't get any of it to work. I've trawled and trawled stack overflow and google, but can't seem to find anyone explaining these things or having a simple solution.
A solution aiming at modern webbrowsers would be fine. If the IE guys and the no javascripts guys just gets the simple html-version, that would be cool - but it's not absolutely necessary.
Please help - any help would be very, very appreciated! Thanx! :-)

What you want is possible, but not quite easy to do.
As already mentioned, the HTML5 History API makes it possible, but you will need a good knowledge of javascript. Displaying more or less static pages isn't exactly what it's intended for, but the sake of learning, let's think about how it could be done.
You might probably want to use a framework like backbone that already comes with a router so that you don't have to write your own abstractions.
The basic idea behind a client side router is that you have an easy way of defining what URL triggers what javascript function similar to this:
var routes = {
"index": "open_index",
"projects": "open_projects",
"contact": "open_contact"
}
var open_index = function(){
// Do the logic that has to be done
// to open the index page
}
...
Note that the code is only there to illustrate the idea, it doesn't conform to any actual framework or library.
Anyway, every time that one of these routes is triggered you need to take care of basically taking apart the entire page and replacing everything with the desired content.
Now you have basically two choices for that. Either you fetch HTML from the server and just plug it in, or you only fetch the actual data in JSON and use client side templating.
What does that mean? Well, right now you use static HTML pages. They do have a basic structure that is shared by all the pages, namely the separation in 'Content', 'Menu' and 'Footer', however, since this is not a web application but a web site, the content of the 'Content' probably does not follow a structure that represents some kind of structured data.
An example for it representing structured data would be a phone directory. You always have a list of 'First name', 'Last name' , 'Phone number' and this is primarily what defines the page. The way it looks is not what the page is about.
The entire content of the page can be defined by an array like this:
var people = [
{ "firstName" : "John", "lastName" : "Doe", "number": "+12-2322132"},
{ "firstName" : "Dick", "lastName" : "Dobson", "number": "+12-656533"},
...
]
and rendered client side using a simple template like for example:
<ul class="phone_book">
{{#each people}}
<li>{{firstName}} {{lastName}} - {{number}}</li>
{{/each}}
</ul>
to generate the needed HTML. (That was handlebars by the way)
Using a framework, you can easily set it up for the script to update the information display automatically upon updating the data - for example by using AJAX.
In your case however, it is most likely that the way the page looks is what it is about. You need one image here and one image there and a bit of text inbetween, and all of this changes with every single page. You need HTML.
That's the reason why what you want isn't exactly what you would use the History API and AJAX for. It is primarily intended for complex web applications that need to spread several pages with their own urls that can also potentially capture the state of the application so that linking to a specific part of a javascript heavy web application becomes possible. Loading static websites works just fine without using AJAX and the History API.
Let's ignore this right now and just continue anyway.
Let's try and see what the open_index function needs to work.
var open_index = function(){
// 1. Fade out the old content and remove it
// 2. Request the new html content from the server
// 3. Mark the new active link in the navigation
// 4. Add the content to the DOM
// 5. Fade in the new content
}
All of this you can easily do with jQuery. You'll have no trouble finding an explanation for how to do this.
Now you are almost there. The only remaining thing to take care of is to make sure that you intercept the click events for your navigation so that you can use the History API and it won't just load the static page from the beginning.
For a simple use such as this, not a whole lot more is needed structure wise.
I'll say it again. This is complete overkill for your purpose and you should not be using it for that other than for learning purposes. If you don't use a library that abstracts away the History API a bit, the code will become a lot more complex.
I hope this helped giving you an idea of what you are dealing with.

Related

Is it possible (probably with javascript) to change the HTML page content without loading a different HTML page? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
So I have just recently started with web design.
My index.html has a menu (consisting of containing links to different pages).
The menu on the index.html page (in a very simplified way, no css and things like that) looks something like this:
<ul>
<li><a class="active" href="index.html"></li>
<li><a href="contactus.html"></li>
<li><a href="help.html"></li>
<ul>
and then there is the content of the page (text, slideshow, images...) - say
<div>
<h1><img><p><script>
</div>
the contactus.html page looks somethinglike this:
<ul>
<li><a href="index.html"></li>
<li><a class="active" href="contactus.html"></li>
<li><a href="help.html"></li>
<ul>
and then there is the content of the page (text, slideshow, images...) - say
<div>
<h1><img2><p><script>
When you click on the link, it leads you to a different page.
So say we have index.html, we click on a link in the menu and it leads us to contactus.html. It changes the page, the contactus.html has to load.
And the question is: is it possible to make it so that the content of contactus.html appears on index.html (and replaces it) but in such a way that does not require another page loading?
I have done some research and found something about innerHTML, but I cannot really understand how to use it. I started with js not a long time ago.
I hope the question somehow makes sense.
Thanks a lot for your suggestions and advice.
Yeah. document.body.innerHTML = "<p>Some new HTML!</p>". And there are lots of other ways as well. I like React, but it definitely has a learning curve. I don't know if real web developers still use jQuery, but it makes a lot of DOM manipulation stuff pretty easy. Good luck!
What server do you use? Do you use apache or ngnix for the html files?
You can get the content of "Contacts.html" and replace the content's html with it.
For example:
$.get("contacts.html", function(data, status){
document.getElementById("content").innerHTML = data;
});
This code uses jQuery for ajax requests and you can use XMLHttpRequest with only javascript.
Caution: You shouldn't run the html only. This will not work without html server.
Cheers.
This will be an extremely simplistic answer because it is a huge argument... but lets start with some basics.
The objective is, starting from a web page (index.html), to load some content and update only part of the content in the current page.
I will suggest two different approaches for both client and server side of the equation.
jQuery + HTML fragments
The idea of this approach is to use jQuery to manage AJAX requests to retrieve some content from the server and to update the DOM of the current page to display the new content.
Server side
Here you need to expose some content, in the simplest of cases it can be just a fragment of html like this:
fragment.html
<p>My asynchronously loaded content!<p>
The fragment above can be exposed directly as static content through apache or nginx, or can be generated dynamically with PHP, Java, C# or any programming language with good support for web development.
Client side
On the client we want to contact the server from javascript and retrieve the content with an AJAX request, then update the html. jQuery enables us to do both of those things.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test page</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
</head>
<body>
<h1>Home page</h1>
<div id="content">
<p>Welcome!</p>
</div>
<div>
<button id="update-btn">Update content</button>
</div>
<script>
$(document).ready(function() {
$('#update-btn').click(function(){
$.get('http://myserver/fragment.html').then(function(data) {
$('#content').html(data);
});
});
});
</script>
</body>
</html>
We have a div with id content which we will use as the target for the new content, and a button with id update-btn to launch the request.
In the <script> block we first associate the click event to the button so that when clicked we send an ajax request to the server using jQuery get method and update the html content with jQuery html method.
Javascript framework + REST API
This is definitely a more complex approach and a complete guide/example is out of scope for a SO answer (there are books hundreds of pages long for each client side framework and for each server side language/framework) but let's explore the base concept behind this idea.
In the previous example we had the server generate an html and then the client ask for more html to update itself. Here the basic idea is the same but with a much more clear separation of concerns where the server is in charge of generating and sending raw data to the client (usually in JSON or XML format), and the client has to manage all of the presentation and user interaction aspects.
As an example we can analyze the hacker-news get item api.
The url structure is https://hacker-news.firebaseio.com/v0/item/{item-id}.json?print=pretty
We can make a GET request with a an id as a path variable and an optional query parameter called print and it will return some JSON data.
For example we can curl https://hacker-news.firebaseio.com/v0/item/25213368.json?print=pretty and get the following response:
{
"by" : "harporoeder",
"descendants" : 8,
"id" : 25213368,
"kids" : [ 25224137, 25224226, 25224397 ],
"score" : 31,
"time" : 1606333258,
"title" : "Use `nproc` and not grep /proc/cpuinfo",
"type" : "story",
"url" : "https://www.flamingspork.com/blog/2020/11/25/why-you-should-use-nproc-and-not-grep-proc-cpuinfo/"
}
Once we have all the services we need exposed the client can be built with many different frameworks and libraries. In the first approach we used jQuery which is fine for very simple use cases but can become a hell to write and maintain when we start adding complexity to our application, this is why there are many different frameworks to implement the client such as: VueJS, React, SvelteJS, Angular, Aurelia and many others.
Each one of those javascript frameworks has a big learning curve and you will most probably also need to learn how to work with Nodejs, NPM, transpilers and bundlers to make use of the whole modern javascript infrastructure.
This will not be an easy journey but you will learn a valuable skill if you decide to go this road.
Hope this gives you an idea on how to go on with learning web development.
This is your answer with vanilla javascript.
index.js file is:
onclick = "changeHtml()";
const button = document.getElementById("btn");
button.addEventListener("click", function () {
document.getElementById("app").innerHTML = `
<h1>I'm another HTML</h1>
<div >
<p>Look at me</p>
</div>
`;
});
and index.html file is:
<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
</head>
<body>
<div id="app">
<h1>Hello Vanilla!</h1>
<div>
<p>This is initial HTML</p>
<button id="btn">Click Me!</button>
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>
You can change the content of any tag in HTML. like <body>, <a>, etc.

menu on only a single page

I am not really into all those coding terms, so I am having some difficulties to find answer to my problem. I want to create a single site menu. So if i press on a list item the browser should open an other content but on the same page. I tried using css with targets but everytime i click a new target the tagets will overlap and the old content will not disappear. I tried using Javascript with innerHTML but in javascript i need to write the whole page in a single line (.innerHTML ='websitecode') this will create a horrible overview.
Is there any other possibility to create something like this? Maybe with the require() / involve() function in php?
Thank you
From your question, what I understood is you want menu navigation without loading the content again.
`http://codepen.io/ArslanRafique/pen/raZybL`
Above is the snippet, I recently developed, simple menu navigation by using simple CSS and HTML. You can achieve simple menu navigation by using HTML label and can swap your views accordingly.
Please have a look at shared snippet, hope it will help you.
Sounds like you would like to create a single page web application:
There are many great javascript frameworks for this, try angular.
https://www.airpair.com/angularjs/building-angularjs-app-tutorial
Put your menu in the header file, and the content you want to replace in to views.
Or use angular UI-router https://github.com/angular-ui/ui-router/wiki
There are few possibilities to achieve your goal.
The simple and not so elegant one would be to generate the complete content and set anchors on the page. From the menu the user can call the anchors and will be brought to a desired part of the page. Example:
<!-- Menu -->
<ul>
<li>About us</li>
<li>Products</li>
</ul>
<!-- Page contents -->
<div id="aboutus">This is about us.</div>
<div id="products">Our products.</div>
More elegant, sophisticated and professional approach would be creating a SPA (single page application). It would include some techniques like AJAX, where you can load (or remove) contents on the page without refreshing.
There are many modern JS frameworks that can help you, for example AngularJS, ReactJS, etc.
Wikipedia offers also more information on SPA:
https://en.wikipedia.org/wiki/Single-page_application
So Arlan's version looks a lot prettier, but you can also use javaScript with divs that you can hide or display with functions. You can format the divs in your css with whatever you want. May get a little clunky if you have a long menu...
<div id="divOne">This will show some text</div>
<div id="divTwo"><p>This will show even more text</p><p>I may even format it differently</p>
</div>
<div id="divThree">This shows text that is different from the other two</div>
var formatOne = document.getElementById("button1"); //create handle for first button
formatOne.onclick = function() { //add functionality
document.getElementById("divOne").style.display = "block";
document.getElementById("divTwo").style.display = "none";
document.getElementById("divThree").style.display = "none";
}
Jsfiddle to show the functionality.
https://jsfiddle.net/lattivalidus/s7a9dLe7/

How to provide a Spanish translation of my website?

I'm a total newbie who is starting to work on jQuery and have minimum knowledge on the subject matter.
I'm working on translating my entire website to another language from English to Spanish, etc. I don't want to burden the site and put all of the translation into 1 js file so I'm thinking if its possible to put a separate file for each translation like english.js, spanish.js, japanese.js and call the specific file when needed and unload others that are not needed. Please if anyone know any existing plugin to use for this approach please tell me.
For moving to one language to another I will be using a dropdown list.
No JavaScript required
Based on your comments, it seems like you have static HTML files, so this should be a breeze
<!-- example.com/en/index.html -->
<nav>
Home
About
<a href="/es/index.html>Español</a>
</nav>
<p>
Hello World
</p>
Then you could write the Spanish page like this
<!-- example.com/es/index.html -->
<nav>
Inicio
<a href="/es/about/index.html">Quienes Somos<a>
English
</nav>
<p>
¡Hola Mundo!
</p>
The basic idea is you will have a separate version of each page of the site. If you have
/en/index.html
/en/foo.html
/en/about/index.html
/en/about/contact.html
Then you will also need
/es/index.html
/es/foo.html
/es/about/index.html
/es/about/contact.html
English files should have links relative to the English root /en and Spanish files should have all links relative to the the Spanish root /es
To make page switching easier on the user, the nav could have the language switcher keep the user on the same page, but just change the language
<!-- example.com/en/some/deep/page.html -->
<nav>
<!-- ... -->
<a href="/es/some/deep/page.html>Español</a>
</nav>
If the user is viewing /en/some/deep/page.html in English and they click the Español link, they will see /es/some/deep/page.html in Spanish without having to re-navigate back to the page.
Specifically to answer your question on loading and unloading JavaScript files, there is a brilliant response already on StackOverflow: Best way to load and unload JS file via JQuery by Chris Pratt
But fundimentially you can't unload a JS once it's been loaded.
Maybe what you should look at is implementing language configuration on the server end, so when outputting the HTML it looks at a language file. If you are using PHP+Smarty for example it is made very easy.

How to forward using Javascript without changing page URL?

I have a home page, and I want to navigate to other pages, say blog or gallery, but without the URL in the address bar to change. I know it's possible on server side, but how to do in Javascript?
Here is my HTML/JS code:
//HTML
<ul>
<li><a onclick="openPage('contact.html')">Contact Us</a></li>
<li><a onclick="openPage('blog.html')">Blog</a></li>
<li><a onclick="openPage('gallery.html')">Gallery</a></li>
</ul>
//Javascript
function openPage(url){
// All these will forward but will change the URL
//window.open(url);
//window.location.href=url;
//self.location=url;
//window.location.replace(url);
}
Initially, the URL will be http://something.com/mainpage.html
And it should stay the same even when navigating to any page.
This is a very simple example of what I have. So, is it possible on client side without server? If not, then what would be the simplest way to do it on server side? Assuming I'm using Java/JSF.
You will have to add hash # if you want to prevent page from reloading.
The css-tricks.com has an excellent screencast on that, have a look at:
Best Practices with Dynamic Content
please check this question in stackoverflow changing-the-url-without-reloading-the-page
I will give you a hint. You can then write the code on your own.
Using ajax, fetch the entire page you want to open. (I assume that they are on the same server.)
Then parse the html.responsetext & find the body.innerHTML of the fetched page.
then use document.body.innerHTML=fetched_body_innerHTML;
Change the document.title also in similar manner.
I am assuming that both pages will have same CSS (for consistency in looks), and quite possibly, same js files loaded.
If you have different set of CSS &/or js files on the 2 pages, you will need to create additional nodes & delete old script/link nodes. (However, the result will not be identical, since old JS was already loaded & body.onload will not be triggered after you change the innerHTML of the body.

iPhone app: getting data without a web API

I am attempting to create a simple iOS application, mostly for the learning process, but one which might also be useful to other botanists. The California Native Plant Society has a new Rare plant database online. At first I would like to just do simple querys for a plant by name. Later adding some type of location search, finding known occurrences of rare plants in your specific area.
So a search for `Layia' brings us to a page with a table. Looking at the source for the page I believe the table is generated by:
<div class="breadcrumb top20">
<div class="line1 center">
<!-- Modify Search Criteria -->
<span id=modifyCriteriaSlot></span>
<span id=exportPdfSlot></span>
<span id=exportExcelSlot></span>
<!-- END line1 -->
<span id=modifyColumnsSlot></span>
<span id=sortSlot></span>
<span id=displayPhotosSlot></span>
</div>
<!-- END line1 -->
</div>
I guess I am stuck. As far as the app goes I have been playing around with ASIHttpRequest and I see references to XMLKiss to parse web pages, but I just don't see any data on this page TO parse, it seems to be generated else ware and then just appears? I know I am a little out of my element here, but I want to put in the time and learn what I need to, so a little direction would be an awesome help! Thanks.
If it helps, they are showing the results table with this DIV
<div id=resultListSlot align=center style="max-width: 960px;"></div>
The DIV is being populated with javascript. The JS can be found here:
http://www.rareplants.cnps.org/org.cnps.Result/org.cnps.Result.nocache.js
Im not sure how you can get that to reply to your own request... let me look at it when I get back later today to see if I can help even more.
--------- Update -----------
If you wanted to skip learning JS you could just use firefox to view the DOM source which will include all the HTML generated by the JS. I just did a search for ALL of their plants, CTRL+A to select all of the page, right click on a highlighted area and "view selection source".
Then you could host your own page like I have done. Look at this page here http://luistovar.com/plants.html
Now you have all the plants, the HTML, the links and everything you need to create your own list. The only downfall is you would have to update every few weeks?? or so. It all depends on how often their data changes, or how much an updated list matters to you.
Might be better than learning JS though.

Categories