From cbb35904e996a2f5156f1a865bb1d55450391ce5 Mon Sep 17 00:00:00 2001 From: alan bount Date: Thu, 24 May 2012 11:47:00 -0400 Subject: [PATCH 1/9] Multiple Checkbox Support - wrapped in labels instead of divs this is a dirty hack, cakephp will wrap each checkbox in a div, and set the lables after the input bootstrap wants the checkbox wrapped in a label, and the text afterward --- View/Helper/TwitterBootstrapHelper.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/View/Helper/TwitterBootstrapHelper.php b/View/Helper/TwitterBootstrapHelper.php index b3868b1..8612cfc 100644 --- a/View/Helper/TwitterBootstrapHelper.php +++ b/View/Helper/TwitterBootstrapHelper.php @@ -285,6 +285,12 @@ public function _combine_input($options) { } } $input = $this->Form->input($options["field"], $opt); + if (isset($options["multiple"]) && $options["multiple"]=='checkbox') { + // this is a dirty hack, cakephp will wrap each checkbox in a div, and set the lables after the input + // bootstrap wants the checkbox wrapped in a label, and the text afterward + $input = str_replace(array('Form->label($options["field"], $input.' '.$options["checkbox_label"], array('class' => 'checkbox')); } From b462931bddb19f6b5dc6f43bb83095af1c756884 Mon Sep 17 00:00:00 2001 From: alan bount Date: Thu, 24 May 2012 11:52:50 -0400 Subject: [PATCH 2/9] Added an example View which will help people see how to set options including basic text, textareas, selects including radio, inline checkboxes, multiple checkboxes (vertical) including append/prepend (text and buttons) @todo: include mockups for success / error messages (validation) --- View/Example.ctp | 330 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100755 View/Example.ctp diff --git a/View/Example.ctp b/View/Example.ctp new file mode 100755 index 0000000..327b66e --- /dev/null +++ b/View/Example.ctp @@ -0,0 +1,330 @@ +

Comparison and Reference

+
+

Horizontal Form Html

+
+
+
+ +
+ +

In addition to freeform text, any HTML5 text-based input appears like so.

+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + + +

Note: Labels surround all the options for much larger click areas and a more usable form.

+
+
+
+ +
+ + +
+
+
+ +
+ + + +
+
+
+ +
+
+ @ +
+

Here's some help text

+
+
+
+ +
+
+ .00 +
+ Here's more help text +
+
+
+ +
+
+ $.00 +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ + +
+
+
+
+
+

Horizontal Form Helper

+ Form->create('Member', array('class' => 'form-horizontal')); ?> +
+ TwitterBootstrap->input('text_input', array( + 'label' => 'Text input', + 'help_block' => 'In addition to freeform text, any HTML5 text-based input appears like so.', + )); ?> + TwitterBootstrap->input('checkbox', array( + 'label' => 'Checkbox', + 'type' => 'checkbox', + 'checkbox_label' => 'Option one is this and that—be sure to include why it\'s great' + )); ?> + TwitterBootstrap->input('select_list', array( + 'options' => array('Something', '2', '3', '4'), + )); ?> + TwitterBootstrap->input('multicon_select', array( + 'label' => 'Multicon-select', + 'options' => array('1', '2', '3', '4'), + 'multiple' => 'multiple', + )); ?> + TwitterBootstrap->input('file_input', array( + 'type' => 'file', + )); ?> + TwitterBootstrap->input('textarea', array( + 'type' => 'textarea', + 'rows' => 3, + 'class' => 'input-xlarge', + )); ?> + TwitterBootstrap->input('xcheckboxes', array( + 'label' => 'Checkboxes', + 'legend' => false, + 'type' => "select", + 'multiple' => "checkbox", + 'options' => array( + "Option one is this and that—be sure to include why it's great", + "Option two can also be checked and included in form results", + "Option three can—yes, you guessed it—also be checked and included in form results", + ), + 'help_block' => "Note: Labels surround all the options for much larger click areas and a more usable form." + )); ?> + TwitterBootstrap->radio('radio_buttons', array( + 'label' => 'Radio buttons', + 'legend' => false, + 'type' => "radio", + 'options' => array( + "Option one is this and that—be sure to include why it's great", + "Option two can is something else and selecting it will deselect option one", + ) + )); ?> + TwitterBootstrap->input('inline_checkboxes', array( + 'label' => 'Inline checkboxes', + 'legend' => false, + 'multiple' => "checkbox", + 'class' => "checkbox inline", + 'separator' => " ", + 'options' => array(1, 2, 3), + )); ?> + TwitterBootstrap->input('prepend_text', array( + 'label' => 'Prepend text', + 'class' => 'span2', + 'prepend' => '@', + 'help_block' => "Here's some help text", + )); ?> + TwitterBootstrap->input('append_text', array( + 'label' => 'Append text', + 'class' => 'span2', + 'append' => '.00', + 'help_inline' => "Here's more help text", + )); ?> + TwitterBootstrap->input('a_p_text', array( + 'label' => 'Append and prepend', + 'class' => 'span2', + 'prepend' => '@', + 'append' => '.00', + )); ?> + TwitterBootstrap->input('a_button_text', array( + 'label' => 'Append with button', + 'class' => 'span2', + 'append' => '', + )); ?> + TwitterBootstrap->input('a_twobutton_text', array( + 'label' => 'Two-button append', + 'class' => 'span2', + 'append' => '', + )); ?> +
+ + +
+
+ +
+
+ 'Male', 'female' => 'Female', 'both' => 'Both', 'other' => 'Other'); +$optionsColors = array('red' => 'Red', 'orange' => 'Orange', 'yellow' => 'Yellow', 'green' => 'Green', 'blue' => 'Blue', 'indigo' => 'Indigo', 'violet' => 'Violet', 'black' => 'Black'); +$optionsPets = array('dogs' => 'Dogs', 'cats' => 'Cats', 'fish' => 'Fish', 'birds' => 'Birds'); +$optionsGroups = array(1 => 'Admin', 2 => 'Really Cool Guys', 3 => 'Underwear Models'); +?> +
+

