Simple jquery modal plugin, how to handle html content - javascript

Basically, i'm building a basic jquery modal plugin as practice, and as much as the many varieties out in the wild have been helpful for reference, I wasn't sure about the best method for pushing html into the modal that is being built in my jQuery.
This code is building my popups:
var container = $('<div class="container"></div>');
var header = $('<div class="modal"><div class="modal-header"></div></div>');
var content = $('<div class="modal-body"></div>');
var footer = $('<div class="modal-footer"><a class="secondary" href="#">Cancel</a><span id = "button-secondary-label">or</span><span class="green_btn"></span></div>');
$(".popup").append(container);
$(".container").append(header);
$(".modal").append(content);
$(".modal").append(footer);
In an html file that is calling the javascript file with the above code, I would like to pass html to modal-body. I know I could just write the following:
$(".modal-body").html("html goes here")
but I would like to make the plugin handle as much as possible, so what would be the best way to do the following:
in example.html:
...
<script type="text/javascript">
$(.popup).modal();
</script>
</head>
<body>
<div class="popup"><div class="body-text">I want this text in the .modal-body</div></div>
in the js file:
I would like to take the html that is in .body-text and move it into the .modal-body class, or something that will get me similar results.
Again, trying to accomplish this in the external js file, and not in example.html

It's common to use IDs (as it can be set as the href and can be used to point to the given content of a link) instead when trying to target DOm element from modal boxes. So you could do
Some content to be in the modal
Then just grab it and append it to the cmodal
$('#boo').appendTo(content);
You can also have an option so that it can be clone and left the original copy behind
$('#boo').clone().appendTo(content);
You can technically handle classes as well but after depends how your plugin is built. As you can grab all and generate a single modal content or create the multiple content to browse between using them.
$('.popup').each(function() {
$(this).appendTo(content);
});
var items = $('.popup'),
len = items.length,
cur = 0;
$next.click(function() {
cur++;
if (cur === len) cur = 0;
items.eq(cur).show();
});

Related

Add complexe Javascript array elements to HTML [duplicate]

I have a template:
function useIt() {
var content = document.querySelector('template').content;
// Update something in the template DOM.
var span = content.querySelector('span');
span.textContent = parseInt(span.textContent) + 1;
document.querySelector('#container').appendChild(
document.importNode(content, true));
}
<button onclick="useIt()">Use me</button>
<div id="container"></div>
<template>
<div>Template used: <span>0</span></div>
<script>alert('Thanks!')</script>
</template>
You can try the code here.
This code basically copies the template(html5 templates does not render on your screen) into another div. This allows you to reuse the DOM.
Problem: The line "span.textContent = parseInt(span.textContent) + 1;" changes the template code directly. I need to manipulate the content DOM and clone it into the container, without changing the template. This is very important since if I want to reuse the code, I need it to stay the same.
I have tried multiple ways to use jQuery to mimic the above javascript code, but I can't manage to figure it out. It would be better if there is a jQuery way.
If you NEED to use the new <template> tag, then you are mildly stuck . . . your cleanest alternative is to use importNode to bring in the content and then modify it after it's been appended.
Assuming that the templated code is realtively small, this should happen fast enough that you would never notice the difference in approach, though, in this specific example, the alert(), would delay the change of the content, so you would see "0", until you clicked "Okay", and then it would update to "1".
The code change for that would be:
function useIt() {
var content = document.querySelector('template').content;
var targetContainer = document.querySelector('#container');
targetContainer.appendChild(document.importNode(content, true));
var $span = $(targetContainer).find("div:last-of-type").find("span");
$span.text(parseInt($span.text() + 1));
}
If you are not married to the idea of <templates>, you could use jQuery's clone() method to do what you want to do, very easily . . . but, clone does not "see" the content of a <template>, due to the special nature of that particular element, so you would have to store the templated code some other way (JS variable, hidden div, etc.).
HOWEVER, this method will not work if you need to clone a script, the way that a <template> will. It will not trigger any script code in the "template container" element when the cloned version is created or appended. Additionally, if you store it in a hidden <div>, any script code in the "template container" element will trigger immediately on page load.
A simple version of the code for the clone() approach would look something like this:
function useIt() {
var $content = $("#template").clone();
var $span = $content.find("span");
$span.text(parseInt($span.text()) + 1);
$content.children().each(function() {
$("#container").append($(this));
});
}
Assuming that your template was:
<div id="template" style="display: none;">
<div>Template used: <span>0</span></div>
<script>alert('Thanks!')</script>
</div>
You could also move the <script>alert('Thanks!')</script> out of the template and into the script section (after you completed the "append loop"), to achive the desired alert functionality, if you wanted to.
It's an old question, but, did you try cloneNode(true)? It works on templates, as this:
var span = content.querySelector('span').cloneNode(true)
regards.

javascript to add second class to element on click event

