Dynamically adding collapsible set and nested list in jQuery mobile - javascript

I am adding a listview inside a collapsible dynamically. And inside that list I am trying to add a nested list. When I am clicking the <li> node, pageinit event is getting fired instead of click event. The click event is getting fired when we click the same li second time.
jsFiddle - http://jsfiddle.net/5zJC5/
HTML:
<body>
<div data-role="page">
<div data-role="collapsible-set" data-theme="b" data-content-theme="d" id="mainColl"></div>
</div>
</body>
jQuery:
$(document).ready(function () {
var ul=$("#mainColl");
var collapsible= $('<div data-role="collapsible">');
collapsible.append('<h2>Collapsible</h2>');
var list = $('<ul data-role="listview" data-divider-theme="b">');
list.append('<li data-role="list-divider">List</li>');
for(var j =0;j<4;j++) {
list.append("<li>Item</li>");
}
collapsible.append(list);
ul.append(collapsible);
ul.trigger('create');
});
$("#mainColl").on("click","li",function() {
var list = $("<ul>");
for(var i=0;i<4;i++) {
list.append("<li>test</li>");
}
$(this).append(list);
//$(this).trigger('create');
$(this).parent().listview('refresh');
});

You have to use list.append("<li>Item</li>"); instead of list.append("<li>Item</li>");.
Updated jSFiddle here.
In addition, note that is is not recommended to use the document ready handler in combination with jQuery Mobile. I would suggest to add an id on the jQM page and use an event handler of the 'pagebeforeshow' event.
$(document).on('pagebeforeshow', '#page-id', function(){...mycode...});
You can find a jsFiddle which includes the suggested fix here
At last I would like to suggest you to avoid creating dynamic parts like that. You will realize that after some time your code will become messy and hard to read.
My proposal is to use Undescore.js as a template engine and make your code reusable and clean.
EDITED to add handler on nested list items:
<!DOCTYPE html>
<html>
<head>
<title>jQuery Mobile Nested List</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>
<script>
$(document).on('pagebeforeshow', '#home-page', function ()
{
var collapsibleSet=$("#mainColl");
var collapsible= $('<div data-role="collapsible"></div>');
collapsible.append('<h2>Collapsible</h2>');
var list = $('<ul data-role="listview" data-divider-theme="b"></ul>');
list.append('<li data-role="list-divider">List</li>');
for(var j =0;j<4;j++)
{
list.append("<li>Item</li>");
}
collapsible.append(list);
collapsibleSet.append(collapsible);
collapsibleSet.trigger('create');
});
$(document).on("click","#mainColl li",function()
{
var list = $("<ul id=\"second-list\"></ul>");
for(var i=0; i<4; i++)
{
var listItem = $("<li id=\"list-" + i + "\">Test</li>").on('click', function(){alert(this.id)})
list.append(listItem);
}
$(this).append(list);
$(this).parent().listview('refresh');
});
</script>
</head>
<body>
<div data-role="page" id="home-page">
<div data-role="content">
<div data-role="collapsible-set" data-theme="b" data-content-theme="d" id="mainColl">
</div>
</div>
</div>
</body>
</html>
I hope this helps.

Related

How to loop 3 divs with jQuery

