Multiple jQuery Mobile Collapsible: Having only one collapsible open at any time - jquery-mobile

Is there any way to make jQuery Mobile Collapsible elements close all other expanded collapsibles whenever you expand another collapsible element?
This is because in my collapsible list, I want only one item expanded at any time.
I checked the documentation, and theres an event that fires whenever you expand a collapsible. I included this in the <script> tag below. I'm not sure if this is the best way to do this or if its some other simple way to do it. And also I have no idea how to traverse the document to close all opened collapsibles.
<div data-role="collapsible">
<h3>Item 1</h3>
<p>Content 1</p>
</div>
<div data-role="collapsible">
<h3>Item 2</h3>
<p>Content 2</p>
</div>
<script>
$( ".selector" ).collapsible({
expand: function(event, ui) {
// code here to close all opened collapsibles, but i need input how to do this
}
});
</script>

The answer was simple.
jQuery Mobile will visually style a set of collapsibles as a group and will make the set behave like an accordion in that only one collapsible can be open at a time if you wrap the collapsibles in a div that has the attribute data-role="collapsibleset".
http://api.jquerymobile.com/collapsibleset/
Making the final code:
<div data-role="collapsible-set">
<div data-role="collapsible">
<h3>Item 1</h3>
<p>Content 1</p>
</div>
<div data-role="collapsible">
<h3>Item 2</h3>
<p>Content 2</p>
</div>
</div>

Related

Data-transition effects does not work with tab navigation jquery mobile

I try to bring some effects to my tabs navigation on my jquery-mobile page but it looks like that the data-transitions argument does not work combined with a tabs navigation.
My code looks like this:
<div data-role="header" data-theme="a" id="header">
<h1>Mainpage</h1>
</div>
<div data-role="main" class="ui-content">
<div data-role="tabs" id="tabs" >
<div data-role="navbar" data-iconpos="left">
<ul>
<li><a id="lblTab1" href="#location" data-ajax="false" class="ui-btn-active" data-icon="search" data-transition="pop">search</a></li>
<li><a id="lblTab2" href="#product" data-ajax="false" data-icon="location" data-transition="pop">product</a></li>
</ul>
</div>
<div id="location" class="ui-body-d ui-content" > content </div>
<div id="product" class="ui-body-d ui-content" > content2 </div>
</div>
</div>
</div>
so how is it possible to bring some effects to the navigation bar?
I use jquery-mobile 1.4.0
Page transitions don't work on tabs as transition classes are activated when hiding/showing pages. You can create your own transitions, use third party CSS transitions or use jQM default ones.
First, you need to listen to tabbeforeactivate event. This event omits a ui object containing data of previous (ui.oldPanel) and next panel (ui.newPanel). All you need is to add animation classes to ui-newPanel and remove them once animation ends by binding Animation End one time only using .one().
$("#tabs").on("tabbeforeactivate", function (e, ui) {
$(ui.newPanel)
.addClass("animation")
.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {
$(this).removeClass("animation");
});
});
Demo - Custom animation by Daneden
Demo - jQM default transitions

How to inject the same panel into multiple pages using jquery mobile

