Creating a form at frontend for making entries to database

update breedform.xml  /site/models/forms/breedform.xml

create filemultiple.php  /site/models/fields/filemultiple.php

create view.html.php  /site/views/breedform/view.html.php

create default.php  /site/views/breedform/tmpl/default.php

create default.xml   /site/views/breedform/tmpl/default.xml

update en-GB.com_breed.ini  /languages/site/en-GB/en-GB.com_breed.ini

Files Details

/site/models/forms/breedform.xml

<?xml version="1.0" encoding="utf-8"?>
<form>
	<fieldset>

              <field name="id" type="text" default="0" label="COM_BREED_FORM_LBL_BREED_ID"
            readonly="true" class="readonly"
            description="JGLOBAL_FIELD_ID_DESC" /> 

       <field name="created_by" type="createdby" default="" 
            label="COM_BREED_FORM_LBL_BREED_CREATED_BY"
            description="COM_BREED_FORM_DESC_BREED_CREATED_BY"  /> 

       <field name="breedname" type="text"
            label="COM_BREED_FORM_LBL_BREED_BREEDNAME"
            description="COM_BREED_FORM_DESC_BREED_BREEDNAME"  required="true" >
         <group label="">
         <option value=""></option>
         </group>
       </field> 

       <field name="pic" type="FileMultiple"
            label="COM_BREED_FORM_LBL_BREED_PIC"
            description="COM_BREED_FORM_DESC_BREED_PIC" 
			upload_directory="breedpic"
            max_size="10">
            <group label="">
            <option value=""></option>
     </group>
        </field> 

       <field name="breedcat" type="radio"
            label="COM_BREED_FORM_LBL_BREED_BREEDCAT"
            description="COM_BREED_FORM_DESC_BREED_BREEDCAT" 
            required="true" 
            option_on="Yes"
            option_off="Yes">
                <option value="hybrids">Hybrids</option>
                <option value="purebreeds">Pure Breeds</option>
        </field> 

 
		<field name="filter_breedcat" type="list" onchange="this.form.submit();">
			<option value="">COM_BREED_BREEDS_BREEDCAT_FILTER</option>
			<option value="HYBRIDS">Hybrids</option>
			<option value="PUREBREEDS">Pure Breeds</option>
		</field> 

       <field name="shortdesc" type="textarea"
            label="COM_BREED_FORM_LBL_BREED_SHORTDESC"
            description="COM_BREED_FORM_DESC_BREED_SHORTDESC" 
            required="true" 
            width="400"
            height="100"
            cols="155"
            rows="4"
            option_on="Yes"
            option_off="Yes">
        </field> 

       <field name="desc" type="editor"
            label="COM_BREED_FORM_LBL_BREED_DESC"
            description="COM_BREED_FORM_DESC_BREED_DESC" 
            required="true" 
            menu_published="0"
            width="500"
            height="400"
            filter="safehtml"
            directory_stripext="true"
            directory_hidenode="true"
            directory_hidedefault="true"
            alias_generator="2195442"
            heading="h4"
            close="true"
            option_on="Yes"
            option_off="Yes">
        </field> 

        <field
        name="state"
        type="list"
        label="JSTATUS"
        description="JFIELD_PUBLISHED_DESC"
        class="inputbox"
        size="1"
        default="1">
        <option value="1">JPUBLISHED</option>
        <option value="0">JUNPUBLISHED</option>
        <option value="2">JARCHIVED</option>
        <option value="-2">JTRASHED</option>
        </field> 

        <field name="checked_out" type="hidden" filter="unset" />
        <field name="checked_out_time" type="hidden" filter="unset" /> 

 </fieldset> 


</form>

 To create a form for making entries to the database, first we have to create an XML file, where we will declare the form elements. These elements will then be converted to proper html and will be displayed to the user as a complete form. This form xml file has form tag at root and then there is nested fieldset element. We have a single fieldset element here, but they could be more than one, depending on the requirement. You will notice that each field has a name and type attributes, which uniquely identifies it. The form elements we have created in our form are mostly text elements, hidden elements, lists and radio buttons etc. After the name and type, there are label and description attributes for every element. Other than the hidden fields, the label of the form element will be displayed beside it and the description will come up when you will mouse over the label. Similarly the size, default and class parameters usage is self explanatory. If a field value is compulsory, you can mark it as required and can also set a validation rule.

 

/site/models/fields/filemultiple.php

<?php

defined('JPATH_BASE') or die;

jimport('joomla.form.formfield');


class JFormFieldFileMultiple extends JFormField
{

	protected $type = 'file';

	protected function getInput()
	{
		$html = '<input type="file" name="' . $this->name . '[]" multiple>';

		return $html;
	}
}

Through JFormField base class, you can create any form field type you want, which is not available in the class by default. For this purpose, you have to extend this base class and provide appropriate field type.

Now in pour case, we are trying to create multiple file select field which will give our form, the functionality of uploading multiple images to our component. We have created a file called filemultiple.php in models / fields folder and in this file we have imported the formfield library first. After than we have created a class JFormFieldFileMultiple which is extending the main JFormField class. Then we have initialized the type variable to ‘file’, which would be the type attribute of the field which the class will generate. Next there is the getInput method in which we have declared a multiple form field type and assigned it to $html variable. This is the value which is returned back by the getInput method. The name of the field will be assigned through XML file so it is kept as dynamic here.

 

/site/views/breedform/view.html.php

<?php

// No direct access
defined('_JEXEC') or die;

jimport('joomla.application.component.view');


class BreedViewBreedform extends JViewLegacy
{
	protected $state;

	protected $item;

	protected $form;
	
	protected $params;
	

	public function display($tpl = null)
	{
		$app  = JFactory::getApplication();
		$user = JFactory::getUser();

	    $this->item    = $this->get('Data');
		$this->state   = $this->get('State');
		$this->params  = $app->getParams('com_breed');
		$this->form		= $this->get('Form');

		// Check for errors.
		if (count($errors = $this->get('Errors')))
		{
			throw new Exception(implode("\n", $errors));
		}

		$this->_prepareDocument();

		parent::display($tpl);
	}



	protected function _prepareDocument()
	{
		$app   = JFactory::getApplication();
		$menus = $app->getMenu();
		$title = null;

		$menu = $menus->getActive();

		if ($menu)
		{
			$this->params->def('page_heading', $this->params->get('page_title', $menu->title));
		}
		else
		{
			$this->params->def('page_heading', JText::_('COM_BREED_DEFAULT_PAGE_TITLE'));
		}

		$title = $this->params->get('page_title', '');

		if ($this->params->get('menu-meta_description'))
		{
			$this->document->setDescription($this->params->get('menu-meta_description'));
		}

		if ($this->params->get('menu-meta_keywords'))
		{
			$this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords'));
		}

		if ($this->params->get('robots'))
		{
			$this->document->setMetadata('robots', $this->params->get('robots'));
		}
		
			if (empty($title))
		{
			$title = $app->get('sitename');
		}
		elseif ($app->get('sitename_pagetitles', 0) == 1)
		{
			$title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title);
		}
		elseif ($app->get('sitename_pagetitles', 0) == 2)
		{
			$title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename'));
		}
		$this->document->setTitle($title);
	}
}

This is the actual view file, which will fetch the form from the default.php and display it to the end user. Like the previous view files that we have created before, here in this view.html.php file, we have started by created a view class first. Next we have declared some variables and assigned the values to them which we are particularly getting from model like form data, user state, original form and parameters from the component, if they are any. Then on line 31, we have included exception handling, to catch any error till to this step. Then we have called the _prepareDocument method and then a call to the parent display method.

There are lot of things going in the _prepareDocument() method. It will get and the attributes or parameters from the menu which we have created at backend for this particular view and on the basis of that parameters, it will set the document attributes like page heading, page title, meta description, meta keywords, robots, site name etc. These attributes are not compulsory when we are working on backend but they play an important role in the frontend of site in terms of user experience and search engine optimization.

/site/views/breedform/tmpl/default.php

 <?php

// No direct access
defined('_JEXEC') or die;

JHtml::_('behavior.keepalive');
JHtml::_('behavior.tooltip');
JHtml::_('behavior.formvalidation');
JHtml::_('formbehavior.chosen', 'select');

// Load admin language file
$lang = JFactory::getLanguage();
$lang->load('com_breed', JPATH_SITE);
$doc = JFactory::getDocument();

?>
<script type="text/javascript">
	if (jQuery === 'undefined') {
		document.addEventListener("DOMContentLoaded", function (event) {
			jQuery('#form-breed').submit(function (event) {
				
		if(jQuery('#jform_pic').val() != ''){
			jQuery('#jform_pic_hidden').val(jQuery('#jform_pic').val());
		}
			});

		});
	} else {
		jQuery(document).ready(function () {
			jQuery('#form-breed').submit(function (event) {
				
		if(jQuery('#jform_pic').val() != ''){
			jQuery('#jform_pic_hidden').val(jQuery('#jform_pic').val());
		}
			});
			
		});
	}
</script>

