How to update DOM in Single Page Application with jQuery? - javascript

This is a really simple question, but I did not find an answer through searching.
When creating an SPA, what is the process for updating the content if you were to do it with jQuery? Is it simply deleting the contents of a node, and writing new HTML?
Here's some code to make the question clearer:
Suppose you have SPA page like this:
<div id='nav'>
<div class='link'>home</div>
<div class='link'>about</div>
...
</div>
<div id='page_content'>
...
</div>
When the user clicks on a nav item, jQuery does an HTTP get for the content: var content = .... To update the page, simply update the page with $('#page_content').html( content )?

If by SPA you mean a Single Page solution, something like this:
<!-- HTML -->
<div id = "page-area" style = "width: 800; height: 600; border: 1px solid silver"></div>
// Javascript
$('#page-area').load('your-page.html');
// or
$.get('your-page.html', function(data){
$('#page-area').html(data);
});
...if you want to load external files without refreshing the page.
Or to update element content:
var pagecontent = "<h1>New Content</h1><p>Some new content</p>";
$('#page-area').html(pagecontent);
Note that elements added to a page in this way will adopt existing styles and will clash with other elements with the same id attribute.

Depends what you;'re trying to do. You can change values of textboxes like:
$("#textBoxID").val("ValueYouWant");
You can append a table row to a table like so:
$("#tableID").append("<tr<td>blahblah</td></tr>");
You can update a div's HTML:
$("#divID").innerhtml("Hello World");
Etc, etc. Your question is pretty vague, but I hope this helps.

Related

How to change add and remove tags with JS in django template

I have a quiz Django app which consists of two parts. One is showing 10 sentences with their audio to remember, one per page, and the second is asking questions for the same set of sentences. First part was set up with js function which creates pagination in my html the following way:
my_template.html
<button id="prev">prev</button>
<button id="next">next</button>
<ul class="list-articles" id="dd">
</ul>
<script>
var my_objects = `{{ my_objects|safe}}:` #list of items from my view function
function paginate(action) {
console.log(action)
if (action ==='next') {
page_number++;
}
else{
page_number--;
}
const audio = document.createElement('audio');
audio.src =`/media/${my_objects[page_number].fields.audio}`;
$('#dd').empty();
$('#dd').append('<li><h1>'+ my_objects[page_number].fields['content'] +'</h1></li>');
$('#dd').append(audio);
$('#page_number').val(page_number);
}
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('#next').onclick = function() {
paginate('next'); #same goes for 'prev' button.
}
})
</script>
Now when the user paginated through all the sentences I want to show the continue button and if the user clicks it, start the second part. The second part has absolutely same page except I need to hide content of my objects and leave only audio or vice versa and add textarea tag for the user's input. After that I need to loop over my objects again - now in the form of questions. I need to do that without page re-rendering so I don't need to store the list of objects or query the DB again.
I tried to make it with tag disabling and activating the second loop after the first ends but that looks quite messy and I suppose there is a smarter way of doing that. I'm not a JS developer so any help would be appreciated!
Thanks for all who viewed and not commented! I found the answer myself. Just need to add JS functions which will empty the main tag and refill with necessary field.
Details: By accessing elements of DOM in the following way you can empty any element on a web page. For example, if we have a div like:
<div class= id="maindiv">
<h2> Hello, world! </h2>
</div>
We can empty and refill it with a new header:
var container = document.getElementById("maindiv");
container.empty();
new_header = document.createElement('h2');
new_header.innerHTML = 'Hello, brave new world!'
container.append(new_header);
Same applies to the whole web-page. The only thing is, if it is too big, you probably going to be tired of manipulating the DOM each time. So, you may want to check out some frameworks like React to make it easier .

Selecting dynamically added classes in Javascript

