How to add span tag in to Drupal webform element label? - drupal

I am trying to style my webform checkboxes and radio buttons differently. For this reason I want to insert span element in to the label and use it instead of original checkboxes.
Found this module : https://www.drupal.org/project/webform_optionsmarkup , but non of the listed options appear in my webform field settings.
Does any body know good solution to accomplish this ?
function bigdaddy_preprocess_webform_element(&$variables) {
if ($variables['element']['#type'] == 'textfield' || $variables['element']['#type'] == 'textarea') {
$variables['element']['#title_display'] = 'after';
}
if ($variables['element']['#type'] == 'checkboxes') {
foreach ($variables['element']['#options'] as $key => $one) {
$variables['element']['#options'][$key] = "<span>jpnas</span>" . $one;
}
}

I was able to achieve what you want by using the hook_form_alter() function. In my module's .inc file, I created a function like MY_MODULE_form_alter. I'll share my code...
function MY_MODULE_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'MY_FORM_ID') {
foreach($form['ELEMENT_#NAME']['#options'] as $key => $value) {
// $form['ELEMENT_#NAME'][$key]['#theme_wrappers'] = array();
$form['ELEMENT_#NAME'][$key]['#prefix'] = '<span>jpnas</span>';
$form['ELEMENT_#NAME'][$key]['#suffix'] = '<span>jpnas</span>';
}
}
}
If you want to place the span before the checkbox, use ['#prefix'].
Obviously replace MY_MODULE with the name of your module, MY_FORM_ID with your actual $form_id name, and ELEMENT_#NAME with the name of the form element you want to alter. Remember you can do a var_dump($form) if you need to see any of these values. I am doing pretty much the same thing it sounds like you would like to do, except I am not putting this into my label as I haven't found a way to attach directly to the label. The input element on the other hand is a different story. Furthermore, if you uncomment the first line in the loop, the wrapper will be removed from around each checkbox, but it will take with it the label. You can then add the label yourself along with your own wrapper element using #prefix and #suffix accordingly.

Related

How to prevent Drupal 7 from converting & to &

I'm adding placeholder to search form like this:
$form['search_block_form']['#attributes']['placeholder'] = ' Search';
But problem is that drupal is printing & sign as & so in HTML output
for placeholder attribute instead of:
placeholder=" Search"
I'm getting:
placeholder="&#xf002; Search"
How to prevent this behavior or is there another way to print that character by it's hex value? Tried using:
[] and decode_entities('') and some other functions, but none of them helped.
I think you were close with decode_entities(), but you could try the PHP function html_entity_decode().
However, unless the field you are trying to add the place holder to is called 'search_block_form', I think it is your construct which is wrong.
If you are doing this is a hook_form_alter() (which you should be if you are writing it like this) and the field you want to add the placeholder to is called "my_text_field", then the function should look for like this:
function custom_module_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'custom_form') {
$form['my_text_field']['#attributes']['placeholder'] = html_entity_decode(' Search');
}
}
Just remember to replace 'custom_form' with the real ID of your form and 'my_text_field' with the name of your field you want to alter.
/**** EDIT ****/
Finally understood what you are trying to do. To get this working on my site I had to lay my form item out like this:
$form['test'] = array(
'#type' => 'textfield',
'#attributes' => array(
'placeholder' => html_entity_decode(''),
'style' => array('font-family: Arial, FontAwesome;'),
),
);
The important thing to add is the style attribute of font family and make sure it includes FontAwesome.
So the above example for you would become:
function custom_module_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'custom_form') {
$form['my_text_field']['#attributes']['placeholder'] = html_entity_decode(' Search');
$form['my_text_field']['#attributes']['style'] = 'font-family: Arial, FontAwesome;';
}
}
Not sure how you have added the JS for Font Awesome, but I added it in a page alter using drupal_add_js() so that I could make sure it only get loaded on the pages its required.
Let me know how that works out for you, and don't forget the flush your caches too!

Drupal: force regions to always render?

