JQuery Mobile Dynamic Div Pages - javascript

I'm new to JQuery + JQuery mobile.
I am attempting to create dynamic div elements for styling purposes. I am pulling in JSON from an AJAX call, tossing it into an unordered list, and wrapping it into a div. The AJAX + JSON works beautifully, but when I go to create the DIV within the script and attach it into another div container, it doesn't work. I've done a lot of reading on this, but none of the solutions I've found seems to work for the div part.
I've simplified my code down to the following:
HTML:
<div data-role="page">
<div data-role="header">
<h1>Page Title</h1>
</div><!-- /header -->
<div id="someDiv" data-role="content"></div>
<div id="anotherDiv"></div>
</div>
JavaScript:
$(document).ready(function() {
var newDiv = '<div id="d1"><p>This will attach to the content</p></div>';
var aDiv = '<div id="test" data-role="page"><p>This never gets displayed because of data-role?</p></div>';
$("#someDiv").html(newDiv).trigger('create');
$("#anotherDiv").html(aDiv).trigger('create');
});​
Note how aDiv doesn't attach to anotherDiv. I suspect this has something to do with the data-role="page" attribute in aDiv.
JSFiddle Link
I've been stuck on this for 1+ day. Any help is greatly appreciated!!

In fact your aDiv is being attached, just not displayed (you can examine your markup in Firebug/WebInspector/DragonFly and see this) since only one JQM page at a time is displayed.
If you want to attach a new page you can try adding it to your body
Here's a fork of your fiddle
http://jsfiddle.net/49LgB/

Related

Jquery .load() only parent and ignore children

So, I am trying to load picture from another page using Jquery .load(), now the element I am trying to load has multiple children element which also load on current page, now obviously I could hide those divs but first I want to know if there's way to only grab parent div and leave out children.
I have tried using parent() method but since .load() works differently, it didn't work as intended. (Unless I missed something)
$('#myNewDiv').load('/robots .heading-image');
Here's HTML code from the other page
<div class="heading-image" style="background-image:url(imagelinkhere.png)">
<div class="heading-image_cover">
<div class="left">
<div class="heading-image title">Heading Title</div>
<div class="heading-image desc">I am a desc</div>
</div>
<div class="right">
<div class="heading-image stat">Stat text</div>
</div>
</div>
</div>
That's the code I am using right now, but .heading-image has multiple child elements as mentioned above.
To sum up, I need to load only parent element and ignore all child elements of the div mentioned above without having to load those children on current page and hide them (If possible)
From what I understand, your goal seems to be to copy the empty div to a new page, while maintaining the background image associated with the <div> tag.
The simplest approach would be to add to a stylesheet in which both of the pages can reach. For example:
CSS
.heading-image{
background-image:url(imagelinkhere.png);
}
JavaScript
$('#myNewDiv').html("<div class="heading-image"></div>");
Then in the head of both HTML documents, have <link rel="stylesheet" href="style.css"> to point towards the correct stylesheet for both pages.
If you just want the empty <div class="heading-image"></div> you could use the load() complete callback to empty it:
$('#myNewDiv').load('/robots .heading-image', function(){
// new html exists in page now, 'this' is #myNewDiv element
$(this).find('.heading-image').empty();
});
If there are resources inside that element like images, videos etc that you don't want to load in page you could also parse the :
$.get('/robots').then(function(html){
var $hImage = $(html).find('.heading-image').empty();
$('#myNewDiv').html($hImage)
});
With all that said I don't see why you need to extract an empty element from another page and can't just do:
$('#myNewDiv').html('<div class="heading-image"></div>')

How append html in a <div>

