Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(components): add inline tabs component with ajax support
Inline tabs component can now be rendered with "page/components/tabs" view. The component allows to switch between pre-populated and ajax-loaded tabs.
- Loading branch information
1 parent
c8fce06
commit 4de1cd2
Showing
8 changed files
with
296 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
mod/developers/views/default/theme_sandbox/components/tabs.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<?php | ||
|
||
echo elgg_view('page/components/tabs', [ | ||
'tabs' => [ | ||
'inline' => [ | ||
'text' => 'Inline Content', | ||
'content' => elgg_view('developers/ipsum'), | ||
], | ||
'ajax' => [ | ||
'text' => 'Ajax [selected]', | ||
'href' => 'ajax/view/theme_sandbox/components/tabs/ajax', | ||
'selected' => true, | ||
'data-ajax-reload' => false, | ||
'data-ajax-query' => json_encode([ | ||
'content' => 'This tab was preselected and loaded via ajax', | ||
]), | ||
], | ||
'inline2' => [ | ||
'text' => 'Inline List', | ||
'content' => elgg_list_entities([ | ||
'types' => 'user', | ||
'list_type' => 'gallery', | ||
'gallery_class' => 'elgg-gallery-users', | ||
'pagination' => false, | ||
]), | ||
], | ||
'ajax2' => [ | ||
'text' => 'Ajax [data-ajax-reload]', | ||
'href' => 'ajax/view/theme_sandbox/components/tabs/ajax', | ||
'data-ajax-reload' => true, | ||
'data-ajax-query' => json_encode([ | ||
'content' => 'This tab reloads every time you click on it', | ||
]), | ||
], | ||
'ajax3' => [ | ||
'text' => 'Ajax [data-ajax-href]', | ||
'href' => 'activity', | ||
'data-ajax-href' => 'ajax/view/theme_sandbox/components/tabs/ajax', | ||
'data-ajax-reload' => false, | ||
'data-ajax-query' => json_encode([ | ||
'content' => 'If you right click on the tab and open it in a new tab, you will end up on the activity page', | ||
]), | ||
], | ||
'callback' => [ | ||
'text' => 'Click Me', | ||
'href' => 'ajax/view/theme_sandbox/components/tabs/ajax', | ||
'data-ajax-query' => json_encode([ | ||
'content' => 'This tab has events attached to it.', | ||
]), | ||
'data-ajax-reload' => false, | ||
'class' => 'theme-sandbox-tab-callback', | ||
] | ||
], | ||
]); | ||
|
||
?> | ||
<script> | ||
require(['jquery', 'elgg/ready'], function($) { | ||
$(document).on('open', '.theme-sandbox-tab-callback', function() { | ||
$(this).find('a').text('Clicked!'); | ||
$(this).data('target').hide().show('slide', { | ||
duration: 2000, | ||
direction: 'right', | ||
complete: function() { | ||
alert('Thank you for clicking. We hope you enjoyed the show!'); | ||
$(this).css('display', ''); // .show() adds display property | ||
} | ||
}); | ||
}); | ||
}); | ||
</script> |
4 changes: 4 additions & 0 deletions
4
mod/developers/views/default/theme_sandbox/components/tabs/ajax.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<?php | ||
|
||
$content = get_input('content', 'No data was sent by the tab with the request'); | ||
echo elgg_view_module('featured', 'Ajax Content', $content); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/** | ||
* Tabbed module | ||
* | ||
* @module page/components/tabs | ||
*/ | ||
define(function (require) { | ||
|
||
var elgg = require('elgg'); | ||
require('elgg/ready'); | ||
var $ = require('jquery'); | ||
var Ajax = require('elgg/Ajax'); | ||
var ajax = new Ajax(false); | ||
|
||
function changeTab($tab) { | ||
|
||
$tab.siblings().andSelf().removeClass('elgg-state-selected'); | ||
$tab.addClass('elgg-state-selected'); | ||
|
||
var $target = $tab.data('target'); | ||
if (!$target || !$target.length) { | ||
return false; | ||
} | ||
|
||
$target.siblings().addClass('hidden').removeClass('elgg-state-active'); | ||
$target.removeClass('hidden').addClass('elgg-state-active'); | ||
|
||
return true; | ||
} | ||
|
||
$(document).on('click', '.elgg-tabs-component .elgg-tabs > li > a', function (e) { | ||
e.preventDefault(); | ||
|
||
var $link = $(this); | ||
var $tab = $(this).parent(); | ||
var $component = $(this).closest('.elgg-tabs-component'); | ||
var $content = $component.find('.elgg-tabs-content'); | ||
|
||
var href = $link.data('ajaxHref') || $link.attr('href'); | ||
var $target = $tab.data('target'); | ||
|
||
if (href.indexOf('#') === 0) { | ||
// Open inline tab | ||
if (!$target || !$target.length) { | ||
var $target = $content.find(href); | ||
$tab.data('target', $target); | ||
} | ||
|
||
if (changeTab($tab)) { | ||
$tab.trigger('open'); | ||
return; | ||
} | ||
} else { | ||
// Load an ajax tab | ||
if (!$target || !$target.length) { | ||
var $target = $('<div>').addClass('elgg-content hidden'); | ||
$content.append($target); | ||
$tab.data('target', $target); | ||
} | ||
|
||
if ($tab.data('loaded') && !$link.data('ajaxReload')) { | ||
if (changeTab($tab)) { | ||
$tab.trigger('open'); | ||
return; | ||
} | ||
} | ||
|
||
ajax.path(href, { | ||
data: $link.data('ajaxQuery') || {}, | ||
beforeSend: function () { | ||
changeTab($tab); | ||
$target.addClass('elgg-ajax-loader'); | ||
} | ||
}).done(function (output, statusText, jqXHR) { | ||
$tab.data('loaded', true); | ||
$target.removeClass('elgg-ajax-loader'); | ||
if (jqXHR.AjaxData.status === -1) { | ||
$target.html(elgg.echo('ajax:error')); | ||
return; | ||
} else { | ||
$target.html(output); | ||
} | ||
|
||
if (changeTab($tab)) { | ||
$tab.trigger('open'); | ||
} | ||
}); | ||
} | ||
}); | ||
|
||
// Open selected tabs | ||
// This will load any selected tabs that link to ajax views | ||
$('.elgg-tabs-component .elgg-tabs > li.elgg-state-selected > a').trigger('click'); | ||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
<?php | ||
/** | ||
* Tabbed module component | ||
* Provides support for inline and ajax tabbing | ||
* | ||
* @uses $vars['id'] Optional ID of the module | ||
* @uses $vars['class'] Additional classes | ||
* @uses $vars['module'] Module name | ||
* Defaults to 'tabs' (.elgg-module-tabs) | ||
* @uses $vars['tabs'] An array of tabs suitable for 'navigation/tabs' view | ||
* Each tab should specify either: | ||
* - a 'href' parameter to load content via AJAX, or | ||
* - a 'content' parameter to display content inline | ||
* If the tab uses a 'href' attribute, it should specify | ||
* whether the contents should be reloaded on a subsequent | ||
* click via 'data-ajax-reload' parameter; by default, | ||
* all tabs will be reloading on subsequent clicks. | ||
* You can pass additional data to the ajax view via | ||
* data-ajax-query attribute (json encoded string). | ||
* You can also set the data-ajax-href parameter of the tab, | ||
* which will override the href parameter, in case you want | ||
* to ensure the tab is clickable even before the JS is bootstrapped. | ||
* <code> | ||
* [ | ||
* ['text' => 'Tab 1', 'href' => '/dynamic', 'data-ajax-reload' => true], | ||
* ['text' => 'Tab 2', 'href' => '/static', 'data-ajax-reload' => false], | ||
* ['text' => 'Tab 3', 'href' => '/static', 'data-ajax-reload' => false, 'data-ajax-query' => json_encode($data)], | ||
* ['text' => 'Tab 3', 'href' => '/page', 'data-ajax-href' => '/ajax/page'], | ||
* ['text' => 'Tab 4', 'href' => 'Tab content'], | ||
* ] | ||
* </code> | ||
*/ | ||
$id = elgg_extract('id', $vars); | ||
if (!isset($vars['id'])) { | ||
$id = "elgg-tabs-" . base_convert(mt_rand(), 10, 36); | ||
} | ||
$vars['id'] = $id; | ||
|
||
$vars['class'] = elgg_extract_class($vars, 'elgg-tabs-component'); | ||
|
||
$tabs = (array) elgg_extract('tabs', $vars, []); | ||
unset($vars['tabs']); | ||
if (empty($tabs)) { | ||
return; | ||
} | ||
|
||
$content = ''; | ||
foreach ($tabs as $index => $tab) { | ||
if (!isset($tab['href']) && !isset($tab['content'])) { | ||
elgg_log('Tab configuration in "page/components/tabs" | ||
requires either a "href" or "content" parameter', 'ERROR'); | ||
continue; | ||
} | ||
|
||
$selected = elgg_extract('selected', $tab); | ||
|
||
if (isset($tab['content'])) { | ||
$class = ['elgg-content']; | ||
$class[] = $selected ? 'elgg-state-active' : 'hidden'; | ||
|
||
$content .= elgg_format_element('div', [ | ||
'class' => $class, | ||
'id' => "{$id}-{$index}", | ||
], $tab['content']); | ||
unset($tab['content']); | ||
|
||
$tab['href'] = "#{$id}-{$index}"; | ||
} else { | ||
if (!isset($tab['data-ajax-reload'])) { | ||
$tab['data-ajax-reload'] = true; | ||
} | ||
} | ||
|
||
$tabs[$index] = $tab; | ||
} | ||
|
||
$tabs = elgg_view('navigation/tabs', [ | ||
'tabs' => $tabs, | ||
]); | ||
|
||
$content = elgg_format_element('div', [ | ||
'class' => 'elgg-tabs-content', | ||
], $content); | ||
|
||
$module = elgg_extract('module', $vars, 'tabs'); | ||
unset($vars['module']); | ||
echo elgg_view_module($module, $tabs, $content, $vars); | ||
|
||
?> | ||
<script> | ||
require(['page/components/tabs']); | ||
</script> | ||
|