jQuery Mobile 1.3.1 has a very nice sliding panel feature, but the panel code must be placed within the same page it's used on.
I'm working on an app that needs to have the same panel on many pages. Instead of replicating code is there a way to dynamically inject the panel into these pages so that it will still retain the jqm panel functionality?
jQuery Mobile >= 1.4
Solution one:
Use an External panel that can be accessed from any page, this is in case you want to have the same panel contents in all pages.
Append panel to $.mobile.pageContainer once only on pagebeforecreate and then enhance the panel using $(".selector").panel().
var panel = '<div data-role="panel" id="mypanel" data-position="right" data-display="push"><h1>Panel</h1><p>stuff</p></div>';
$(document).one('pagebeforecreate', function () {
$.mobile.pageContainer.prepend(panel);
$("#mypanel").panel();
});
Add button to open the panel in each header (or wherever you want).
Note: When using External Panel data-theme should be added to panel div, as it doesn't inherit any styles/theme.
Demo
Solution two:
If you wish to do changes to panel before appending it, based on number of pages in DOM, add panel to each one with a different ID and a button to open that panel.
Note that you don't need to call any kind of enhancement, because you're adding panels on pagebeforecreate. Hence, panels will be auto-initialized once page is created.
var p = 1,
b = 1;
$(document).one('pagebeforecreate', function () {
$.mobile.pageContainer.find("[data-role=page]").each(function () {
var panel = '<div data-role="panel" id="mypanel' + p + '" data-position="right" data-display="push"><h1>Panel</h1><p>stuff</p></div>';
$(this).prepend(panel);
p++;
});
$.mobile.pageContainer.find("[data-role=header]").each(function () {
var panelBtn = ''
$(this).append(panelBtn);
b++;
});
});
Demo
Note: Make sure you use .one() not .on(), if you use the latter, panels will be added whenever a page is created.
jQuery Mobile <= 1.3
You can do it this way, using pagebeforecreate event and by checking if there is no Panel added already. Keeping in mind that panels markup should always be placed before [data-role=header] that's why I used .before().
There is no need to call any enhancement method since panels are added on pagebeforecreate. They will be initialized during that event.
Demo
Your panel
var panel = '<div data-role="panel" id="mypanel" data-position="right" data-display="push"><h1>Panel</h1><p>stuff</p></div>';
Add panels dynamically
$(document).on('pagebeforecreate', '[data-role=page]', function () {
if ($(this).find('[data-role=panel]').length === 0) {
$('[data-role=header]').before(panel);
}
});
Update
There are two alternative methods to inject "External Panel" dynamically.
For some one coming across this issue, there is something called External Panels in JQuery Mobile 1.4+, which can make our life easier.
http://demos.jquerymobile.com/1.4.0/panel-external/
You can do something like this.
<div data-role="panel" id="mainPanel">
<!-- .... -->
</div>
<div data-role="page" id="page1" >
<!-- .... -->
</div>
<div data-role="page" id="page2" >
<!-- .... -->
</div>
You can also do one thing create a panel at the end or start of all pages and open that by Id and script code mentioned below.....its working fine for me.
$(function(){
$("#navigation").enhanceWithin().panel();
});
<div data-role="page" id="page1">
<div data-role="main" class="ui-content ui-body-a ui-responsive">
<div data-role="header">
<div data-role="navbar">
<ul>
<li class="">
</li>
</li>
</ul>
</div>
</div>
</div>
</div>
<div data-role="page" id="page2">
<div data-role="main" class="ui-content ui-body-a ui-responsive">
<div data-role="header">
<div data-role="navbar">
<ul>
<li class="">
</li>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="ui-panel ui-panel-position-left ui-panel-display-reveal ui-body-b ui-panel-animate ui-panel-open" data-role="panel" id="navigation" data-position="left" data-display="overlay" data-theme="b" data-dismissible="true" data-swipe-close="true">
<div class="ui-panel-inner">
<ul class="">
</ul>
</div>
</div>
In order for hashcoder his response to work you need to initialize the external panel. Also add .enhanceWithin() to make listviews etc render properly within the panel.
Als add a data-rel=... attribute to the link via which you want to open the external panel.
<script>
$(function () {
$("div[data-role='panel']").panel().enhanceWithin();
});
</script>
<div data-role="panel" id="mainMenu">
<!-- .... -->
</div>
<div data-role="page" id="page1" >
Open main menu panel
<!-- .... -->
</div>
<div data-role="page" id="page2" >
Open main menu panel
<!-- .... -->
</div>

jQuery UI not working for accordion

my html looks like this
<div id="menu">
<h3>Section 1</h3>
<div>
<p>I'm the first section!</p>
</div>
<h3>Section 2</h3>
<div>
<p>I'm the second section!</p>
</div>
<h3>Section 3</h3>
<div>
<p>I'm the third section!</p>
</div>
</div>
And this is my js
$(document).ready(function() {
$('#menu').accordion();
});
Somehow my accordion is not working even though I took this directly off of codeacademy. Previously, I had made my own accordion and it wasn't working so I took it off codeacademy where i first learnt it and still it wasn't working. I am hosting off google. Is something wrong with this?
I tried adding header: 'h3'
but it still has no effect. It just looks like an alternate of h3 and divs.
Your link to jquery should come before jquery UI or else it would not work.

accordion insideYii Clistview - not working

i m using Yii framework component CLISTVIEW on page load with ajax accordion stop working
i have tried follow, but it didn't work
$(".items").on('load',function(){
$(this).accordion();
});
when i change the event type in on form load to click it starts working. what would be the right event type to call here.
Accordion plugin expects this kind of content:
<h3>Section 1</h3>
<div>
<p>Content section 1</p>
</div>
<h3>Section 2</h3>
<div>
<p>Content section 2</p>
</div>
But if I've understand your situation, you have this kind of code:
<body>
<div class="items">
<h3>Section 1</h3>
<div>
<p>Content section 1</p>
</div>
</div>
<div class="items">
<h3>Section 2</h3>
<div>
<p>Content section 2</p>
</div>
</div>
</body>
With this script firs I .wrapAll .items elements and then I rewrite elements as accordion plugin want:
<script>
$(function() {
$('.items').wrapAll($('<div>').attr('id','accordion'));
$.each($('.items'),function(){
$(this).remove();
$('#accordion').append($(this).html());
});
$('#accordion').accordion();
});
</script>
HTML will be:
<div id="accordion">
<h3>Section 1</h3>
<div>
<p>Content section 1</p>
</div>
<h3>Section 2</h3>
<div>
<p>Content section 2</p>
</div>
</div>
And accordion will work fine.

How to build accordian style debugger with DOM - a nudge?

I have given up doing this in pure js. And I can't find the jquery accordian stuff i was looking over when I started this project originally. What is the best way to do this? My code is linked here
Here is jQuery UI Accordion.
All you need is:
<div id="accordion">
<h3>Section 1</h3>
<div>
<p>
Paragraph 1
</p>
</div>
<h3>Section 2</h3>
<div>
<p>
Paragraph 2
</p>
</div>
</div>
and
$(document).ready(function() {
$("#accordion").accordion();
});

Resources