<div class="breed-edit front-end-edit">
	<?php if (!empty($this->item->id)): ?>
		<h1>Edit <?php echo $this->item->id; ?></h1>
	<?php else: ?>
		<h1>Make Entry</h1>
	<?php endif; ?>

	<form id="form-breed"  action="<?php echo JRoute::_('index.php?option=com_breed&task=breed.save'); ?>" method="post" class="form-validate form-horizontal" enctype="multipart/form-data">
		
	<input type="hidden" name="jform[id]" value="<?php echo $this->item->id; ?>" />

	<input type="hidden" name="jform[ordering]" value="<?php echo $this->item->ordering; ?>" />

	<input type="hidden" name="jform[state]" value="<?php echo $this->item->state; ?>" />

	<input type="hidden" name="jform[checked_out]" value="<?php echo $this->item->checked_out; ?>" />

	<input type="hidden" name="jform[checked_out_time]" value="<?php echo $this->item->checked_out_time; ?>" />

	<?php if(empty($this->item->created_by)): ?>
		<input type="hidden" name="jform[created_by]" value="<?php echo JFactory::getUser()->id; ?>" />
	<?php else: ?>
		<input type="hidden" name="jform[created_by]" value="<?php echo $this->item->created_by; ?>" />
	<?php endif; ?>
	<div class="control-group">
		<div class="control-label"><?php echo $this->form->getLabel('breedname'); ?></div>
		<div class="controls"><?php echo $this->form->getInput('breedname'); ?></div>
	</div>
	<div class="control-group">
		<div class="control-label"><?php echo $this->form->getLabel('pic'); ?></div>
		<div class="controls"><?php echo $this->form->getInput('pic'); ?></div>
	</div>
	<?php if (!empty($this->item->pic)) :
		foreach ((array) $this->item->pic as $singleFile) : 
			if (!is_array($singleFile)) :
				echo '<a href="' . JRoute::_(JUri::root() . 'components/com_breed/breedpic' . DIRECTORY_SEPARATOR . $singleFile, false) . '">' . $singleFile . '</a> ';
			endif;
		endforeach;
	endif; ?>

	<input type="hidden" name="jform[pic][]" id="jform_pic_hidden" value="<?php echo str_replace('Array,', '', implode(',', (array) $this->item->pic)); ?>" />
	<div class="control-group">
		<div class="control-label"><?php echo $this->form->getLabel('breedcat'); ?></div>
		<div class="controls"><?php echo $this->form->getInput('breedcat'); ?></div>
	</div>
	<div class="control-group">
		<div class="control-label"><?php echo $this->form->getLabel('shortdesc'); ?></div>
		<div class="controls"><?php echo $this->form->getInput('shortdesc'); ?></div>
	</div>
	<div class="control-group">
		<div class="control-label"><?php echo $this->form->getLabel('desc'); ?></div>
		<div class="controls"><?php echo $this->form->getInput('desc'); ?></div>
	</div>				<div class="fltlft" <?php if (!JFactory::getUser()->authorise('core.admin','breed')): ?> style="display:none;" <?php endif; ?> >
                <?php echo JHtml::_('sliders.start', 'permissions-sliders-'.$this->item->id, array('useCookie'=>1)); ?>
                <?php echo JHtml::_('sliders.panel', JText::_('ACL Configuration'), 'access-rules'); ?>
                <fieldset class="panelform">
                    <?php echo $this->form->getLabel('rules'); ?>
                    <?php echo $this->form->getInput('rules'); ?>
                </fieldset>
                <?php echo JHtml::_('sliders.end'); ?>
            </div>
				<?php if (!JFactory::getUser()->authorise('core.admin','breed')): ?>
                <script type="text/javascript">
                    jQuery.noConflict();
                    jQuery('.tab-pane select').each(function(){
                       var option_selected = jQuery(this).find(':selected');
                       var input = document.createElement("input");
                       input.setAttribute("type", "hidden");
                       input.setAttribute("name", jQuery(this).attr('name'));
                       input.setAttribute("value", option_selected.val());
                       document.getElementById("form-breed").appendChild(input);
                    });
                </script>
             <?php endif; ?>
		<div class="control-group">
			<div class="controls">

					<button type="submit" class="validate btn btn-primary">
						<?php echo JText::_('JSUBMIT'); ?>
					</button>

				<a class="btn" href="/nomi/<?php echo JRoute::_('index.php?option=com_breed&task=breedform.cancel'); ?>"
				   title="<?php echo JText::_('JCANCEL'); ?>">
					<?php echo JText::_('JCANCEL'); ?>
				</a>
			</div>
		</div>

		<input type="hidden" name="option" value="com_breed"/>
		<input type="hidden" name="task"
			   value="breedform.save"/>
		<?php echo JHtml::_('form.token'); ?>
	</form>
</div>

Like we have created at backend, we are developing a form for frontend as well here, so that records could also be entered from component frontend portion. In this default.php file, first we are including some JHtml class utilities for various operations, like, we are including “behavior.keepalive” for keeping the session alive while saving the form, “behavior.tooltip” for creating onhover tooltips. These tooltips require Mootools to work, so if this js framework is not included before in the template, it will be added automatically through this JHtml utility. Next is the “behavior.formvalidation“, which is meant for validating the form at the client side and includes validate.js file in the template for js based validations which are carried out on the basis of parameters set in the from xml file and in last, “formbehavior.chosen” for styling the select fields. Next we are including the language file, which will translate our form fields labels and messages language strings.