I need a little help looping multiple divs (3 or more) using jQuery. The look I am after is having my home page rotate its main image div with other divs so that both the background image (of the div only) changes as well as links contained within the div.
I had created the effect with stacking CSS and fading in to an image behind, however now I also require the links in the div to change.
This is the HTML for the section -
<head>
<title>Sample</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="bootstrap.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="jquery.leanModal.min.js"></script>
<link type="text/css" rel="stylesheet" href="index.css" />
</head>
Now the Div that I want changing
<div class="jumbotron-1">
<div class="container">
<h1>What We Are</h1>
<p> A Paragraph</p>
<div class="divbutton">
Learn more
</div>
</div>
</div>
<div class="jumbotron-2">
<div class="container">
<h1>What We Are</h1>
<p> A Paragraph</p>
<div class="divbutton">
Learn more
</div>
</div>
</div>
<div class="jumbotron-3">
<div class="container">
<h1>What We Are</h1>
<p> A Paragraph</p>
<div class="divbutton">
Learn more
</div>
</div>
</div>
I found a similar code to what I am after :
var slideShowDivs = ['.jumbrotron-1', '.jumbotron-2', '.jumbotron-3'];
var currentID = 0;
var slideShowTimeout = 1000;
$(document).ready(function() {
for (var i = 1; i < slideShowDivs.length; i++) $(slideShowDivs[i]).hide();
setTimeout(slideShowChange, slideShowTimeout);
});
function slideShowChange() {
var nextID = currentID + 1;
if (nextID >= slideShowDivs.length) nextID = 0;
$(slideShowDivs[currentID]).stop(true).fadeOut(400);
$(slideShowDivs[nextID]).stop(true).fadeIn(400, function() {
setTimeout(slideShowChange, slideShowTimeout);
});
currentID = nextID;
}​
But it doesnt seem to work.
Any additional thoughts?
Try jquery each insted of for loop
$('.jumbrotron-1,.jumbotron-2,.jumbotron-3').each(function() {
$(this).hide();
setTimeout(slideShowChange, slideShowTimeout);
});
jsfiddle: http://jsfiddle.net/66Lz2xou/2/
or
$('div[class^="jumbrotron"]').each(function() {
$(this).hide();
setTimeout(slideShowChange, slideShowTimeout);
});
http://jsfiddle.net/66Lz2xou/3/
Sorry I need 50 reputation to comment, but I wanted to go off of #ARUN BERTILs answer.
You could put the divs in a array like:
var div_array = ['.jumbotron-1', '.jumbotron-2', '.jumbotron-3']
jQuery.each(div_array,function(i, val){
/* What you want each one to do*/
//example
$(val).css('background','blue');
})
Hi the best approach is to use this approach
$( "div" ).each(function( i ) {
//Your condition
} });
use class selectors
$(".jumbotron-1 .jumbotron-2 .jumbotron-3").each(function( i ) {
//process your code here
} });
or if you want child container divs attach > container to each of the selectors like .jumbotran-1 > container

Copy CSS style from one element to a new element in a separate document

How do I copy CSS style from one element to a new element in a separate document (an IFRAME for instance)?
I've tried to do so by using bobince's answer at JavaScript & copy style.
Please see my attempt below.
Thank you
http://jsbin.com/uvOFIXIZ/1/
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>copy CSS</title>
<script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
<style type='text/css'>
.myClass p {font-size:20px;color:blue;}
</style>
<script type="text/javascript">
$(function () {
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
$(iframe).load(function(){
$('.myClass').each(function(){
var to=iframe.contentWindow.document.body.appendChild(this.cloneNode(true));
console.log(to);
var from=this;
//Option 1
to.style.cssText= from.style.cssText;
//Option 2
for (var i= from.style.length; i-->0;) {
var name= from.style[i];
to.style.setProperty(name,
from.style.getPropertyValue(name),
priority= from.style.getPropertyPriority(name)
);
}
});
});
});
</script>
</head>
<body>
<div class="myClass">
<p>Stuff!</p>
<img alt="an image" src="dropdown_arrow_blue.gif">
</div>
<div class="myClass">
<p>More stuff!</p>
</div>
</body>
</html>
EDIT. Technically, this should work, however, it seems overkill.
//Option 3
var arrStyleSheets = document.getElementsByTagName("link");
for (var i = 0; i < arrStyleSheets.length; i++){
iframe.contentWindow.document.head.appendChild(arrStyleSheets[i].cloneNode(true));
}
var arrStyle = document.getElementsByTagName("style");
for (var i = 0; i < arrStyle.length; i++){
iframe.contentWindow.document.head.appendChild(arrStyle[i].cloneNode(true));
}
You could try what this post refers to -- since you're able to control the src document the iframe uses you can have css class defined in parent then use it in the iframe. link to another post on the subject.
You could attach the stylesheet of the previous document that you want to transfer the css from to your web page and import only what you want using plain css. I usually keep a class file with general properties and setting for various element such as fonts.

jQuery .insertAfter() copying input field values

