I understood the CakePHP validation that way: Only fields which are in the request (e.g. ['Post']['NAME'] and ['Post']['STREET']) are validated in the appmodel, even if in the appmodel there are declarations for many more fields.
Now I call this->Post->save($this->request->data) and Cake throws validation errors for fields which are not in the request and now I don´t know what to do.
Controller:
debug of this->request->data:
array(
'Post' => array(
'TYPE' => '1',
'B/S' => 'S',
'LATITUDE' => '50.98549',
'LONGITUDE' => '11.31551',
'CART' => 'jkl',
'MARKET' => 'jk',
'INCOMETYPE' => '1',
'INCOME' => '8',
'DEADLINE' => '1',
'DATE' => '31.08.2014',
'TIME' => '',
'PREFERREDDATES' => 'nach Absprache',
'address' => 'Fuldaer Straße, 99423, Weimar',
'STREET' => 'Fuldaer Straße',
'DELIVERYAREA' => '99423',
'CITY' => 'Weimar',
'TEL' => '1234567654321',
'saveAppendix' => 'edit'
)
)
Controller:
debug of $this->Post-validationErrors:
array(
'ZIPCODE' => array(
(int) 0 => 'Bitte eine gültige Postleitzahl eingeben.'
),
'VEHICLE' => array(
(int) 0 => 'Bitte das Fahrzeug angeben'
),
'SPACE' => array(
(int) 0 => 'Bitte den verfügbaren Platz angeben'
)
)
Controller:
Code with debug-statements:
if (isset($this->request->data['Post']['saveAppendix']) && $this->request->data['Post']['saveAppendix'] == "edit") {
debug($this->request->data);
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash('Dein Inserat wurde erfolgreich bearbeitet.', 'flash_success');
$this->set('action', 'goToIndex');
$this->render('addRedirect', 'ajax');
} else {
debug($this->Post->validationErrors);
...further code...
}
}
EDIT
As requested by burzum, the validation rules:
class Post extends AppModel {
public function beforeValidate(array $options = array()) {
$request = $this->data[$this->alias];
if (isset($request['INCOMETYPE']) && ($request['INCOMETYPE'] == "1" || isset($request['INCOMETYPE']) && $request['INCOMETYPE'] == "2")) {
$this->data[$this->alias]['INCOME'] = preg_replace(
'/^([^,]*).*$/', '$1', $request['INCOME']
);
$this->data[$this->alias]['INCOME'] = preg_replace(
'/\D/', '', $request['INCOME']
);
};
//für validation die schaltungsart-variablen setzen
if (isset($request['DEADLINE']) && $request['DEADLINE'] == "1") {
$this->validator()->remove('TIME');
$date = $request['DATE'];
};
if (isset($request['DEADLINE']) && $request['DEADLINE'] == "2") {
$this->validator()->remove('PREFERREDDATES');
$date = $request['DATE'];
};
if (isset($request['DEADLINE']) && $request['DEADLINE'] == "3") {
$this->validator()->remove('DATE');
$this->validator()->remove('TIME');
};
if (isset($date) && $date <> "") {
//datepicker date in sortierbares datum wandeln: Y M D
$tmpdate = list($day, $month, $year) = explode('.', $date);
$altdate = $year.$month.$day;
$this->data[$this->alias]['ALTDATE'] = $altdate;
};
if (isset($request['INCOMETYPE']) && $request['INCOMETYPE'] == "4") {
$this->validator()->remove('INCOME');
};
if (isset($request['INCOMETYPE']) && $request['INCOMETYPE'] == "5") {
$this->validator()->remove('INCOME');
};
// B/S-Feld füllen mit entsprechendem String
if (isset($request['TYPE']) && isset($request['B/S'])) {
if ($request['TYPE'] == 1 && $request['B/S'] == "S") {
$this->data[$this->alias]['B/S'] = "Suche Kurier";
};
if ($request['TYPE'] == 2 && $request['B/S'] == "S") {
$this->data[$this->alias]['B/S'] = "Suche Bildungsdienstleistung";
};
if ($request['TYPE'] == 3 && $request['B/S'] == "S") {
$this->data[$this->alias]['B/S'] = "Suche Elektronik & Technik";
};
if ($request['TYPE'] == 4 && $request['B/S'] == "S") {
$this->data[$this->alias]['B/S'] = "Suche Freizeit & Sport";
};
if ($request['TYPE'] == 5 && $request['B/S'] == "S") {
$this->data[$this->alias]['B/S'] = "Suche Haushalt und Garten";
};
if ($request['TYPE'] == 6 && $request['B/S'] == "S") {
$this->data[$this->alias]['B/S'] = "Suche Soziales";
};
if ($request['TYPE'] == 1 && $request['B/S'] == "B") {
$this->data[$this->alias]['B/S'] = "Biete Kurier";
};
if ($request['TYPE'] == 2 && $request['B/S'] == "B") {
$this->data[$this->alias]['B/S'] = "Biete Bildungsdienstleistung";
};
if ($request['TYPE'] == 3 && $request['B/S'] == "B") {
$this->data[$this->alias]['B/S'] = "Biete Elektronik & Technik";
};
if ($request['TYPE'] == 4 && $request['B/S'] == "B") {
$this->data[$this->alias]['B/S'] = "Biete Freizeit & Sport";
};
if ($request['TYPE'] == 5 && $request['B/S'] == "B") {
$this->data[$this->alias]['B/S'] = "Biete Haushalt & Garten";
};
if ($request['TYPE'] == 6 && $request['B/S'] == "B") {
$this->data[$this->alias]['B/S'] = "Biete Soziales";
};
};
//inserat-datum darf nicht in vergangenheit liegen
/*if ($request['DATE'] == date("d.m.Y") && $request['TIME'] < date("H:i")) {
unset($this->data[$this->alias]['TIME']);
};*/
return parent::beforeValidate($options);
}
var $validate = array(
'STREET' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Hidden input B/S wurde geändert'
),
'rule-2' => array(
'rule' => '/^[a-z]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'STREET' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte eine Straße angeben'
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'HOUSENUMBER' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte eine Hausnummer angeben'
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'ZIPCODE' => array(
'rule-1' => array(
'rule' => array('postal', null, 'de'),
'message' => 'Bitte eine gültige Postleitzahl eingeben.',
'last' => true
),
'rule-2' => array(
'rule' => array('ZipExists'),
'message' => 'Postleitzahl existiert nicht!'
)
),
'CITY' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte eine Stadt angeben'
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'CART' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte etwas eingeben'
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'MISC' => array(
'rule-1' => array(
'allowEmpty' => true
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'MARKET' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte einen Markt angeben'
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'DATE' => array(
'rule' => 'notEmpty',
'required' => 'true',
'message' => 'Bitte das Datum eingeben'
),
'PREFERREDDATES' => array(
'rule' => 'notEmpty',
'required' => 'true',
'message' => 'Bitte die passenden Zeiten eingeben'
),
'DEADLINE' => array(
'rule' => 'notEmpty',
'required' => 'true',
'message' => 'Bitte die Art der Schaltung festlegen'
),
'TIME' => array(
'rule' => 'time',
'required' => 'true',
'message' => 'Bitte die Zeit eingeben'
),
'INCOME' => array(
'rule' => 'notEmpty',
'required' => 'true',
'message' => 'Bitte die Bezahlung eingeben'
),
/*'INCOME' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte die Bezahlung angeben'
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),*/
'INCOMETYPE' => array(
'rule' => 'notEmpty',
'required' => 'true',
'message' => 'Bitte die Art der Bezahlung festlegen'
),
'VEHICLE' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte das Fahrzeug angeben'
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'DELIVERYAREA' => array(
'rule-1' => array(
'rule' => array('postal', null, 'de'),
'message' => 'Bitte eine gültige Postleitzahl eingeben.',
'last' => true
),
'rule-2' => array(
'rule' => array('ZipExists'),
'message' => 'Postleitzahl existiert nicht!'
)
),
'SPACE' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte den verfügbaren Platz angeben'
),
'rule-2' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{1,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'TEL' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte die Telefonnummer eingeben'
),
'rule-2' => array(
'rule' => '/^[0-9_\/\d\w\s?!\.:,\'"\(\)=\+-]{0,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
)
),
'NAME' => array(
'rule' => '/^[a-z0-9_äÄöÖüÜߧ$%&*\/\d\w\s?!\.:,\'"\(\)=\+-]{0,}$/i',
'message' => 'Hacker kommen hier nicht weit!'
),
'LATITUDE' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte gültige Adresse angeben'
),
'rule-2' => array(
'rule' => 'numeric',
'message' => 'Bitte gültige Adresse angeben'
)
),
'LONGITUDE' => array(
'rule-1' => array(
'rule' => 'notEmpty',
'message' => 'Bitte gültige Adresse angeben'
),
'rule-2' => array(
'rule' => 'numeric',
'message' => 'Bitte gültige Adresse angeben'
)
),
'TYPE' => array(
'rule-1' => array(
'rule' => 'numeric'
),
'rule-2' => array(
'rule' => array('maxLength', 1)
)
)
);
public function ZipExists($zipcode){
$value = array_values($zipcode);
$value = $value[0];
$Zipcode = ClassRegistry::init('Zipcode');
$valid = $Zipcode->find('count', array('conditions'=> array('Zipcode.zipcode' =>$value)));
if ($valid >= 1){
return true;
}
else{
return false;
}
}
};
If i understand you correctly, than you got it all wrong.
cake will validate everything that is in the validation rules, and required. keep in mind that omitting a field, might be a validation error for itself..
edit:
Validation works in the context of the model, not the request. it validates the data that will be saved to the database, against the validation rules.
The meaning is: it will compare the POST data to the rules.
and, if a field is required in the validation-rules, it will throw an error.
Please attach the validation errors
Related
I had developed a block in 2.5. I installed the block successfully..and gave permissions settings on front end to view this block only for one role users say 'Manager'. So, Manager/Admin can only view this block and no one else.
But this block is still visible for all. Could you please judge me.. where I went wrong.. Here is my leisure block code
Blocks/block_leisure/block_leisure.php
<?php
class block_leisure extends block_base
{
public function init()
{
global $CFG;
$this->title = get_string('leisure', 'block_leisure');
}
public function get_content()
{
global $COURSE, $DB, $PAGE, $CFG, $USER, $CFG, $SESSION, $OUTPUT;
if ($this->content !== null)
{
return $this->content;
}
$this->content = new stdClass;
$context = $PAGE->context;
$this->content->text = 'This is a leisure block content';
$this->content->footer = 'Footer here...';
return $this->content;
} // Function - get_content().
public function getmodules()
{
return true;
}
}
Blocks/block_leisure/db/access.php
<?php
defined('MOODLE_INTERNAL') || die;
$capabilities = array(
'block/leisure:myaddinstance' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'user' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/my:manageblocks'
),
'block/leisure:addinstance' => array(
'riskbitmask' => RISK_SPAM | RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/site:manageblocks'
),
'block/leisure:viewpages' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
'legacy' => array(
'guest' => CAP_PREVENT,
'student' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
),
'block/leisure:managepages' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
'legacy' => array(
'guest' => CAP_PREVENT,
'student' => CAP_PREVENT,
'teacher' => CAP_PREVENT,
'editingteacher' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
)
);
and as usual I have lang folder, version.php and read me file.
You need to do something with the capability you have defined, otherwise it will have no effect.
Check the capability within get_content, then return null if nothing should be displayed.
I have developed ajax drupal and add a form (textfield and button) in it using #ajax key and callback function where I do my process and return my form new element.
So when I starts adding my data form, it works fine for me and form_state['values'] are updated fine.
The problem here is when I reload my form and I add some data, form_state['values'] are not the same in my form fields.
Here is my code:
function my_horoscope_menu() {
$items = array();
$items['admin/horoscopes'] = array(
'title' => 'Horoscopes',
'page callback' => 'drupal_get_form',
'page arguments' => array('my_horoscope_admin_form'),
'access arguments' => array('Administer site configuration '),
//'type' => MENU_LOCAL_TASK,
);
return $items;
}
function my_horoscope_admin_form($form, &$form_state) {
$form['settings']['horoscopes']['add_horoscopes'] = array(
'#type' => 'fieldset',
'#title' => t('Add horoscopes'),
'#collapsible' => TRUE,
'#collaspsed' => TRUE,
);
$form['settings']['horoscopes']['add_horoscopes']['name'] = array(
'#type' => 'textfield',
'#title' => t('Horoscope name'),
'#default_value' => t('Horoscope name'),
'#size' => 20,
'#maxlength' => 60,
'#required' => FALSE,
);
$form['settings']['horoscopes']['add_horoscopes']['beginning_date_rang'] = array(
'#type' => 'date',
'#title' => t('Horoscope beginning date rang'),
'#description' => t('Set the beginning date rang of this horoscope.'),
'#required' => FALSE,
);
$form['settings']['horoscopes']['add_horoscopes']['ending_date_rang'] = array(
'#type' => 'date',
'#title' => t('Horoscope ending date rang'),
'#description' => t('Set the ending date rang of this horoscope.'),
'#required' => FALSE,
);
$form['settings']['horoscopes']['add_horoscopes']['add_button'] = array(
'#type' => 'button',
'#value' => t('Add this horoscope'),
'#submit' => array(''),
'#ajax' => array(
'event' => 'click',
'callback' => 'add_horoscope_ajax_process',
'wrapper' => 'add_horoscope_wrapper',
),
);
$form['settings']['horoscopes']['add_horoscopes']['adding_horoscope_wrapper'] = array(
'#type' => 'markup',
'#prefix' => '<div id="add_horoscope_wrapper">',
'#suffix' => '</div>',
);
return $form;
}
function add_horoscope_ajax_process ($form, &$form_state) {
if (isset($form_state['values'])) {
if (isset($form_state['values']['name']) AND $form_state['values']['name'] != '') {
$name = $form_state['values']['name'];
}
if (isset($form_state['values']['beginning_date_rang']) AND $form_state['values']['beginning_date_rang'] != '') {
$beginning_date_rang = $form_state['values']['beginning_date_rang'];
$beginning_date_rang1 = sprintf("%04d-%02d-%02d", $beginning_date_rang['year'], $beginning_date_rang['month'], $beginning_date_rang['day']);
}
if (isset($form_state['values']['ending_date_rang']) AND $form_state['values']['ending_date_rang'] != '') {
$ending_date_rang = $form_state['values']['ending_date_rang'];
$ending_date_rang1 = sprintf("%04d-%02d-%02d", $ending_date_rang['year'], $ending_date_rang['month'], $ending_date_rang['day']);
}
// Prepare record to add
$record = array(
'h_name' => $name,
'h_date_begin' => $beginning_date_rang1,
'h_date_end' => $ending_date_rang1,
);
// Add the record
$res = drupal_write_record('my_horoscope_structure', $record);
if($res != FALSE) {
drupal_set_message(t('Horoscope #name is inserted successfully!', array('#name' => $name)));
}
}
// return $form
return $form['settings']['horoscopes']['add_horoscopes']['adding_horoscope_wrapper'];
}
I have created a form in drupal programmatically. How could i wrap each elements of the form with div. Below is my sample code
function emailusers_compose_form($context, $account) {
$form['to'] = array(
'#type' => 'value',
'#value' => $account,
);
$form['message']['subject'] = array(
'#type' => 'textfield',
'#title' => t('Subject'),
'#size' => 50,
'#maxlengh' => 255,
'#description' => t('The subject of the email message.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Send Mail'),
);
return $form;
}
Here is the answer
function emailusers_compose_form($context, $account) {
$form['to'] = array(
'#type' => 'value',
'#value' => $account,
);
$form['message']['subject'] = array(
'#type' => 'textfield',
'#title' => t('Subject'),
'#size' => 50,
'#maxlengh' => 255,
'#description' => t('The subject of the email message.'),
'#prefix' => '<div id="elementid">',
'#suffix' => '</div>'
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Send Mail'),
);
return $form;
}
I would like to create a fieldset under each radio/checkbox item.
e.g
Which animals do you like:
[x] Cats
[Fieldset of cat related questions]
[ ] Dogs
[Fieldset of dog related questions]
...
I can create Fieldsets and Forms with ease, but nesting them under each item is causing me some headaches.
Ultimately I had in mind something like this:
$this->add(array(
'type' => 'Zend\Form\Element\Radio',
'name' => 'profile_type',
'options' => array(
'label' => 'Which animals do you like:',
'label_attributes' => array('class'=>'radio inline'),
'value_options' => array(
'1' =>'cats',
'fieldsets' => array(
array(
'name' => 'sender',
'elements' => array(
array(
'name' => 'name',
'options' => array(
'label' => 'Your name',
),
'type' => 'Text'
),
array(
'type' => 'Zend\Form\Element\Email',
'name' => 'email',
'options' => array(
'label' => 'Your email address',
),
),
),
)),
'2'=>'dogs',
'fieldsets' => array(
array(
'name' => 'sender',
'elements' => array(
array(
'name' => 'name',
'options' => array(
'label' => 'Your name',
),
'type' => 'Text'
),
array(
'type' => 'Zend\Form\Element\Email',
'name' => 'email',
'options' => array(
'label' => 'Your email address',
),
),
),
))
),
),
'attributes' => array(
'value' => '1' //set checked to '1'
)
));
Ok I managed to get round this issue using a bit of a hack, but it works.
TestForm.php (note the additional attributes in the elements ('parent' and 'childOf')
class TestForm extends Form
{
public $user_agent;
public $user_ip;
public function __construct($name = null)
{
// we want to ignore the name passed
parent::__construct('profile');
$this->setAttributes(array(
'method'=>'post',
'class'=>'form-horizontal',
));
$this->add(array(
'type' => 'Zend\Form\Element\Radio',
'name' => 'profile_type',
'options' => array(
'label' => 'Which animals do you like:',
'label_attributes' => array('class'=>'radio inline'),
'value_options' => array(
array('label' =>'cats', 'value'=>1, 'parent'=>'cat'),
array('label'=>'dogs', 'value'=>2, 'parent'=>'dog'),
),
),
'attributes' => array(
'value' => '1' //set checked to '1'
)
));
$this->add(array(
'type' => 'Text',
'name' => 'name',
'attributes' => array(
'childOf' => 'cat',
),
'options' => array(
'label' => 'Your name',
),
));
$this->add(array(
'type' => 'Zend\Form\Element\Email',
'name' => 'email',
'attributes' => array(
'childOf' => 'dog',
),
'options' => array(
'label' => 'Your email address',
),
));
}
}
Then extended Zend\Form\View\Helper\FormMultiCheckbox and overwrote the RenderOptions Method (look out for the new optionSpec 'parent') this basically creates a tag e.g.{#cat#} after the parent element:
protected function renderOptions(MultiCheckboxElement $element, array $options, array $selectedOptions,
array $attributes)
{
$escapeHtmlHelper = $this->getEscapeHtmlHelper();
$labelHelper = $this->getLabelHelper();
$labelClose = $labelHelper->closeTag();
$labelPosition = $this->getLabelPosition();
$globalLabelAttributes = $element->getLabelAttributes();
$closingBracket = $this->getInlineClosingBracket();
if (empty($globalLabelAttributes)) {
$globalLabelAttributes = $this->labelAttributes;
}
$combinedMarkup = array();
$count = 0;
foreach ($options as $key => $optionSpec) {
$count++;
if ($count > 1 && array_key_exists('id', $attributes)) {
unset($attributes['id']);
}
$value = '';
$parent = '';
$label = '';
$inputAttributes = $attributes;
$labelAttributes = $globalLabelAttributes;
$selected = isset($inputAttributes['selected']) && $inputAttributes['type'] != 'radio' && $inputAttributes['selected'] != false ? true : false;
$disabled = isset($inputAttributes['disabled']) && $inputAttributes['disabled'] != false ? true : false;
if (is_scalar($optionSpec)) {
$optionSpec = array(
'label' => $optionSpec,
'value' => $key
);
}
if (isset($optionSpec['value'])) {
$value = $optionSpec['value'];
}
if (isset($optionSpec['parent'])) {
$parent = $optionSpec['parent'];
}
if (isset($optionSpec['label'])) {
$label = $optionSpec['label'];
}
if (isset($optionSpec['selected'])) {
$selected = $optionSpec['selected'];
}
if (isset($optionSpec['disabled'])) {
$disabled = $optionSpec['disabled'];
}
if (isset($optionSpec['label_attributes'])) {
$labelAttributes = (isset($labelAttributes))
? array_merge($labelAttributes, $optionSpec['label_attributes'])
: $optionSpec['label_attributes'];
}
if (isset($optionSpec['attributes'])) {
$inputAttributes = array_merge($inputAttributes, $optionSpec['attributes']);
}
if (in_array($value, $selectedOptions)) {
$selected = true;
}
$inputAttributes['value'] = $value;
$inputAttributes['checked'] = $selected;
$inputAttributes['disabled'] = $disabled;
$input = sprintf(
'<input %s%s',
$this->createAttributesString($inputAttributes),
$closingBracket
);
if (null !== ($translator = $this->getTranslator())) {
$label = $translator->translate(
$label, $this->getTranslatorTextDomain()
);
}
$tag = ($parent != '')? "{#*".$parent."*#}": "";
$label = $escapeHtmlHelper($label);
$labelOpen = $labelHelper->openTag($labelAttributes);
$template = $labelOpen . '%s%s%s' . $labelClose;
switch ($labelPosition) {
case self::LABEL_PREPEND:
$markup = sprintf($template, $label, $input, $tag);
break;
case self::LABEL_APPEND:
default:
$markup = sprintf($template, $input, $label, $tag);
break;
}
$combinedMarkup[] = $markup;
}
return implode($this->getSeparator(), $combinedMarkup);
}
Extended and overwrote Zend\Form\View\Helper\FormRow render method this is the same except for the return of the method:
..... more code .....
$child_of = $element->getAttribute('childOf');
if($child_of != '')
{
return array($child_of => sprintf('<div class="control-group%s">%s</div>', $status_type, $markup));
}
return sprintf('<div class="control-group%s">%s</div>', $status_type, $markup);
And finally extended and overwrote the render method of Zend\Form\View\Helper\FormCollection and changed the element foreach loop, basically overwriting the tags if the element is an array, and therefore has a ChildOf tag. Then a clean up of tags:
foreach ($element->getIterator() as $elementOrFieldset) {
if ($elementOrFieldset instanceof FieldsetInterface) {
$markup .= $fieldsetHelper($elementOrFieldset);
} elseif ($elementOrFieldset instanceof ElementInterface) {
$elementString = $elementHelper($elementOrFieldset);
if(!is_array($elementString))
{
$markup .= $elementString;
}
// is child of another element
else
{
foreach($elementString as $key => $value)
{
$match = "{#*".$key."*#}";
$replacement = $value.$match;
$markup = str_replace($match, $replacement, $markup);
}
}
}
}
$pattern = '/[{#\*]+[a-z0-0A-Z]*[\*#}]+/';
$markup = preg_replace($pattern, '', $markup);
This (although ugly) produces the desired results, also because we are just playing with the rendering, validation and form creation are untouched.
All the best,
Aborgrove
I am writing a custom module which has a form but the submit handler is just not working, the form just submits back to itself?
Any help much appreciated.
I have an add guest custom form and that is working fine.
The URL on my site is: /user/booking_editguest/LBD0413/1
The code is below:
function uUserBookings_editGuestForm($form, &$form_state, $ManageBooking) {
//var_dump($ManageBooking);
$guestSeq = arg(3);
$masterEventCode = $ManageBooking->Contact->{'MasterEventCode'};
$eventCode = $ManageBooking->Contact->{'EventCode'};
$attendeeContact = $ManageBooking->Contact->{'AttendeeContact'};
global $user;
$account = user_load($user->uid);
$memberCode = $account->name;
// booking
$form['booking'] = array(
//'#type' => 'vertical_tabs',
);
foreach($ManageBooking->guests as $Guest)
{
if ($guestSeq == $Guest->{'GuestSeq'} )
{
$form['guest_form']['FirstName'] = array(
'#required' => TRUE,
'#type' => 'textfield',
'#title' => t('GUEST FIRST NAME'),
'#default_value' => $Guest->{'Guest FirstName'}
);
$form['guest_form']['Surname'] = array(
'#required' => TRUE,
'#type' => 'textfield',
'#title' => t('GUEST LAST NAME'),
'#default_value' => $Guest->{'Guest Surname'}
);
$form['guest_form']['DietaryRequirements'] = array(
'#required' => FALSE,
'#type' => 'textfield',
'#title' => t('SPECIAL DIETARY REQUIREMENTS'),
'#default_value' => $Guest->{'Dietary Requirements'}
);
$form['guest_form']['CompanyName'] = array(
'#required' => TRUE,
'#type' => 'textfield',
'#title' => t('GUEST COMPANY NAME'),
'#default_value' => $Guest->{'Company Name'}
);
$form['guest_form']['Position'] = array(
'#required' => TRUE,
'#type' => 'textfield',
'#title' => t('GUEST POSITION'),
'#default_value' => $Guest->{'Attendee Position'}
);
$form['guest_form']['Email'] = array(
'#required' => TRUE,
'#type' => 'textfield',
'#title' => t('GUEST EMAIL'),
'#default_value' => $Guest->{'Guest Email'}
);
//MasterEventCode
$form['guest_form']['masterEventCode'] = array(
'#required' => TRUE,
'#type' => 'hidden',
'#default_value' => $masterEventCode
);
//EventCode
$form['guest_form']['eventCode'] = array(
'#required' => TRUE,
'#type' => 'hidden',
'#default_value' => $eventCode
);
//Member_code
$form['guest_form']['memberCode'] = array(
'#required' => TRUE,
'#type' => 'hidden',
'#default_value' => $memberCode
);
//Attendee_Contact
$form['guest_form']['Attendee_Contact'] = array(
'#required' => TRUE,
'#type' => 'hidden',
'#default_value' => $attendeeContact
);
//GuestSeq
$form['guest_form']['GuestSeq'] = array(
'#required' => TRUE,
'#type' => 'hidden',
'#default_value' => $Guest->{'GuestSeq'}
);
//GuestID
$form['guest_form']['GuestID'] = array(
'#required' => TRUE,
'#type' => 'hidden',
'#default_value' => $Guest->{'Guest Contact Counter'}
);
//EventNameDetailsID uniqueidentifier
$form['guest_form']['EventNameDetailsID'] = array(
'#required' => TRUE,
'#type' => 'hidden',
'#default_value' => $Guest->{'EventNameDetailsID'}
);
//ID uniqueidentifier
$form['guest_form']['ID'] = array(
'#required' => TRUE,
'#type' => 'hidden',
'#default_value' => $Guest->{'ID'}
);
$form['guest_form']['Submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
'#submit' => array('tmsUserBookings_editGuestForm_submit')
);
}
}
return $form;}
function userBookings_editGuestForm_validate($form, &$form_state) {
// Validation logic.
// Don't custom-validate if previous validation errors (still) exist
if (form_get_errors()) return;
// .. Otherwise, process custom form validation goes here }
function userBookings_editGuestForm_submit($form, &$form_state) {
//Get Form variables
$guestFirstname = $form_state['input']['FirstName'];
$guestSurname = $form_state['input']['Surname'];
$guestDietary = $form_state['input']['DietaryRequirements'];
$guestCompany = $form_state['input']['CompanyName'];
$guestPosition = $form_state['input']['Position'];
$guestEmail = $form_state['input']['Email'];
$memberCode = $form_state['input']['Member_code'];
$masterEventCode = $form_state['input']['MasterEventCode'];
$eventCode = $form_state['input']['EventCode'];
$bookerContactCounter = $form_state['input']['Attendee_Contact'];
$guestSeq = $form_state['input']['GuestSeq'];
$guestTitle = $form_state['input']['Title'];
$guestContactCounter = $form_state['input']['GuestID'];
$eventNameDetailsId = $form_state['input']['EventNameDetailsID'];
$id = $form_state['input']['ID'];
//Redirect back to the Booking.
$form_state['redirect'] = '/user/booking_guestupdated';}
For those using hidden textfields and have them set as required, make sure you check the values being entered!