Hiding a text input without making it `type="hidden"` - cakephp

What I have
I'm using the FormController to create inputs. A specific input will be frequently updated by Javascript for internal purposes and I want it hidden. In this case, I can't use type="hidden", instead it needs to be type="text" so that it won't be checked by the form tampering prevention when submitted.
What I tried
Adding 'hidden' => true to $this->Form->create() options works if the whole form needs to be hidden. That exact attribute doesn't seem to be working for individual inputs though, created using both $this->Form->input() and $this->Form->control()
For a specific input, first thing that comes to mind is adding 'style' => 'display:none' to its options, but that does not seem like a clean CakePHP-way solution
I think I've seen someone mention a way to do exactly that here. I think it was an attribute you'd add to the options. I searched around my answers and comments, using both this site and Google, but found nothing.
Please advise!

You can create a hidden input and make it exempt from form security in case required, either by unlocking the field via the unlockField() method:
$this->Form->unlockField('field_name');
echo $this->Form->hidden('field_name');
or by passing false or 'skip' for the secure option:
echo $this->Form->hidden('field_name', ['secure' => false]);
echo $this->Form->hidden('field_name', [
'secure' => \Cake\View\Helper\FormHelper::SECURE_SKIP
]);
See also
Cookbook > Views > Helpers > Form > Working with SecurityComponent > unlockField()

Related

No way to disable search in Antd 3.x Select component(even when showSearch prop is set to false)

I am using Select component from Antd 3.x library with mode="multiple" and other options as shown in codesandbox link below. The Search is not disabled even when setting showSearch={false}
Now, I can't upgrade to Antd 4.x. The issue is when I use Axe Accessibility tool on my web app, it complains about an extra "Input" in my Select, which doesn't have aria-label set. If I manually set it in chrome console, all is fine
Is there a way to work around this situation either by removing search field(not sure how?) or someway to set the aria-lable of the input to something like aria-lable="search"?
codesandbox link
TIA
You can use filterOption to control your option list.
In my case, my options's value is a list of accounts, which will change every times I input keyword. Option's value is account.id and label is account.name.
filterOption, set it () => true (that means, all of options are OK).
onSearch, I call API to request new list of accounts, which meet with my keyword.
But in your case, I think, set filterOption to () => true will solve your problem.
Hope you solve with my solution!

Problem with output from the database yii2

I have in the database the path to the files that i want to get outputed.
like:
<audio src="/yii2-biblioteca/frontend/web/uploads/audio/lya1.mp3" controls type="audio/mpeg">
and i am using:
<?=HtmlPurifier::process($model->audio)?>
for the output.
I used the same thing for images and it's ok, it works, but for the audio and for the pdf embed not so much.
At the beginning the pdf worked, i changed some things with a js funtion, it was not suppos to have a negative impact. I reversed all back to when it was good, but it's not working now.
the pdf exemple: <embed src="/yii2-biblioteca/frontend/web/uploads/pdf/dying.pdf" type="application/pdf" width="100%" height="100%" />
Yii2's HTMLPurifier wrapper takes a second argument:
echo HtmlPurifier::process($html, [
// options go here
]);
For <embed>, you should be able to use the HTML.SafeEmbed setting:
echo HtmlPurifier::process($html, [
'HTML.SafeEmbed' => true,
]);
Unfortunately, for <audio>, the underlying problem here is that HTML Purifier isn't HTML5-aware, which is going to make adding that a lot more complicated.
There are user-supplied patches to allow HTML Purifier to understand HTML5, but as far as I know, none has been audited and so it's hard to say what this will do to the security of your site. (Arguably, HTML Purifier with userland supplied HTML5 definitions is still better than no HTML Purifier at all, though.)
I've given some rough instructions about how to make HTML Purifier (the library itself, not its Yii2 wrapper) aware of only the <audio> tag over on another question. Quoting the relevant pieces:
You'll have to look at the "Customize!" end-user documentation, where it will tell you how to add tags and attributes that HTML Purifier is not aware of.
To quote the most vivid code example from the linked documentation
(this code teaches HTML Purifier about the <form> tag):
Time for some code:
$config = HTMLPurifier_Config::createDefault();
$config->set('HTML.DefinitionID', 'enduser-customize.html tutorial');
$config->set('HTML.DefinitionRev', 1);
$config->set('Cache.DefinitionImpl', null); // remove this later!
$def = $config->getHTMLDefinition(true);
[...]
$form = $def->addElement(
'form', // name
'Block', // content set
'Flow', // allowed children
'Common', // attribute collection
array( // attributes
'action*' => 'URI',
'method' => 'Enum#get|post',
'name' => 'ID'
)
);
$form->excludes = array('form' => true);
Each of the parameters corresponds to one of the questions we asked. Notice that we added an asterisk to the end of the action attribute to
indicate that it is required. If someone specifies a form without that
attribute, the tag will be axed. Also, the extra line at the end is a
special extra declaration that prevents forms from being nested within
each other.
Once you've followed those instructions to make your purifying routine
aware of <audio>, adding the tag <audio> to your configuration
whitelist will work.
So, in brief, if you want to be able to purify just <audio> tags without losing them altogether, you're going to have to do some research on the tags' capability and add the information to HTML Purifier.
You could base your code on what you can find in xemlock/htmlpurifier-html5's HTML5Definition.php file if you don't want to work on it from scratch.

