...

View Full Version : jQuery Problems using Tabs in a Dialog populated from a Template



WolfyUK
11-11-2010, 12:09 PM
Hi all,

I am attempting to use three jQuery plugins to render some templated content that should include tabs within a dialog. I am using jQuery.tmpl() for the template along with Tabs and Dialog from jQuery UI. The problem I have is to do with context in that setting the selector to an id of the <div> to make tab-able only works on the first attempt.

To understand what I am on about, please check out the following code which is missing the references to jquery.js, jquery-ui.js and jquery.tmpl.js:


<script id="tabTemplate" type="text/x-jquery-tmpl">
<div id="tabs">
<ul>
<li>
<a href="#tabs-1">Tab 1</a>
</li>
<li>
<a href="#tabs-2">Tab 2</a>
</li>
</ul>
<div id="tabs-1">
Tab 1 content ${key}
</div>
<div id="tabs-2">
Tab 2 content
</div>
</div>
</script>

<ul>
<li><a href="#" id="dialogButton">dialogify</a></li>
</ul>

<script type="text/javascript">

$('#dialogButton').click(function () {
var test = new Object();
test['key'] = 'value';

var $dialog = $('<div></div>')
.html($('#tabTemplate').tmpl(test))
.dialog({ autoOpen: false });

$dialog.bind('dialogopen', function() {
$('#tabs', $(this)).tabs();
});
$dialog.bind('dialogclose', function() {
$('#tabs', $(this)).tabs('destroy');
$(this).dialog('destroy');
});

$dialog.dialog('open');
return false;
});

</script>

Clicking the dialogify link for the first time will display the content as expected, but subsequent times do not. I have tried playing around with using a selector other than '#tabs' (such as by className) as well as dynamically adding tabs but I could not seem to get this working.

Any advice on what else I could try would be appreciated!

Thanks,

Marc

SB65
11-11-2010, 12:51 PM
Not familiar with the template function you're using, but it looks like you're reloading #tabTemplate, and your reloaded content doesn't have the click event attached.

.live() (http://api.jquery.com/live/) should do the trick:


$('#dialogButton').live('click',function () { etc

WolfyUK
11-13-2010, 08:48 AM
Hi,

Thanks but it is not the click() event that is firing incorrectly. It is the rendering of the dialog contents into tabs that is the problem. This may be replicated without using the tmpl() plugin as follows:


<div id="tabs">
<ul>
<li>
<a href="#tabs-1">Tab 1</a>
</li>
<li>
<a href="#tabs-2">Tab 2</a>
</li>
</ul>
<div id="tabs-1">
Tab 1 content
</div>
<div id="tabs-2">
Tab 2 content
</div>
</div>


<ul>
<li><a href="#" id="dialogButton">dialogify</a></li>
</ul>

<script type="text/javascript">

$('#dialogButton').click(function () {
var $dialog = $('<div></div>')
.html($('#tabs').clone())
.dialog({ autoOpen: false });

$dialog.bind('dialogopen', function() {
$('#tabs', $(this)).tabs();
});
$dialog.bind('dialogclose', function() {
$('#tabs', $(this)).tabs('destroy');
$(this).dialog('destroy');
});

$dialog.dialog('open');
return false;
});

</script>

The problem is the clone()-ing of the content leading to multiple #tabs on the page, and the tabs() plugin seemingly ignoring the context provided for the current dialog through $(this).

SB65
11-13-2010, 09:53 AM
Been playing about with this for a while, but I'm not sure I fully understand what it is you're trying to do. On clicking the dialogify button this should create a dialog with tabbed content, which is copied from #tabs (here as a normal div, but otherwise as a template) - is that right?

The problem I'm seeing is that because #tabs is cloned, the divs containing the tabbed content are also cloned and hence there are multiple divs with the same id including tab content - so the tabs in the dialog don't work.

Is that the problem? Or am I way off beam?

WolfyUK
11-13-2010, 10:24 AM
Hi,

No, that is the problem exactly.

Thanks for looking into this on a miserable morning in West Yorkshire!

Marc

SB65
11-13-2010, 01:25 PM
OK, have a try with:


<div class="tabs">
<ul>
<li>
<a href="#tabs-1">Tab 1</a>
</li>
<li>
<a href="#tabs-2">Tab 2</a>
</li>
</ul>
<div id="tabs-1" class="content">
Tab 1 content
</div>
<div id="tabs-2" class="content">
Tab 2 content
</div>
</div>


<ul>
<li><a href="#" id="dialogButton">dialogify</a></li>
</ul>

<script type="text/javascript">

var dialogCounter = 1;

$('#dialogButton').click(function () {
var $dialog = $('<div></div>')
.html($('.tabs').clone())
.dialog({ autoOpen: false });

$dialog.bind('dialogopen', function() {
console.log(dialogCounter);
$(this).find('a').each(function(){
$(this).attr('href',$(this).attr('href')+'_'+dialogCounter);
});
$(this).find('div.content').each(function(){
$(this).attr('id',$(this).attr('id')+'_'+dialogCounter);
});
dialogCounter++;
console.log($(this));
$(this).find('.tabs').tabs().removeClass('tabs');
});
$dialog.bind('dialogclose', function() {
$(this).find('.tabs').tabs('destroy');
$(this).dialog('destroy');
});

$dialog.dialog('open');
return false;
});

</script>

Logic here: Initialise a counter to record the number of dialogs open (assuming there could be many). When the html is cloned, amend the ids of the anchors and divs to append the dialogCounter (so then they all have unique ids), and increment the dialogCounter. Remove the class of 'tabs' to stop the newly created element being cloned on a second or subsequent dialogify click.

html:I changed the id on the template to a class and added a content class to the content divs just to make things easier to manipulate.

This seems to work for me OK. It also seems ever so slightly clunky...

What else is there to do on a wet Saturday? Are you in WY too then?

WolfyUK
11-13-2010, 02:35 PM
Excellent, that's exactly what I was after due to the problems with multiple identical ids. To get this working with tmpl() I've used the following:


<script id="tabTemplate" type="text/x-jquery-tmpl">
<div class="tabs">
<ul>
<li>
<a href="#tabs-1">Tab 1</a>
</li>
<li>
<a href="#tabs-2">Tab 2</a>
</li>
</ul>
<div id="tabs-1" class="content">
Tab 1 content ${key}
</div>
<div id="tabs-2" class="content">
Tab 2 content
</div>
</div>
</script>

<ul>
<li><a href="#" id="dialogButton">dialogify</a></li>
</ul>

<script type="text/javascript">
var dialogCounter = 1;

$('#dialogButton').click(function () {
var test = new Object();
test['key'] = 'value';

var $dialog = $('<div></div>')
.html($('#tabTemplate').tmpl(test))
.dialog({ autoOpen: false });

$dialog.bind('dialogopen', function() {
$(this).find('a').each(function(){
$(this).attr('href', $(this).attr('href') + '_' + dialogCounter);
});
$(this).find('div.content').each(function(){
$(this).attr('id', $(this).attr('id') + '_' +dialogCounter);
});
dialogCounter++;
$(this).find('.tabs').tabs().removeClass('tabs');
});
$dialog.bind('dialogclose', function() {
$(this).find('.tabs').tabs('destroy');
$(this).dialog('destroy');
});

$dialog.dialog('open');
return false;
});

</script>

Yes, I am in sunny Leeds at work on a Saturday :(. You can't complain about all of the rainbows though!

Thanks again.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum