3

Question:

I'm creating a javascript object to hold css attributes. If I add new variables to the object on the fly, I run into an unknown problem with the jQuery .css() method and nothing happens. However, if I initiate the object with the variables I want to/do change, the .css() method works fine.

In reference to a post I found, is it necessary that I preset the variables of the object, or is there a way to improve my code to be more dynamic?
(If I can find a way to add variables on the fly I would be able to set any css attribute, not just the ones I predetermine.)


Extended Explanation:

I'm trying to change the padding and margin values on the fly in my HTML. I have created a function that works based on a similar question. However if I simply create an empty object,

var cssObject = {};

instead of,

var cssObject = {
            padding : "inherit",
            paddingBottom : "inherit",
            paddingLeft : "inherit",
            paddingRight : "inherit",
            paddingTop : "inherit",
            margin : "inherit",
            marginBottom : "inherit",
            marginLeft : "inherit",
            marginRight : "inherit",
            marginTop : "inherit"
          };

When I add each new css attribute to the cssObject, the $.css() method doesn't do anything.

i.e.

    for(...){
      cssObject[cssName] = cssValue;
    };

    // The cssObject has (for loop).length many attributes.
    // Set new css with cssObject

    $(this).css(cssObject);

The cssObject gets created (as viewed in the source code and console logs) but the css of $(this) doesn't change. Adversely, When I create the cssObject with preset variables using all the same code, it executes fine.

Steps of the function:

  1. Loop through each HTML objects (i.e. div, etc.) with a class name(s) that contains "setspacing".

  2. The class names of the current object are split into an array.

  3. Loop through the class names, and stop if the name contains "setspacing".

  4. The parts of the current class name are split into an array.

  5. Use class name parts to add new attributes to the css object.

Sample HTML Code:

<div class="full-band">
     <div class="inner-wrapper setspacing-margin-right-left-0">
         <h3 class="setspacing-padding-30px">Bleep Blorp!</h3>
    </div>
</div>

jQuery Code:

$("[class*='setspacing']").each(function(){
    var classList = $(this).attr('class').split(" ");

    for (var i = classList.length - 1; i >= 0; i--) {
      if (classList[i].indexOf("setspacing") >= 0) {
        var splitName = classList[i].split("-");

        var cssName=null, cssValue=null;
        var cssObject = {}; /*
            padding : "inherit",
            paddingBottom : "inherit",
            paddingLeft : "inherit",
            paddingRight : "inherit",
            paddingTop : "inherit",
            margin : "inherit",
            marginBottom : "inherit",
            marginLeft : "inherit",
            marginRight : "inherit",
            marginTop : "inherit"
          };*/

        for (var j = 2; j < splitName.length-1; j++) {

          if (splitName.length<=3) {
            cssName = splitName[1];
          } else {
            part = splitName[j].substring(0,1).toUpperCase() + splitName[j].substring(1);
            cssName = splitName[1]+part;
          };

          cssValue = splitName[splitName.length-1]+" !important";
          cssObject[cssName] = cssValue;
        };
        console.log(JSON.stringify(cssObject)); // EDIT : Added after comment
        $(this).css(cssObject);
      };
    };
  });

Console output when empty object is used:

[Log] {"marginTop":"0px !important","marginBottom":"0px !important","marginRight":"0px !important","marginLeft":"0px !important"} (setup.js, line 50)
[Log] {"paddingTop":"0px !important","paddingBottom":"0px !important","paddingRight":"0px !important","paddingLeft":"0px !important"} (setup.js, line 50)
[Log] {"marginTop":"0 !important","marginBottom":"0 !important","marginRight":"0 !important","marginLeft":"0 !important"} (setup.js, line 50)
[Log] {"paddingTop":"0 !important","paddingBottom":"0 !important","paddingRight":"0 !important","paddingLeft":"0 !important"} (setup.js, line 50)
Community
  • 1
  • 1
Chong Waldo
  • 248
  • 2
  • 13
  • Please post the results of `console.log(JSON.stringify(cssObject));` – Fresheyeball Apr 08 '14 at 16:49
  • jQuery css() method doesn't support `!important` statement. That's said, you should use `data-*` attributes, not using class to set specific data to element or set style according to class, in CSS – A. Wolff Apr 08 '14 at 16:51

2 Answers2

2

As Wolf said in his comments and according to this SO question, jQuery css() method doesn't support !important, if you try to remove !important part then it will works, here is a JSFiddle to test.

Also the inner for loop var j = 1; j < splitName.length-1; is starting from the 3rd item, so in case of setspacing-padding-30px it will not iterate since the condition j < splitName.length-1; is false.

$("[class*='setspacing']").each(function(){
    var classList = $(this).attr('class').split(" ");

    for (var i = classList.length - 1; i >= 0; i--) {
      if (classList[i].indexOf("setspacing") >= 0) {
        var splitName = classList[i].split("-");

        var cssName=null, cssValue=null;
        var cssObject = {}; /*
            padding : "inherit",
            paddingBottom : "inherit",
            paddingLeft : "inherit",
            paddingRight : "inherit",
            paddingTop : "inherit",
            margin : "inherit",
            marginBottom : "inherit",
            marginLeft : "inherit",
            marginRight : "inherit",
            marginTop : "inherit"
          };*/

        for (var j = 1; j < splitName.length-1; j++) {// start from 2nd item

          if (splitName.length<=3) {
            cssName = splitName[1];
          } else {
            if(j==1) continue; // if it is the 2nd skip..
            part = splitName[j].substring(0,1).toUpperCase() + splitName[j].substring(1);
            cssName = splitName[1]+part;
          };

          cssValue = splitName[splitName.length-1];// remove !imprtant since it is not supported +" !important";
          cssObject[cssName] = cssValue;
        };
        console.log(JSON.stringify(cssObject)); // EDIT : Added after comment
        $(this).css(cssObject);
      };
    };
});
Community
  • 1
  • 1
Akram Berkawy
  • 4,920
  • 2
  • 19
  • 27
1

I don't know if you are able to modify your code much, but I came up with this much simpler alternative. It uses data attributes instead of classes so you don't have to go about splitting class names.

It is as follows:

http://jsfiddle.net/yn7tB/1/

HTML:

<div class="full-band">
    <div class="inner-wrapper setspacing" data-margin="0px 0px auto 0px">
        <h3 data-padding="30px" class="setspacing">Bleep Blorp!</h3>
    </div>
</div>

Javascript:

$(".setspacing").each(function(){
    var attrib = $(this).data();
    var el = $(this);

    $.each(attrib, function (i, e) { 
        el.css(i,e); 
    });
});
pconnor88
  • 345
  • 3
  • 13