I have created a html webpage here:
http://diagrams.inse1d.info/wbt.html
Code:
<!DOCTYPE html>
<html>
<head>
<title>WBT Charts</title>
<link rel="stylesheet" type="text/css" href="wbt.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="wbt.js"></script>
<link href='http://fonts.googleapis.com/css?family=Ubuntu:400,500,700' rel='stylesheet' type='text/css'>
</head>
<body>
<section>
<article>
<div id="wbtBlock">
<p>Press enter to save amendments</p>
<h1>Title of wbt:<input type="text" id="wbtTitle" /></h1>
<div id="graph">
<p>Graph to go here</p>
</div>
<p><strong>Notes: </strong></p>
<p><span><input type="textarea" id="wbtNote" /></span></p>
</div>
</article>
</section>
<button>Add New WBT Chart</button>
</body>
Here is the jQuery code I wrote:
$(document).ready(function() {
$("h1").keypress(function(e) {
//get
wbtTitle = $('#wbtTitle').val();
// Write text after enter
if (e.which == 13) {
$("h1").text(wbtTitle);
}
});
$("span").keypress(function(e) {
//get
wbtNote = $('#wbtNote').val();
// Write note after enter
if (e.which == 13) {
$("span").text(wbtNote);
}
});
//Insert new WBT on button click
$("button").each(function() {
$(this).click(function() {
var wbtSet = $( "article" ).html();
$(wbtSet).insertAfter('section');
});
});
});
What I want to do is set the title and some note text using input boxes which works using jQuery. I then want to add a copy of the html into another article when the button is pressed without copying the inputs previously made with the possibility of setting new values when the article is cloned. The process should repeat over and over again.
Here is an image to help explain:
I am quite new to jQuery, I think you need to use a loop to fix this, I read that a .each() can be used http://api.jquery.com/jQuery.each/ but not quite sure.
Any help will be appreciated. Thanks.
I think I got your answer.
I changed the html a bit, because you duplicated some id's with your approach, that's not good. id's have to be unique on a page. I simply changed them to classes.
<!DOCTYPE html>
<html>
<head>
<title>WBT Charts</title>
<link rel="stylesheet" type="text/css" href="wbt.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="wbt.js"></script>
<link href='http://fonts.googleapis.com/css?family=Ubuntu:400,500,700' rel='stylesheet' type='text/css'>
</head>
<body>
<section>
<article>
<div class="wbtBlock">
<p>Press enter to save amendments</p>
<h1>Title of wbt:<input type="text" class="wbtTitle" /></h1>
<div class="graph">
<p>Graph to go here</p>
</div>
<p><strong>Notes: </strong></p>
<p><span><input type="textarea" class="wbtNote" /></span></p>
</div>
</article>
</section>
<button>Add New WBT Chart</button>
</body>
And of course the jQuery. I got rid of your first two functions because they had no purpose in this context.
$(document).ready(function() {
//Insert new WBT on button click
$("button").on('click', function() {
var title = $(this).prev().find('.wbtTitle').val();
var note = $(this).prev().find('.wbtNote').val();
var wbtSet = $(this).prev("section").html();
$(this).prev().find('.wbtTitle').replaceWith(title);
$(this).prev().find('.wbtNote').replaceWith(note);
$(this).prev("section").after('<section>' + wbtSet + '</section>');
});
});
Here is a working fiddel
Fixing the answer given by hitokun_s
window.onload = function() {
// Save a copy of the element wbtSet element on pageload
var wbtSet = $("article").clone();
$("button").each(function() {
$(this).click(function() {
// Append a new one to the holder of the wbSets
$(wbtSet).appendTo($('section'));
});
});
}
I think this is what you want to do.
window.onload = function() {
$("button").each(function() {
$(this).click(function() {
var wbtSet = $("article:first-child").clone();
wbtSet.find("input").val("");
$(wbtSet).appendTo($('section'));
});
});
}

Can't dynamically add anchor tag after enclosing div inside a div with data-role="page"