I'll try to keep the question short and clear as mush as possible. I will really appreciate every help I can get but really important, is a solution in vanilla Javascript. So here come;
I created some elements (div and p) and added classes to these dynamically created elements using javascript. So that when the HTML is opened in the browser, these elements are added based on some actions.
Here is the HTML below:
<div class="work-container-outer"></div>
That is all the HTML there is.
Here is the Javascript code used to add the elements and the classes;
for (const items of areaOfWork) {
//create elements---------------------------------------------------------------
let workContainer, workAreaDiv, workTitle, pTitle;
workContainer = document.createElement('div');
workAreaDiv = document.createElement('div');
workTitle = document.createElement('div');
pTitle = document.createElement('p');
//add classes--------------------------------------------------------------------
workContainer.classList.add('work-container');
workAreaDiv.classList.add('work-area-div');
workTitle.classList.add('work-title');
//append as necessary------------------------------------------------------------
workTitle.append(pTitle);
workAreaDiv.append(workTitle);
//append workAreaDiv
workContainer.append(workAreaDiv);
//append the above to the main from the selector
workContainerOuter.append(workContainer);
//fill in with content from the database------------------------------------------
pTitle.innerHTML = items.title;
}
So all these elements created were appended together and finally added to the div container in the HTML file.
Here is what the HTML file looks like in the console after these stuffs has been added:
<div class="work-container-outer">
<div class="work-container">
<div class="work-area-div">
<div class="work-title">
<p>Promoting energy efficiency</p>
</div>
</div>
</div>
</div>
The issue now is, when I try to queryselect these dynamically created elements with their added classes, I get null. Therefore, I can't do anything with them. For example, when I try to select work-area-div, it returns null even though now i
Thank you for reading up to this point and I will really appreciate every assistance here. Thank you all :)
You can simplify your script considerably if you set it up with a template. In HTML5 and modern browsers you can use the new <template> element for this. As this element does not yet work reliably in all browsers, I have used the <script> here in exactly the same way:
const block=document.getElementById('tmpl').innerHTML,
parr=["Promoting energy efficiency",
"Make products repairable/sustainable",
"Do other useful stuff"
];
document.querySelector(".work-container-outer")
.innerHTML=parr.map(p=>block.replace("#",p)).join("<hr>");
// scan the new structure for all `p` elements:
console.log( [...document.querySelectorAll('p')].map(p=>p.textContent).join("\n"));
div {background-color:#8882; padding:10px}
<div class="work-container-outer"></div>
<script type="text" id="tmpl"
><div class="work-container">
<div class="work-area-div">
<div class="work-title">
<p>#</p>
</div>
</div>
</div>
</script>
The generated elements can be found just like any other elements in the DOM, as you can see from the console output.

How would I make a self-linking <div>?

After much Googling, I resort to the chance at ridicule and moderation on Stack Exchange.
What I am trying to do sounds simple enough. I want to make a <div> id/class that will link automatically create a link to itself via some kind of scripting.
Let me put down some pseudocode, before I make it sound more complicated than it is:
#Let div.link = xxx.html
#Let div.pic = xxx.png/jpg
for div in HTMLdocument:
if div.class == "autolink":
div = "<img src=\"mysite/" + div.pic + ">"
Now, obviously that's Python pseudocode, but I am familiar(ish) with PHP and Javascript. Basically, I want to make the div generate an HTML link without having to actually type out the tags and links for every given div on a web page. I want to be able to type, in my index.html:
<html>
<head></head>
<body>
<div class = "1"></div>
<div class = "2"></div>
</body>
</html>
and then to be presented with a page that has the two divs linked, imaged, and, preferably, formatted.
Like I said, the problem seems simple, but I can't seem to get it to work right, in any language. This seems like a thing that would be very useful for begiiner web designers.
PERSONAL NOTE:
I would preferably like to see a solution in PHP or Javascript, but if you are good with Django and want to show me how to get it done in that, I would be just as grateful!
=========================================
EXAMPLE:
Let's say you have a browser based RPG, and you want to show your player's inventory. The Inventory page would display the items in a players inventory, complete with a link and image, based on whatever was in that user's inventory page. It would look like this (this is VERY rough output, Statements tagged in #these# are not code, and should be interpereted as what they describe):
<h1>User's Inventory:</h1>
<p><div class = "item_1">#Link to page of 'item_1', image of 'item_1'#</div></p>
<p><div class = "item_2">#Link to page of 'item_2', image of 'item_2'#</div></p>
The above would display, roughly, a header that said "User's Inventory", and then display a linked image of item_1, followed by a newline and then a linked image of item_2, where said items would be in a separate file OR a list that lists all the items and their respective links and images.
You can use jquery, and when page dom is loaded, you cycle through each div that has the class autolink and do your manipulations (add your desired html into each div). You can use the id of each div to place data inside. You can use a prefix to that id values for different types of data. For example, im using "inventory_" as a prefix.
<h1>User's Inventory:</h1>
<p><div class = "autolink" id="inventory_item_1">#Link to page of 'item_1', image of 'item_1'#</div></p>
<p><div class = "autolink" id="inventory_item_1">#Link to page of 'item_2', image of 'item_2'#</div></p>
then jquery on document ready:
<script type="text/javascript">
$(document).ready(function ()
{
// define your website here
var mysite = "http://www.example.com/";
// this will cycle through each div with class autolink. using `this` to reffer to each.
$(".autolink").each(function () {
// we get for div with id="inventory_item_1" ...
var mylink = $(this).attr('id').replace("inventory_",""); // ... a value item_1
var myimagesrc = $(this).attr('id').replace("inventory_","image_"); // ... image_item_1
$(this).html('<img src="'+mysite+'images/'+myimagesrc+'.jpg">');
// the above will add html code of this format:
// <img src="http://www.example.com/images/image_item_1.jpg">
});
});
</script>
try it here:
http://jsfiddle.net/5APhT/2/
I'll give a sample in php. Here is an example if you already have a set of links to use
<?php
//Create a multidimensional array to store all you need to create links
$links['1'][]="http://www.yahoo.com";
$links['1'][]="yahoo.com";
$links['2'][]="http://www.facebook.com";
$links['2'][]="yahoo.com";
$links['3'][]="http://www.google.com";
$links['3'][]="yahoo.com";
foreach($links as $class => $innerArray){
$link=innerArray[0];
$linktext=innerArray[1];
echo "<div class='$class'><a href='$link'>$linktext</a></div>";
}
?>
This creates the divs for you so you don't have to add them in advance.
You can add images in the same manner

Store HTML and CSS of target container

I have a container div containing some html - for example:
<div id="container">
<h1>Bla bla</h1>
<div class="myItem"></div>
Send
</div>
and some css related to the container:
#container {background:red;}
#container h1 {font-size:30px;}
#container .myItem {color:red;font-size:12px;}
I would like to store all the html inside the container and all the related css to it in some variable/database/whatever is available, and then load it back on a new page. The content is dynamic and it's up to the user to style the container and it's content.
How could I accomplish this? One way I was thinking was to retrieve all this properties using javascript and than store them somehow in the database to load them back later or try to do this with html5 webstorage.
Is there any plugin that does this?
EDIT:
I've also tried html2canvas but it's support for css3 is not good enough to render the elements correctly.
If the CSS and HTML are both stored within the page, you can just grab the content (based on the wrapper) and store it in localStorage (if this works for your purpose).
An example with jQuery and localStorage... you will need to change where things are being saved from to fit your case.
jsFiddle
Saving the items:
var html = $('#container').html();
localStorage.setItem('html', html);
var css = $('#csscontainer').html();
localStorage.setItem('css', css);
Pulling/showing the items:
var showHtml = localStorage.getItem('html');
var showCss = localStorage.getItem('css');
$('#showHtml').html(showHtml);
$('#showCss').html(showCss);

calling a function on one page from a link on another page

I have an html page (django) that contains several divs(each displaying different data) and one div that has navigation links. I'll call this my main page. I have an external .js file (jQuery) that reveals one display div on the main page and simultaneously hides all of the others (except the navigation div) based on which nav link is chosen.
$(function(){
$("#sl_sectorbr").click(function showSectorMini(){
$(".minimenu").hide();
$(".minimenu > *").hide();
$("#sector_mini").fadeIn("slow");
$("#sector_mini > *").fadeIn("slow");
});
All of this works fine. My question is, if I want to place "navigation links" on a second html page; that when clicked would both load my main page AND call/execute a specific function like
"showSectorMini()" just as if it were clicked from the main page itself — how would I write that code? I'd really appreciate any help I could get.
Oh.... existing class is...
}
/* ------- Interaction Containers Class -------- */
.interactContainers {
padding:8px;
border:#999 1px solid;
display:none;
}
But you probably already knew that!
Steve
Gentlemen...
This is exactly what I need and mine is less complicated than this. Just one div to open with the script. I am a javascript incompetent person so far. :(
How do you dumb this down to my needs?
Seperate page link is:
Email</div>
Page it goes to code is:
function toggleSlideBox(x) {
if ($('#'+x).is(":hidden")) {
$(".interactContainers").slideUp(200);
$('#'+x).slideDown(300);
} else {
$('#'+x).slideUp(300);
}
}
and the div is this...
<div class="interactContainers" id="interactContainers" style="background-color: #EAF4FF;">
I just want to click the link (Email) from one page...have it open the correct persons(id) profile page...and then execute my existing toggleSlideBox javascript.
Is that doable without a bunch or re-code with javascript that I have about an IQ of 4 in. :\
Thank you for any assistance you provide
S
You could use the hash - link to http://example.com/#sectionOne and read the hash in your ready function.
As SidneySM suggested, a hash is the standard way of handling this. It could go something like this:
In your external js file:
var initSectorUI = function(){
if (location.hash) showSectorMini(location.hash);
};
var showSectorMini = function(sector){
$('#sectors > div').hide();
$(sector).show();
};
On your other pages:
$(function(){
initSectorUI();
$("#navigator a").click(function(){
showSectorMini($(this).attr('href'));
});
});
<div id="navigator">
One
Two
</div>
<div id="sectors">
<div id="one" style="display:none">A one</div>
<div id="two" style="display:none">A two</div>
</div>
You should arrange to produce different versions of the page, and put different onload actions into each version. For example, make the div to show a query parameter, and make django fill in the right onload depending on the query parameter. Then put the different query parameters into the links.

Categories