I am trying to add a second class to my element on click
Before
<div class="foo1">
<a class="class1" >Text</a>
</div>
After
<div class="foo1">
<a class="class1 class2" >Text</a>
</div>
here are my javascript codes; both of them work:
either this one (thanks to #Shomz)
var elements = document.getElementsByClassName('class1 ');
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
element.className += ' class2';
}
or this one (thanks to #t-j-crowder)
[].forEach.call(document.querySelectorAll(".class1 "), function(element) {
element.className += " class2";
});
Question
The site allows the users to click on class1 and change it to class1 class2 . However, by running these codes, the class1 only temporarily changes to class1 class2, I mean the clicking event is not implemented, it has only visually changed. When the site is reloaded, it is back to the previous state. How to apply a fix to change permanently the class by clicking on it?How to achieve the class changing through a click event and to record this permanently? How can these js codes record this click and change it permanently?
Ok so based upon your comment you need to communicate the change to a server, then when the page loads it needs to request the data back from the server to reflect any stored changes. Theres a number of ways to do this depending on your programming capability, preference in language and compatibility requirements.
The most popular method would likely be a data file that is written dynamically by a php script. When the page is loaded it would generate your content based upon the contents of the datafile on the server(not to be confused with your HTML page). When the user modifies and element your page would call the php script using the AJAX POST method in javascript, then the php script would read the existing datafile, modify it accordingly and save it to the server.
For starters you will need a web server with PHP; if your testing locally MAMP is a good choice for Mac and I believe they now do a windows version as well.
Your would have 3 files( presuming all of your css and js is written in your HTML file):
index.htm
data.js
update.php
Assuming a linear list of div elements, each with a switchable class and child content.
index.htm
<html>
<head>
<script src='datafile.js'></script>
<script>
window.addEventListener('load',onload,false); //register the on load handler
function onload(){
var body = document.getElementsByTagName('body')[0];
var newelement;
for(var i = 0; i < elements.length; i++){
//for each element in the data file
newelement = document.createElement('div');
//create a div element
newelement.innerHTML = elements[i].content;
//place the content within the div
newelement.className = elements[i].class;
//set our classes
body.appendChild(newelement);
//add the div to the body
newelement.addEventListener('click',onclick,false);
//add a click listener to the element
}
}
function onclick(){ //on click function
var elementIndex = elements.indexOf(this); //this will be the element in the callback context
//modify class
postchange(elementIndex,classList);
}
function postchange(element,class){
// new post method
// data = {'element':element,'class':class};
// post data to update.php
}
</head>
<body>
</body>
</html>
data.js
var elements = [
{
"content":'Hello I am div 1',
"class":'classA'
},
{
"content":'Hi, I have been known as div 2... but you can call me Tim',
"class":'classA classB'
}
]
I've left the PHP out, it's not my main language so I don't feel happy improvising any code for you without looking it up and testing it first. That and it shouldn't be too hard for you to find information on POST methods on Stack Overflow.
Similarly I left the POST method in the JS out because the standard JS method is a little overcomplicated. Look up the jQuery POST method which is much more simple, again examples should be easy to find.

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);

Getting the current script DOM object in a (jquery) ajax request

I have a html component that includes some javascript.
The component is a file in a template engine, so it can be used
in the initial rendering of the whole html page
as stand-alone html rendered through an ajax request
The javascript should be applied to an object in the template, i.e. :
<div class="grid" >
<div class="item" id="item_13">
This is item 13
</div>
<div class="item" id="item_14">
This is item 14
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){
$(HOW_DO_I_GET_PREVIOUS_ELEMENT???).someEffect(params)
})
</script>
I've checked this similar question but the best answers seem to rely on the current script being the last one in the 'scripts' variable as the next ones are not loaded yet. If I append the html and js with an ajax request, it will not be the case.
To be 100% clear : the question is about getting the previous object WITHOUT reference to any specific attribute : no unique id for the tag, no random id as there is theoretically always a chance it will show up twice, no unique class attribute,as exactly the same component could be displayed in another part of the HTML document.
Simple solution involving a two step process:
1) find out which element your script tag is
2) find the previous sibling of that element
in code:
<div id="grid">
<!-- ... -->
</div>
<script type="text/javascript">
var scripts = document.getElementsByTagName("script");
var current = scripts[scripts.length-1];
var previousElement = current.previousSibling;
// there may be whitespace text nodes that should be ignored
while(previousElement!==null && previousElement.nodeType===3) {
previousElement = previousElement.previousSibling; }
if(previousElement!==null) {
// previousElement is <div id="grid"> in this case
$(document).ready(function(){
$(previousElement).someEffect(params);
});
}
</script>
Is this good web programming? No. You should know which elements should have effects applied to them based on what you're generating. If you have a div with an id, that id is unique, and your generator can tell that if it generates that div, it will also have to generate the js that sets up the jQuery effect for it.
But let's ignore that; does it work? Like a charm.
If you can give your <script/> block an Id you could easily call prev() to get the previous element.
<script type="text/javascript" id="s2">
$(document).ready(function(){
$("#s2").prev().append("<h1>Prev Element</h2>");
})
</script>
Example on jsfiddle.
You will need to get a way to reference the script tag immediately after the "grid" div. As #Mark stated, the easiest way to do this is by giving the script tag a unique id. If this is beyond your control, but you do have control of the script contents (implicit by the fact that you are creating it) you can do something like this:
var UniqueVariableName;
var scripts = document.getElementsByTagName('script');
var thisScript = null;
for(var i = 0; i < scripts.length; i++){
var script = $(scripts[i]);
if(script.text().indexOf('UniqueVariableName') >= 0){
thisScript = script;
break;
}
}
if(thisScript){
thisScript.prev().append("<h1>Prev Element</h2>");
}
Hack? Yes. Does it Work? Also, yes.
Here's something that works in FF, Chrome and IE 8, untried anywhere else. It looks at the element before the last element on the page (which is the script being parsed), stores it locally (with a self calling function) so the load handler can use it.
http://jsfiddle.net/MtQ5R/2/
<div class="grid" >
<div class="item" id="item_13">
This is item 13
</div>
<div class="item" id="item_14">
This is item 14
</div>
</div><script>(function(){
var nodes = document.body.childNodes;
var prevSibling = nodes[nodes.length - 2];
$(document).ready(function(){
console.log( prevSibling );
})
})();</script>
Having said that. I still have to mention that you're tightly coupling the behavior (JS) and HTML, by putting them into the same file which kind of goes against the web flow of separating them. Also, I don't know how you'd expect this to work with an AJAX request since you're not just adding it to the HTML as it's being rendered. In that case, it would be very easy to get a reference to the html you just inserted though.

Categories