Difference between revisions of "Joomla 4 Tips and Tricks: Modal Box Data"

From Joomla! Documentation

m (Result)
m (Finished)
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
{{underconstruction}}
 
 
== Introduction ==
 
== Introduction ==
 +
 
This Tip arises from a component that has many list views and the user wants to see some quite large chunks of additional data or perform some task such as send an email. These features are triggered by buttons or links in the list table. The trigger opens a common modal dialog and the display of the dialog triggers data retrieval using Javasript.
 
This Tip arises from a component that has many list views and the user wants to see some quite large chunks of additional data or perform some task such as send an email. These features are triggered by buttons or links in the list table. The trigger opens a common modal dialog and the display of the dialog triggers data retrieval using Javasript.
  
Line 39: Line 39:
  
 
== Javascript ==
 
== Javascript ==
 +
 
<source lang="javascript">
 
<source lang="javascript">
 
var modalbox = document.getElementById("modal-box");
 
var modalbox = document.getElementById("modal-box");
Line 59: Line 60:
 
// get the description and set in modal-body
 
// get the description and set in modal-body
 
if (action == 'showCampDescription') {
 
if (action == 'showCampDescription') {
 +
// this is a simple display so the action button should not be seen
 
modalSave.classList.add('hidden');
 
modalSave.classList.add('hidden');
//showDescription(button.getAttribute('data-bs-id'));
 
 
setModalContent('camp.getDescription', button.getAttribute('data-bs-id'), '')
 
setModalContent('camp.getDescription', button.getAttribute('data-bs-id'), '')
 
}
 
}
Line 95: Line 96:
 
}
 
}
 
</source>
 
</source>
 +
 
== The Server Side Handler ==
 
== The Server Side Handler ==
 +
 
Notice that the url set in the javascript calls the component, controller and task. In this case '''com_mycomponent''', '''CampController.php''' in the src/Controllers folder, and the public function getDescription; A fragment of the code there:
 
Notice that the url set in the javascript calls the component, controller and task. In this case '''com_mycomponent''', '''CampController.php''' in the src/Controllers folder, and the public function getDescription; A fragment of the code there:
  
Line 110: Line 113:
 
}
 
}
 
</source>
 
</source>
 +
 
== Result ==
 
== Result ==
 +
 
[[File:joomla-4-tips-and-tricks-modal-box-data.png|border|Modal Box Data Example]]
 
[[File:joomla-4-tips-and-tricks-modal-box-data.png|border|Modal Box Data Example]]
  

Latest revision as of 09:51, 5 May 2021

Introduction

This Tip arises from a component that has many list views and the user wants to see some quite large chunks of additional data or perform some task such as send an email. These features are triggered by buttons or links in the list table. The trigger opens a common modal dialog and the display of the dialog triggers data retrieval using Javasript.

The HTML

The code for the trigger button is located in a table in a default.php list view file. By default there are 20 rows of data so 20 similar buttons:

<button
	class="btn btn-sm btn-info w5rem mb-1" 
	data-bs-toggle="modal" 
	data-bs-target="#modal-box" 
	data-bs-title="Fixing the ice shelves" 
	data-bs-id="14794" 
	data-bs-action="showCampDescription" 
	onclick="return false;">
		Description
</button>

The code for the modal dialog is included at the bottom of the file like so:

<?php include_once JPATH_COMPONENT . '/layouts/modalbox.php'; ?>

And the layout file contains the following:

<?php echo HTMLHelper::_(
	'bootstrap.renderModal',
	'modal-box', // selector
	array( // options
		'modal-dialog-scrollable' => true,
		'title'  => 'Test Title',
		'footer' => '<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
					<button type="button" class="btn btn-primary" id="modal-save">Send</button>',
	),
		'<div id="modal-body">Content set by ajax.</div>'
); ?>

Note that at this stage the modal dialog contains placeholder text for the title, body and two footer buttons. These items are updated using Javascript when the modal dialog is displayed.

Javascript

var modalbox = document.getElementById("modal-box");
var modalSave = document.getElementById("modal-save");
if (modalbox) {
	var modalTitle = modalbox.querySelector('.modal-title');
	var modalBody = modalbox.querySelector('.modal-body');	
}

modalbox && modalbox.addEventListener('show.bs.modal', function (event) {
	// Button that triggered the modal
	let button = event.relatedTarget;
	// Extract info from data-bs-* attributes
	let title = button.getAttribute('data-bs-title');
	let action = button.getAttribute('data-bs-action');
	let item_id  = button.getAttribute('data-bs-id');
	modalTitle.textContent = title;
	// Set the modal content empty.
	modalBody.textContent = 'Fetching content - Please Wait!';
	// get the description and set in modal-body
	if (action == 'showCampDescription') {
		// this is a simple display so the action button should not be seen
		modalSave.classList.add('hidden');
		setModalContent('camp.getDescription', button.getAttribute('data-bs-id'), '')
	}
	...
	// many more action options each with an async funtion to fetch data
	...
})

async function setModalContent(itemTask, itemId, saveTask) {
	const token = Joomla.getOptions('csrf.token', '');
	let url = 'index.php?option=com_mycomponent&task=' + itemTask;
	let data = new URLSearchParams();
	data.append(`itemId`, itemId);
	data.append(token, 1);
	const options = {
		method: 'POST',
		body: data
	}
	let response = await fetch(url, options);
	if (!response.ok) {
		throw new Error (Joomla.Text._('COM_MYCOMPONENT_JS_ERROR_STATUS') + `${response.status}`);
	} else {
		let result = await response.text();
		let description = document.querySelector(".modal-body");
		description.innerHTML = result;
		let modalSave = document.querySelector("#modal-save");
		if (saveTask) {
			modalSave.setAttribute('saveTask', saveTask);
			modalSave.classList.remove('hidden');
		} else {
			modalSave.classList.add('hidden');
		}
	}
}

The Server Side Handler

Notice that the url set in the javascript calls the component, controller and task. In this case com_mycomponent, CampController.php in the src/Controllers folder, and the public function getDescription; A fragment of the code there:

	public function getDescription() {
		Session::checkToken('post') or die;
		$app = Factory::getApplication();
		$camp_id = $app->input->get('itemId', 0, 'int');
		...
		// get the data as a html string
		...
		echo $result;
		exit();
	}

Result

Modal Box Data Example

Parent Links

Back to J4.x:Tips and Tricks for Joomla 4 Developers