CakePHP 3 custom form - cakephp-3.7

I am using CakePHP3 and Angular to provide some front-end validation on form inputs. This is working nicely but I'm looking to minimise my front-end mark-up - as follows:
$this->Form->control('Name', [
'placeholder' => 'Test',
'ng-model' => 'listing.test',
'templateVars' => [
'has_errors' => 'ng-class="{\'has-error\': addListing.$submitted && addListing.name.$invalid}"',
'error' => '<div class="error-message" ng-show="addListing.$submitted && addListing.name.$invalid">Please specify your name</div>',
]
]);
In my app_form.php I have the following:
'input' => '<input class="form-control mb15" type="{{type}}" name="{{name}}"{{attrs}} />{{error}}',
I don't want to have to repeat '<div class="error-message"...' for each and every input, it would be better to just pass in the the 'ng-show'.
My thoughts were to do something like tihs:
'templateVars' => [
'has_errors' => 'ng-class="{\'has-error\': addListing.$submitted && addListing.name.$invalid}"',
'show' => 'addListing.$submitted && addListing.name.$invalid',
'message' => 'Please input your name'
]
'customError' => '<div class="error-message" ng-show"{{show}}>{{error-message}}</div>',
'input' => '<input class="form-control mb15" type="{{type}}" name="{{name}}"{{attrs}} />{{customError}}',
However I think this customisation beyond what is possible since I would be creating my own template key. Is this possible?

Related

Creating a table of data submitted on form submit using ajax without saving the data in the database. - Drupal8

Here is the requirement that I need to achieve in Drupal8.
Add user email and show it in a table format row wise
The user will enter the email and click on the Add button. Then the added emails will be shown in a table format just below the form with remove link. It will be a ajaxified form.
Below is the code that I have used.
public function buildForm(array $form, FormStateInterface $form_state) {
$form['email'] = [
'#type' => 'email',
'#placeholder' => $this->t('Enter Email address To Add'),
'#required' => TRUE,
];
// Attach Ajax callback to the Submit button.
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Add'),
'#ajax' => array(
'callback' => '::ajaxAddEmailRow',
'event' => 'click',
'wrapper' => 'email-row-wrapper',
),
];
$header = [
'email' => t('Email'),
'accounttype' => t('Account Type'),
'permission' => t('Permission Level'),
'operation' => t('Operation'),
];
// For testing only.
$rows[0] = array(
'email' => 'test1#gm.com',
'accounttype' => 'account',
'permission' => 'permission',
'operation' => 'operation',
);
$form['email_rows'] = [
'#type' => 'table',
'#header' => $header,
'#rows' => $rows,
'#prefix' => '<div id="email-row-wrapper">',
'#suffix' => '</div>',
'#empty' => t('No users found'),
];
return $form;
}
Any help or guidance highly appreciated. Thanks.

How to get a full_html textarea field in a Drupal 8 configuration form?

In my module I have a configuration form (ConfigFormBase) with a simple textarea field without formatting that works correctly.
$form['page_message'] = [
'#type' => 'textarea',
'#title' => $this->t('Message'),
'#description' => $this->t('Message display to customer contacts.'),
'#default_value' => $config->get('page_message'),
];
But I would like a textarea full_html field.
Is this possible and how with Drupal 8?
Yes it is possible, but you have to do it like this:
$form['page_message'] = [
'#type' => 'text_format',
'#title' => $this->t('Message'),
'#format' => 'full_html',
'#description' => $this->t('Message display to customer contacts.'),
'#default_value' => $config->get('page_message'),
];
You can check Drupal api for TextFormat.php here, just click on view source and you will have all the info you need.

Does $this->Html->url() generate RESTful URL?