TinyMCE: cake php plugin [ cannot submit form ]

I use https://github.com/CakeDC/TinyMCE to download plugin and did follow all the step to integrate on my cakePHP project. so right now, all the textarea was successfully changed to tinyMCE editor
But when click "SUBMIT" to submit my form, page cannot submit and post data. Without loading editor my form can submit and post data.
Is any jquery problem ? please advise me.
thank you.
Bootsrab.php
CakePlugin::load('TinyMCE');
Configure::write('TinyMCE.editorOptions', array('width' => '500px','height'=>'250px' ));
Controller:
public $helpers=array('Html','Form','TinyMCE.TinyMCE');
View:
$this->TinyMCE->editor(array('theme' => 'advanced', 'mode' => 'textareas'));
echo $this->Form->input('user_requirements',array('required'=>true) );
Layout : default
loding js file:
echo $this->Html->script(array('ddsmoothmenu','jquery-1.7.1.min','jquery-ui-1.8.17.custom.min'));
You've set the field to be required, so the problem you are experiencing is probably the browser based form validation.
The problem is that the validation applies before TinyMCE injects the contents into the textarea, and so the validation will always fail as the textarea is empty. This is a very long known "bug" btw:
http://www.tinymce.com/develop/bugtracker_view.php?id=4768
http://www.tinymce.com/develop/bugtracker_view.php?id=5671
In Firefox you might notice a validation bubble that appears "behind" the browser in the bottom left corner of the screen, and in Chrome for example it would throw the following error: "An invalid form control with name='...' is not focusable".
The quick and dirty fix would be to set required to false. In order to keep the required class on the generated container div you would have to set this manually using the div option:
'div' => array('class' => 'input text required')
It's also possible to disable browser validation completely by defining the novalidate attribute on the form:
$this->Form->create('ModelName', array('novalidate' => true));
or using the formnovalidate attribute on the submit button:
$this->Form->submit('Submit', array('formnovalidate' => true));
Theoretically it would also be possible to listen to the invalid event and display custom validation bubbles, but the problem here is that the browser behavior is not consistent, ie in Chrome it's not possible to validate invisible (using display or visibility) fields. Also the content would still be missing in the textarea field.
What seems to work is using opacity to hide the field, that way one could position the textarea under the editor, and the validation bubble would be displayed correctly. However that would also require to inject the editor contents in the textarea manually when pressing Enter and when clicking the submit button (or probably even simpler using proper editor change events). I'll see if I can come up with an example for this later on.
Update: I've implemented a fix/workaround in form of a TinyMCE 4.x plugin, as this was bugging me in some of my own applications too, see https://github.com/ndm2/tinymce-validatable

Cakephp forms - Is there a way to make a field read only (in the view)