I'd like to always render all regions. Even if they don't contain any blocks.
I render my regions like this (in page.tpl.php):
<?php print render($page['region_name']); ?>
Here's the code I'm using, but this has no effect.
function theme_name_page_alter(&$page) {
$regions = system_region_list($GLOBALS['theme'], REGIONS_ALL);
foreach ($regions as $region => $name) {
if(empty($page[$region])) {
$page[$region] = array();
}
}
}
You can make sure Drupal renders every region with the following code (in a custom module):
function hook_page_alter(&$page) {
foreach($page as $region => $blocks) {
if(is_array($blocks) && in_array($region, array('region_1', 'region_2', 'region_3'))) {
if(count($blocks)==1) {
$page[$region]['phantom_content']['#markup'] = ' ';
}
}
}
}
You will need to replace region_1, region_2, region_3 with the names of your regions that you want to make sure are always rendered.
To explain the code a little, if the count of the blocks array is 1 then it means it is empty as it will always contain the #sorted attribute.
It's not just that you don't have any blocks assigned to that region, but almost certainly because the render array is empty. Keep in mind what the render function does-- it calls drupal_render on any/all elements & children in the render array, which converts them to an html string for output. If there are no renderable elements, it doesn't return any html.
The correct (programmatic) way of rendering these regions would be to define a render array for each region, setting the #markup element to whatever html you want Drupal to output there. This would have to be done in your custom module.
If you need to do this from the gui only, I don't see any way other than defining a phantom block. In which case you should probably re-consider what it is you're trying to accomplish.
I think the answer lies in the region.tpl.php file and associated template_preprocess_region() function.
The template file checks that there is a valid variable called $content available, which is loaded up from the preprocess function. If that $content array is empty, the condition will fail and no markup will be rendered (which will happen if the region contains no blocks).
Try adding a copy of region.tpl.php to your theme, removing the if ($content): condition, and then flushing Drupal's cache.

Adding space to select option in form alter

I have taxonomy terms hierarchy and I am using them as a filter in a view. It is showing hierarchy in the selectbox, but child terms appearing with hyphen(-). I have tried to drop hyphen in form alter, and I did, but I couldn't replace it blank space.
if ($form_id == 'views_exposed_form') {
$i = 0;
foreach ($form['field_region_tid']["#options"] as $op) {
foreach ($op->option as $key => $arr) {
if ($arr != null) {
$form['field_region_tid']["#options"][$i]->option[$key] = str_replace("-"," ", $arr);
}
}
$i++;
}
}
How can I put blank space at the beginning of the child options. Or should I do some other way?
Thanks!
From the form_id I get that it is a form generated by views. If so, the code inside the if condition never gets called because your module is executed after the views module due to the weight of both modules. To fix that:
Open your database manager (PhpMyAdmin in most cases) and open system table.
Then change the weight for your module to something larger than 10, because it is the default weight for the views module and you need you module to be executed after the views module.
Hope this helps... Muhammad.
if the problem is when your hook is called the answer lies in
hook_module_implements_alter()
but it is not as you say. Your code looks fine,
Have you tried
str_replace("-"," ", $arr);
?

How can I get the title of a form element in Drupal?

