I'm using cakePHP with its default model validation. On error cake add the class "error" to my container div. Great! But what about if everything is entered correctly but one form element? I would like the inputs that are correct to receive the class "success" (and maybe a message or icon telling my user how awesome they are).
Here is my form create code:
echo $this->Form->create('User',
array(
'class' => 'form-horizontal',
'inputDefaults' =>
array(
'format' => array('before', 'label', 'between', 'input', 'error', 'after'),
'div' => array('class' => 'control-group'),
'label' => array('class' => 'control-label'),
'between' => 'div class="controls">',
'after' => '/div>',
'error' => array('attributes' => array('wrap' => 'span', 'class' => 'help-inline')),
)
)
);
What I ended up doing was copy /lib/Cake/View/HelperFormHelper.php to /app/View/Helper/FormHelper.php. I then modified /app/View/Helper/FormHelper.php around line 1028 (on my copy, it's the end of the 'input' function) so that it looks like this:
1028:
if ($this->_introspectModel($modelKey, 'validates', $fieldKey)) {
$divOptions = $this->addClass($divOptions, 'required');
}
if($this->request->is('post')) {
if(!$this->isFieldError($modelKey.'.'.$fieldKey)) {
// This is the important line.
$divOptions = $this->addClass($divOptions, 'success');
}
}
if (!isset($divOptions['tag'])) {
$divOptions['tag'] = 'div';
}
}//end input function
Don't know if it's the cleanest way, but it would work.
I would add the following lines to my View, checking if the request is a POST. All the fields with the class 'control-group' would adopt the new style.
if($this->request->is('post')){
echo '<style type="text/css">div.control-group { background-color:#000; }</style>';
}
As you don't wan't to show the new style in the fields that use class 'error', just put !important after the style rules at the CSS file revoking the change.
Example 'style.css':
error {
background-color: none !important;
}
Related
I have created a site using CakePHP 3. I have static page which has contact us form something like this:
inside contactus.ctp:
<?=$this->Form->create(); ?>
<?=$this->Form->hidden('form_type',['value' => 'contact']) ?>
<?=$this->Form->input('name',[
'label' => false,
'placeholder' => 'Your Full Name',
'required' => true
]); ?>
<?=$this->Form->input('email',[
'label' => false,
'placeholder' => 'Your Email',
'type' => 'email',
'require' => true
]); ?>
<?=$this->Form->textarea('message',[
'placeholder' => 'Your message...'
]) ?>
<?= $this->Recaptcha->display()?>
<button>Submit Query!</button>
<?=$this->Form->end(); ?>
Using the following link I created Recaptcha:
https://github.com/agiletechvn/Recaptcha
Just beside the Submit button I have Recaptcha.
In the pageController I have the submit check happening:
if($this->request->is(['post']) && $this->request->data('form_type') == 'contact'){
$name = $this->request->data('name');
$email = $this->request->data('email');
$message = $this->request->data('message');
if(!$name){
$this->Flash->set('Please enter a name' . $name,['element' => 'error']);
} elseif (!$email || filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
$this->Flash->set('The email you entered is invalid',['element' => 'error']);
} elseif(!$message){
$this->Flash->set('Message cannot be blank',['element' => 'error']);
} else {
if($this->Recaptcha->verify()) {
$emailObj = new Email();
$emailObj
->from(['contactus#mydomain.com' => 'Developer'])
->replyTo([$email => $name])
->to(['contactus#contactus.com'])
->template('pages/contactus')
->viewVars([
'quickAction' => [
'description' => 'Contact form',
'action' => "from: $name"
],
'name' => 'contactus#mydomain.com',
'senderName' => $name,
'email' => $email,
'message' => $message
])
->subject('Contact email from ' . $name)
->send();
$this->Flash->set('Your message has been sent', ['element' => 'success']);
}
$this->Flash->error(__('Please pass Google Recaptcha first'));
}
If I click submit button I get:
Unexpected field 'g-recaptcha-response' in POST data
I moved the reCaptcha code outside the form. Everything works correctly but the captcha but is sitting outside some random location like this:
How do I solve this issue?
This message can show if you are using CakePHP Security Component, and this component does not recognize one of your form fields. You should unlock this field using:
$this->Form->unlockField('g-recaptcha-response');
More info: CakePHP 3.x Security Component
I've created a large form in Cake and set default options via inputDefaults. However I wish to change the default values for an individual field.
In setting the form defaults, I wrote approximately this:
'inputDefaults' => array(
'error' => array(
'attributes' => array(
'wrap' => 'span',
'class' => 'invalidate column-7 offset-3')));
...with the result that all like fields produce the same error message. But, when I attempt to change the defaults for a single field, like so:
echo $this->Form->input('name', array(
'error' => array(
'attributes' => array(
'wrap' => 'span',
'class' => 'invalidate column-10'))));
It doesn't work. The field name produces an error whose class reads column-7 and offset-3, whereas I'd intended column-10.
Anybody know a solution?
$options['inputDefaults'] You can declare a set of default options for input() with the inputDefaults key to customize your default input creation:
echo $this->Form->create('User', array(
'inputDefaults' => array(
'label' => false,
'div' => false
)
));
All inputs created from that point forward would inherit the options declared in inputDefaults. You can override the defaultOptions by declaring the option in the input() call:
echo $this->Form->input('password'); // No div, no label
// has a label element
echo $this->Form->input(
'username',
array('label' => 'Username')
);
I'm trying to create a custom magento extension.
It works, only 1 form field is not saved to the db.
public function saveAction()
{
if ($postData = $this->getRequest()->getPost()) {
$model = Mage::getSingleton('foo_bar/baz');
$model->setData($postData);
try {
$model->save();
Mage::getSingleton('adminhtml/session')->addSuccess($this->__('The baz has been saved.'));
$this->_redirect('*/*/');
return;
}
catch (Mage_Core_Exception $e) {
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
}
catch (Exception $e) {
Mage::getSingleton('adminhtml/session')->addError($this->__('An error occurred while saving this baz.'));
}
Mage::getSingleton('adminhtml/session')->setBazData($postData);
$this->_redirectReferer();
}
}
The form:
protected function _prepareForm()
{
$model = Mage::registry('foo_bar');
$form = new Varien_Data_Form(array(
'id' => 'edit_form',
'action' => $this->getUrl('*/*/save', array('id' => $this->getRequest()->getParam('id'))),
'method' => 'post'
));
$fieldset = $form->addFieldset('base_fieldset', array(
'legend' => Mage::helper('checkout')->__('Baz Information'),
'class' => 'fieldset-wide',
));
if ($model->getId()) {
$fieldset->addField('id', 'hidden', array(
'name' => 'id',
));
}
$fieldset->addField('name', 'text', array(
'name' => 'name',
'label' => Mage::helper('checkout')->__('Name'),
'title' => Mage::helper('checkout')->__('Name'),
'required' => true,
));
$fieldset->addField('stock', 'text', array(
'name' => 'stock',
'label' => Mage::helper('checkout')->__('stock'),
'title' => Mage::helper('checkout')->__('stock'),
'required' => true,
));
$form->setValues($model->getData());
$form->setUseContainer(true);
$this->setForm($form);
return parent::_prepareForm();
}
}
The value of the 'stock field is not saved'.
I checked that the column stock exist in the db and en name's are the same.
Does anyone know what I'm doing wrong?
Thanks in advance.
If you have added stock field after all the others it is possible that you only need to clear cache through admin System -> Cache Management (Flush Magento Cache and Flush Cache Storage buttons).
Magento likes to cache previous queries so adding new fields without clearing the cache can cause problems with new columns not being saved.
I've installed Miles Johnson's Uploader plugin and set it up with one of my models and got it working perfectly. Very nice.
Then I went and set it up on another model with almost identical code [the only difference is the upload path] and it won't work on the second model. When I submit the form the plugin doesn't seem to notice; I get an SQL error from an attempt to insert the POST file array straight into the DB.
Here is the code. [Other than this the plugin is imported in the bootstrap]
public $actsAs = array(
'Uploader.Attachment' => array(
'photo' => array(
'name' => 'formatFileName',
'uploadDir' => '/uploads/uses/img/',
'dbColumn' => 'photo',
'maxNameLength' => 30,
'overwrite' => true,
'stopSave' => true,
'allowEmpty' => false,
'transforms' => array(
array('method' => 'resize', 'width' => 240, 'dbColumn' => 'photo_thumb'))
)
),
'Uploader.FileValidation' => array(
'fileName' => array(
'extension' => array('gif', 'jpg', 'png', 'jpeg'),
'required' => true
)
)
);
This is on the model that is not uploading and the only difference is the uploadDir.
Does the plugin only work on one model? Any clues? thnx :}
Edit for extra clarity
Here is my view code:
echo $this->Form->create('Use', array('type' => 'file'));
echo $this->Form->input('Use.photo', array('type' => 'file'));
echo $this->Form->input('Use.desc', array('rows' => '3', 'label' => 'Description'));
echo $this->Form->end('Add to Gallery');
And here is my controller code:
public function add() {
if ($this->request->is('post')) {
$this->Use->set('user_id', $this->Auth->user('id'));
if ($this->Use->save($this->request->data)) {
$this->Session->setFlash('Your Use has been saved.');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('Unable to add your Use.');
}
}
}
The plugin doesn't work in only one model. You can add more uploader into your site.
The model seems to be good, I suggest you to see into your form to see if you have create the form in the right way into your view (is imporant to put into your form: 'type' => 'file'
example:
echo $this->Form->create('Product', array ('class' => 'form', 'type' => 'file'));
echo $this->Form->input('ModelImage.filename', array('type' => 'file'));
echo $this->Form->submit('Add Image', array('id'=>'add_image'));
echo $this->Form->end();
Or the problem is the name Use try to change the name with another
After checking thru the code with Alessandro [thank you :)] I found the problem.
If you look in the View and Controller code you can see that the model is named 'Use'. This was the problem, as Use is a loaded word in PHP and I shouldn't have used it for a model name.
I renamed the model to Outcome and now the Uploader works perfectly.
For some reason my allowed_values_function never gets called when showing a field on a user bundle. Code:
function get_business_units()
{
$options = entity_load('business_unit', FALSE, NULL, FALSE);
$opt = bu_to_list_values($options);
return $opt;
}
function MYMODULE_enable()
{
if (!field_info_field('field_user_business_unit')) {
$field = array(
'field_name' => 'field_user_business_unit',
'type' => 'text',
'settings' => array(
'allowed_values' => array(),
'allowed_values_function' => 'get_business_units',
)
);
field_create_field($field);
// Create the instance on the bundle.
$instance = array(
'field_name' => 'field_user_business_unit',
'entity_type' => 'user',
'label' => 'Business Unit',
'bundle' => 'user',
'required' => FALSE,
'settings' => array(
'user_register_form' => 1,
),
'widget' => array(
'type' => 'options_select',
),
);
field_create_instance($instance);
}
}
The field is created, and even displayed on the users "edit" page when editing their info. But the only value is "Select" or "None". My method is never called (I even placed a debug point). This is all in MYMODULE.install file.
The problem is: 'type' => 'text'.
You have to use: 'type' => 'list_text'.
Allowed values is meaningless for a text type.
Your get_business_units() function needs to be in the MYMODULE.module file; the .install files aren't included in a normal Drupal bootstrap.
Have you tried
drush features-revert MYMODULE ?