I want to dynamically add anchor tag to the div="myDiv".
It works fairly as long as I didn't enclose it inside another dive with data-role="page".
I want to enclose it in a page so that it can be called as page on a button link.What could be the problem.
Below is the code.
<html>
<head>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
<!--<script type="text/javascript" src="http://swfobject.googlecode.com/svn/trunk/swfobject/swfobject.js"></script> -->
<style>
figure{
float:left
}
figcaption{
font-size: small;
}
img {
float:left;
}
a {
color: black;
text-decoration: none;
}
a:hover {
color:black;
text-decoration:none;
cursor:pointer;
}
</style>
</head>
<body>
<div data-role="page"> //remove this and it will start working.
<div data-role="div" id="myDiv" ></div>
<div data-role="popup" id="popupMap1" class="ui-content" data-overlay-theme="a" data-theme="a" data-corners="false" data-tolerance="15,15"></div>
</div>
<script>
function play(id){
document.getElementById("popupMap1").innerHTML="<a href='#' data-rel='back' data-role='button' data-theme='a' data-icon='delete' data-iconpos='notext' class='ui-btn-right'>Close</a><iframe src='http://www.youtube.com/embed/"+id+"' width='480' height='320' seamless='' id='plyerIframe1'></iframe>";
}
</script>
<script type="text/javascript"
src="http://gdata.youtube.com/feeds/api/standardfeeds/most_popular?time=today&alt=json-in-script&callback=showMyVideos2&max-results=15&format=5">
</script>
<script type="text/javascript">
var title=new Array();
var thumbnailUrl=new Array();
var playerUrl=new Array();
var mydiv = document.getElementById("myDiv");
var duration=new Array();
var views=new Array();
var idi=new Array();
function showMyVideos2(data) {
var feed = data.feed;
var entries = feed.entry || [];
var html = ['<ul class="videos">'];
for (var i = 0; i < entries.length; i++) {
var entry = entries[i];
title[i] = entry.title.$t.substr(0,20);
thumbnailUrl[i] = entry.media$group.media$thumbnail[0].url;
playerUrl[i] = entry.media$group.media$content[0].url;
duration[i]= entry.media$group.media$content[0].duration;
views[i]= entry.yt$statistics.viewCount;
var aTag = document.createElement('a');
aTag.setAttribute('href','#popupMap1');
aTag.setAttribute('data-rel','popup');
aTag.setAttribute('data-position-to','window');
aTag.setAttribute('data-theme','b');
aTag.setAttribute('data-inline','true');
//idi[i]=playerUrl[i].substring(25,36);
idi[i]=entry.media$group.yt$videoid.$t;
aTag.innerHTML ="<figure onclick='play(idi["+i+"])'><figcaption>"+title[i]+"...</figcaption><img src="+thumbnailUrl[i]+" width='200px' height='150px' ><footer>Duration: "+duration[i]+" seconds<br><span>Total Views: "+views[i]+"</span></footer></figure>" ;
mydiv.appendChild(aTag);
}
}
</script>
</body>
</html>
I've made a jsFiddle with the solution for your problem.
Explanation:
When you use the data-role="page" div, you're engaging jQuery-Mobile framework, which will perform some operations on the DOM, re-arranging some elements. I won't go any deeper into this as I'm really not sure what exactly goes on behind the scenes, but what seemed to be happening was that jQuery-Mobile had not yet finished rendering the page at the time the youtube script was trying to call showMyVideos2.
So I removed the <script> tag where you included that script, and instead added the following javascript code:
$(document).on('pageshow', function() {
$.getScript("http://gdata.youtube.com/feeds/api/standardfeeds/most_popular?time=today&alt=json-in-script&callback=showMyVideos2&max-results=15&format=5");
});
Two things you should know about this:
I've put this code in a callback for the pageshow event, to ensure that jQuery-Mobile has finished all the work it needs to do on the page before you start any DOM manipulation. Other jQuery-Mobile events such as pagechange and pagecreate would also have worked.
I loaded the youtube script using jQuery's getScript() method, which allows you to dynamically retrieve an external script and execute it. It is actually just a shorthand notation for the following case of the $.ajax() method:
$.ajax({
url: "http://gdata.youtube.com/feeds/api/standardfeeds/most_popular?time=today&alt=json-in-script&callback=showMyVideos2&max-results=15&format=5",
dataType: "script"
});

Adding style to Header when div is clicked using Javascript

