Adding style to CakePHP automatically created input div - css

CakePHP creates a div that automatically wraps any of its input tags that are built with the formhelper as followed:
$this->formhelper->input('something');
Such that the output looks about as followed:
<div class='input'>
<input />
</div>
I know that there is a way to add classes to the input tag i.e.
$this->formhelper->input('text', array('class' => 'some_css'));
But how would you add a style to the div that is automatically created by CakePHP. This might be something where the core needs to be hacked, but I want to know if there is a better way to do this, so that I get something as followed:
<div class='input other_class_I_want_here'>
<input />
</div>
Thank you to anyone who can help.

Simply add a new class to the div.
$this->formhelper->input('text', array('div'=>array('class'=>'divClass'),'class' => 'some_css'));
should actually output
<div class='input divClass'>
<input class='other_class_I_want_here' />
</div>

The above answer is certainly correct. And works beautifully if you only require adding a class in a one (or a few) specific locations.
However, anyone arriving here looking for a way to add a class to input div wrappers application-wide (ex: if you're using a front-end framework which often requires a specific class name be added to input wrappers to enable auto-styles) there is a MUCH better solution. That being, a custom FormHelper.
In the App/View/Helper directory create and save a file "MySuperCoolFormHelper.php"
Place the following code in the file:
App::uses('FormHelper', 'View/Helper');
class MySuperCoolFormHelper extends FormHelper {
protected function _divOptions($options) {
if(isset($options['div'])
$options['div'] .= ' class1 class2 class3'; //note the prefixing space
else
$options['div'] = 'class1 class2 class3';
return parent::_divOptions($options);
}
}
To use this new form helper globally, add the following code to your AppController:
public $helpers = array(
'Form' => array(
'className' => 'MySuperCoolFormHelper'
)
//The rest of your helper inits
);
... and BLAMMO you're done!

CakePHP 3:
For applying 'form-group' to DIV and 'form-control' to the input field
<?=
$this->Form->control('year', [
'type' => 'select',
'value' => $year,
'options' => $years,
'label' => false,
'class' => 'form-control',
'templates' => ['inputContainer' => '<div class="form-group">{{content}}</div>']
]);
?>

Related

How can I add css classes to specific symfony2 form choices?

I could do this with Javascript, but I was wondering if I could add a css class to specific symfony2 form choices (not the choice field itself, but the individual choices).
For example I want to apply different css styles to individual 'option' tags inside a 'select'. I could only find a way to add a class to the tag.
Thanks in advance.
I think you can simply do:
{{ form_widget(form.name, { 'attr' : { 'class' : 'myClass' } }) }}
... as explained here, without creating your own form style.
You can override the layout of specific widgets in your form, which means you can override the way the select renders and put in custom code to check what the value of the option is and output your custom class there.
You need to apply a custom layout to your form, like so
{% form_theme form 'form_theme.html.twig' %}
Then inside the layout file you need to override the specific field for that specific form (unless of course you want to edit the choice_widget directly in which case all fields that use choice will have the functionality).
To do that you have to copy the widget, so choice_widget, then name it [_formName_fieldName_widget]
So if your form name was events and your field name was requireTickets, it'd be _events_requireTickets_widget
The answers that were already provided are very good, and I think #CriticalImpact's is the most flexible. But I just wanted to mention that if you're using a form class, you can also add extra attributes to the field via the form builder definition itself:
class SomeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('someField', "text", array("attr" => array("class" => "someCssClass")))
->add("save", "submit");
}
}
I've found this helpful for basic forms, because it still allows you to make a simple {{ form(someForm) }} call in your Twig file.
(Note that this solution still has the drawback that #CriticalImpact mentioned above)
Add attributes like CSS styles to individual choices can nowadays be achieved with choice_attr, e.g.:
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add('attending', ChoiceType::class, array(
'choices' => array(
'Yes' => true,
'No' => false,
'Maybe' => null,
),
'choice_attr' => function($val, $key, $index) {
// adds a class like attending_yes, attending_no, etc
return ['class' => 'attending_'.strtolower($key)];
},
));

Magento: add icons to the menu-links in your Account-dashboard

Is it possible to add icons to all/some of the menu-links in your account-dashboard? Is there a node/style-attribute in the layout XML-file that should come with the addLink-action?
<action method="addLink" translate="label" module="randomname"><name>randomname</name><path>randomname/index/credits</path><label>Credits</label></action>
You have your default Account Dashboard, Account Information, Addresses, My Orders,... menu-items, but I added a new one; "Credits", and I want to make it "pop" out with an icon and/or another background-color. Couldn't figure out how to do it so far.
Thanks!
EDIT:
Ok, I've found out that there's no parameter to set a css class or id in the addLink() function:
public function addLink($name, $path, $label, $urlParams=array())
{
$this->_links[$name] = new Varien_Object(array(
'name' => $name,
'path' => $path,
'label' => $label,
'url' => $this->getUrl($path, $urlParams),
));
return $this;
}
Now you have two options to add icons to the links. 1. Overwrite the Mage_Customer_Block_Account_Navigation Block Class within your own module and extend the addLink method or 2. you could set the css class/id via jQuery. Good Luck!

Autocomplete without using a callback

I want to use autocomplete-fields that link to an external source for their autocomplete-data. Drupal seems to refuse all autocomplete_paths that are not reachable within Drupal. Any ideas how to circumvent that problem? The form field looks like that:
$form['business_city'] = array(
'#type' => 'textfield',
'#size' => 30,
'#title' => t('city'),
'#autocomplete_path' => '_/city?=',
'#default_value' => $userProfile->field_address_business_city[0]['value'],
);
_/city is not reachable within Drupal for performance reasons. The script bootstraps Drupal up to session-level to check for a valid login.
UPDATE:
If I create an autcomplete-field by attaching the needed markup manually to the field it works but it is awkward to maintain:
'#attributes' => array('class' => 'form-autocomplete'),
'#suffix' => '<input type="hidden" disabled="disabled" value="/_/city?n=" id="edit-private-city-autocomplete" class="autocomplete">',
Instead of hacking, you could make sure that the path you are querying "/_/city?n=" is a valid menu_hook item. That way it will validate against the drupal_valid_path() inside theme_textfield(). From within the menu hook function callback you could then forward the request to your external data source.
Drupal 6 validates in theme_textfield() if the autocomplete path is a valid (internal) path.
So, you can't work around this unless you override that theme function.

Add CSS attributes to Symfony form labels?

I try to add some css attributes to labels in my custom sfForm but I can't achieve it.
In my custom class myForm extends sfForm, I create all textfields dynamically:
public function configure()
{
$widgetFixtures = array();
foreach ($fixtures as $fixture) {
$widgetFixtures[$fixture->getId()] = new sfWidgetFormInputText(
array('label' => $fixture->getTeamNameDom()),
// I would like to add something like: array('class' => $fixture->getCSS()),
array('value' => $fixture->getScore1(), 'readonly' => 'readonly')
);
}
$this->setWidgets($widgetFixtures);
}
I tried to format the rendering with setFormFormatterName but without success.
Note: I can't use renderLabel($value, $attributes = array()) in the template because I get the CSS class from the DB (as you may have seen, I have to use: $fixture->getCSS()).
Could someone shed my light?
Many thanks.
Here is how I solved it.
I took both suggestions from johnwards and richsage and put them together :
"This sort of stuff should be handled in the view/action."
"Access to the options/attributes passed to the Widget itself."
First, I add the CSS class to the input itself (even if I will not use it).
In my custom class myForm extends sfForm,
foreach ($fixtures as $fixture) {
$widgetFixtures[$fixture->getId()] = new sfWidgetFormInputText(
array('label' => $fixture->getTeamNameDom()),
array('value' => $fixture->getScore1(),
'readonly' => 'readonly',
'class' => $fixture->getCSS())
);
}
Then, in the template, instead of using echo $form;, I add the CSS class to the label as shown below:
foreach ($form as $widgetId => $widget) {
...
$labelClass = $widget->getWidget()->getAttribute('class');
echo '<td>'.$widget->renderLabel(null, array('class' => $labelClass)).'</td>';
...
}
Maybe it is not the best way to solve this issue but it works.
Thanks all for your feedback!
What you're trying to do seems possible but your greyed out syntax seems a little off. Try this:
$widgetFixtures[$fixture->getId()] = new sfWidgetFormInputText(
array('label' => $fixture->getTeamNameDom()),
array('class' => $fixture->getCSS()),
array('value' => $fixture->getScore1(), 'readonly' => 'readonly')
);
... or check "The sfWidgetForm Base Class" section here: http://www.symfony-project.org/forms/1_4/en/A-Widgets
The class attribute needs to be passed in as an array in the second parameter for all form widgets.
$this->setWidget('foo', new sfWidgetFormInputText(array(),array('class','fooclass'));
You could try overriding the widget class if you want to add CSS to labels - specifically the methods that render the label. You could then do something like
$foo = new myWidgetFormInputText(array("myCSSClass" => $fixture->getCSS()));
and then override your renderLabel() method or similar in your widget. Your widget will have access to the options you pass in - in the above example myCSSClass is the option key. You can then apply this class value to your widget's label.
It's much easier than that. Just apply CSS to the label for tag...
label[for=payment_cardNumber]
{
margin-top: 20px;
color: red;
}

including javascript function in .module file in drupal

on click of button i want hi message to be displayed using javascript in drupal.I have made a .js file and know that to incude that i must use drupal_add_js(drupal_get_path('module', 'document') .'/click.js'); but the problem is to create button i used $form['click'] = array(
'#type' => 'button',
'#attributes' => array('onclick' =>drupal_add_js(drupal_get_path('module', 'document') . '/cancel.js')),
'#value' => t('click'),
);
I want that hi message which i have included in js file to be shown when button is clicked.
Please help
Hi thanx for your concern..........
here is the way i proceeded in .module file
function document_form(&$node) {
$form['click'] = array(
'#type' => 'button',
'#attributes' => array('onclick' =>message()),
'#value' => t('click'),
);
}
function document_form_alter(&$form, &$form_state, $form_id) {
drupal_add_js(drupal_get_path('module', 'document').'/cancel.js', 'module');
$settings['click'] = array(
'nid' => $form['nid']['#value'],
'cid' => $form['cid']['#value'],
'uid' => $form['uid']['#value'],
'pid' => $form['pid']['#value'],
);
drupal_add_js($settings, 'setting');
}
and my .js file code is as follows:
function message()
{
alert("This alert box was called");
}
<body>
</body>
but still onclick of button i m not getting the message "This alert box was called"
Kindly help where the problem is coming now.......
Thanx in advance....
in wait of your response
The form alter won't add the JS file in the way you are wanting.
In the function you create the form you can use drupal_add_js, outside of the creation of the form array.
Then you can use the onclick to call the function in your JS file.
A better way to do this is to use drupal behaviours to add an click listner to the button (see example here).
Looks like simplest solution would be, as you actually don't need the button to go to submit and other form stuff.
add a link to the text
style the the link as button using css .mybuttons{}
hook the js on the id. $(#mybutton1).alert..

Resources