diff --git a/README.md b/README.md index 47498f4..b241669 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,41 @@ -#Twitter Bootstrap 3 Form for Zend Framework 1 +#Twitter Bootstrap 3 Form for Zend Framework 1 extended + +This library was originally created by @zfbase and forked by @wendrowycz +This is an extended version, adding an HTML element, inline form option with labels, form-group class option and more. ## Form types The library supports all Bootstrap 3 form types. ### One PHP code +```php +class Application_Form_Example extends Twitter_Bootstrap3_Form_* +{ + public function init() + { + $email = new Twitter_Bootstrap3_Form_Element_Email('email'); + $email->setLabel('Email')->setAttrib('placeholder', 'Email'); + + $password = new Zend_Form_Element_Password('password'); + $password->setLabel('Password')->setAttrib('placeholder', 'Password'); + + $checkbox = new Zend_Form_Element_Checkbox('checkbox'); + $checkbox->setLabel('Remember me'); + + $submit = new Zend_Form_Element_Submit('submit'); + $submit->setLabel('Sign in'); + + $this->addElements(array( + $email, + $password, + $checkbox, + $submit + + )); + } +} +``` +#### OR ```php class Application_Form_Example extends Twitter_Bootstrap3_Form_* @@ -127,6 +158,26 @@ The form must be inherited from class `Twitter_Bootstrap3_Form_Inline`. ``` +To use inlineforms with labels you can use the class `Twitter_Bootstrap3_Form_Inlinelabel`. + +If you are using inline forms, the dimensions will not be set of course. If you need dimensions, you can add them using the attribute formgroupclass like this: + +```php + + $count = new Twitter_Bootstrap3_Form_Element_Number('count'); + $count->setAttrib('formgroupclass','col-xs-6'); + +``` + +This will give you the following output: + +```html +
+ +
+``` + + ## Supported controls The library supports all Zend Framework 1 and Bootstrap 3 form elementes. @@ -425,4 +476,4 @@ $this->addElement('static', 'static', array( ``` ### Other decorated elements -The library also contains elements for decorators: `file`, `hidden`, `hash` and `captcha`. \ No newline at end of file +The library also contains elements for decorators: `file`, `hidden`, `hash` and `captcha`. diff --git a/composer.json b/composer.json index ce301d7..23444d2 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { - "name": "zfbase/zend1-bootstrap3", - "description": "Twitter Bootstrap v.3 Forms for Zend Framework v.1", + "name": "cruiser13/zend1-bootstrap3", + "description": "Twitter Bootstrap v.3 Forms for Zend Framework v.1 extended", "require": { "php": ">=5.3.0", "zendframework/zendframework1": "~1" @@ -15,6 +15,7 @@ "zend", "zend form", "zend form decorators", + "zend form elements", "form", "twitter", "bootstrap", diff --git a/library/Twitter/Bootstrap3/Form.php b/library/Twitter/Bootstrap3/Form.php index 9a8e0b8..63ed00d 100755 --- a/library/Twitter/Bootstrap3/Form.php +++ b/library/Twitter/Bootstrap3/Form.php @@ -23,6 +23,7 @@ abstract class Twitter_Bootstrap3_Form extends Zend_Form const DISPOSITION_HORIZONTAL = 'horizontal'; const DISPOSITION_VERTICAL = 'vertical'; const DISPOSITION_INLINE = 'inline'; + const DISPOSITION_INLINE_LABEL = 'inlinelabel'; /** * Disposition type class @@ -32,6 +33,7 @@ abstract class Twitter_Bootstrap3_Form extends Zend_Form self::DISPOSITION_HORIZONTAL => 'form-horizontal', self::DISPOSITION_VERTICAL => 'form-vertical', self::DISPOSITION_INLINE => 'form-inline', + self::DISPOSITION_INLINE_LABEL => 'form-inline', ); /** @@ -100,6 +102,12 @@ abstract class Twitter_Bootstrap3_Form extends Zend_Form * @var array */ protected $_simpleElementDecorators; + + /** + * Global decorators to apply to all elements type file + * @var array + */ + protected $_fileElementDecorators; /** * Global decorators to apply to all elements type checkbox @@ -188,7 +196,8 @@ public function loadDefaultElementDecorators() $this->_checkboxDecorators = $this->getDefaultCheckboxDecorators(); $this->_buttonsDecorators = $this->getDefaultButtonsDecorators(); $this->_imageDecorators = $this->getDefaultImageDecorators(); - + $this->_fileElementDecorators = $this->getDefaultFileElementDecorators(); + return $this; } @@ -212,6 +221,37 @@ public function getDefaultSimpleElementDecorators() array('Description', array( 'tag' => 'p', 'class' => 'help-block', + 'escape' => false, + )), + array('Label', array( + 'class' => 'control-label', + )), + array('Container'), + array('FieldSize'), + ); + } + + /** + * Retrieve all decorators for file type elements + * + * @return array + */ + public function getDefaultFileElementDecorators() + { + return array( + array('File'), + array('Addon'), + array('Feedback_State', array( + 'renderIcon' => $this->_renderElementsStateIcons, + 'successIcon' => $this->_elementsSuccessIcon, + 'warningIcon' => $this->_elementsWarningIcon, + 'errorIcon' => $this->_elementsErrorIcon, + )), + array('Errors'), + array('Description', array( + 'tag' => 'p', + 'class' => 'help-block', + 'escape' => false, )), array('Label', array( 'class' => 'control-label', @@ -233,6 +273,7 @@ public function getDefaultCaptchaDecorators() array('Description', array( 'tag' => 'p', 'class' => 'help-block', + 'escape' => false, )), array('Label', array( 'class' => 'control-label', @@ -256,6 +297,7 @@ public function getDefaultCheckboxDecorators() array('Description', array( 'tag' => 'p', 'class' => 'help-block', + 'escape' => false, )), array('CheckboxControls'), array('Container'), @@ -275,6 +317,7 @@ public function getDefaultButtonsDecorators() array('Description', array( 'tag' => 'p', 'class' => 'help-block', + 'escape' => false, )), array('ViewHelper'), array('Container'), @@ -294,6 +337,7 @@ public function getDefaultImageDecorators() array('Description', array( 'tag' => 'p', 'class' => 'help-block', + 'escape' => false, )), array('Image'), array('Errors'), @@ -366,6 +410,78 @@ public function createElement($type, $name, $options = null) return parent::createElement($type, $name, $options); } + + /** + * Add a new element + * + * $element may be either a string element type, or an object of type + * Zend_Form_Element. If a string element type is provided, $name must be + * provided, and $options may be optionally provided for configuring the + * element. + * + * If a Zend_Form_Element is provided, $name may be optionally provided, + * and any provided $options will be ignored. + * + * @param string|Zend_Form_Element $element + * @param string $name + * @param array|Zend_Config $options + * @throws Zend_Form_Exception on invalid element + * @return Zend_Form + */ + public function addElement($element, $name = null, $options = null) + { + if ($element instanceof Zend_Form_Element) { + // type string + $exploderesult = explode('_', $element->getType()); + $type = lcfirst(trim(end($exploderesult))); + + if (null !== $options && $options instanceof Zend_Config) { + $options = $options->toArray(); + } + + // Load default decorators + if ((null === $options) || !is_array($options)) { + $options = array(); + //Class is maybe not properly transfered to this element. We'll add class if it exists here. + if($element->class){ + $options['class'] = $element->class; + } + } + + if (!array_key_exists('decorators', $options)) { + $decorators = $this->getDefaultDecoratorsByElementType($type); + if (!empty($decorators)) { + $options['decorators'] = $decorators; + } + } + + // Elements type use 'form-control' class + $element_fc = array( + // all input: + 'text', 'password', 'dateTime', 'dateTimeLocal', 'date', 'month', + 'time', 'week', 'number', 'email', 'url', 'search', 'tel', 'color', + // and other: + 'textarea', 'select', 'multiselect', + ); + if (in_array($type, $element_fc)) { + if (null === $options) { + $options = array('class' => 'form-control'); + } elseif (array_key_exists('class', $options)) { + if (!strstr($options['class'], 'form-control')) { + $options['class'] .= ' form-control'; + $options['class'] = trim($options['class']); + } + } else { + $options['class'] = 'form-control'; + } + } + + $element->setOptions($options); + + } + + parent::addElement($element, $name, $options); + } /** * Retrieve a registered decorator for type element @@ -406,8 +522,15 @@ public function getDefaultDecoratorsByElementType($type) return $this->_simpleElementDecorators; } break; - case 'note': case 'static': case 'select': case 'multiselect': - case 'file': case 'textarea': case 'radio': case 'multiCheckbox': + case 'file': + if (is_array($this->_fileElementDecorators)) { + return $this->_fileElementDecorators; + } + break; + case 'html': + return array('ViewHelper'); + case 'note': case 'static': case 'select': case 'multiselect': + case 'textarea': case 'radio': case 'multiCheckbox': if (is_array($this->_simpleElementDecorators)) { $decorators = $this->_simpleElementDecorators; $removeI = null; diff --git a/library/Twitter/Bootstrap3/Form/Decorator/Container.php b/library/Twitter/Bootstrap3/Form/Decorator/Container.php index 8745bb2..cb96ede 100755 --- a/library/Twitter/Bootstrap3/Form/Decorator/Container.php +++ b/library/Twitter/Bootstrap3/Form/Decorator/Container.php @@ -43,6 +43,11 @@ public function render($content) $class = ' ' . $this->getOption('class'); $class .= ' form-group'; + + //Add possibility to add custom classes to the form-group class by attribute + if($element->getAttrib('formgroupclass')) { + $class .= ' '.$element->getAttrib('formgroupclass'); + } if ($element->hasErrors()) { $class .= ' has-error'; diff --git a/library/Twitter/Bootstrap3/Form/Decorator/File.php b/library/Twitter/Bootstrap3/Form/Decorator/File.php new file mode 100644 index 0000000..389a5e0 --- /dev/null +++ b/library/Twitter/Bootstrap3/Form/Decorator/File.php @@ -0,0 +1,43 @@ + + */ + +/** + * Email form element + * + * @category Forms + * @package Twitter_Bootstrap3_Form + * @subpackage Element + */ +class Twitter_Bootstrap3_Form_Element_Html extends Zend_Form_Element_Xhtml +{ + + public $helper='FormHtml'; + + public function isValid($value){ + + return true; + } +} diff --git a/library/Twitter/Bootstrap3/Form/Horizontal.php b/library/Twitter/Bootstrap3/Form/Horizontal.php index 84c9138..80c9fef 100755 --- a/library/Twitter/Bootstrap3/Form/Horizontal.php +++ b/library/Twitter/Bootstrap3/Form/Horizontal.php @@ -50,6 +50,38 @@ public function getDefaultSimpleElementDecorators() array('FieldSize'), ); } + + /** + * Retrieve all decorators for file type elements + * + * @return array + */ + public function getDefaultFileElementDecorators() + { + return array( + array('File'), + array('Addon'), + array('Feedback_State', array( + 'renderIcon' => $this->_renderElementsStateIcons, + 'successIcon' => $this->_elementsSuccessIcon, + 'warningIcon' => $this->_elementsWarningIcon, + 'errorIcon' => $this->_elementsErrorIcon, + )), + array('Errors'), + array('Description', array( + 'tag' => 'p', + 'class' => 'help-block', + 'escape' => false, + )), + array('Label', array( + 'class' => 'control-label', + )), + array('HorizontalControls'), + array('HorizontalLabel'), + array('Container'), + array('FieldSize'), + ); + } /** * Retrieve all decorators for all captcha elements diff --git a/library/Twitter/Bootstrap3/Form/Inlinelabel.php b/library/Twitter/Bootstrap3/Form/Inlinelabel.php new file mode 100644 index 0000000..29d0a38 --- /dev/null +++ b/library/Twitter/Bootstrap3/Form/Inlinelabel.php @@ -0,0 +1,49 @@ + + */ + +/** + * An "inline" Twitter Bootstrap's UI form + * + * @category Forms + * @package Twitter_Bootstrap3 + * @subpackage Form + */ +class Twitter_Bootstrap3_Form_Inlinelabel extends Twitter_Bootstrap3_Form +{ + /** + * Disposition + * @var integer + */ + protected $_disposition = self::DISPOSITION_INLINE_LABEL; + + /** + * Retrieve all decorators for all simple type elements + * + * @return array + */ + public function getDefaultSimpleElementDecorators() + { + return array( + array('ViewHelper'), + array('Addon'), + array('Feedback_State', array( + 'renderIcon' => $this->_renderElementsStateIcons, + 'successIcon' => $this->_elementsSuccessIcon, + 'warningIcon' => $this->_elementsWarningIcon, + 'errorIcon' => $this->_elementsErrorIcon, + )), + array('Label', array( + //Remove the following line for labels in InlineForms! + //'class' => 'sr-only', + )), + array('Container'), + ); + } +} diff --git a/library/Twitter/Bootstrap3/Form/SubForm.php b/library/Twitter/Bootstrap3/Form/SubForm.php new file mode 100644 index 0000000..9967401 --- /dev/null +++ b/library/Twitter/Bootstrap3/Form/SubForm.php @@ -0,0 +1,46 @@ + + */ + +/** + * This is the base abstract form for the Twitter's Bootstrap UI + * + * @category Forms + * @package Twitter + * @subpackage Bootstrap3 + */ +class Twitter_Bootstrap3_Form_SubForm extends Twitter_Bootstrap3_Form +{ + /** + * Whether or not form elements are members of an array + * @var bool + */ + protected $_isArray = true; + + /** + * Load the default decorators + * + * @return Zend_Form_SubForm + */ + public function loadDefaultDecorators() + { + if ($this->loadDefaultDecoratorsIsDisabled()) { + return $this; + } + + $decorators = $this->getDecorators(); + if (empty($decorators)) { + $this->addDecorator('FormElements') + ->addDecorator('HtmlTag', array('tag' => 'dl')) + ->addDecorator('Fieldset') + ->addDecorator('DtDdWrapper'); + } + return $this; + } +} diff --git a/library/Twitter/Bootstrap3/View/Helper/FormHtml.php b/library/Twitter/Bootstrap3/View/Helper/FormHtml.php new file mode 100644 index 0000000..c3a54ed --- /dev/null +++ b/library/Twitter/Bootstrap3/View/Helper/FormHtml.php @@ -0,0 +1,28 @@ + + */ + +/** + * Helper to generate a "html" element + * + * @category Forms + * @package Twitter_Bootstrap3_View + * @subpackage Helper + */ +class Twitter_Bootstrap3_View_Helper_FormHtml extends Zend_View_Helper_FormElement { + + public function FormHtml($name, $value = null, $attribs = null) { + $info = $this->_getInfo($name, $value, $attribs); + extract($info); // name, value, attribs, options, listsep, disable + if (null === $value) {$value = $name;} + + return $value; + } + + } \ No newline at end of file diff --git a/library/Twitter/Bootstrap3/View/Helper/FormReset.php b/library/Twitter/Bootstrap3/View/Helper/FormReset.php index 36336ff..a9ad99c 100755 --- a/library/Twitter/Bootstrap3/View/Helper/FormReset.php +++ b/library/Twitter/Bootstrap3/View/Helper/FormReset.php @@ -32,7 +32,7 @@ class Twitter_Bootstrap3_View_Helper_FormReset extends Zend_View_Helper_FormRese * * @return string The element XHTML. */ - public function formReset($name, $value = null, $attribs = null) + public function formReset($name = '', $value = 'Reset', $attribs = NULL) { if (isset($attribs['class'])) { $attribs['class'] = 'btn ' . $attribs['class'];