Second Test - automagics

+ Form->create('Member', array('class' => 'form-horizontal')); ?> +
+ TwitterBootstrap->input('id'); ?> + TwitterBootstrap->input('email'); ?> + TwitterBootstrap->input('first_name'); ?> + TwitterBootstrap->input('last_name'); ?> + TwitterBootstrap->input('is_active'); ?> + TwitterBootstrap->radio('gender', array('label' => 'Gender', 'options' => $optionsGender)); ?> + TwitterBootstrap->input('favorite_color', array('label' => 'Favorite Color', 'options' => $optionsColors)); ?> + TwitterBootstrap->input('hated_color', array('label' => 'Hated Colors', 'multiple' => 'checkbox', 'options' => $optionsColors)); ?> + TwitterBootstrap->input('pets', array( + 'multiple' => "checkbox", + 'class' => "checkbox inline", + 'options' => $optionsPets, + )); ?> + TwitterBootstrap->input('salary', array( + 'class' => 'span2', + 'prepend' => '$', + 'append' => 'per year', + )); ?> + TwitterBootstrap->input('Group.Group', array( + 'multiple' => "checkbox", + 'options' => $optionsGroups, + )); ?> +
+ +
+
+

Third Test - automagics + defaults

+ data, which gets merged into $this->Form->data + $this->Form->data = array( + 'Member' => array( + 'id' => 12345, + 'email' => 'member@domain.com', + 'first_name' => 'Jane', + 'last_name' => 'Doe', + 'is_active' => 1, + 'gender' => 'female', + 'favorite_color' => 'blue', + 'hated_colors' => array('green', 'orange', 'violet'), + 'pets' => array('dogs', 'fish'), + 'salary' => '1,000,000', + ), + 'Group' => array( + array('id' => 1, 'title' => 'admin'), + array('id' => 3, 'title' => 'model'), + ), + ); + ?> + Form->create('Member', array('class' => 'form-horizontal')); ?> +
+ TwitterBootstrap->input('id'); ?> + TwitterBootstrap->input('email'); ?> + TwitterBootstrap->input('first_name'); ?> + TwitterBootstrap->input('last_name'); ?> + TwitterBootstrap->input('is_active'); ?> + TwitterBootstrap->radio('gender', array('label' => 'Gender', 'options' => $optionsGender)); ?> + TwitterBootstrap->input('favorite_color', array('label' => 'Favorite Color', 'options' => $optionsColors)); ?> + TwitterBootstrap->input('hated_colors', array('label' => 'Hated Colors', 'multiple' => 'checkbox', 'options' => $optionsColors)); ?> + TwitterBootstrap->input('pets', array( + 'multiple' => "checkbox", + 'class' => "checkbox inline", + 'options' => $optionsPets, + )); ?> + TwitterBootstrap->input('salary', array( + 'class' => 'span2', + 'prepend' => '$', + 'append' => 'per year', + )); ?> + TwitterBootstrap->input('Group.Group', array( + 'multiple' => "checkbox", + 'options' => $optionsGroups, + )); ?> +
+ +
\ No newline at end of file From 6c6c4b6b39ac68d4ff9587c56940875781be42e9 Mon Sep 17 00:00:00 2001 From: alan bount Date: Sat, 1 Dec 2012 22:36:09 -0500 Subject: [PATCH 3/9] added create() method so $defaultModel can be set If you use Form->create('Model') and then add TwitterBootstrap->input('fieldname') the verification steps to check for errors don't work... namely $this->error() This is because the defaultModel property is set on the Form helper, not the TwitterBootstrap instance of the Form helper There is no clean and easy way to get it out of the other helper instance.. so intstead we allow them to create the form through this helper instance (which extends the FormHelper anyway and as such, means it's really, really simple/easy) (note: this will tie in with a forthcoming commit to add some skel files for view bakind with TwitterBootstap form inputs) --- View/Helper/TwitterBootstrapHelper.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/View/Helper/TwitterBootstrapHelper.php b/View/Helper/TwitterBootstrapHelper.php index 9a35b31..6f48431 100644 --- a/View/Helper/TwitterBootstrapHelper.php +++ b/View/Helper/TwitterBootstrapHelper.php @@ -40,6 +40,13 @@ public function search($name = null, $options = array()) { return $this->BootstrapForm->search($name, $options); } + public function create($model = null, $options = array()) { + if (empty($options['class'])) { + $options['class'] = 'form-horizontal'; + } + return $this->BootstrapForm->create($model, $options); + } + public function input($field, $options = array()) { return $this->BootstrapForm->input($field, $options); } From a58211197fdb1fd629700cb19aebf149bad607c1 Mon Sep 17 00:00:00 2001 From: alan bount Date: Sat, 1 Dec 2012 23:02:38 -0500 Subject: [PATCH 4/9] Added another alias for addCrumb() for conventions The method add_crumb() does not follow cakphp convention and as such is confusing for people who want to be able to add crumbs and realize they can not with the HtmlHelper, but instead need to do so with with TwitterBootstrapHelper... No change was made to the add_crumb() method, so it remains backwards compatible --- View/Helper/TwitterBootstrapHelper.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/View/Helper/TwitterBootstrapHelper.php b/View/Helper/TwitterBootstrapHelper.php index 6f48431..16ee3c9 100644 --- a/View/Helper/TwitterBootstrapHelper.php +++ b/View/Helper/TwitterBootstrapHelper.php @@ -91,6 +91,10 @@ public function add_crumb($title, $url, $options = array()) { return $this->BootstrapHtml->addCrumb($title, $url, $options); } + public function addCrumb($title, $url, $options = array()) { + return $this->BootstrapHtml->addCrumb($title, $url, $options); + } + public function label($message = "", $style = "", $options = array()) { return $this->Bootstrap->label($message, $style, $options); } From 886277cb80043ba3e70e4b4270bf717d48523272 Mon Sep 17 00:00:00 2001 From: alan bount Date: Sat, 1 Dec 2012 23:14:57 -0500 Subject: [PATCH 5/9] Added basic Skel/Templates for baking new views I took a few liberties and created a couple of elements to facilitate breadcrumbs and pagination... as this is how I usually have implemented it in the past and it's simpler than across several views... but if you frown on this solution (which I can understand) please feel free to recreate/rewite as you see fit We might want to implement a better HABTM checkbox input setup... Also, I am wondering if we want to add any extra blank options to form inputs, to facilitate their use? --- .../Templates/twitterbootstrap/views/form.ctp | 79 ++++++++++ .../twitterbootstrap/views/index.ctp | 92 +++++++++++ .../Templates/twitterbootstrap/views/view.ctp | 146 ++++++++++++++++++ View/Elements/breadcrumb.ctp | 62 ++++++++ View/Elements/pagination.ctp | 82 ++++++++++ 5 files changed, 461 insertions(+) create mode 100644 Console/Templates/twitterbootstrap/views/form.ctp create mode 100644 Console/Templates/twitterbootstrap/views/index.ctp create mode 100644 Console/Templates/twitterbootstrap/views/view.ctp create mode 100755 View/Elements/breadcrumb.ctp create mode 100755 View/Elements/pagination.ctp diff --git a/Console/Templates/twitterbootstrap/views/form.ctp b/Console/Templates/twitterbootstrap/views/form.ctp new file mode 100644 index 0000000..330e1ba --- /dev/null +++ b/Console/Templates/twitterbootstrap/views/form.ctp @@ -0,0 +1,79 @@ + +element('TwitterBootstrap.breadcrumb'); ?>\n"; ?> +
+TwitterBootstrap->create('{$modelClass}', array('class' => 'validate form-horizontal'));\n" . + "\t// this is done to setup the FormHelper insteance to the correct model\n" . + "\t\$this->Form->create('{$modelClass}');\n" . + "\t?>\n"; ?> +
+ ", Inflector::humanize($action), $singularHumanName); ?> +TwitterBootstrap->input('{$field}', array(" . + "\n\t'label' => '" . Inflector::humanize($field) . "'," . + "\n\t'input' => \$this->Form->text('{$field}')," . + "\n\t'help_inline' => ''," . + "\n\t'help_block' => ''," . + "\n\t));\n"; + } + } + if (!empty($associations['hasAndBelongsToMany'])) { + foreach ($associations['hasAndBelongsToMany'] as $assocName => $assocData) { + echo "\t\techo \$this->Form->input('{$assocName}');\n"; + } + } + echo "\t?>\n"; +?> +
+
+ +
+ + Action + + + +
+
+
+ diff --git a/Console/Templates/twitterbootstrap/views/index.ctp b/Console/Templates/twitterbootstrap/views/index.ctp new file mode 100644 index 0000000..7475cce --- /dev/null +++ b/Console/Templates/twitterbootstrap/views/index.ctp @@ -0,0 +1,92 @@ + +element('TwitterBootstrap.breadcrumb'); ?>\n"; ?> +
+

