3 minutes reading time (554 words)

Using custom field of jform create textcounter

Using-custom-field-of-jform-create-textcounter-1

Joomla already has powerful form management libraries - jform, supported by jfield. There is plenty of built-in field types (text, textarea, integer, file, calendar and several more). However, once in a while you come across a special field that is not present. Or maybe extending the existing field types to add more features.

These are perfect candidates for creating your own JFields. The JField class is very easy to understand, and using the same you can create any kind of simple or complex fields. Bear in mind that while the JField class will render your field, it's up to your model to save the data.

In a recent project, I had to create a text field with a character limit and a  character counter. My earlier thought was to include a piece of javascript, but I soon realized that this was a good opportunity to create a reusable field which supports the above. So today I will be explaining how to create your own JFields through an example of the character counter field.

So let's start to create the field which will add the character counter for the simple text field

Step 1: Create new field type PHP file in your component folder. (components/your_component/models/fields/textcounter.php)

  • Create the class with name JFormFieldTextcounter
  • Extend this class from JFormFieldText (since this is an input box with a counter)
  • Add the below code into your PHP file
    class JFormFieldTextcounter extends JFormFieldText
    {
    	protected $type = 'textcounter';
    	protected $maxLength;
    	protected $inputmode;
    	protected $dirname;
    
    	public function setup(SimpleXMLElement $element, $value, $group = null)
    	{
    		$return = parent::setup($element, $value, $group);
    
    		if ($return)
    		{
    			$this->countertext = isset($this->element['countertext']) ? (string) $this->element['countertext'] : '';
    			$this->countertext = JText::_($this->countertext);
    			$this->maxlength = isset($this->element['maxlength']) ? (int) $this->element['maxlength'] : 0;
    			$this->class .= ' charcounter';
    		}
    
    		return $return;
    	}
    	protected function getInput()
    	{
    		
    		$html = parent::getInput();
    		$html .= $this->getCounterMask();
    
    		// @TODO : Convert this into a snippet that loads only once
    		// using the .charcounter selector
    		$doc = JFactory::getDocument();
    		$doc->addScriptDeclaration('
    			jQuery(document).ready(function() {
    				jQuery("#'.$this->id.'").on("keyup", function() { 
    					jQuery("#usedchars_'.$this->id.'").text(jQuery("#'.$this->id.'").val().length);
    					jQuery("#remainingchars_'.$this->id.'").text(('.$this->maxlength.' - jQuery("#'.$this->id.'").val().length));
    				});
    			});
    		');
    
    		return $html;
    	}
    	private function getCounterMask()
    	{
    
    		$text = '';
    		$text .= $this->countertext;
    
    		$text = str_replace('{used}', '0', $text);
    		$text = str_replace('{remaining}', ''.$this->maxlength.'', $text);
    		$text = str_replace('{maxlength}', ''.$this->maxlength.'', $text);
    
    		$text .= '';
    		return $text;
    	}
    } 
  • Step 2: create XML field with type 'Textcounter' as below

    <field name="testfield"
        type="textcounter"
       countertext="Characters Used {used} / {maxlength} (Remaining {remaining})"
        maxlength="100"
        required="true"
        size="120"
        filter="safehtml"
        label="COM_EXAMPLE_NAME_LABEL"
        description="COM_EXAMPLE_NAME_DESCRIPTION"
        hint=""
        class="" />

    If the maxlength attribute is specified for the inputbox, the field can also display remaining character. This field adds a new countertext attribute where you can specify the text that shows the counter. It's possible to use 3 replacement tokens {maxlength}, {used} and {remaining} which will dynamically be replaced with the right values when the field loads. The text and values load in the span element with a unique id so it's possible to style it independently.

  •  Step 3Just render this field where you want to in your form

    echo $this->form->getLabel('testfield); 

You can do this with Textarea also, just by replacing the code accordingly. You can find this all code here. Big thanks to Ashwin for the git hub repo.

What kind of fields have you created with JField? Did you face any issues? Need any help with your fields, do share feedback below!

Let me know your thoughts in comments!

Suggestions/Corrections are Most welcome!

1
Quick2Cart 2.9.1, JGive 1.9.2 and JTicketing 1.8.5...
Joomla World Conference is going to Vancouver! Are...

Related Posts