After this initial libraries inclusion,we have written some javascript code block which will come into execution when the user will save the form by clicking the submit button at the end or submits the form through the enter key. What this code block doing is, it first checks for proper DOM loading and then tries to pick the submit event of form. It then assigns the value of jform_pic field to a hidden field if that jform_pic field value is not empty. The reason for doing this is, it will help while editing the form, so that if the value of the file upload field is not updated while editing the form, the previous value will be picked from that hidden field, while submitting the form.

Then comes our main form which will be submitting the field values to the breed.php controller where there would be a method called “save”, which will handle the request. After the initial form definition, there are five hidden fields which will hold the values for record id, its ordering number, its state and the checked out value and time. All of these fields will be filled up with values when we are editing the form and at the time of creating a new record, they will be auto assigned through controller. Next there is a “created_by” hidden field which will hold the id of the user which is creating or has created the record. After that there starts our actual form fields which are picked from the xml form, we have created above. When in the dit mode, their values would be auto populated by the controller, which it will fetch from model. At the end of form, we have put the form submit and cancel button along with hidden fields for specifying component name, controller and method to which form will be submitted and a form token.

 

/site/views/breedform/tmpl/default.xml

 <?xml version="1.0" encoding="utf-8"?>
<metadata>
    <layout title="COM_BREED_TITLE_FORM_VIEW_BREED" option="View">
        <message>
                        <![CDATA[COM_BREED_TITLE_FORM_VIEW_BREED_DESC]]>
        </message>
    </layout>
    <fields name="params">
        <fieldset  name="basic"
            label="COM_BREED_FIELDSET_ITEM_ID_SELECT_LABEL">
            <field
                name="item_id"
                query="SELECT 0 as `id` UNION SELECT `id` FROM #__breed_breed ORDER BY `id`"
                type="sql"
                key_field="id" 
                value_field="id"
                label="COM_BREED_ITEM_ID_SELECT_LABEL_FORM"
                require="true"
                description="JGLOBAL_SHOW_TITLE_DESC">
            </field>
        </fieldset>
    </fields>
</metadata>	

 When creating a menu item for the breed edit page, this simple XML code gives an option to the admin if he wants to load an existing filled form on the basis of ID. If he wants this thing, he can select item id from the required settings drop down select box. In the instance he wants to make a new entry, he can select 0. The above mentioned XML code, contained in the default.xml file will provide this feature to the admin of the site.

 

/languages/site/en-GB/en-GB.com_breed.ini

COM_BREED_FORM_LBL_BREED_BREEDNAME="Breed Name"
COM_BREED_FORM_DESC_BREED_BREEDNAME=""
COM_BREED_FORM_LBL_BREED_PIC="Pic"
COM_BREED_FORM_DESC_BREED_PIC=""
COM_BREED_FORM_LBL_BREED_BREEDCAT="Breed Category"
COM_BREED_FORM_DESC_BREED_BREEDCAT=""
COM_BREED_FORM_LBL_BREED_SHORTDESC="Short Description"
COM_BREED_FORM_DESC_BREED_SHORTDESC=""
COM_BREED_FORM_LBL_BREED_DESC="Description"
COM_BREED_FORM_DESC_BREED_DESC=""
COM_BREED_TITLE_LIST_VIEW_BREEDS="Breeds"
COM_BREED_TITLE_LIST_VIEW_BREEDS_DESC="Show a list of Breeds"
COM_BREED_BREEDS_ACTIONS="Actions"
JFIELD_RULES_LABEL="ACL Rules"
COM_BREED_ITEM_SAVED_SUCCESSFULLY="Item saved successfully"

COM_BREED_BREEDS_BREEDCAT_FILTER="- Select Breed Category -"
COM_BREED_BREEDS_BREEDCAT_OPTION_HYBRIDS="Hybrids"
COM_BREED_BREEDS_BREEDCAT_OPTION_PUREBREEDS="Pure Breeds"

 In last, we are updating the language configuration file with the above mentioned language strings and their values, which were being used in this step. 

 

Download Code

 

Add a Comment

Your email address will not be published. Required fields are marked *

Enjoy best web development services at an affordable price. Looking forward to build a good relationship and serve you better...

ABOUT CODINGACE

My name is Nohman Habib and I am a web developer with over 10 years of experience, programming in Joomla, Wordpress, WHMCS, vTiger and Hybrid Apps. My plan to start codingace.com is to share my experience and expertise with others. Here my basic area of focus is to post tutorials primarily on Joomla development, HTML5, CSS3 and PHP.

Nohman Habib

CEO: codingace.com

Request a Quote