"; ?>

+ + + + + + + + \n"; + echo "\t\n"; + foreach ($fields as $field) { + $isKey = false; + if (!empty($associations['belongsTo'])) { + foreach ($associations['belongsTo'] as $alias => $details) { + if ($field === $details['foreignKey']) { + $isKey = true; + echo "\t\t\n"; + break; + } + } + } + if ($isKey !== true) { + // TODO: standardize different display types, eg: date + echo "\t\t\n"; + } + } + // actions as a drop down menu + echo "\t\t\n"; + echo "\t\n"; + echo "\n"; + ?> +
Paginator->sort('{$field}'); ?>"; ?>"; ?>
" . + "\n\t\t\t" . + "\n\t\t\t\tHtml->link(\${$singularVar}['{$alias}']['{$details['displayField']}'], array('controller' => '{$details['controller']}', 'action' => 'view', \${$singularVar}['{$alias}']['{$details['primaryKey']}'])); ?>" . + "\n\t\t\t" . + "\n\t\t \n"; + echo "\t\t\t
\n"; + echo "\t\t\t\tAction \n"; + echo "\t\t\t\t
    \n"; + echo "\t\t\t\t\t
  • Html->link(__('View'), array('action' => 'view', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>
  • \n"; + echo "\t\t\t\t\t
  • Html->link(__('Edit'), array('action' => 'edit', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>
  • \n"; + echo "\t\t\t\t\t
  • Form->postLink(__('Delete'), array('action' => 'delete', \${$singularVar}['{$modelClass}']['{$primaryKey}']), null, __('Are you sure you want to delete # %s?', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>
  • \n"; + echo "\t\t\t\t
\n"; + echo "\t\t\t
\n"; + echo "\t\t
+ element('TwitterBootstrap.pagination'); ?>\n"; ?> +
+
+
+ + Action + + + +
+
diff --git a/Console/Templates/twitterbootstrap/views/view.ctp b/Console/Templates/twitterbootstrap/views/view.ctp new file mode 100644 index 0000000..6d25e91 --- /dev/null +++ b/Console/Templates/twitterbootstrap/views/view.ctp @@ -0,0 +1,146 @@ + +element('TwitterBootstrap.breadcrumb'); ?>\n"; ?> +
+

"; ?>

+
+ $details) { + if ($field === $details['foreignKey']) { + $isKey = true; + echo "\t\t
\n"; + echo "\t\t
\n\t\t\tHtml->link(\${$singularVar}['{$alias}']['{$details['displayField']}'], array('controller' => '{$details['controller']}', 'action' => 'view', \${$singularVar}['{$alias}']['{$details['primaryKey']}'])); ?>\n\t\t\t \n\t\t
\n"; + break; + } + } + } + if ($isKey !== true) { + echo "\t\t
\n"; + echo "\t\t
\n\t\t\t\n\t\t\t \n\t\t
\n"; + } +} +?> +
+
+
+

"; ?>

+
    +Html->link(__('Edit " . $singularHumanName ."'), array('action' => 'edit', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?> \n"; + echo "\t\t
  • Form->postLink(__('Delete " . $singularHumanName . "'), array('action' => 'delete', \${$singularVar}['{$modelClass}']['{$primaryKey}']), null, __('Are you sure you want to delete # %s?', \${$singularVar}['{$modelClass}']['{$primaryKey}'])); ?>
  • \n"; + echo "\t\t
  • Html->link(__('List " . $pluralHumanName . "'), array('action' => 'index')); ?>
  • \n"; + echo "\t\t
  • Html->link(__('New " . $singularHumanName . "'), array('action' => 'add')); ?>
  • \n"; + + $done = array(); + foreach ($associations as $type => $data) { + foreach ($data as $alias => $details) { + if ($details['controller'] != $this->name && !in_array($details['controller'], $done)) { + echo "\t\t
  • Html->link(__('List " . Inflector::humanize($details['controller']) . "'), array('controller' => '{$details['controller']}', 'action' => 'index')); ?>
  • \n"; + echo "\t\t
  • Html->link(__('New " . Inflector::humanize(Inflector::underscore($alias)) . "'), array('controller' => '{$details['controller']}', 'action' => 'add')); ?>
  • \n"; + $done[] = $details['controller']; + } + } + } +?> +
+
+ $details): ?> + + $details): + $otherSingularVar = Inflector::variable($alias); + $otherPluralHumanName = Inflector::humanize($details['controller']); + ?> + + diff --git a/View/Elements/breadcrumb.ctp b/View/Elements/breadcrumb.ctp new file mode 100755 index 0000000..bfe7c0f --- /dev/null +++ b/View/Elements/breadcrumb.ctp @@ -0,0 +1,62 @@ +TwitterBootstrap->addCrumb() + * + * @param array $crumbs (optional) overwrites the basic crumbs + * @param array $extra_crumbs (optional) additional to the basic crumbs + * @param array $parent (optional) additional to the basic crumbs, right before the current controller + * @param array $beforeAction (optional) additional to the basic crumbs, right before the current action + * + * Examples: + * $this->element('TwitterBootstrap.breadcrumb') + * $this->element('TwitterBootstrap.breadcrumb', array('parent' => array('Edit' => array('action' => 'edit', $event['Event']['id'])))) + * $this->element('TwitterBootstrap.breadcrumb', array('crumbs' => array( + * 'Root' => array('action' => 'root'), + * 'Parent Page ABC' => array('action' => 'some_action', 'some_param'), + * 'Current Page' => '#', + * ))); + */ +if (!isset($crumbs)) { + // auto-determine basic crumbs + $crumbs = array(); + if (array_key_exists('admin', $this->params) && $this->params['admin']) { + $crumbs['Admin'] = '/admin/'; + } + $action = str_replace($this->params['prefix'] . '_', '', $this->params['action']); + if (!empty($parent) && is_array($parent)) { + $crumbs = array_merge($crumbs, $parent); + } + if ($action=='index') { + $crumbs[Inflector::Humanize($this->params['controller'])] = '#'; + if (!empty($beforeAction) && is_array($beforeAction)) { + $crumbs = array_merge($crumbs, $beforeAction); + } + } else { + $crumbs[Inflector::Humanize($this->params['controller'])] = array('controller' => $this->params['controller'], 'action' => 'index'); + if (!empty($beforeAction) && is_array($beforeAction)) { + $crumbs = array_merge($crumbs, $beforeAction); + } + $crumbs[Inflector::Humanize($action)] = '#'; + } + if (isset($current) && is_string($current) && !empty($current)) { + array_pop($crumbs); + $crumbs[$current] = '#'; + } +} +if (isset($extra_crumbs) && is_array($extra_crumbs)) { + $crumbs = array_merge($crumbs, $extra_crumbs); +} +if (!empty($crumbs)) { + foreach ($crumbs as $text => $url) { + if ($text == "Admin") { + echo $this->TwitterBootstrap->addCrumb("".strtoupper($text)."", $url, array('escape' => false)); + } else { + echo $this->TwitterBootstrap->addCrumb($text, $url); + } + } + echo $this->TwitterBootstrap->breadcrumbs(); +} diff --git a/View/Elements/pagination.ctp b/View/Elements/pagination.ctp new file mode 100755 index 0000000..13bc045 --- /dev/null +++ b/View/Elements/pagination.ctp @@ -0,0 +1,82 @@ +Paginator->hasPrev() || $this->Paginator->hasNext()); +if (!empty($this->params['prefix']) && $this->params['prefix']=='admin') { + $showPagination = $showTotal = true; +} +$params = $this->Paginator->params(); +?> + +
    + Paginator->hasPrev()): ?> + 10 && $params['page'] > 5): ?> +
  • Paginator->link('← First', array('page' => 1), array('rel' => 'noindex')); ?>
  • + + Paginator->prev('← Previous', + array('tag' => 'li', 'rel' => 'noindex'), null, + array('tag' => 'a')); ?> + + + Paginator->numbers(array('separator' => false, 'currentClass' => 'active', 'tag' => 'li', 'modulus' => $numbersToDisplay, 'currentTag' => 'a', 'rel' => 'noindex'), + array('tag' => 'li'), null, + array('tag' => 'a')); ?> + + Paginator->hasNext()): ?> + Paginator->next('Next →', + array('tag' => 'li', 'rel' => 'noindex'), null, + array('tag' => 'a', null)); ?> + 10): ?> +
  • Paginator->link('Last →', array('page' => $params['pageCount']), array('rel' => 'noindex')); ?>
  • + + + +
  • + + +
  • + + page: Paginator->counter(); ?> + + $params['count']) { + $params['count'] = $params['current']; + } + ?> +   + +
  • + + +
  • Paginator->link(25, array('page' => 1, 'limit' => 25), array('title' => "number of results per page")); ?>
  • +
  • Paginator->link(100, array('page' => 1, 'limit' => 100), array('title' => "number of results per page")); ?>
  • + 200): ?> +
  • Paginator->link(200, array('page' => 1, 'limit' => 200), array('title' => "number of results per page")); ?>
  • + + 400): ?> +
  • Paginator->link(400, array('page' => 1, 'limit' => 400), array('title' => "number of results per page")); ?>
  • + + +
+ From 8df49852d92ec15e3c6c69543b19421a52b92261 Mon Sep 17 00:00:00 2001 From: alan bount Date: Fri, 1 Mar 2013 10:28:37 -0500 Subject: [PATCH 6/9] updates to the twitterbootstrap template --- .../twitterbootstrap/common_params.php | 57 +++++++++++++++ .../Templates/twitterbootstrap/views/form.ctp | 72 +++++++++++-------- 2 files changed, 101 insertions(+), 28 deletions(-) create mode 100644 Console/Templates/twitterbootstrap/common_params.php diff --git a/Console/Templates/twitterbootstrap/common_params.php b/Console/Templates/twitterbootstrap/common_params.php new file mode 100644 index 0000000..d4eca96 --- /dev/null +++ b/Console/Templates/twitterbootstrap/common_params.php @@ -0,0 +1,57 @@ +params['noAppTestCase'])) { + $useAppTestCase = false; +} + +if (!empty($this->params['property'])) { + $property = true; +} + +if (!empty($this->params['parent'])) { + $parentIncluded = true; + $parentClass = Inflector::classify($this->params['parent']); + $parentIdDbVar = Inflector::underscore($parentClass . 'Id'); + $parentIdVar = Inflector::variable($parentClass . 'Id'); + $singularParentName = Inflector::variable($parentClass); + $singularHumanParentName = Inflector::humanize(Inflector::underscore(Inflector::singularize($parentClass))); + $additionalParams = ', $' . $parentIdVar; + if (!empty($this->params['parentSlug'])) { + $parentSlugged = true; + $parentSlugVar = Inflector::variable($parentClass . 'Slug'); + $additionalParams = ', $' . $parentSlugVar; + } +} + +if (!empty($this->params['slug'])) { + $slugged = true; +} + +if (!empty($this->params['user'])) { + $userIncluded = true; + if (is_string($this->params['user'])) { + $userModel = $this->params['user']; + } else { + $userModel = 'User'; + } +} else { + $userIncluded = false; +} + + +?> \ No newline at end of file diff --git a/Console/Templates/twitterbootstrap/views/form.ctp b/Console/Templates/twitterbootstrap/views/form.ctp index 330e1ba..f554a82 100644 --- a/Console/Templates/twitterbootstrap/views/form.ctp +++ b/Console/Templates/twitterbootstrap/views/form.ctp @@ -15,63 +15,79 @@ * @since CakePHP(tm) v 1.2.0.5234 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ +$pageTitle = sprintf('%s %s', Inflector::humanize($action), $singularHumanName); ?> +Meta->add('title', __('{$pageTitle}')); + "?>\n"; ?> element('TwitterBootstrap.breadcrumb'); ?>\n"; ?> -
TwitterBootstrap->create('{$modelClass}', array('class' => 'validate form-horizontal'));\n" . + "echo \$this->TwitterBootstrap->create('{$modelClass}', array(\n" . + "\t'class' => 'validate form-horizontal {$pluralVar}',\n" . + "\t'url' => array('action' => \$this->params['action']{$additionalParams}),\n" . + "\t));\n" . "\t// this is done to setup the FormHelper insteance to the correct model\n" . "\t\$this->Form->create('{$modelClass}');\n" . + (strpos($action, 'add') !== false ? '' : + "\t\$this->Form->hidden('id');\n" + ) . "\t?>\n"; ?>
- ", Inflector::humanize($action), $singularHumanName); ?> +

