University of Oregon

JS Tweak to the Drupal 7 Contact Form

I tweaked our Drupal 7 Contact form today.
The goal was to allow users to select the reason for contact and potentially the subject via the URL.
We had this in place for our Drupal 6 site and the code ported over nicely.

The process was similar to the last post: JS Tweak to the Drupal 7 Menu Management Screen.

The JS consists of two parts, get the URL Var and value and update the form.
I use a stand alone function (getURLVars) to get the URL Var. Then I drop it like it’s hot (so to speak) using jQuery.

Sample URL: /contact?cid=4&subject=What%20is%20all%20this%20then.

Sample JS to try in your console:

if (typeof getURLVars !== 'function') { 
  function getURLVars(urlVar) {
    if(!urlVar){
       return false;
    }
    if(typeof (document.location.href.split('?')) === 'undefined') {
       return false; 
    }
    if (typeof (document.location.href.split('?')[1]) === 'undefined') {
       return false;
    }
    varArray = document.location.href.split('?')[1].split('&');
  
    for(var x=0; x<varArray.length; x++)
    {
      var tmp = varArray[x].split('=');
      eval(unescape(tmp[0]) + '="' + unescape(tmp[1]) + '"');
      if(urlVar == tmp[0]){
        urlVar = eval(unescape(tmp[0]) + '="' + unescape(tmp[1]) + '"');
        return urlVar;
      }
    }
    return ;
  }
}
//getURLVars('cid')

cidVal = getURLVars('cid')?getURLVars('cid'):'';
if(cidVal !== ''){
  theArray = jQuery('#edit-cid').children().map(function() {return jQuery(this).val();}).get();
  if (jQuery.inArray(cidVal, theArray) !== -1){
    //alert('yup');
    jQuery('#edit-cid').val(cidVal);
  }else{
    //alert('nope');
  }
}

subjectVal = getURLVars('subject')?getURLVars('subject'):'';
if(subjectVal !== ''){
  jQuery('#edit-subject').val(subjectVal.trim());
}

Full JS w/ Drupal.behaviors code wrapper where needed:

/**
 * JS to update the contact id based on a URL var. Ported from D6. 
 */

if (typeof getURLVars !== 'function') { 
  function getURLVars(urlVar) {
    if(!urlVar){
       return false;
    }
    if(typeof (document.location.href.split('?')) === 'undefined') {
       return false; 
    }
    if (typeof (document.location.href.split('?')[1]) === 'undefined') {
       return false;
    }
    varArray = document.location.href.split('?')[1].split('&');
  
    for(var x=0; x<varArray.length; x++)
    {
      var tmp = varArray[x].split('=');
      eval(unescape(tmp[0]) + '="' + unescape(tmp[1]) + '"');
      if(urlVar == tmp[0]){
        urlVar = eval(unescape(tmp[0]) + '="' + unescape(tmp[1]) + '"');
        return urlVar;
      }
    }
    return ;
  }
}

/** Set Defaults
 * Reason for Contact
 * if url var = cid
 * and 
 *   val is in the list of vars then jQuery('#edit-cid').val(2);
 *
 * Subject
 * Set subject
 */
 
(function () {
  Drupal.behaviors.setCid = {
    //for use on Attachment content edit screens
    attach: function(context) {
      if(typeof context !== 'undefined'){ //run only if there is a context var
        /*
          Check the type of the context var and type. Process if context = [object HTMLDocument]
          Note: when context == [object HTMLDocument] then this is page load. You may wont some script to run only on page load. Some not and some all the time.
        */
        if(typeof context == 'object' && context.toString().indexOf('HTMLDocument')!=-1){
          //Page Load
          cidVal = getURLVars('cid')?getURLVars('cid'):'';
          if(cidVal !== ''){
            theArray = jQuery('#edit-cid').children().map(function() {return jQuery(this).val();}).get();
            if (jQuery.inArray(cidVal, theArray) !== -1){
              //alert('yup');
              jQuery('#edit-cid').val(cidVal);
            }else{
              //alert('nope');
            }
          }
          
          subjectVal = getURLVars('subject')?getURLVars('subject'):'';
          if(subjectVal !== ''){
            jQuery('#edit-subject').val(subjectVal.trim());
          }
        }
      }
    }
  }
})();

Again I implemented this in a block w/ the Code Per Node (cpn) CSS and JS additions.
Here are the specifics:

Block title:
None;
Block description:
JS for Contact Page
Block body:
 
