A jQuery Primer for SharePoint: Manipulation and CSS

This entry is part 3 of 4 in the series A jQuery Primer for SharePoint

In my previous article, I covered jQuery’s selectors, attributes, and traversing capabilities. Those three broad jQuery capabilities allow you to find what you want to work with in the page’s document object model (DOM). The next thing you will want to think about is how to change the elements, attributes, and/or CSS of the DOM that you have managed to find.

  • jQuery Core
  • Selectors
  • Attributes
  • Traversing
  • Manipulation
  • CSS
  • Events
  • Effects
  • Ajax
  • Utilities
  • jQuery UI

This is where manipulation and CSS come in. In this article, I’ll give you a little overview of some of the things you can accomplish with those two capabilities. Later in this article series I’ll show you how to connect the manipulation and CSS functions to events (which means you can react to user actions), but it’s also useful to just be able to manipulate the DOM. You might do this on page load, for example, to simply override something specific SharePoint has put in the page. (Yes, I know, some would say this is evil and that you should write really complicated managed code instead. However, a well-placed line of jQuery can often get the job done more cleanly and reliably.)

Manipulation

Manipulation allows you to change things in the DOM. We already did a little of that in the prior article when I talked about attributes, because what fun is it just to find something? We want to make changes, baby! If you are flipping back and forth between this article and the jQuery API documentation, you may notice that some of the functions in the Attribute section show up again. This is because there are functions that simply return values, such as .attr(), but can also be used to manipulate those values.

There are far too many functions shown in the manipulation section to go over all of them, so I’ll show you a few useful ones, and I hope you’ll be able to extrapolate from there.

Let’s go back to one of our simple examples. We changed the CSS class of the div in the prior article, but we can do some other interesting things.

<div id="helloDiv">
    Hello, world! </div>

With this line of jQuery:

$("#helloDiv").append("And you're welcome to it!");

you can add some additional content to the DOM. The net effect of this manipulation is to add some more text inside the div by appending it to the div’s contents. After this line of jQuery runs, the DOM contains this:

<div id="helloDiv">
  Hello, world!    And you're welcome to it!
</div>

Keep in mind that if you do a View Source on the page, the “And you’re welcome to it!” string will not be there. View Source shows the HTML that the server sent to the browser initially: the source for the page. As you start to work more and more with scripting that runs in the browser (dare I say in the middle tier?), you’ll choose to use View Source less and less. Instead, you will need to use the Developer Tools (in IE8+) and/or Firebug (Firefox), and so on, to see what is going on in the “live” version of the DOM.

Here is another example, which takes the manipulation a bit further:

$("#helloDiv").append("And you're welcome to it!");
$("#helloDiv").clone().appendTo("#helloDiv");

Here we are adding the same string to the div, but then we are cloning it and adding it back to itself. What we end up with is this:

<div id="helloDiv">
  Hello, world!    And you're welcome to it!
  <div id="helloDiv">
    Hello, world!      And you're welcome to it!
  </div></div>

The .clone() function is cool because it does a “deep” copy: you get an exact copy of the branch of the DOM tree to which you refer.

You can manipulate the DOM in many ways. I’ll take this opportunity to remind you again that the DOM simply contains HTML. HTML is simply a special form of XML, and if you’ve ever worked with XML, you probably think of it as data rather than something immutable. In fact, this is one of the many places when you’re working in SharePoint’s middle tier where code is content is code is content. This is something that may take some getting used to. Because the HTML contained in the DOM is essentially data, you can manipulate that data in the same sorts of ways that you may have seen done with XML in other contexts.

Here’s a more complicated example, this time from the SPSetMultiSelectSizes function in SPServices. In this function, the goal is really simple, but the execution is less simple. All the function does is set the width of the left and right boxes in a multiselect “drop-down” based on their contents. Read through the documentation for the function if you’d like to understand this more fully.

To make this work, I make a clone of the existing markup so that I can manipulate it, grab some of the resulting characteristics, apply those characteristics to the real markup, and then delete the clone. Here’s a small section of that jQuery:

var possibleValues = $("select[ID$='SelectCandidate'][Title^='" + opt.multiSelectColumn + " ']");
...possibleValues.clone().appendTo(possibleValues.closest("span")).css({
  "width": "auto",		// We want the clone to resize its width based on the contents
  "height": 0,			// Just to keep the page clean while we are using the clone
  "visibility": "hidden"	// And let's keep it hidden
}).attr({
  id: cloneId,			// We don't want the clone to have the same id as its source
  length: 0			// And let's start with no options
});

Here I’m finding the possibleValues object in the markup (the left box). Then I make a clone of it and append that clone to the closest (in “parentage”) span. Next I set some CSS attributes for the clone, as well as two attributes. This is a good example of manipulation because it’s not only adding some new objects to the DOM but also changing some of the characteristics of those objects.

Note that this example also shows some additional syntax that is important to understand. When you want to set one attribute of a DOM element, your script looks something like this:

possibleValues.attr(id, cloneId);

However, if you want to set multiple values at the same time, the syntax is a little different:

possibleValues.attr({id: cloneId, length: 0});

As you start to write your own jQuery, this syntax will trip you up often; it still trips me up after having written tons of jQuery. I find that writing the script on multiple lines:

possibleValues.attr({
  id: cloneId,	// We don't want the clone to have the same id as its source
  length: 0	// And let's start with no options
});

when I’m setting multiple values helps me to keep the syntax straight and also means more readable code. It also leaves you room for nice, informative comments. Because you always comment your code, right?

One last thought on manipulation: it’s actually something with which you are very familiar with in existing SharePoint pages, though SharePoint uses plain old JavaScript. For instance, think about the instance when you see the little plus and minus icons (+/-) in a grouped view. Those little icons have script attached to their click events (as I mentioned, more on events in an upcoming article) that manipulate the DOM by changing the CSS of the container for the subordinate content. By switching between display: block; and display: none;, the script simply toggles the visibility of the container.

CSS

Because CSS attributes for elements in the DOM have some unique characteristics, there is a whole set of functions in jQuery to manipulate CSS. Although you can use .attr() to manipulate CSS (as I showed in the last article), the .css() function gives you richer capabilities specifically built to manipulate CSS.

One consideration you should always be thinking about is when to manipulate an element’s CSS directly and when to add, remove, or toggle classes, using the .addClass(), .removeClass(), or toggleClass() functions. The latter approach is generally preferable, since you are then separating the presentation layer (CSS) and the markup (HTML) cleanly. Because your CSS and scripts may go through different deployment processes, this separation is almost always going to be a good idea, especially in a SharePoint context.

That said, you can get and set any CSS attribute directly with the .css() function, and depending upon your own coding guidelines, it may be totally acceptable in many cases. The syntax is pretty simple.

Back to our simple example again:

<div id="helloDiv">
    Hello, world!</div>

We can get a CSS attribute like so:

var helloDivBackgroundColor = $("#helloDiv").css("background-color");

or set it like so:

$("#helloDiv").css("background-color", "fuchsia");

The other CSS functions allow you to add or remove classes as I mentioned earlier and get the values for an element for height, width, scroll bar location, and so on. Changing the CSS means that the existing elements in the DOM will change their appearance but not their existence.

Summary

Between the manipulation and CSS functions in jQuery, you can significantly alter what is present in the active DOM and how it appears to the user. Use manipulation to create, alter, or delete elements, and use CSS to change their appearance. (Consider that a broad brush statement; there are a few nits in it.) These functions (along with the preceding selector and traversing and attribute functions) are often useful to override default SharePoint behavior and layout.

The next step will be to understand how to use these functions in response to specific user actions. That capability is provided by what I’ll cover in my next article: events and effects.

Series NavigationA jQuery Primer for SharePoint: Selectors, Attributes, and Traversing – Oh My!A jQuery Primer for SharePoint: Events and Effects
Twitter Digg Delicious Stumbleupon Technorati Facebook Email

No comments yet... Be the first to leave a reply!

Leave a Reply

Before you post, please prove you are sentient.

What is 3 times 8?