1

I'm a bit lost with this and could do with some help from a Drupal JS veteran.

In my module I'm dynamically generating a settings form based on a CSS file, part of which provides a font select list with real-time updated preview text underneath. There can be any number of these font select lists + preview depending on the contents of the CSS file. The relevant (simplified) markup is something like:

<!-- First font select & preview -->
<div id="font-selector-group-1" class="font-selector-group">
  <label for="font-select-1">Font</label>
  <select id="font-select-1" class="font-select" name="font-select-1">
    <option value="arial">Arial</option>
    <option value="verdana">Verdana</option>
    <option value="helvetica">Helvetica</option>
  </select>
  <div id="font-preview-1" class="font-preview">Preview: <span class="">The quick brown fox jumped etc ...</span></div>
</div>

<!-- Second font select & preview -->
<div id="font-selector-group-2" class="font-selector-group">
  <label for="font-select-2">Font</label>
  <select id="font-select-2" class="font-select" name="font-select-2">
    <option value="arial">Arial</option>
    <option value="verdana">Verdana</option>
    <option value="helvetica">Helvetica</option>
  </select>
  <div id="font-preview-2" class="font-preview">Preview: <span class="">The quick brown fox jumped etc ...</span></div>
</div>

<!-- Et cetera ... -->

In addition to styling (applying the correct font to) each font option I also want to change the class of #font-preview-x span to the selected option value from the relevant #font-select-x (i.e. "arial", "verdana" etc), thus showing a real-time preview of what the font will look like.

At present I have all this working OK using something like the following in my form array to change the preview text's class to the correct font class:

'#attributes' => array(
  'onchange' => "jQuery('#font-preview-" . $i . " span').removeClass().addClass(jQuery('select[name=\"font-select-" . $i ."\"]').val());",
),

This mostly works onchange but not on page load, but on reading up further I gather there is probably a cleaner and better way i.e. using '#attached' to attach a Drupal behaviour, and I also shouldn't need to pass in the specific id. With jQuery I should be able to attach event handlers to each font select that update their respective preview text.

Any direction or advice would be much appreciated, as this aspect of Drupal is relatively new to me. Have read the docs and googled around but still am a little lost.

1 Answer 1

0

In drupal 7, If you need to add JavaScript or CSS to your page where a form may be rendered, there is already a rendered array variable available from the Form API for just that. drupal_add_js() will not always add the JS to the form as the hook does not always run when the form will be displayed, in certain scenarios like if the page is cached. You should use the #attached array on any form element, if you want to add JavaScript or CSS, because this array will rendered in all certain scenarios.


$form['#attached']['js']["jQuery('#font-preview-" . $i . " span').removeClass().addClass(jQuery('select[name=\"font-select-" . $i ."\"]').val())"] = array( 'type' => 'inline');

For More details you can visit: https://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7#attached

2
  • Thanks, yes I understand #attached is the better way to reference the JS as I mentioned in the original post, but what I'm struggling with I guess is more the jQuery that goes in my script to accomplish what I want e.g. '#attached' => array( 'js' => array(drupal_get_path('module', 'my_module_name') . '/scripts/update_font_preview.js')) How do I either 1) pass element IDs to that external JS, OR better yet 2) write jQuery in the external JS that doesn't require passing those IDs? I suspect the latter is possible given the above markup, but just a little stumped.
    – inteja
    Commented May 28, 2014 at 5:30
  • You can go either of option here because drupal support both way. 1. Pass element id using 'setting' option drupal.stackexchange.com/questions/4482/… and use this variable value in external js file. 2. Write inline js as I suggested above. Commented May 28, 2014 at 5:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.