I use CakePHP 2.4.6.
In routes.php, I put
Router::mapResources('themes');
Then, I can access 'localhost/themes/211' which display screen generated by the action "view" of the controller "themes" just as I expect.
BUt in a view file, I use
<?php
echo $this->Html->url(array(
'controller' => 'themes',
'action' => 'view',
$theme['Theme']['id']));
?>
Then this generate '/themes/view/211' in html, where I expected '/themes/211'.
Does $this->Html->url() generate RESTful URL?
If not, How can Cake view file generate RESTful URL in other way?
Do I do any mistake?
Thanks in advance.
leave the action blank
<?php
echo $this->Html->url(array(
'controller' => 'themes',
'action' => '',
$theme['Theme']['id']));
?>
Or,
<?php
echo $this->Html->url(array(
'controller' => 'themes',
'action' =>$theme['Theme']['id']
));
?>
If you want this to happen, go to your \app\Config\routes.php and add Router::connect('/themes', array('controller' => 'themes', 'action' => 'view'));
You don't have to change
<?php
echo $this->Html->url(array(
'controller' => 'themes',
'action' => 'view',
$theme['Theme']['id']));
?>
You probably have some more Restfull api calls to define, so maybe something more generic:
Router::connect('/api/:controller', array('api' => true, 'action' => 'index', "[method]" => "GET"), array('pass' => array('id'), 'id' => '([0-9]+|me)'));
Router::connect('/api/:controller', array('api' => true, 'action' => 'add', "[method]" => "POST"), array('pass' => array('id'), 'id' => '([0-9]+|me)'));
Router::connect('/api/:controller/:id', array('api' => true, 'action' => 'view', "[method]" => "GET"), array('pass' => array('id'), 'id' => '([0-9]+|me)'));
Router::connect('/api/:controller/:id', array('api' => true, 'action' => 'edit', "[method]" => "POST"), array('pass' => array('id'), 'id' => '([0-9]+|me)'));
These route calls like "api/Themes/123" to the action index in the Themes controller, however, if you try and do a POST request it will route to the add action.

Displaying a custom twig template with Sonata and Symfony2

For my need, I'm planning to add a custom column to a entity list.
I've written this inside the configureListFields :
->add('_action', 'actions', array(
'actions' => array(
'code' => array('template' => 'BOBAdminBundle:test:custom.html.twig'),
)
))
My twig :
<img src="{{ asset('bundles/sonataadmin/famfamfam/delete.png') }}" />
It works.
Problem : I don't know why :S, since I've just copy/paste the code from somewhere.
I figured out than the '_action' determined the name of the column. But what if I want to change it ?
Where does this 'actions' name come from ? Where can I change it ?
The _action is used to add custom actions for the list items. Like edit and delete which are set by default. Here is a full documentation:
List actions
You can set actions for the list items by adding an ‘_action’ field in configureListFields:
<?php
$listMapper->add('_action', 'actions', array(
'actions' => array(
'view' => array(),
'edit' => array(),
)
))
Edit and delete actions are enabled in the default configuration. You can add your own! Default template file is: *SonataAdminBundle:CRUD:list_action[ACTION_NAME].html.twig*
You can specify your own by setting up the ‘template’ option like so:
<?php
$listMapper->add('_action', 'actions', array(
'actions' => array(
'view' => array(),
'edit' => array(),
'delete' => array('template' => 'MyBundle:MyController:my_partial.html.twig'),
)
))

Cakephp validating if my user checked at least one option

I have a problem validating if my user checked at least one option from a list of checkboxes.
Here is what i tried:
My view looks like this:
echo $this->Form->input('market_segment_targeted', array(
'multiple' => 'checkbox',
'label'=>array('text' => 'Market segment targeted', 'class'=>'w120'),
'options' => array(
'Home users' => 'Home users',
'SOHO' => 'SOHO',
'SMB' => 'SMB',
'Enterprise' => 'Enterprise'
),
));
In my controller i have added this snippet of code:
$validate_on_fly = array(
'market_segment_targeted' => array(
'notEmpty' => array(
'rule' => array('multiple', array('min' => 1)),
'required' => true,
'message' => 'Please select at least one!'
))
)));
$this->Partner->validate = Set::merge(
$this->Partner->validate,
$validate_on_fly
);
Any ideas what am i doing wrong?
Thank you
In CakePHP you can use Model Validation for checkboxes. Here is a quick example.
Your Form can look like:
$this->Form->create('User');
$this->Form->input('User.agree', array('type'=>'checkbox', 'hiddenField'=>false, 'value'=>'0'));
$this->Form->submit('Save'):
$this->Form->end();
Then in your Model under public $validate, use:
'agree'=>array(
'Not empty'=>array(
'rule'=>array('comparison', '!=', 0),
'required'=>true,
'message'=>'You must agree to the ToS'
)
)