Using jQuery Learning from a year of SharePoint branding Lunch & Learn Zeddy Iskandar / Food Manager UX Engineer
Dec 05, 2014
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