My intent is to add a class to the header when a div is clicked. I have included the website I'm working with, just to make thing's easier:
URL - http://itsmontoya.com/work/iM/
I have added a class 'expanded' to the header. This is to show how the navigation should look after the button has been pressed. I created a simple Javascript which is supposed to provide an alert when I click the button. I can't seem to get this to work. Any ideas of what I did wrong?
Thanks!
EDIT - I was able to get the alert to properly work when clicking the button div. I'm very close to having this complete! :) Now I'm getting stuck with the variable not passing correctly.
<script type= "text/javascript">
var expanded = false;
function btnClick(){
alert('The variable expanded is '+expanded);
if(expanded === false) {
document.getElementById("header").className = "expanded";
var expanded = true;
} else {
document.getElementById("header").className.replace(/\bexpanded\b/,'');
var expanded = false;
}
};
</script>
I'm updating the ftp server now :)
When using jQuery, you have to bind your events in such a way that the elements have already loaded.
You have:
<script type= "text/javascript">
$("#expandBtn").click(function(){
alert('hello');
});
</script>
I think what you want is:
<script type= "text/javascript">
$(document).ready(function(){
$("#expandBtn").click(function(){
alert('hello');
$('header').addClass('expanded');
});
});
</script>
The API documentation is going to be your friend here. First step -- ready().
UPDATE
You have this call to jQuery:
$j('#header').addClass('expanded');
But your markup is for the HTML5 element <header>. In that case your jQuery needs to change to:
$j('header').addClass('expanded');
Where $j is your jQuery object. More typically you would use $ or jQuery.
Time to bone up on jQuery Selectors!
UPDATE
Here's your updated page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>itsMontoya</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<link rel="shortcut icon" href="/favicon.ico" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
<script type= "text/javascript">
$(document).ready(function(){
$('.expandBtn').bind('click', function(){
$('header').toggleClass('expanded');
});
});
</script>
</head>
<body>
<div class="wrap">
<header id="header" class="">
<div class="blackBG transparent"></div>
<nav>
<ul>
<li>
Home<img src="images/home.png">
</li>
<li>
Pictures<img src="images/pictures.png">
</li>
<li>
Music<img src="images/mymusic.png">
</li>
<li>
About Me<img src="images/aboutme.png">
</li>
<li>
Resume<img src="images/resume.png">
</li>
</ul>
</nav>
<div id="logo" class="logo"><p>itsMontoya</p></div><div id="expandBtn" class="expandBtn anchor"></div>
</header>
<section class="content">
<article class="blogEntry"></article>
</section>
<footer class="anchor">
<div class="over anchor"><p>2011 itsMontoya.com</p></div>
<div class="blackBG transparent anchor under"></div>
</footer>
</div>
</body>
</html>
Using jQuery:
$('#your_div_id').click(function(){
console.log("Clicked.");
$("#header").addClass('expanded');
});
Update
In your code:
var expanded = false;
function btnClick(test){
if($expanded === false) {
.
.
.
What the heck is $expanded? Notice that in JavaScript we don't need the $ sign for variables.
This is how you would bind a click handler to your div and add the class to your header:
var yourDiv = document.getElementById('your-div-id');
var header = document.getElementById('header');
yourDiv.onclick = function(){
alert("yourDiv was clicked");
header.className = "newCssClass";
};
The above assumes markup like so:
<div id="your-div-id">Click</div>
<div id="header"></div>
Here's an example.
Update: The reason that the expanded variable isn't working as you'd expect is because you're creating a duplicate local variable called expanded in your btnClick() method. As a result, the global expanded variable you declare outside the function is never updated.
This is being caused by how you're using the var keyword:
When used outside a function, var creates a global variable that's accessible anywhere within the current document.
When used inside a function var creates a local variable that is accessible only within that function.
Here's your function cleaned up to work as you'd expect:
// Define global variable (using var outside function)
var expanded = true;
function btnClick(){
alert('The variable expanded is '+expanded);
// Condition for true
if(expanded) {
// do something
// Condition for false
} else {
// do something else
}
// Flips boolean value of the global variable (notice lack of var keyword)
expanded = !expanded;
}
Here's an example showing the correct way to update the expanded variable.

Categories