I have a div in my html page with a id:
<div id="home">
I need to put some html like a link so I use jquery and my code is:
$('#home').add('<a href=..../a>);
The problem is that if I go control the DOM with google chrome I can see the element in the div but I can't see the link the page.Anyone can help me?
Use append() to append content to the div.
$('#home').append('<a href=..../a>');

jQuerys wrap function wrap works quite odd

I stumbled over jQuery's wrap() function.
Somehow it behaves different when I'm trying to wrap two div tags which have some text in between them, than without text between the two divs.
jquery:
var wrapper1 = '<div class="wrap1">something in between<div class="innerwrap1">';
$('.content1').wrap(wrapper1);
var wrapper2 = '<div class="wrap2"><div class="innerwrap2">';
$('.content2').wrap(wrapper2);
The resulting HTML is this:
<div class="wrap1">
something in between
<div class="innerwrap1"></div> <!-- wtf? -->
<div class="content1">Lorem</div>
</div>
<div class="wrap2">
<div class="innerwrap2">
<div class="content2">Ipsum</div>
</div>
</div>
Here's a fiddle:
http://jsfiddle.net/RfJN5/
The first result is quite surprising, isn't it? I would think that both closing divs should be placed after .content1, no matter if theres any text between the divs.
Of course I know it's safer to add the closing divs myself to control the behaviour, but is this some kind of bug or just a missunderstanding of how to use jQuery wrap?
Thanks in advance!
that works as expected, your wrapper1 would be the main object that would be wrapped around content1 and as you haven't closed the innerwrapper1, jquery closes it for you. If you want to wrap with inner wrapper then make this an object, wrap content and then append the inner wrapper to wrapper:
var wrapper1 = $('<div class="wrap1">something in between</div>'),
innerWrapper = $('<div class="innerwrap1" />');
$('.content1').wrap(innerWrapper);
wrapper1.append($('.innerwrap1'));
Example

jQueryMobile - Why is a new dynamically generated page not updated to the last version?

I'm generating pages dynamically in jQueryMobile, but I can't understand why the new generated page is not updated to the last version.
This is the use case:
Page A contains a list of 'a' elements. When I click one, the app redirects to a new page that is generated dynamically. Then I go back to page A. I click another 'a' element, but from now on, the app will always redirect to the first page that was dynamically generated.
Please look at this fiddle:
http://fiddle.jshell.net/cqUrD/
This is my code:
HTML
<div data-role="page" id="home">
<div data-role="header" data-position="fixed">
<h1>static page</h1>
</div>
<div data-role="content"> Create new page
<div data-role="content"> Create another new page
</div>
<div data-role="footer" data-position="fixed">
<h1>footer</h1>
</div>
</div>
jQueryMobile:
$(document).on('click','a',function() {
nameId = $(this).attr('id');
page = '<div data-role="page" id="page" data-theme="e"><div data- role="header"><a data-role="button" href="#" data-rel="back" data-icon="back" data-iconpos="notext">back</a><h1>Dynamic page</h1></div><div data-role="content"> Last id was: '+nameId+'</div><div data-role="footer" data-position="fixed"><h1>footer</h1></div></div>';
//alert(nameId); this prints the right value
$.mobile.activePage.after(page);
$.mobile.changePage('#page', {
transition: 'flip'
});
});
How can I solve this problem? I need to always show the updated version of the new page.
Thanks in advance!
Working example: http://jsfiddle.net/Gajotres/Xfh8p/
Before new page is created previous one must be removed. In this case a DOM was filled with new pages but first one was still there and because they all had same name that first one had a priority.
Also when binding a click event don't bind it to a tag only, this was also a problem. Each time return button was pressed another page was created in DOM.
All in all this will work:
$(document).on('pageinit', '#home', function(){
$(document).on('click','#createfirst, #createanother',function() {
nameId = $(this).attr('id');
alert(nameId);
page = '<div data-role="page" id="page" data-theme="e"><div data- role="header"><a data-role="button" href="#" data-rel="back" data-icon="back" data-iconpos="notext">back</a><h1>Dynamic page</h1></div><div data-role="content">'+nameId+'</div><div data-role="footer" data-position="fixed"><h1>footer</h1></div></div>';
$.mobile.activePage.after(page);
$.mobile.changePage('#page', {
transition: 'flip'
});
});
});
$(document).on('pagehide', '#page', function(){
$(this).remove();
});
In this case pagehide event has been bound to dynamically created page. Because it is bound to the document object it will still be there when page is removed. It tells jQuery Mobile to remove page #page during the transition from it.
As you can see I have used jQuery Mobile page events to trigger a page removal. If you want to find more about this topic take a look at my other ARTICLE (my personal blog) or find it HERE.
When you are clicking the button second time, the page with same ID is already in DOM so I think jQuery is unable to create a second one with the same ID (maybe caching). I changed the code a bit. You need to remove the #page if it already exists.
if ($('body').find('#page').length != 0) $("#page").remove();
Link: http://fiddle.jshell.net/cqUrD/1/

How to prime HTML for use with JS accordion effect?

I've got a website set up with well structured pages, eg. <h1> for the website name, <h2> for the page name and <h3> for the different sections on the page.
Anyway, I was looking to set a bunch of the really long pages (an FAQ page for example) up with an "accordion" effect, with the <h3> elements being the toggle and the content directly following being toggled. But the collapsible content needs to be in it's own <div class="draw"> (or similar) and this isn't how the content is set up currently. I was hoping this was possible without touching the existing HTML and just somehow changing the DOM with JS (with jQuery assistance?) to accommodate.
I thought maybe wrapping content between the <h3> elements in a classed <div> might work but wouldn't know how to get this done. Help?
Here's one way to do it that doesn't rely on traversable DOM elements between the h3 tags. I'm not sure how efficient it is to swap out the entire contents of the body tag like this on every load though...
$(document).ready(function(){
var content = $('body').html();
content = content.replace(/(<\/h3>)((.|\n|\r)*?)(<h\d>|$)/gi, "$1<div class=\"draw\">$2</div>$4");
$('body').html(content);
});
I tested this out on content formatted like so:
<body>
<h1>Title</h1>
<h2>Sub-Title</h2>
<h3>Section Title</h3>
this is some content
<h1>Title</h1>
<h2>Sub-Title</h2>
<h3>Section Title</h3>
this is some content
...
</body>
The jQuery documentation on the accordion widget is very easy to use. http://docs.jquery.com/UI/Accordion. But using the jQuery method only works if you have the structure they describe in the docs. In other words (as far as I know) it is impossible to use the jQuery accordion widget without touching your HTML. This is the structure:
<div id="accordion">
<h3>Tab 1</h3>
<div>
First tab content
</div>
<h3>Tab 2</h3>
<div>
Tab two content
</div>
<h3>Tab 3</h3>
<div>
Tab three content
</div>
</div>
Then you would create the widget using the line of javascript:
$("#accordion").accordion();
If you wanted to use jQuery to format your HTML for you, you still need a way to select and parse your HTML. Each tab's content needs to be selectable some how. If your HTML already has the tabs separated somehow, then you need to take a look at this page http://docs.jquery.com/Manipulation. It should be pretty straightforward.
If you're willing to consider non-JS alternatives, Stu Nicholls has some interesting html/css (no js) options on his CSS Play website:
http://www.cssplay.co.uk/menu/gallery3l
http://www.cssplay.co.uk/menus/tabmenu.html
(Among others)
I suppose it looks like this:
<html>
<h1>site name</h1>
<h2>page name</h2>
<h3>section</h3>
<p>some stuff</p>
<p>different paragraph</p>
<ul><li>a list</li></ul>
<h3>next section</h3>
<p>different stuff</p>
...
</html>
you could iterate over all direct children of html. At first h3 you start collection all subsequent items until the next h3. if a next h3 comes or page end you create a div, and add it after the starting h3 all collected elements should be removed from their parent (the html) and added as children of the div.
looking at http://docs.jquery.com/Traversing this should be easy. I'm not an expert on jquery, but it should be doable.
Dave Ward of Encosia has great 10 minute tutorial on jQuery, Firebug and selectors that builds exactly what you looking for.

Categories

Resources