Text format:
Code input (custom type allowing html)
Pages – Only the listed pages:
contact;
CSS:
#block-block-55 {
  display: none;
  visibility: hidden;
}

*Note the specific block ID in that id selector

JS:
As pasted above

JS Tweak to the Drupal 7 Menu Management Screen

I tweaked Drupal Menu management screen today.
Previously after editing a menu item the menu page would reload and you’d be at the top of the menu list, essentially losing your place.

This was a problem for one of our admin users when digging through 390 menu items, so I thought I’d give it a quick fix.

Now when you edit a menu item and land back on the menu page, the JS below will scroll you to that last element and highlight the row.

Here’s a screenshot:

Screen Shot of menu management screen after editing a menu item

Sample JS to try in your console:

function scrollToReferrer(){
  //get the referrer URL
  referrerArr = document.referrer.split('/');
  //check if referrer was menu item edit screen
  if(referrerArr[3] == "admin" && referrerArr[5] == "menu" && (referrerArr[8] == "edit")) {
    referrerArr.pop(); //ditch edit
    //capture mlid - alt referrerArr[6]
    referrerMlid = referrerArr.pop();
    //scroll to mlid
    location.hash = "#edit-mlid"+referrerMlid+"-operations-edit";
    //slide up a "pinch" to keep the element visable (in the case of Admin Menu)    
    var x = pageXOffset, y = pageYOffset;
    scrollTo(x,y-60);
    //remove 'drag-previous' class from tr's on the page
    jQuery('tr').removeClass('drag-previous');
    //set waring class on this tr to highlight it
    jQuery("#edit-mlid"+referrerMlid+"-operations-edit").parents('tr').addClass('drag-previous');
    return true;
  }else{
    return false;
  }
}
scrollToReferrer();

And here’s the code in D7 Drupal.behaviours format as I implemented it:

(function ($) {
  Drupal.behaviors.scrollToReferrer = {
    //for use on admin/structure/menu/manage/main-menu
    attach: function(context) {
      if(typeof context !== 'undefined'){ //run only if there is a context var
        if(typeof context == 'object' && context.toString().indexOf('HTMLDocument')!=-1){ //Page Load
          //get the referrer URL
          referrerArr = document.referrer.split('/');
          //check if referrer was menu item edit screen
          if(referrerArr[3] == "admin" && referrerArr[5] == "menu" && (referrerArr[8] == "edit")) {
            referrerArr.pop(); //ditch edit
            //capture mlid - alt referrerArr[6]
            referrerMlid = referrerArr.pop();
            //scroll to mlid
            location.hash = "#edit-mlid"+referrerMlid+"-operations-edit";
            //slide up a "pinch" to keep the element visable (in the case of Admin Menu)    
            var x = pageXOffset, y = pageYOffset;
            scrollTo(x,y-60);
            //remove 'drag-previous' class from tr's on the page
            jQuery('tr').removeClass('drag-previous');
            //set waring class on this tr to highlight it
            jQuery("#edit-mlid"+referrerMlid+"-operations-edit").parents('tr').addClass('drag-previous');
            return true;
          }else{
            return false;
          }
        }//end if(typeof context == 'object' && context.toString().indexOf('HTMLDocument')!=-1){ //Page Load
      }//end typeof context !== und
    }//end function(context)
  }//end Drupal.behaviors
})(jQuery);

Now, the way to implement this correctly would be a custom module or perhaps adding the js to the themes’ .js file.

I added it via Code Per Node (cpn) to a new block that has user and page restrictions in our admin theme.
Here are the specifics:

Block title:
None;
Block description:
JS Seven Menu Page Scripts
Block body:
 
Text format:
Code input (custom type allowing html)
Pages – Only the listed pages:
admin/structure/menu/manage/main-menu;
CSS:
#block-block-53 {
    display: none;
    visibility: hidden;
    }

*Note the specific block ID in that id selector

JS:
As pasted above

A quick fix out and out.

Updating select lists in bulk – w/ jquery, drupal

So I wrote this script 1 year and 1/2 ago about bulk label operations (Drupal 7 CCK – Creating ‘Label Bulk Operations’). Well the updateLabels() function from that code came in handy today.
I needed to update dozens of CCK formats from various defaults to editable. If you’ve used editable fields you know it can come in handy but if you have a lot of fields you’ll be in a carpel tunnel conundrum if you try to change then all.
So I pulled up the updateLabels() function opened the Firebug console and set all the various defaults to editable. And then back again. (more…)

Drush enable all inactive modules

