jQuery for Sharepoint Dev

Preview:

DESCRIPTION

I presented this lecture to the new SharePoint devs joining our team. As I take on the challenge of Surface v2 development, I felt the urge to share my knowledge of branding SharePoint portals with jQuery for the past 1 year.

Citation preview

Using jQueryLearning from a year of SharePoint branding

Lunch & Learn

Zeddy Iskandar / Food ManagerUX Engineer

Pay Attention!

Rewards for occasional questions:

Rewards for tougher questions:

What is jQuery?

What we see

#lga { height: 231px;}

<img height="95" width="275" src="/logo2w.png" alt="Google">

We generate HTML from server-side API

What is jQuery?

What we want to see

We want a Client-Side API to manipulate

generated content

What is jQuery?

What we want to see

We want a cross-browser

framework to access DOM

DOMDocument

Object Model

What is jQuery?

• Paste code below to FireBug console, after jQuery-fying Google.com homepage

jQuery("#lga").hover(function() {

jQuery("#lga img").attr("src", "http://www.gravatar.com/avatar/6872bc097bdddbfec28a56f76d0569a7");

jQuery("#lga img").attr("width", "150");jQuery("<div>Happy Birthday

Zeddy</div>").insertAfter("#lga img");}, function() {

jQuery("#lga img").attr("src", "/intl/en_com/images/srpr/logo2w.png");

jQuery("#lga img").removeAttr("width");jQuery("#lga div").remove();

});

What is jQuery?

What we want to see

cross-browser

framework to access

DOM

DOMDocument

Object Model

==

jQuery Setup

• The framework: http://jquery.com• The jQuery-friendly browser:– http://mozilla.com

• The DOM-inspector browser plugin:– http://getfirebug.com

• Additional FireBug plugins:– http://firequery.binaryage.com– http://robertnyman.com/firefinder

jQuery for SharePoint Dev

• Use NotePad++ to open:– .CSS & .JS in TEMPLATE\LAYOUTS– .ASCX in TEMPLATE\CONTROLTEMPLATES

• Use FireBug console to test jQuery scripts

• Use FireBug inspector to edit CSS• Copy the tested jQuery & CSS to

NotePad++• Test in IE7+ and fix browser-compatibility

issues

How to use jQuery

• Find the element– the one(s) you think will help you

achieve that magic look & feel

• Do stuff to it– add hover effect, move position, replace

the HTML tag with completely different tag(s), delete, animate, etc.

jQuery Syntax

jQuery(“selector”).doStuff();

SELECTORS

Most-used Selectors

• (“#ZCarousel”) – selects element with id=ZCarousel

• (“.item”)– selects element(s) with class=item

• (“#ZCarousel li div.item”)– CSS-style selectors: select all <div> with

class=item under <li> tag which is under ZCarousel element

Most-used Selectors

• (“#ZCarousel li:first”) – selects the 1st <li> tag found under ZCarousel

• (“#ZCarousel li:last”) – selects the last <li> tag found uner ZCarousel

• (“#ZCarousel li:even”)

• (“#ZCarousel li:odd”)– get all the even or odd <li> elements, useful

for alternating effect

Most-used Selectors

• (“element [attribute=something]”) – the example below grabs the 1st <tbody>

emitted by the tag <asp:Calendar>

– the example below changes the Prev Month arrow emitted by the tag <asp:Calendar>

var tbody = jQuery("#calendarArea table[title=Calendar] tbody:first");

// Change month arrowsvar iconPrev = "<img src='/_layouts/darkBlueArrow-Left.png' />";var prevLink = jQuery("#calendarArea a[title='Go to the previous month']");prevLink.html(iconPrev);

Most-used Selectors

• (“input[id$=‘txtCurrency1']”) – element <input> with attribute id ends with

‘txtCurrency1’, eg. this ASP.NET tag:

– will generate this HTML:

– this jQuery will get that element’s value:

<asp:TextBox ID="txtCurrency1" runat="server" />

var curr1Pref = jQuery("input[id$=‘txtCurrency1']").val();

<input type="text" value=“United Arab Emirates (AED)" id="ctl00_m_g_50b54854_4b09_4b72_a69d_6ded7f051845_ctl00_txtCurrency1" />

METHODS

Most-used Methods

• .css(“style”, “value”)– or use the map argument:

• .addClass(“redTheme”)

• .removeClass(“redTheme”)– adds / removes class from element

jQuery(this).css({ position: “absolute", top: “10px" left: “100px"});

Most-used Methods

• .hasClass(“certainClass”)– check if element is using certainClass

• .is(“:visible”)

if (!jQuery(this).hasClass("ui-accordion-content-active")) {spacer.insertAfter(jQuery(this));

}

var leftPanel = jQuery("#s4-leftpanel");if (leftPanel.length > 0 && leftPanel.is(":visible'"))

Most-used Methods

• Used to add horizontal scrollbar in Allitems.aspx page// If #s4-leftpanel is visible, make the table layout scrollable// so it doesn't fall to the bottom in IE8+, FF, Chromevar leftPanel = jQuery("#s4-leftpanel");if (leftPanel.length > 0 && leftPanel.is(":visible'")) { // allow horizontal scrollbar on right column var rightCol = jQuery("#parentPlaceHolderMain"); rightCol.css("overflow-x", "auto"); if (jQuery.browser.msie && jQuery.browser.version < 8.0) { // only happens in IE 7 var height = rightCol.height(); rightCol.css("height", height + 30 + "px"); }}

Most-used Methods

• .text()– gets/sets combined string of element

• .val()– gets/sets values of form elements

• .hide() / .show() / .toggle()– hide/show element. Use .toggle for

toggling between hiding/showing

var date = jQuery("input[id$='hiddenEventStartDate']").val();

Most-used Methods

• .attr()– gets/sets attribute of element

– guess what the above does?

jQuery("[id$='txtFirstName']").focus(function () { if (jQuery(this).val() == jQuery (this).attr("title")) jQuery (this).val("");}).blur(function () { if (jQuery(this).val() == "") jQuery(this).val(jQuery(this).attr("title"));});

Default value of field FirstName is set in custom attribute Title (set via server-side, reading from resource). If you click on the field, the value is cleared, allowing you to type a value. When you move outside the field and no value is entered, a default value is set once again (Used for “Enter First Name here” helper)

Most-used Methods

• .clone() followed by .insertAfter() / .append()– clone an element, then appends or insert it after

another element

– guess what the above does?– does .clone() persist element event-binding?

var copy = tr.clone();// Modificationscopy.find("td.colNoOfShares > input").val("");copy.find("td.colPricePerShare > input").val("");copy.find("td.colAddRemoveButtons > a[title=delThis]").show();tbody.append(copy);

Most-used Methods

var copy = tr.clone();// Modificationscopy.find("td.colNoOfShares > input").val("");copy.find("td.colPricePerShare > input").val("");copy.find("td.colAddRemoveButtons > a[title=delThis]").show();tbody.append(copy);

Above code used to clone a row when “Add Stock” button is clicked

Most-used Methods

.clone() only copies the HTML tag, does not copy events attached to the elements. See example for our Advanced Search below; after we clone the advanced search criteria row, we re-attach the event handlers to the cloned element

var copy = jQuery(tr).clone();// ModificationsjQuery(copy).children("td.colWhereTheProperty").text("");jQuery(copy).find("td.colAddRemoveButtons > a:eq(1)").show(); // show del buttonvar selectors = jQuery(copy).find("div.selectorWrapper");jQuery(selectors).each(function () { addClickHandler(this); …});

EVENTS

Most-used Events

• .hover()– sets up on hover and on leave in one go

jQuery("#ZCarousel").hover(function () { jQuery(“.divArrows”).show(); window.clearInterval(autoscroller_timer);},function () { jQuery(“.divArrows”).hide(); setupAutoScrollerTimer();});

Most-used Events

• .click()– sets up on hover and on leave in one go

– guess what the above does?

jQuery(“a#changeMonth”).click(function () { jQuery(monthFacadeText).text($(this).text()); jQuery ("input[id$='hiddenTxtMonth']").val($(this).text()); jQuery (monthOptions).hide(); jQuery ("input[id$='btnChangeMonthYear']").trigger("click")});

Most-used Events

jQuery(“a#changeMonth”).click(function () { jQuery(monthFacadeText).text($(this).text()); jQuery ("input[id$='hiddenTxtMonth']").val($(this).text()); jQuery (monthOptions).hide(); jQuery ("input[id$='btnChangeMonthYear']").trigger("click")});

When “custom dropdown” Change Month is clicked:1. Set the month façade div to the selected month2. Set ASP.NET viewstate variable to the selected month3. Hide month scrollable div4. Trigger ASP.NET postback button with ID

btnChangeMonthYear

ANIMATION

How to Build a Carousel

• .animate()– allows to animate an element style property

(top, left, opacity, etc.)

How to Build a Carousel (1)

• Step 1: Output a series of <li> items to be carouseled:<div id="ZSlideShow"> <div id="container"> <ul id="carousel"> <asp:Repeater ID="carouselRepeater" runat="server"> <ItemTemplate> <li> <div class="item"> <a href='<%# Eval("ReadMoreLink") %>'><img src='<%# Eval("ImageUrl") %>' alt='<%# Eval("Title") %>'/></a> <a href='<%# Eval("ReadMoreLink") %>'><h3><%# Eval("Title") %></h3></a> <div class="description"> <%# Eval("Description")%> </div> <div class="readmore"> <a href='<%# Eval("ReadMoreLink") %>' class=“xButton"><%= ResourceReader.GetGlobal(“XWebParts", “XWebPart_ReadMore_Text")%></a> </div> </li> </ItemTemplate> </asp:Repeater> </ul> </div><div id="prevButton"><a href="javascript:carousel_prev();"><img src="/_layouts/Images/WebParts.Ets/left_arrow.png" alt="Prev" /></a></div><div id="nextButton"><a href="javascript:carousel_next();"><img src="/_layouts/Images/WebParts.Ets/right_arrow.png" alt="Prev" /></a></div> <asp:HiddenField ID="hiddenIntervalTimeInSeconds" runat="server" /></div>

How to Build a Carousel (2)

• Step 2: Float items to the left & set viewport#ZSlideShow{width: 600px;background-color: #e9e7db;padding: 5px 4px 5px 4px;display: block;overflow: hidden;position: relative;}

#ZSlideShow #container{height: 226px;width: 600px;position: relative;overflow: hidden;}

#ZSlideShow ul#carousel{margin: 0;padding: 0;height: 226px;overflow: visible;position: relative;top: 0;}

#ZSlideShow ul#carousel li{list-style: none outside none;float: left;margin-right: 5px;height: 226px;width: 161px;}

Viewport of 600px

How to Build a Carousel (3)

• Step 3: Set up helper CONSTANTS in .jsvar ITEM_WIDTH = 166; // 161 div + 5px marginvar LEFT_START_OFFSET = -113;var LEFT_OPACITY_ITEM_INDEX;var RIGHT_OPACITY_ITEM_INDEX;var BACK_TO_START_LEFT_POS;var START_POS_AFTER_SLIDE;var MINIMUM_ITEMS_SCROLLABLE = 4; // only scroll if >= this number

var original_items;

var item_revolution_counter; // if < -(original_items.length), back to start position// if > (original_items.length), back to (start position + slide)

var autoscroller_timer;

How to Build a Carousel (4)

• Step 4: Set up Carouse on when DOM is ready

– `

jQuery(document).ready(function () { var items = jQuery("#carousel > li"); original_items = items; // save for appending to create circular effect if (items.length >= MINIMUM_ITEMS_SCROLLABLE) { appendOriginalsToFront(); appendOriginalsToBack();

BACK_TO_START_LEFT_POS = -(original_items.length * ITEM_WIDTH) + LEFT_START_OFFSET; START_POS_AFTER_SLIDE = BACK_TO_START_LEFT_POS + ITEM_WIDTH; jQuery("#carousel").css("left", START_POS_AFTER_SLIDE + "px"); item_revolution_counter = 0;

LEFT_OPACITY_ITEM_INDEX = original_items.length - 1; RIGHT_OPACITY_ITEM_INDEX = LEFT_OPACITY_ITEM_INDEX + MINIMUM_ITEMS_SCROLLABLE; makeEdgeItemsTransparent(); }

// adjust the width according to no. of items var carouselWidth = jQuery("#carousel > li").length * ITEM_WIDTH; jQuery("#carousel").css("width", carouselWidth + "px");

// setup hover for prev/next to show up, and pause auto-scrolling jQuery("#ZSlideShow").hover(function () { toggleButtons(); clearInterval(autoscroller_timer); }, function () { toggleButtons(); setupAutoScroller(); });

// setup auto-scroll setupAutoScroller();});

How to Build a Carousel (5)

• Step 5: Helper functions

– `

function setupAutoScroller() { var intervalInSeconds = parseInt(jQuery("#ZSlideShow input[id$='hiddenIntervalTimeInSeconds']").val()); autoscroller_timer = window.setInterval(function () { carousel_next(); } , intervalInSeconds * 1000);}

function toggleButtons() { jQuery("#prevButton").toggle(400); jQuery("#nextButton").toggle(400);}

function makeEdgeItemsOpaque() { var items = jQuery("#carousel > li"); // prevent array-out-of-bounds if (LEFT_OPACITY_ITEM_INDEX >= 0 && LEFT_OPACITY_ITEM_INDEX < items.length) jQuery(items[LEFT_OPACITY_ITEM_INDEX]).css({ filter: "alpha(opacity=100)", opacity: "1.0" });

if (RIGHT_OPACITY_ITEM_INDEX >= 0 && RIGHT_OPACITY_ITEM_INDEX < items.length) jQuery(items[RIGHT_OPACITY_ITEM_INDEX]).css({ filter: "alpha(opacity=100)", opacity: "1.0" });}

function makeEdgeItemsTransparent() { var items = jQuery("#carousel > li"); if (LEFT_OPACITY_ITEM_INDEX >= 0 && LEFT_OPACITY_ITEM_INDEX < items.length) jQuery(items[LEFT_OPACITY_ITEM_INDEX]).css({ filter: "alpha(opacity=50)", opacity: "0.5" });

if (RIGHT_OPACITY_ITEM_INDEX >= 0 && RIGHT_OPACITY_ITEM_INDEX < items.length) jQuery(items[RIGHT_OPACITY_ITEM_INDEX]).css({ filter: "alpha(opacity=50)", opacity: "0.5" });}

How to Build a Carousel

• Visual logic: we are animating the Left property of the #carousel to slide left or right. The Viewport with overflow:hidden hides the out-of-view items

Viewport of 600px

We’re scrolling the Left property of #carousel

How to Build a Carousel (6)

• Step 6: Append items to front & back for smooth circular effect

function appendOriginalsToFront() { var firstItem = jQuery("#carousel > li:first"); for (var i = 0; i < original_items.length; ++i) { var cloned = jQuery(original_items[i]).clone(); styleEtsButton_restoreHoverEffects(cloned); cloned.insertBefore(firstItem); }}

function appendOriginalsToBack() { var lastItem = jQuery("#carousel > li:last"); for (var i = original_items.length - 1; i >= 0; --i) { var cloned = jQuery(original_items[i]).clone(); styleEtsButton_restoreHoverEffects(cloned); cloned.insertAfter(lastItem); }}

How to Build a Carousel (7)

• Step 7: What happens when you click Next button

function carousel_next() { var items = jQuery("#carousel > li"); if (items.length >= MINIMUM_ITEMS_SCROLLABLE) { ++item_revolution_counter; if (item_revolution_counter > original_items.length) { item_revolution_counter = 1;

// back to 1st item -- circular effect jQuery("#carousel").css("left", START_POS_AFTER_SLIDE + "px"); LEFT_OPACITY_ITEM_INDEX = original_items.length - 1; RIGHT_OPACITY_ITEM_INDEX = LEFT_OPACITY_ITEM_INDEX + MINIMUM_ITEMS_SCROLLABLE; }

makeEdgeItemsOpaque(); ++LEFT_OPACITY_ITEM_INDEX; ++RIGHT_OPACITY_ITEM_INDEX; makeEdgeItemsTransparent();

var carousel = jQuery("#carousel"); var newLeft = carousel.position().left - ITEM_WIDTH; jQuery("#carousel").animate({ left: newLeft + "px" }, "slow"); }}

How to Build a Carousel (8)

• Step 8: What happens when you click Prev button

function carousel_prev() { var items = jQuery("#carousel > li"); if (items.length >= MINIMUM_ITEMS_SCROLLABLE) { --item_revolution_counter; if (item_revolution_counter <= -original_items.length) { item_revolution_counter = 0;

// back to 1st item -- circular effect jQuery("#carousel").css("left", BACK_TO_START_LEFT_POS + "px"); LEFT_OPACITY_ITEM_INDEX = original_items.length; RIGHT_OPACITY_ITEM_INDEX = LEFT_OPACITY_ITEM_INDEX + MINIMUM_ITEMS_SCROLLABLE; }

makeEdgeItemsOpaque(); --LEFT_OPACITY_ITEM_INDEX; --RIGHT_OPACITY_ITEM_INDEX; makeEdgeItemsTransparent();

var carousel = jQuery("#carousel"); var newLeft = carousel.position().left + ITEM_WIDTH; jQuery("#carousel").animate({ left: newLeft + "px" }, "slow");

THANK YOUQ&A

Recommended