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.

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 hide/show a sidebar with jQuery

I’ve hid the right sidebar on the HR website today.
I used jQuery so that it degrades gracefully when users don’t have JS enabled.

The sidebar-right region is used for ancillary information; links, the audience for the node content, etc… So it was determined that we could hide it but make the information available if people wanted more. (more…)

Drupal 7: jQuery and Subtotaling Views Calc Tables

As a follow up to Drupal 6: Using jQuery to pick up where views_calc falls short, I worked on a project this week that used views_calc in D7 and we wanted to leverage the same subtotaling that I demonstrated in D6.

There are a lot of similarities in the code so it didn’t take much tweaking. (more…)

Drupal 6: Using jQuery to pick up where views_calc falls short

Views Calc is a great Drupal module but there are a few things it doesn’t do.
It doesn’t:

  1. Accommodate totals by group
  2. Total CCK viewfield field values
  3. Total Views Customfield PHP values

I wanted to fix all three of those issue in a views report I’m using.
To be clear: My solution is uses jQuery as a hack/fix, specifically addressing the fields I want to count and sum. It does not address the inherent issue in views_calc. (more…)

Drupal 7 CCK – Creating ‘Label Bulk Operations’

I have a new D7 site in the works and I found that I wanted the majority of my content type field labels to display: inline as opposed to the default: ‘above’.
Several of my content types have dozens and dozens of fields to I wanted a quick way to automate changing all the selectors at once.

I suppose ‘repetition and redundancy are the Aunt and uncle of invention’.

Here’s what I came up with:
image of the new fieldset and buttons
(more…)

Drupal 6 – Add css with drupal_add_js

I’ve used this method for years and I wanted to post a complete example as a reference.

I love the css_injector module but I like to keep my views’ css with my view.
So this code example has all my required elements for inserting css into a views php header;

  • CSS is readable during editing thanks to php’s HEREDOC
  • function are not re-declared
  • css is minified (Mostly, I keep the white space…)
  • the Drupal.behaviors syntax that ensures code is only ran on the page load
  • and it leverages drupal_add_js

Here it is with in-line comments: (more…)

Handle sites/default/files redirect in Drupal 6 with Custom Errors module

When I’ve migrated sites into Aegir recently, I find that the users have many links in the content hard-coded to files in the default directory.
While it is possible to use the Scanner search & replace module to ferret those out. It’s not always thorough enough. For example, it doesn’t search and replace menu link urls, or content in blocks, views, headers, footers or custom fields. You can specify custom fields and locations to search but that’s another bag of worms that fraught with issues.
So I wanted to find a simple way to catch any hard coded links that I missed.
Enter the Custom Error module.

I’ve been using it to provide a populated search form on the 404 ‘Not found’ page as well as a site map but I also have a few custom redirects in there so adding an option for sites/default/files was simple.

Here’s the code: (more…)

Used jQuery to add a header for a group of courses

We had a group of courses for Take our Daughter and Sons to Work Day added to Making Tracks that all used the abbreviation of the name in their title: TODSTWD. They didn’t spell out the event name anywhere. So I added a jQuery script to the header that prepended the listing with the full title.
I limited this to course listing pages and confined it to a date range so it stopped running after the event.

Here’s a screenshot of the course list summary with out the jQuery header (before):

And here’s a screenshot of the course list summary with the jQuery header (after):

It also runs on the indiv. course details page.

Here’s the code:

&lt;?php
if(strtotime(date(&#039;Y-m-d&#039;)) &lt;= strtotime(date(&#039;2011-4-29&#039;))){ //display until 4-29-11
	$todstwd_script = &lt;&lt;&lt;javascript
	/* ########## Add TODSWD JS ########## */
	Drupal.behaviors.testBehavior=function(context){
		//run only if there is a context var
		if(typeof context !== &#039;undefined&#039;){
			/*
			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 want some script to run only on page load. Some not and some all the time.
			*/
			if(window.location.href.search(/course_view|course_list/)!==-1){
				$(&#039;.courseSummary h3 a&#039;).each(function(){
					if($(this).text().search(/TODSTWD/)!==-1){
						$(this).parent().parent().prepend(&#039;<h2 class="todstwd" style="color:#006600">Take Our Daughters and Sons To Work Day - 4-28-2011</h2>');
					}
				});

				$('#t_content h2').each(function(){
					if($(this).text().search(/TODSTWD/)!==-1){
						if(!$('#todstwd').length){
							$('#main').prepend('<h1 id="todstwd" style="color:#006600">Take Our Daughters and Sons To Work Day - 4-28-2011</h1>');
						}
					}
				});
			} //end if(window.location.href.search(/course_view|course_list/)!==-1){
		} //end if(typeof context !== 'undefined'){
	} //end Drupal.behaviors.testBehavior=function(context){
	/* ########## end Add JS ########## */
JAVASCRIPT;
	drupal_add_js($todstwd_script, 'inline');
}
?&gt;

Here’s a link:
Making Tracks | Organizational Development and Training ODT.