For example, in the registration form, there is "Username" and the text field for it which has the input type="text" name="name" ....
I need to know how can I get the title from the input field's name.
I'm expecting a function like:
$title = get_title_for_element('name');
Result:
assert($title == 'Username'); // is true
Is there something like this in Drupal?
Thanks.
You have the form and the form state variables available to your validation function. You should use form_set_error() to set the error.
There is no function that I am aware of which will map from the values array to the form array. But it is not dificult to work it out. Understanding the form data structure is one of the key skills you need when building drupal.
In this case the form in question is generated (in a roundabout way) by user_edit_form, you can see the data structure in there.
$form['account']['name'] is the username field. and the array key for the title is '#title' as it will be in most cases for form elements.
You can do it in two different ways as I see it. Let's create a module called mycustomvalidation.module (remember to create the mycustomvalidation.info file also).
Note: The code below has not been tested, so you might have to do some minor adjustments. This is Drupal 6.x code by the way.
1) Using hook_user()
What you need is a custom module containing your own implementation of hook_user() http://api.drupal.org/api/function/hook_user/6.
<?php
function mycustomvalidation_user($op, &$edit, &$account, $category = NULL) {
if ($op == 'validate') {
// Checking for an empty 'profile_fullname' field here, but you should adjust it to your needs.
if ($edit['profile_fullname'] != '') {
form_set_error('profile_fullname', t("Field 'Fullname' must not be empty."));
}
}
}
?>
2) Using form_alter() and a custom validation function
Personally, I would go for this option because I find it cleaner and more "correct". We're adding a custom validation function to our profile field here.
<?php
function mycustomvalidation_form_alter(&$form, $form_state, $form_id) {
// Check if we are loading 'user_register' or 'user_edit' forms.
if ($form_id == 'user_register' || $form_id == 'user_edit') {
// Add a custom validation function to the element.
$form['User information']['profile_fullname']['#element_validate'] = array('mycustomvalidation_profile_fullname_validate');
}
}
function mycustomvalidation_profile_fullname_validate($field) {
// Checking for an empty 'profile_fullname' field here, but you should adjust it to your needs.
if ($field['#value'] != '') {
form_set_error('profile_fullname', t("Field %title must not be empty.", array('%title' => $field['#title']));
}
}
?>

How do I alter the #weight of the content generated by the upload.module?

On my Drupal powered website, I want to list available downloads at the top of a node page (within a narrow float:right <div>), not at the bottom where they normally appear.
Within my theme, I've overridden the theme_upload_attachments() function to generate a <div> of width 40%, but this is showing up at the bottom of the page.
Within the upload.module file is code that controls where the attachments are listed on the page:
// function upload_nodeapi(), line #284 of upload.module
$node->content['files'] = array(
'#value' => theme('upload_attachments', $node->files),
'#weight' => 50,
);
If I manually hack this #weight to -1, my custom list of attachments shows where I want, floating at the righthand side of the top of the content area.
However, I don't want to manually hack the core file upload.module, as my changes will be lost next time I apply an upgrade (say, for a security patch).
How/Where do I modify the #weight of content['files'] within my theme code?
Or, am I going about this the wrong way?
You'll need a module to do this, not just a theme. A module can implement hook_nodeapi(), which will give it a chance to change the contents of that $node->content array before it's rendered. If your module is named 'upload_tweaker' for example, you'd use the following function:
function upload_tweaker_nodeapi(&$node, $op) {
if ($op == 'view') {
$node->content['files']['#weight'] = -1;
}
}
Each module gets a crack at changing the node during this 'nodeapi' event; if you want to change the stuff that's added by one module, you need to make sure that your module loads after it. This can be done by naming it something like 'zzz', or by changing its "weight" field in the system table of your site's database. Modules can be weighted just like form elements.
api.drupal.org has more information.
For those who uses CCK and want to alter body weight:
CCK module uses pre_render function
/**
* Pre-render callback to adjust weights of non-CCK fields.
*/
function content_alter_extra_weights($elements) {
if (isset($elements['#content_extra_fields'])) {
foreach ($elements['#content_extra_fields'] as $key => $value) {
// Some core 'fields' use a different key in node forms and in 'view'
// render arrays. Check we're not on a form first.
if (!isset($elements['#build_id']) && isset($value['view']) && isset($elements[$value['view']])) {
$elements[$value['view']]['#weight'] = $value['weight'];
}
elseif (isset($elements[$key])) {
$elements[$key]['#weight'] = $value['weight'];
}
}
}
return $elements;
}
So due to this callback you are not able to alter weight using normal behavior.
You should do this:
function YOUR_MODULE_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
// Only for node pages.
if ($op == 'view' && $a4) {
$body_weight = 15 // Any weight.
$node->content['#content_extra_fields']['body']['weight'] = $body_weight; // This value CCK module will use to alter body weight in the callback from above.
}
}

Resources