J1.5

Using the editor in a component

From Joomla! Documentation

The "J1.5" namespace is an archived namespace. This page contains information for a Joomla! version which is no longer supported. It exists only as a historical reference, it will not be improved and its content may be incomplete and/or contain broken links.

Introduction[edit]

To get some interaction with the visitors of your website your visitors need to be able to add some content.

This article will show you how visitors can add some data using a rich text editor.

Lets start with the component created in the article Developing a Model-View-Controller Component - Part 4 - Creating an Administrator Interface which lets the administrator add new entries to the database. The component can be downloaded at: com_hello4_01. If you haven't done already, install this component on your developing website and create a menu link to this component.

Expand the data model[edit]

The model used in the tutorial can only hold a text of 25 characters. Lets add a new field which can be used to hold a lot more text, so we can save the editor contents.

Use your favorite tool to access the php database and open the jos_hello tabel in your joomla database. Add a new field to this table and add some intial text into it by running this SQL statement:

ALTER TABLE `jos_hello` ADD `content` TEXT NOT NULL ;
UPDATE jos_hello SET content = '<p>The A "hello world" program is a computer program that prints out "Hello, world!"
 on a display device. It is used in many introductory tutorials for teaching a programming language. Such a program is typically one
 of the simplest programs possible in a computer language. Some are surprisingly complex, especially in some graphical user interface (GUI)
 contexts, but most are very simple, especially those which rely heavily on a particular command line interpreter ("shell") to perform the
 actual output. In many embedded systems, the text may be sent to a one or two-line liquid crystal display (LCD), or some other appropriate
 signal, such as a LED being turned on, may substitute for the message.<p>' WHERE `jos_hello`.`id` = 1

We have to change the table definition accordingly. Open the table definition stored in the file administrator/components/com_hello/tables/hello.php and add the new field as a variable below the current ones:

var $greeting = null;
var $content = null;

Show the new field on the front end[edit]

To show the new content we must:

  • Change the model to read the field from the database
  • Change the view to pass the value of the field into the template
  • Change the template to actually show the text

The model was stored in the file: components/com_hello/models/hello.php
We must change the query to get the new field from the database. The loadResult method only retrieves the first field of the record, so we change this in loadObject to get the data into an object. Our new getGreeting() method will therefore look like:

function getGreeting()
{
	$db =& JFactory::getDBO();

	$query = 'SELECT * FROM #__hello';
	$db->setQuery( $query );
	$greeting = $db->loadObject();

	return $greeting;
}

The view was stored in the file: components/com_hello/views/hello/view.html.php
As a reminder: The view pulls the data from the model and fees the data into the template
Because the output of the model is now an object instead of just text, we change the line which assigns the greeting to the template to only assign the greeting text of the object. We add similars line to assign the id and content to the template.

function display($tpl = null)
{
	$greeting = $this->get( 'Greeting' );
	$this->assignRef( 'greeting',	$greeting->greeting );
	$this->assignRef( 'id',		$greeting->id );
	$this->assignRef( 'content',	$greeting->content );
		
	parent::display($tpl);
}

Finally we will change the template in components/com_hello/views/hello/tmpl/default.php to become:

<?php // no direct access
defined('_JEXEC') or die('Restricted access'); ?>
<h1><?php echo $this->greeting; ?></h1>
<?php echo $this->content; ?>

You can now refresh your frontend site and you should see the added content.

Edit form[edit]

To edit the current record we must:

  • Add a link to the edit form
  • Add a new template to edit the data
  • Save the data

Creating a link to the edit form can be done in the template directly. But to keep the template nice and simple we will build the link in the view and pass in onto the template for displaying. Add this line to the view:

$this->assignRef( 'editlink',	JRoute::_('index.php?option=com_hello&view=hello&task=edit') );

And add these lines to the template:

<br /><br />
<a href="<?php echo $this->editlink; ?>">Edit</a>

If your template doesn't already include a reference to the library includes/js/joomla.javascript.js it has to be included at this moment. This can be done by adding the following two lines to view.html.php.

$document =& JFactory::getDocument();
$document->addScript('includes/js/joomla.javascript.js');

The task=edit in the url triggers the edit function in the controller. So let's add this method to our controller:

/**
* Method to call the edit form
*/
function edit()
{
	JRequest::setVar( 'layout', 'form' );
	parent::display();
}

Before adding the model to the view, we change the layout to our edit form.