"; ?>

TwitterBootstrap->input('{$field}', array(" . - "\n\t'label' => '" . Inflector::humanize($field) . "'," . - "\n\t'input' => \$this->Form->text('{$field}')," . - "\n\t'help_inline' => ''," . - "\n\t'help_block' => ''," . - "\n\t));\n"; + } elseif (!in_array($field, array('id', 'created', 'modified', 'updated'))) { + echo "\t\techo \$this->TwitterBootstrap->input('{$field}', array(\n" . + "\t\t'label' => '" . Inflector::humanize($field) . "',\n" . + "\t\t'help_inline' => ''\n," . + "\t\t));\n"; } } if (!empty($associations['hasAndBelongsToMany'])) { foreach ($associations['hasAndBelongsToMany'] as $assocName => $assocData) { - echo "\t\techo \$this->Form->input('{$assocName}');\n"; + echo "\t\t?>\n" . + "\t\t
\n" . + "\t\t\t\n" . + "\t\t\t
\n" . + "\t\t\t\tForm->input('{$assocName}'); ?>\n"; + "\t\t\t
\n" . + "\t\t
\n" . + "\t\t\n"; + echo "\t\t?>\n"; ?>
+ Html->link('Cancel', \$this->here); ?>"; ?>
Action
From b089df53c93da31d86de745be57a6be29a141b96 Mon Sep 17 00:00:00 2001 From: alan bount Date: Fri, 17 May 2013 12:20:28 -0400 Subject: [PATCH 7/9] Strict validation fixes for parent methods options --- View/Helper/BootstrapFormHelper.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/View/Helper/BootstrapFormHelper.php b/View/Helper/BootstrapFormHelper.php index bddecc5..950e541 100644 --- a/View/Helper/BootstrapFormHelper.php +++ b/View/Helper/BootstrapFormHelper.php @@ -347,7 +347,7 @@ public function _helpMarkup($options) { * @access public * @return string */ - public function radio($field, $options = array()) { + public function radio($field, $options = array(), $attributes = array()) { if (is_array($field)) { $options = $field; } else { @@ -360,12 +360,12 @@ public function radio($field, $options = array()) { unset($options["options"]); $inputs = ""; $hiddenField = (isset($options['hiddenField']) && $options['hiddenField']); + $attributes = Set::merge( + array("label" => false, 'hiddenField' => $hiddenField), + $attributes + ); foreach ($opt as $key => $val) { - $input = parent::radio( - $options["field"], - array($key => $val), - array("label" => false, 'hiddenField' => $hiddenField) - ); + $input = parent::radio($options["field"], array($key => $val), $attributes); $id = array(); preg_match_all("/id=\"[a-zA-Z0-9_-]*\"/", $input, $id); if (!empty($id[0])) { From 2ce32090a20b68a45d54ae58b6ff7e082f162516 Mon Sep 17 00:00:00 2001 From: Chris Johnson Date: Tue, 21 May 2013 18:34:42 +0000 Subject: [PATCH 8/9] Add check to compare the option value with the specified input value so we can pre-check radio buttons --- View/Helper/BootstrapFormHelper.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/View/Helper/BootstrapFormHelper.php b/View/Helper/BootstrapFormHelper.php index 950e541..bebc4c0 100644 --- a/View/Helper/BootstrapFormHelper.php +++ b/View/Helper/BootstrapFormHelper.php @@ -365,6 +365,8 @@ public function radio($field, $options = array(), $attributes = array()) { $attributes ); foreach ($opt as $key => $val) { + $checked = ($key === Re::pluck($options, '/value')); + $attributes['checked'] = $checked; $input = parent::radio($options["field"], array($key => $val), $attributes); $id = array(); preg_match_all("/id=\"[a-zA-Z0-9_-]*\"/", $input, $id); From b83a96aa450fe739003cd8648753676f4f1f0354 Mon Sep 17 00:00:00 2001 From: Chris Johnson Date: Thu, 31 Oct 2013 22:31:47 +0000 Subject: [PATCH 9/9] Add escapeError option to allow specifying escapeError => false to disable HTML escaping validation errors --- View/Helper/BootstrapFormHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/View/Helper/BootstrapFormHelper.php b/View/Helper/BootstrapFormHelper.php index bebc4c0..7201ab0 100644 --- a/View/Helper/BootstrapFormHelper.php +++ b/View/Helper/BootstrapFormHelper.php @@ -230,7 +230,7 @@ public function input($field, $options = array()) { $options['state'] = 'error'; $help_block = $this->Html->tag( "span", - $this->error($options['field']), + $this->error($options['field'], null, array('escape' => (isset($options['escapeError']) && $options['escapeError'] === false) ? false : true)), array("class" => "help-block") ); }