Advertisement
Add Modal Window Option For Menu Items
-
- Joomla! Guru
- Posts: 734
- Joined: Wed Aug 15, 2018 8:23 pm
Add Modal Window Option For Menu Items
A recent project required modal window display of various content, including login form, and it had to be simple usage.
I had to create a system plugin and template overrides to achieve the result, however I think this should be a method included with Joomla core since it fully supports Bootstrap.
Add a third Modal Window option to menu item Target Window select Add text field to insert modal target element ID along with method to select a module to insert as the modal content The result when Login menu item is clicked
I had to create a system plugin and template overrides to achieve the result, however I think this should be a method included with Joomla core since it fully supports Bootstrap.
Add a third Modal Window option to menu item Target Window select Add text field to insert modal target element ID along with method to select a module to insert as the modal content The result when Login menu item is clicked
You do not have the required permissions to view the files attached to this post.
Advertisement
-
- I've been banned!
- Posts: 13639
- Joined: Sun Jul 05, 2009 3:30 am
- Location: Canberra, Australia
Re: Add Modal Window Option For Menu Items
Great idea! I can't remember how many third-party or home-grown methods I've used to display something as simple as a login form on a website, without the form tying up screen real estate, but somethin like this would be very useful if included with the J! core. Features like these could attract more people to lean towards J! when building or making-over their websites and may even motivate those set-in-their-ways people who refuse to update their websites to the current release!
People love eye-candy, don't they?
People love eye-candy, don't they?
-
- Joomla! Guru
- Posts: 734
- Joined: Wed Aug 15, 2018 8:23 pm
Re: Add Modal Window Option For Menu Items
I certainly agree with that statement. A user should not have to go searching for yet another extension just to achieve what seems like it should be a simple default method. The option would allow for modal display of anything a module can output.
-
- I've been banned!
- Posts: 13639
- Joined: Sun Jul 05, 2009 3:30 am
- Location: Canberra, Australia
Re: Add Modal Window Option For Menu Items
If there was a prize for the best idea of the year for J!, this would be on my shortlist of favourites to win. We see a few ideas posted here (and, in my opinion, I don't think most of them are worth a second look) and, probably because this J! ideas forum has been lacking in meritorious content, this may explain why the developers don't take a lot of interest in selecting ideas from the forum and investing their time to implement them.
I suggest that someone might flag this idea as something for J! 3.10—if this were a new feature for J! 3.10 I would certainly be keen to be among the early adopters—as well as a feature for J! 4.0 (or possibly J! 4.1).
I suggest that someone might flag this idea as something for J! 3.10—if this were a new feature for J! 3.10 I would certainly be keen to be among the early adopters—as well as a feature for J! 4.0 (or possibly J! 4.1).
-
- Joomla! Guru
- Posts: 734
- Joined: Wed Aug 15, 2018 8:23 pm
Re: Add Modal Window Option For Menu Items
If you wish to review the plugin and use as desired, see the attached file. Feel free to redistribute. Usage
- Install and enable the menu_modal plugin
- Publish an instance of mod_login. It does not need to be assigned to any position, but must be available sitewide.
- Select the modal layout for mod_menu which will be in use. Can be set for all instances of mod_menu
- Set a menu item to user login and choose Modal Window from the Target Window select
- In the Link Type tab view, set the modal target ID and choose the login module from the Modal Content list
File structure Installer process
Code: Select all
<?php defined('_JEXEC') or die();
/**
* @package menu_modal
* @copyright Copyright (C) anydomain.com All rights reserved.
* @license GNU General Public License version 2 or later; see http://www.gnu.org/licenses/
**/
use Joomla\Registry\Registry;
class plgSystemMenu_ModalInstallerScript
{
public function postflight($type, $parent)
{
/*
move the mod_menu template files into modules/mod_menu/tmpl
to be available for selection in Advanced module tab
*/
JFolder::copy(JPATH_PLUGINS.'/system/menu_modal/_copyfiles/mod_menu/tmpl', JPATH_ROOT.'/modules/mod_menu/tmpl', '', true, true);
}
/* uninstall
-------------------------*/
public function uninstall($parent)
{
$filedelete = [
JPATH_ROOT.'/modules/mod_menu/tmpl/modal.php',
JPATH_ROOT.'/modules/mod_menu/tmpl/modal_component.php',
JPATH_ROOT.'/modules/mod_menu/tmpl/modal_url.php'
];
foreach($filedelete as $file) {
if( file_exists($file) )
JFile::delete($file, true);
}
JFactory::getApplication()->enqueueMessage(JText::_('Successfully uninstalled plugin menu_modal and overide files'));
}
}
Code: Select all
<?xml version="1.0" encoding="utf-8"?>
<extension version="3.9.0" type="plugin" group="system" method="upgrade">
<name>System - Menu Modal</name>
<author>anydomain.com</author>
<creationDate>10.14.2020</creationDate>
<copyright>All Rights Reserved.</copyright>
<license>license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html</license>
<authorEmail>[email protected]</authorEmail>
<authorUrl>http://www.anydomain.com</authorUrl>
<version>1.0</version>
<description>Menu Modal</description>
<files>
<filename plugin="menu_modal">menu_modal.php</filename>
<filename>index.html</filename>
<filename>helper.php</filename>
<folder>_copyfiles</folder>
</files>
<scriptfile>install.php</scriptfile>
</extension>
Code: Select all
<?php defined('_JEXEC') or die();
/**
* @package menu_modal
* @copyright Copyright (C) anydomain.com All rights reserved.
* @license GNU General Public License version 2 or later; see http://www.gnu.org/licenses/
**/
// load functions globally
include_once __DIR__.'/helper.php';
class plgSystemMenu_Modal extends JPlugin
{
public function __construct($subject, $params) {
parent::__construct($subject, $params);
}
/** Form Field
--------------------------------*/
public function onContentPrepareForm($form, $data)
{
// menu
if( $form->getName()=='com_menus.item' )
{
JForm::addFormPath(__DIR__.'/_copyfiles/');
// remove core target window select field and replace with modified select
$form->removeField('browserNav');
$form->loadFile('menuitem', false);
}
}
}
Code: Select all
<?php defined('_JEXEC') or die();
/**
* @package menu_modal
* @copyright Copyright (C) anydomain.com All rights reserved.
* @license GNU General Public License version 2 or later; see http://www.gnu.org/licenses/
**/
use Joomla\CMS\Factory;
use Joomla\CMS\Helper\ModuleHelper;
function myGetInput($query=null, $method=null, $format='get')
{
$app = Factory::getApplication();
$input = $app->input;
if( $format == 'string' ) {
$format = 'getString';
}else
if( $format == 'int' ) {
$format = 'getInt';
}
if( is_null($query) ) {
$value = $app;
}else
if( $query == 'input' ) {
$value = $input;
}else
if( $query == 'admin' ) {
$value = $app->isAdmin();
}else{
$value = $input->$format($query);
}
if( !empty($method) )
{
switch($method)
{
case 'request': $value = $input->request->$format; break;
case 'cookie': $value = $input->cookie->$format; break;
case 'server': $value = $input->server->$format($query); break;
case 'post': $value = $input->post->$format; break;
}
}
return $value;
}
// database query
function myDbTask($query, $method='result')
{
$db = Factory::getDbo();
$db->setQuery($query);
switch($method)
{
case 'object': $value = $db->loadObject(); break;
case 'objectlist': $value = $db->loadObjectList(); break;
case 'row': $value = $db->loadRow(); break;
case 'rowlist': $value = $db->loadRowList(); break;
case 'column': $value = $db->loadColumn(); break;
case 'columnlist': $value = $db->loadColumnList(); break;
case 'assoc': $value = $db->loadAssoc(); break;
case 'assoclist': $value = $db->loadAssocList(); break;
case 'execute': $value = $db->execute(); break;
default: $value = $db->loadResult();
}
return $value;
}
// get module by ID and render
function myModuleRender($id, $style='')
{
$mod = myDbTask("
SELECT title,module,showtitle
FROM #__modules
WHERE id = $id
AND published = 1
AND client_id = 0",
"object");
if( !empty($mod) && is_object($mod) )
{
$module = ModuleHelper::getModule($mod->module, $mod->title);
$chromestyle = ['style' => !empty($style) ? $style : 'none', 'title' => $mod->showtitle];
return ModuleHelper::renderModule( $module, $chromestyle );
}else{
return myMsg('no module with the ID available or maybe unpublished','warning');
}
}
/* Modal Window*/
function myModal($id, $content, $ismodule=false, $title='', $closetext='Close')
{
if( $ismodule )
$content = myModuleRender((int)$content);
if( !empty($title) )
$title = '<h4 class="modal-title">'.$title.'</h4>';
$html = '
<div id="'.$id.'" class="modal fade" role="dialog" style="display: none;">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
'.$title.'
</div>
<div class="modal-body">
'.$content.'
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">'.$closetext.'</button>
</div>
</div>
</div>
</div>
';
return $html;
}
function myMsg($msg, $alert='info') {
return Factory::getApplication()->enqueueMessage(JText::_($msg),$alert);
}
modules.php form list select element that retrieves active modules
Code: Select all
<?php defined('_JEXEC') or die();
/**
* @package menu_modal
* @copyright Copyright (C) anydomain.com All rights reserved.
* @license GNU General Public License version 2 or later; see http://www.gnu.org/licenses/
**/
use Joomla\Registry\Registry;
JFormHelper::loadFieldClass('list');
class JFormFieldModules extends JFormFieldList
{
protected $type = 'Modules';
protected function getOptions()
{
$modules = myDbTask("
SELECT id,title
FROM #__modules
WHERE published = 1 AND client_id = 0",
"objectlist");
$options = [];
foreach($modules as $module)
{
$id = ' - ('.$module->id.')';
// do not include self if in module edit view
if( !is_null(myGetInput('id')) && $module->id == myGetInput('id') ) {
continue;
}
$options[] = JHtml::_('select.option', $module->id, str_replace('_', ' ', $module->title).$id, 'value', 'text');
}
return $options;
}
}
Code: Select all
<?xml version="1.0" encoding="utf-8"?>
<form>
<field
type="list"
name="browserNav"
label="COM_MENUS_ITEM_FIELD_BROWSERNAV_LABEL"
description="COM_MENUS_ITEM_FIELD_BROWSERNAV_DESC"
default="0"
filter="int"
>
<option value="0">COM_MENUS_FIELD_VALUE_PARENT</option>
<option value="1">COM_MENUS_FIELD_VALUE_NEW_WITH_NAV</option>
<option value="2">COM_MENUS_FIELD_VALUE_NEW_WITHOUT_NAV</option>
<option value="3">Modal Window</option>
</field>
<fields name="params" addfieldpath="/plugins/system/menu_modal/_copyfiles/">
<fieldset name="menu-options">
<field type="text" name="modalid" hint="mymodal" label="Modal Window ID" />
<field type="modules" name="modalcontent" label="Modal Window Content" />
</fieldset>
</fields>
</form>
These files are copied during installation to modules/mod_menu/tmpl and become available for selection in Advanced > Layout of the mod_menu. They can be placed in the frontend default template's override directory, however this method is available independent of template in use.
modal.php represents default.php
Code: Select all
<?php
/**
* @package Joomla.Site
* @subpackage mod_menu
* @subpackage plugin / system / menu_modal
* @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
$id = '';
if ($tagId = $params->get('tag_id', ''))
{
$id = ' id="' . $tagId . '"';
}
// The menu class is deprecated. Use nav instead
?>
<ul class="nav menu<?php echo $class_sfx; ?> mod-list"<?php echo $id; ?>>
<?php
foreach ($list as $i => &$item)
{
$class = 'item-' . $item->id;
// define modal window variable and process
$modalwin='';
if( $item->browserNav == 3 )
{
$modalwin = myModal(
$item->params->get('modalid','mymodal'),
$item->params->get('modalcontent'),
true,
$item->title
);
}
if ($item->id == $default_id)
{
$class .= ' default';
}
if ($item->id == $active_id || ($item->type === 'alias' && $item->params->get('aliasoptions') == $active_id))
{
$class .= ' current';
}
if (in_array($item->id, $path))
{
$class .= ' active';
}
elseif ($item->type === 'alias')
{
$aliasToId = $item->params->get('aliasoptions');
if (count($path) > 0 && $aliasToId == $path[count($path) - 1])
{
$class .= ' active';
}
elseif (in_array($aliasToId, $path))
{
$class .= ' alias-parent-active';
}
}
if ($item->type === 'separator')
{
$class .= ' divider';
}
if ($item->deeper)
{
$class .= ' deeper';
}
if ($item->parent)
{
$class .= ' parent';
}
echo '<li class="' . $class . '">';
echo $modalwin;
switch ($item->type) :
case 'separator':
case 'component':
case 'heading':
case 'url':
// changed 'default' to 'modal' to load associated files
require JModuleHelper::getLayoutPath('mod_menu', 'modal_' . $item->type);
break;
default:
require JModuleHelper::getLayoutPath('mod_menu', 'default_url');
break;
endswitch;
// The next item is deeper.
if($item->deeper) {
echo '<ul class="nav-child unstyled small">';
}
// The next item is shallower.
elseif ($item->shallower)
{
echo '</li>';
echo str_repeat('</ul></li>', $item->level_diff);
}
// The next item is on the same level.
else
{
echo '</li>';
}
}
?></ul>
Code: Select all
<?php
/**
* @package Joomla.Site
* @subpackage mod_menu
* @subpackage plugin / system / menu_modal
* @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
$attributes = array();
if ($item->anchor_title)
{
$attributes['title'] = $item->anchor_title;
}
if ($item->anchor_css)
{
$attributes['class'] = $item->anchor_css;
}
if ($item->anchor_rel)
{
$attributes['rel'] = $item->anchor_rel;
}
$linktype = $item->title;
if ($item->menu_image)
{
if ($item->menu_image_css)
{
$image_attributes['class'] = $item->menu_image_css;
$linktype = JHtml::_('image', $item->menu_image, $item->title, $image_attributes);
}
else
{
$linktype = JHtml::_('image', $item->menu_image, $item->title);
}
if ($item->params->get('menu_text', 1))
{
$linktype .= '<span class="image-title">' . $item->title . '</span>';
}
}
if( $item->browserNav == 1 ) {
$attributes['target'] = '_blank';
}else
if( $item->browserNav == 2 ) {
$options = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes';
$attributes['onclick'] = "window.open(this.href, 'targetWindow', '" . $options . "'); return false;";
}else
// return modal window process
if( $item->browserNav == 3 ) {
$item->flink = 'javascript:;';
$attributes['data-target'] = '#'.$item->params->get('modalid', 'mymodal');
$attributes['data-toggle'] = 'modal';
}
echo JHtml::_('link', JFilterOutput::ampReplace(htmlspecialchars($item->flink, ENT_COMPAT, 'UTF-8', false)), $linktype, $attributes);
Code: Select all
<?php
/**
* @package Joomla.Site
* @subpackage mod_menu
*
* @copyright Copyright (C) 2005 - 2020 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
$attributes = array();
if ($item->anchor_title)
{
$attributes['title'] = $item->anchor_title;
}
if ($item->anchor_css)
{
$attributes['class'] = $item->anchor_css;
}
if ($item->anchor_rel)
{
$attributes['rel'] = $item->anchor_rel;
}
$linktype = $item->title;
if ($item->menu_image)
{
if ($item->menu_image_css)
{
$image_attributes['class'] = $item->menu_image_css;
$linktype = JHtml::_('image', $item->menu_image, $item->title, $image_attributes);
}
else
{
$linktype = JHtml::_('image', $item->menu_image, $item->title);
}
if ($item->params->get('menu_text', 1))
{
$linktype .= '<span class="image-title">' . $item->title . '</span>';
}
}
if ($item->browserNav == 1)
{
$attributes['target'] = '_blank';
$attributes['rel'] = 'noopener noreferrer';
if ($item->anchor_rel == 'nofollow')
{
$attributes['rel'] .= ' nofollow';
}
}
else
if ($item->browserNav == 2)
{
$options = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,' . $params->get('window_open');
$attributes['onclick'] = "window.open(this.href, 'targetWindow', '" . $options . "'); return false;";
}else
// return modal window process
if( $item->browserNav == 3 )
{
$item->flink = 'javascript:;';
$attributes['data-target'] = '#'.$item->params->get('modalid', 'mymodal');
$attributes['data-toggle'] = 'modal';
}
echo JHtml::_('link', JFilterOutput::ampReplace(htmlspecialchars($item->flink, ENT_COMPAT, 'UTF-8', false)), $linktype, $attributes);
You do not have the required permissions to view the files attached to this post.
-
- I've been banned!
- Posts: 13639
- Joined: Sun Jul 05, 2009 3:30 am
- Location: Canberra, Australia
Re: Add Modal Window Option For Menu Items
Thank you. It's on my to do list.
-
- I've been banned!
- Posts: 13639
- Joined: Sun Jul 05, 2009 3:30 am
- Location: Canberra, Australia
Re: Add Modal Window Option For Menu Items
I gave the plugin a quick tryout and I can confirm:
- The menu_modal plugin was installed and enabled
- An instance of the mod_login module is published ... and assigned to all pages on the site
- Modal was selected from the drop-down layout choices the chosen mod_menu module
- A menu item was created of type Users » Login Form.
- There was no option to choose Modal Window for the Target Window setting.
- I cannot see how to use the Link Type tab view to set the modal target ID and choose the login module from the Modal Content and so forth
You do not have the required permissions to view the files attached to this post.
-
- Joomla! Guru
- Posts: 734
- Joined: Wed Aug 15, 2018 8:23 pm
Re: Add Modal Window Option For Menu Items
It seems the file menu_modal.php is somehow not being executed. That file is what should set the fields in the menu edit view. Are you using any special menu component override which has a name other than com_menus? Because the condition depends on that value
if( $form->getName()=='com_menus.item' )
Check the browser's URL when in menu edit view
index.php?option=com_menus&view=item&client_id=0&layout=edit&id=287
Code: Select all
class plgSystemMenu_Modal extends JPlugin
{
public function __construct($subject, $params) {
parent::__construct($subject, $params);
}
/** Form Field
--------------------------------*/
public function onContentPrepareForm($form, $data)
{
// menu
if( $form->getName()=='com_menus.item' )
{
JForm::addFormPath(__DIR__.'/_copyfiles/');
// remove core target window select field and replace with modified select
$form->removeField('browserNav');
$form->loadFile('menuitem', false);
}
}
}
-
- I've been banned!
- Posts: 13639
- Joined: Sun Jul 05, 2009 3:30 am
- Location: Canberra, Australia
Re: Add Modal Window Option For Menu Items
Thanks for your reply. The test website is fairly ordinary but, to eliminate the possibility of any other extension intervening in the process, I will conduct the test on a brand new, unmodified (apart from installing Akeeba Backup, which is something I always use) J! 3.9.22 website. I will let you know in the next 10-15 minutes.
-
- I've been banned!
- Posts: 13639
- Joined: Sun Jul 05, 2009 3:30 am
- Location: Canberra, Australia
Re: Add Modal Window Option For Menu Items
Very well; here's what I found.
Success (but not without a couple of minor issues). Yes, I went through the process on a bare-bones J! 3.9.22 website and, yes, I found the option under Target Window setting for "Modal" Without proceeding to double-check the new setting on the Link Type tab, I saved the menu item setting and refreshed the frontend of my test site --> 503 Service Unavailable
Changed the Link Type » Modal Window Content = "Login Form (16)", refreshed the frontend again, the site loaded (this time) and clicking the Login menu item displays the login form as a modal. Logged in, no problem.
I will check the order the plugins are loaded on my first test site to see if there's something conflicting there.
Success (but not without a couple of minor issues). Yes, I went through the process on a bare-bones J! 3.9.22 website and, yes, I found the option under Target Window setting for "Modal" Without proceeding to double-check the new setting on the Link Type tab, I saved the menu item setting and refreshed the frontend of my test site --> 503 Service Unavailable
Changed the Link Type » Modal Window Content = "Login Form (16)", refreshed the frontend again, the site loaded (this time) and clicking the Login menu item displays the login form as a modal. Logged in, no problem.
I will check the order the plugins are loaded on my first test site to see if there's something conflicting there.
-
- I've been banned!
- Posts: 13639
- Joined: Sun Jul 05, 2009 3:30 am
- Location: Canberra, Australia
Re: Add Modal Window Option For Menu Items
Hmmm ... I've been experimenting with my original test site. I was able to display the menu item settings (by changing the load order for the plugin to "Order first") ... but that may be a piece of folklore and I wouldn't put too much faith in my skill set However, while I was able to make the changes (after a bit of a fiddle, I suppose), on clicking the menu item to login, the lightbox/shadowbox effect loads but the form did not display. So there may be some Javascript conflict occurring. Not a major issue for me; the test site was just for testing. I can confirm that, on a vanilla, out-of-the-box, J! 3.9.22 website (using Protostar), with nothing else installed except for Akeeba Admin Tools and Akeeba Backup, the plugin works as described and I'm happy with that.
Thanks very much.
Thanks very much.
-
- Joomla! Guru
- Posts: 734
- Joined: Wed Aug 15, 2018 8:23 pm
Re: Add Modal Window Option For Menu Items
Good to know it finally works, but of concern that it was not quick and painless. As you review the coding, feel free to tweak and make better. As stated before, it was just a project for a client and I have no intent to distribute.
Hopefully this method will be made a core function of Joomla, and extensions will not be necessary.
Thanks for the participation.
-
- I've been banned!
- Posts: 13639
- Joined: Sun Jul 05, 2009 3:30 am
- Location: Canberra, Australia
Re: Add Modal Window Option For Menu Items
Thanks, Anna. If you'd like me to assist you with any additional beta testing I'd be more than happy to give you some time. If you think I can help, I invite you to contact me—send me a PM, for instance—and we could arrange to discuss the matter offline (via a [Skype] teleconference if that suits). In the meantime, I've got some carpentry work that will keep me very happy. Cheers.
You're right: before this idea finds its way into the J! core, we'd need to iron-out any wrinkles.
You're right: before this idea finds its way into the J! core, we'd need to iron-out any wrinkles.
-
- Joomla! Guru
- Posts: 734
- Joined: Wed Aug 15, 2018 8:23 pm
Advertisement