1

This is in Drupal 7.

I'm attaching some JavaScript via drupal_attach_js(), using "settings` to be able to pass the "height" parameter to a JavaScript function. The height is used in a modal dialog, and it will vary depending on the amount of data that the modal will contain.

Here is my JavaScript code:

(function ($) {

  Drupal.behaviors.designer = {
    attach: function (context, settings) {
      // ...some code to activate modal...
      height: settings.designer.jquery_modal_height,
      // ...some more code...
    }
  };

})(jQuery);

If I run console.log(settings.designer.jquery_modal_height), then the console displays the value of this variable, but the actual "height" parameter seems to take the code literally and never applies it's actual value.

Am I doing something wrong?

  • I should add that the height is a paramater inside a function call, ex: $('.my-class').fancybox({ width: 720, height: settings.designer.jquery_modal_height, overlayShow: 1 }); If I try height: 400, things work as expected, and if I run console.log(settings.designer.jquery_modal_height) I see 400 in the console. – Charlie Schliesser Jan 19 '12 at 18:36
  • Can you show us the output of console.log(settings.designer.jquery_modal_height) using the above code? – amateur barista Jan 19 '12 at 18:58
  • 1
    Also, if you say that height: 400 works right. Then what you want is an integer in that property. It would seem that what you are getting is a "string literal". You could just try and cast that from a string literal to an integer in JavaScript. Also, in PHP, when setting up the property, are you assigning a string, or an integer to that property? My spider senses tell me you are assigning a string... – amateur barista Jan 19 '12 at 19:02
  • Oh my gosh, you're right. I have gotten sloppily dependent upon how PHP plays nice with strings/integers. – Charlie Schliesser Jan 19 '12 at 19:22
1
...  
  Drupal.behaviors.designer = {
    // attach is a property of Drupal.behaviors.designer, that points to a method.
    // This method will later on get called by Drupal core on initialization.
    attach: function (context, settings) {
      // Here this doesn't make a lot of sense.
      // Here you are writing height as if it were the property of an object.
      // Technically it is not wrong syntax because everything in JavaScript is an
      // an object. That means methods are objects too! Which also means that your 
      // attach() method above supports both properties and methods.
      // However, here practically you are assigning the contents of settings.designer.jquery_modal_height
      // to the height property of the attach() method.
      height: settings.designer.jquery_modal_height,
    }
  };
...

So basically what you are saying above is

// Add the height property to the attach() method, and add some value to it.
Drupal.behaviors.designer.attach.height = settings.designer.jquery_modal_height;

I don't think you want to do that! Of all the Drupal JavaScript objects there are, I would not consider the attach() method the most durable object.

If you want to use the contents of settings.designer.jquery_modal_height, you either pass it to another method, or assign it to a more durable object. For example.

// Assuming you assigned the string "foo" to settings.designer.jquery_modal_height in PHP.

someFunction(param1, param2) {
  console.log(param1);
  console.log(param2);
}

var someRandomObject = {
  aProperty = "";

  someRandomMethod: function() {
    console.log(this.aProperty);
  }
}

Drupal.behaviors.designer = {
  myCustomMethod: function(param) {
    console.log(param);
  }

  attach: function (context, settings) {
    // Consume the contents of settings.designer.jquery_modal_height.
    // This should print your string properly.
    // prints "foo"
   console.log(settings.designer.jquery_modal_height);

    // Could print "foo". Maybe you should consider accessing myCustomMethod() through
    // the context variable passed into attach().
    console.log(Drupal.behaviors.designer.myCustomMethod( settings.designer.jquery_modal_height);

    // Probably won't work. "this" right now probably refers to "attach" and not "designer"
    console.log(this.myCustomMethod(settings.designer.jquery_modal_height));

    // Here we assign it to a local variable. Not a very durable storage location
    // because we are within a closure right now. As soon as the attach() method
    // finishes it's execution, localVar goes Ka-Poof!
    var localVar = settings.designer.jquery_modal_height;

    // But we can do some stuff with it in the meantime.
    // Should print "foo bar".
    someFunction(localVar, " bar");

    // Here we store our "Drupal setting" in a relatively more durable object.
    someRandomObject.aProperty = settings.designer.jquery_modal_height;

    // Should print "foo".
    someRandomObject.someRandomMethod().
  }
};

So the short answer is: you're probably doing it wrong, revise your code ;)

  • I added a comment to my original question. The // some code here was meant to describe that my height assignment was happening inside my own function. Still, are you saying that my custom function should really be constructed outside of attach? That is how I see other modules adding jQuery functions / code. – Charlie Schliesser Jan 19 '12 at 18:38
  • Your custom "method" should really be accessed thru Drupal.behaviors.designer.myCustomMethod(). Not in Drupal.behaviors.designer.attach.myCustomMethod() or Drupal.behaviors.designer.attach.myProperty, which is what you are literally doing in your code example. In my example I show you how to do Drupal.behaviors.designer.myCustomMethod(). As for doing Drupal.behaviors.designer.attach.myProperty, you should not need to that, since that's the purpose of ...jquery_modal_height's existence in the first place. – amateur barista Jan 19 '12 at 18:42
  • Also, there's nothing that says that you can't construct your own function within another function, like I carefully pointed out before. You can. That's why your application did not crash. You can even assign properties to other functions. Should you do that? That's another matter, and another question. I probably would not do a named method within another named method, which is what you suggest in your comment. – amateur barista Jan 19 '12 at 18:48
  • In the case that I did not want to declare a named method within the designer object, I would for example, use an anonymous function within attach(). But that solution rests on a particular use case, which is not necessarily clear in your original question :) – amateur barista Jan 19 '12 at 18:49
  • I'm going to read everything you've posted very closely because I need to understand what I'm doing 100%. The answer was ultimately as simple as me not performing parseInt(mystring) so that Fancybox received an integer as expected. Not Drupal's fault, nor JS, nor the context's fault, although I need to understand everything you've outlined here. Thanks again! – Charlie Schliesser Jan 19 '12 at 19:24
1

If you do

{
  ..
  height: settings.designer.jquery_modal_height,
  ..
}

You are doing it right, else you should do

..
var height = settings.designer.jquery_modal_height;
..

Most likely it's not the variable that's the problem but some other part of your code.

  • The height is a paramater inside a function call, ex: $('.my-class').fancybox({ width: 720, height: settings.designer.jquery_modal_height, overlayShow: 1 }); If I try height: 400, things work as expected, and if I run console.log(settings.designer.jquery_modal_height) I see 400 in the console. – Charlie Schliesser Jan 19 '12 at 18:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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