I have a Cakephp 1.3 form that allows users to edit the profile data. But some of the information in the forms needs to be read only (sometimes).
Is my only option to echo and format the field contents in the read only case or is there a flag in the Cake form that allows for read only fields. Ideally the read only fields would be greyed out similar to other interfaces.
echo $this->Form->create('User', array('url' => array('controller' => 'User', 'action'=>'editUser')));
echo $this->Form->input('id', array('type'=>'hidden'));
If (!isset($IsAdmin)) {
// Only display username - read only! Add code here
echo $this->Form->input('username', array('label' => __d('users', 'User',true)));
} else {
// Admins can edit user names
echo $this->Form->input('username', array('label' => __d('users', 'User',true)));
}
... more fields here
echo $this->Form->end(__d('users', 'Submit',true));
You can add a 'disabled' key to the options array, however realise that this is only the front-end/presentation of the form, people will be able to override the 'disabled' property of the input field and modify its value.
To prevent unwanted changes to be saved, you need to specify a 'fieldList' when saving the data using your model
To output a disabled form field;
echo $this->Form->input('fieldname', array('type'=>'hidden', 'disabled' => 'disabled'));
Then, when saving the data, specify a fieldlist (documentation: http://book.cakephp.org/1.3/en/The-Manual/Developing-with-CakePHP/Models.html#saving-your-data)
$this->MyModel->save($this->data, true, array('field1', 'field2'));
The fieldlist should include all fields that are allowed to be updated by the user
The disabled attribute is fine but actually, input fields have a 'readonly' attribute. And it sounds like you want the field to still be shown to the user so using 'hidden' isn't really addressing what you want done.
So an alternative (and actually specifically addressing your requirement for 'read only'):
echo $this->Form->input('fieldname', array('readonly' => 'readonly'));
I found that using disabled prevents jquery click triggers from firing versus readonly still fires e.g. using a bootstrap datepicker text field
Here's a link to WC3 for it: http://www.w3schools.com/tags/att_input_readonly.asp
if you really want to make a field read only why you want to use form field, just echo the value, one can easily change disable or readonly attribute of form field with simple javascript or firebug.
Okay, after having tried several approaches, here is what I like.
1) Use readonly (disabled will remove the value after hitting "save", when you are in update mode, which sucks):
echo $this->Form->input('email', array('readonly' => 'readonly'));
2) To prevent this from updating when removing 'readonly' via browser plugins, you can add this to beforeSave of your model:
if(isset($this->data[$this->alias]['id'])) // id is only set if we update
{
unset($this->data[$this->alias]['email']);
}
Field lists are not comfortable. Why should I add all the fields, when I actually only want to exclude one?
Unsetting will prevent CakePHP from updating it in the database. Of course, after hitting save with an (invalidly) updated e-mail address, this update will be shown in the form once. But as the user has manipulated the HTML form and since the database field stays unchanged, this should not matter.
You can do either of two things:
Make the field hidden
(Ex. echo $this->Form->input ('username, array ('type' => 'hidden'));
Reset the value of username to it's original value, before submitting the form or possibly in beforeSave.

CakePHP form helper - change value of hidden input for checkbox/radio

Using CakePHP's form helper to generate a checkbox is easy enough; to use the example from the documentation:
echo $this->Form->checkbox('done',array('value' => 555));
This will produce the following HTML:
<input type="hidden" name="data[User][done]" value="0" id="UserDone_" />
<input type="checkbox" name="data[User][done]" value="555" id="UserDone" />
This is all well and good, and the hidden field serves to force submission of a value for the "done" field even if the box remains unchecked.
Now, for the sake of argument, let's say the database definition of this field is ENUM('yes','no'). Of course I can easily change the value of the checkbox to "yes". However, if it's unchecked, a value of "0" is submitted from the hidden element. This produces no error or warning from mysql, as 0 is always a legal value for an enum field; it appears as an empty string.
Can I change value of the hidden field that CakePHP generates (to "no"), or do I need to suppress the auto-generation and create the hidden field myself? (An annoyance that grows with the number of checkboxes.)
I believe this all applies to radio button groups, too—at least if they don't have a default selection.
I'm using CakePHP 1.3. Thanks.
With FormHelper::checkbox, you can use hiddenField to set the default value.
<?php echo $this->Form->checkbox('done', array('value'=>'yes', 'hiddenField'=>'no');?>
With FormHelper::radio, you can only set value to default to one of the options, if the values match. This will also suppress the hidden field.
<?php echo $this->Form->radio('done', array('yes' => __('Yes')), 'no' => __('No'), array('value'=>'no');?>
Also, you should remember that CakePHP does not support enums (and I am sure this sort of scenario is one reason)
If your field data is truly binary (yes/no true/false enables/disabled etc.) then for the sake of CakePHP conventions you should just use an int(1) or tinyint(1) field and then convert the boolean value to yes/no etc in the view.
Then you don't have to worry about creating your own hidden input values and disabling the generated hidden inputs.
Another option would be to override the form->helper checkbox method that gets called by form->input to accept a new key in the options array that sets the value to something other than a 0 / false.
Unfortunately, FormHelper::checkbox allows you to disable the hidden element, but not to select its value, so you will need to do so and create the hidden field yourself. For example:
<?php echo $this->Form->hidden('done',array('value'=>'no'))?>
<?php echo $this->Form->checkbox('done',array('value'=>'yes','hiddenField'=>false))?>
With FormHelper::Radio worked for me like that
echo $this->Form->radio(
'done',
['yes' => __('Yes'), 'no' => __('No')],
['hiddenField' => false]
);

Resources