Of course we have to provide this form. Create the file components/com_hello/views/hello/tmpl/form.php:

<?php defined('_JEXEC') or die('Restricted access'); ?>

<form action="index.php" method="post" name="adminForm" id="adminForm">
<div class="col100">
	<fieldset class="adminform">
		<legend><?php echo JText::_( 'Details' ); ?></legend>

		<table class="admintable">
		<tr>
			<td width="100" align="right" class="key">
				<label for="greeting">
					<?php echo JText::_( 'Greeting' ); ?>:
				</label>
			</td>
			<td>
				<input class="text_area" type="text" name="greeting" id="greeting" size="25" maxlength="25" value="<?php echo $this->greeting;?>" />
			</td>
		</tr>
		<tr>
			<td width="100" align="right" class="key">
				<label for="content">
					<?php echo JText::_( 'Content' ); ?>:
				</label>
			</td>
			<td>
				<?php
					$editor =& JFactory::getEditor();
					echo $editor->display('content', $this->content, '550', '400', '60', '20', false);
				?>
			</td>
		</tr>
	</table>
	</fieldset>
</div>
<div class="clr"></div>

<input type="hidden" name="option" value="com_hello" />
<input type="hidden" name="id" value="<?php echo $this->id; ?>" />
<input type="hidden" name="task" value="save" />
<input type="hidden" name="controller" value="" />
</form>

Most of this is just like the form of the backend. The important addition in this form is how we call the editor:

$editor =& JFactory::getEditor();
echo $editor->display('content', $this->content, '550', '400', '60', '20', false);

The parameters of the display method are:

   * string $name: The control name
   * string $html: The contents of the text area
   * string $width: The width of the text area (px or %)
   * string $height: The height of the text area (px or %)
   * int $col: The number of columns for the textarea
   * int $row: The number of rows for the textarea
   * boolean $buttons: True and the editor buttons will be displayed
   * array $params: Associative array of editor parameters

Refresh your browser and the edit link will show. Use the link to open the edit form including the editor.

Save the data[edit]

Next we need to add the save and cancel buttons and for some extra security we add a token to the form.

<?php echo JHTML::_( 'form.token' ); ?>
<button type="button" onclick="submitbutton('save')"><?php echo JText::_('Save') ?></button>
<button type="button" onclick="submitbutton('cancel')"><?php echo JText::_('Cancel') ?></button>

The buttons call some javascript which is added on the top of the form file after the first line:

<script language="javascript" type="text/javascript">
<!--
function submitbutton(pressbutton) {
	var form = document.adminForm;
	if (pressbutton == 'cancel') {
		submitform( pressbutton );
		return;
	}

	<?php
		$editor =& JFactory::getEditor();
		echo $editor->save( 'content' );
	?>
	submitform(pressbutton);
}
//-->
</script>

On the form we added the hidden field task with a value of save. This will trigger the save method inside the controller. So lets create this method:

function save()
{
	// Check for request forgeries
	JRequest::checkToken() or jexit( 'Invalid Token' );
    	
	// get the model
	$model =& $this->getModel();
        
	//get data from request
	$post = JRequest::get('post');
	$post['content'] = JRequest::getVar('content', '', 'post', 'string', JREQUEST_ALLOWRAW);
        
	// let the model save it
	if ($model->store($post)) {
		$message = JText::_('Success');
	} else {
		$message = JText::_('Error while saving');
		$message .= ' ['.$model->getError().'] ';
	}
	$this->setRedirect('index.php?option=com_hello', $message);
}

The standard way of getting the form data $post = JRequest::get('post'); is not enough in the case of using a editor. This will filter the content, hence losing line breaks and paragraps. So we add an extra line to get the editor contents in a raw unfiltered way. This data will be passed to the model to save into the database.

The store method in the model is now straightforward:

function store($data)
{
	// get the table
	$row =& $this->getTable();
                
	// Bind the form fields to the hello table
	if (!$row->bind($data)) {
		$this->setError($this->_db->getErrorMsg());
		return false;
	}
		
	// Make sure the hello record is valid
	if (!$row->check()) {
		$this->setError($this->_db->getErrorMsg());
		return false;
	}

	// Store the web link table to the database
	if (!$row->store()) {
		$this->setError( $row->getErrorMsg() );
		return false;
	}
		
	return true;         
}

Now try this on your website. You should be able to change the greeting and the contents.

Download[edit]

The component can be downloaded from: [1]