I’ve been using make files a lot lately and when ever I’m ready to release an updated file I like to verify that all the project versions are up to date.
To leverage Drupal’s update functionality each project needs to be enabled. So I typically generate a new site from the make file and enable all the projects with drush. The key to that is the combination of commands:

drush en `drush pm-list --status="disabled,not installed" --pipe`

Here I’m enabling a list of module; specifically drush’s list of disabled and not installed modules.

drush pm-list --status="disabled,not installed"

That code gets you part of the way there. The addition of this:

--pipe

makes it a script-able list. Then when I surround that with back-ticks and feed it to

drush en `...`

I’m in business. (more…)

Drupal 6 – Contact Override custom module

Just created a quick and dirty custom module: Contact Override.
I posted it on bitbucket: bitbucket.org/_vid/contact_override

 

Nothing too exciting, just an override to the D6 contact form. It appends the senders email into the body of the email.

 

We had noticed that while emails from the Drupal contact form contained the senders email in the reply field that email address was often lost when forwarding the message.

Here’s the readme: (more…)

Drupal 7 – resizing the content area based on publish date

I was asked to look at a site where the content created before Jan. 15th 2013 was crafted to display nicely in a 600px wide area.
New content is being added with a much wider area and with some thought given to the possibility of a fluid width (potentially responsive).

So while setting a fixed width isn’t ideal I came up with a proof of concept that demonstrated the possibility using jQuery to resize the content area on page load.
The content in question has two key elements to identify for jQuery:

  1. The publish date:
    $('.field-name-field-publish-date .date-display-single')
  2. The content area:
    $('.field-name-body')

Here’s a sample of the code that could re-format the older content based on the published date:
$(‘.field-name-field-publish-date .date-display-single’).length
//if( (currentContentDate < narrowContentCutOffDate)) { if ( ( new Date($('.field-name-field-publish-date .date-display-single').text()).getTime() < new Date('January 15, 2013').getTime() ) ) { $('.field-name-body').css('width','600px'); }//end if [/code] Wrapped in a Drupal.behaviors function it could be added to the site in a js file like so, to run once on each page load: (more…)

Drupal 6 – Pre-Popluate Menu Parents with jQuery

Here’s a fun one.
I wanted the menu parent to be pre-populated on node creation.

Use case:

  • When a content editor creates a new ‘Electronic Flyer’ it will be added to the per-determined menu: Primary Links >> Resources >> Electronic Flyers.

Here’s a screenshot demonstrating the pre-filled out menu parent: (more…)

Drupal 7 Views – Manipulating Args with php

I wanted to pass a string to a view that only accepts an entity id as an argument.
I the past I’d been able to use a string based argument after adding relationships but that wasn’t possible in this case.

So I decided to override the incoming argument during validation and replacing the string with the relevant entity id.

The use case:

I mentioned that the view only takes a entity id (nid) as an argument. That nid isn’t available to me when I call the view, but I do know a ‘location’ that I can associate with entities.
Ideally the town name “Eugene” is passed to the view but the entity id (237) is what’s used in the view.

The key was to call another view from within my contextual filter argument validation field.
There I pass the ‘location’ name argument to another view (nid_from_townname) using php and the views_get_view() function.
That view returns the nid for the entity in question. So then I override the original view’s argument with the nid and we’re in business.

Here’s a screenshot of the (view display’s contextual filter argument) validation field: (more…)

Drupal 7 – list taxonomy terms

I’m running some tests and thought I’d post the php code to display the terms for a taxonomy:

< ?php
$terms = taxonomy_get_tree(taxonomy_vocabulary_machine_name_load('temp_auth_temp_agency')->vid);
if ($terms) {
  foreach ($terms as $term) {
    $options[$term->tid] = str_repeat('-', $term->depth) . $term->name;
  }
}
echo '<pre>$options: '. print_r($options,true) . '</pre>';

/* Returns:
$options: Array
(
    [439] => DePaul
    [441] => Express
    [440] => Galt Foundation
    [442] => Kelly Services
    [443] => Manpower
    [444] => Personnel Source
)
*/
?>

At the moment I’m considering leveraging the benefits of CCK Select Other for ease of entry with taxonomies for term management. Not sure if it’ll be worth it but this was an interesting code hunt.
(more…)

Bash – Add drupal site name to PS1

I updated my bash prompt (PS1) the other day. Now it displays what site I’m in.
I recently posted my former change: An improved PS1 for Git in Bash.
Now I added an extra bit of code that inserts the current ‘site’.
It looks like this:

vid@server:(prod.mydomain.com) currentdir (origin [master])$ 

(more…)