When I needed a conditional field for a Drupal 7 content type, of course I just googled "drupal conditional fields" to see if a module exists. One did exist, but its D7 release came with a big, red flag warning any would-be downloaders that it's not supported any longer and is vulnerable to security issues. Instead of risking it on the entrerprise-level website, I decided to code up a solution myself. And I would use JavaScript inserted by the PHP code. Easy!
Disclaimer: You should never "hack" your Drupal site. Primarily, what I mean by that is that you should never change any of the PHP code in the Drupal core modules and contributed Drupal modules (with the exception of community-tested code patches). The correct way to alter any of the PHP logic of a core or contributed module is to create a custom module that uses the "hook" functions provided by Drupal, such as the hook_form_alter() function demostrated in this article. Therefor, I'm not actually hacking Drupal and this is the preferred method for achieving my goal.
First, I needed a custom module. Actually, I already had one for this website, but it's a first step non-the-less for anyone following from home.
Second, I began inserting the basic boilerplate code:
/* * Implementation of hook_form_alter() */ function my_custom_module_form_alter(&$form, &$form_state, $form_id){ // blog nodes if ($form_id == "blog_node_form") { } }
Next, I began poking around and seeing what I could get away with. Sure enough, JavaScript inserted anywhere into the form would work just fine.
/* * Implementation of hook_form_alter() */ function my_custom_module_form_alter(&$form, &$form_state, $form_id){ // blog nodes if ($form_id == "blog_node_form") { $form['body'][LANGUAGE_NONE][0]['#description'] .= "<script>alert('hello world?')</script>"; } }
Now it was just a matter of forming the JavaScript code, which is JQuery 101. Here's what I came up with:
<script> jQuery( document ).ready(function() { // default is the second set of radio inputs are hidden because they're irrelevant jQuery('#edit-field-conversations-category').hide(); // but if the "conversations" input is checked, then the second set of radio inputs are now relevant so show them // first, check if it's already checked/selected when the page is loaded jQuery('#edit-field-blog-category .form-radio:checked').map(function(){ var value = this.value; if (value == 6166) { // 6166 is the Drupal TID for the "conversations" taxonomy term jQuery('#edit-field-conversations-category').show(); } }); // now, any time the blog category changes, see if it's the "conversations" one that is selected and act accordingly jQuery('#edit-field-blog-category .form-radio').change(function(){ var value = this.value; if (value == 6166) { jQuery('#edit-field-conversations-category').show(); } else { jQuery('#edit-field-conversations-category').hide(); } }); }); </script>
However, to inject it into the Drupal PHP framework, I needed to minimize it to get it all on one line and use the 'jQuery' variable name rather than '$'. I then put the un-minifed JS code in a comment block in case I needed to edit it later on.
So, all together, the whole thing looks like this:
// blog nodes if ($form_id == "blog_node_form") { // for Conversations with Dan Skinner, make a conditional taxonomy field $conditionalFieldsJS = 'jQuery(document).ready(function(){jQuery("#edit-field-conversations-category").hide(),jQuery("#edit-field-blog-category .form-radio:checked").map(function(){6166==this.value&&jQuery("#edit-field-conversations-category").show()}),jQuery("#edit-field-blog-category .form-radio").change(function(){6166==this.value?jQuery("#edit-field-conversations-category").show():jQuery("#edit-field-conversations-category").hide()})});'; /* * un-minified JS for above: * jQuery( document ).ready(function() { // default is the second set of radio inputs are hidden because they're irrelevant jQuery('#edit-field-conversations-category').hide(); // but if the "conversations" input is checked, then the second set of radio inputs are now relevent so show them // first, check if it's already checked/selected when the page is loaded jQuery('#edit-field-blog-category .form-radio:checked').map(function(){ var value = this.value; if (value == 6166) { jQuery('#edit-field-conversations-category').show(); } }); // now, any time the blog category changes, see if it's the "conversations" one that is selected and act accordingly jQuery('#edit-field-blog-category .form-radio').change(function(){ var value = this.value; if (value == 6166) { jQuery('#edit-field-conversations-category').show(); } else { jQuery('#edit-field-conversations-category').hide(); } }); }); */ $form['body'][LANGUAGE_NONE][0]['#description'] = "<script>" . $conditionalFieldsJS . "</script>"; } }