jump to navigation

Best way to speed up Javascript (specifically jQuery) load times November 12, 2012

Posted by willhlaw in Javascript, jQuery, Web 2.0.
Tags: , , ,
1 comment so far

Image

The obvious way is to use a popular CDN, short for Content Delivery Network, such as Google’s. Dave Ward explains the reasons very well in his article, “3 reasons why you should let Google host jQuery for you” and his three main points are:

  1. Decreased Latency – CDN allows the download to occur from the closest server to the user.
  2. Increased Parallelism – The local web server can be serving up content while the other connection is pulling from Google.
  3. Better Caching – Since so many other sites are using Google’s CDN, the user may already have the jQuery or javascript file in their cache.

However, there is a caveat. What if the connection to Google goes down? Can your site survive without jQuery? It should, if you developed the site with a responsive design and progressive enhancement.

The answer is to fall back to a local copy (code sample below).

  1. Write a script tag that refers to Google’s CDN.
  2. Then in the next script fragment, check to see if the jQuery or some public variable from the javascript file exists.
  3. If the object does not exist, then dynamically write another script to the page that refers to the local file.
<!-- Grab Google CDN's jQuery, with a protocol relative URL; fall back to local if necessary -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.5.1.min.js">\x3C/script>')</script>

I learned this concise technique while watching a Twitter Bootstrap 101 tutorial (kudos to David Cochran for the great videos) that referred to this best practice that appears to have come from the HTML5 Boiler Plate project.

By the way, the numbers (from Pingdom) support Google as being most likely the best CDN to use.

CDN performance numbers


Client Side AJAX Applications in SharePoint 2010 – Live Blogging at SUGDC April 9, 2010

Posted by willhlaw in jQuery, SharePoint.
Tags: , , , , ,
add a comment

sugdcTitle4

I am listening to Lee Richardson at SharePoint User Group DC (SUGDC) Reston, VA.  I apologize in advance for the terse code examples and potential incoherent notes.  I am trying to capture everything on the fly and have only touched up a few concepts and added my opinion in the conclusion.  To see this subject in greater depth, visit Lee’s blog.

With client side scripting, there is no compiling, no syntax checking, no type checking.  There is no LINQ, no ADO.NET.  So why would we use it?

Two technologies will be discussed:

  1. WCF Data Services came from ADO.NET Services and previously, Astoria.  OData is a specification that a podcaster, Scott Hanselman, mentioned in connection with SharePoint 2010.
  2. ASP.NET AJAX Templates.

WCF Data Services is an API in SharePoint that allows you to use RSS / Atom and JSON.  It is not just a pure data access layer, it also adheres to the security model built in and returns proper HTTP specification error codes.  It also has validation built-in.  There is also a uniqueness constraint in SharePoint 2010 that will double-check when inserting a new item and return an error code if an item already exists with the same value that was marked for uniqueness (Something that databases have been doing for years).

Polling the crowd on who has used ASP.NET AJAX framework and would not use it on their next project.  5 people raised their hands.  5 people kept their hands up.  An UpdatePanel in SharePoint has just been too difficult over the years, it sends the entire ViewState to the server on each request, and updating the framework as it matures with SharePoint has been painful.

Templating is part of ASP.NET AJAX 4.  It is still in BETA.  Best way to describe it is by describing what it is not.  What would you use if you were to return 100 items from the server and display in a table and page.  I commented, “jPoint and the flexigrid jQuery plugin.”  A few people turned around and said, “Are you the jPoint guy?”  Lee didn’t hear the jPoint comment, but he smiled, and said, “Yes, jQuery.  You could do that.”

Enough talking and he jumps into the demo.  He first shows a response on a webpage and describes the data that we are looking at.  Opens Visual Studio and comments that, “it is not an out of the box, unfortunately”.  An Administrator needs to turn on a feature after installing the WCF Data Services.  A new project is started in Visual Studio.  In SharePoint 2010 and Visual Studio 2010, SharePoint project templates come out of the box.  That’s cool and several people in the crowd acknowledged seeing other demos, but no one admitted to having hands on experience.

Several files are referenced are pasted in from Clipboard, SharePoint basic js files, ADONET, jQuery, and jQuery-ui.  In the code, you typically see three different approaches.  Declarative, imperative, and the jQuery approach.  Everything tonight that is shown will be the imperative approach.  On the web, you always see declarative (using xmlns, it looks nice, but it is too magical).

There are two data types, DataContext knows how to talk to OData services and WCF Data Services.  A Subtype is the AdoNetContext knows how to talk to WCF Data Services.

Then, he starts to explain the code.  $create is a shortcut to create things.

dataview=$create(Sys.UI.Dataview,

{

autofetch: true,

dataProvider: dataContext,

fetchOperation: …

$get(‘userStories’)

}

<div class=”sys-template”)

<div> { {Title }} </div>  //this is a one way binding, like a read view.

</div>

Just in time compiling sometimes takes a while even though nothing changes.  Not sure why this happens.  The items were pulled and displayed in a list.  A background style was applied and some other script was pasted into the ASPX page in Visual Studio, and the userStories showed up as index cards on a corkboard background image.

Now to drag and drop the index cards onto the corkboard and create a master view so when you click on a userStory from the list, it will pop up on the corkboard.  He moved it around on the corkboard because he applied jQuery-ui draggable to the userStories div.  But after a page refresh, the index cards moved back to their original place.  So, custom columns X and Y were added to the userStories which were Tasks contents that can be synched with Outlook.  These new columns are to keep track of the screen coordinates so upon display, they will remain in place.

sys:style=”{{…can use sys to identify a template syntax in an attribute.  Inside the function call, string concatenation can be used.  First, though, the sys namespace needed to be defined xmlns:sys = “Javascript:sys”.  The sys templating allows the class style to be dynamically set from the item’s X and Y values.  Pretty neat.  Normally, you would have to compute these values in javascript and could not do it inline with your HTML.

After dragging and dropping, the new X value is assigned inside the jQuery dropped routine.

Sys.Observer.setValue(obj, “X”, newX) updates the DOM and prepares the object to be saved back to the server.

Fiddler is opened so that we can see exactly what is going on.  The .svc call is returning a $batch.  The dataview keeps track of what JSON objects are being changed and only sends those to the server.  That is pretty efficient.

<div> { {Title }} </div>  //this is a one way binding, like a read view.

<div> { binding X } </div> //this is a two way binding.

Note: if you use this binding in a <input type=”text”> HTML element, it will automatically update the JSON objects and the DOM so you do not need to type the Sys.Observer line above.

Now we are going to work on the Master Detail view and add an edit button to the Detail view.  Here live binding is used.

Sys.bind(“DetailDataView”,…)

<img sys.bind=…/>

Clicking on the edit img of a userStory Task, the object becomes “selected” so the binding knows when the edit input box is typed in and it automagically updates the DOM so you see the read only version of the userStory Task in the background change.  Pretty neat!

To conclude, you will need to learn a new syntax, but writing inline code in your HTML to generate styles from properties of fetched SharePoint items and live bind objects between the DOM and in-memory JSON objects is very powerful.  Also, the ASP.NET AJAX 4 is able to only send the data for items that have changed back to the server.  That is smart bulk loading.  Lee was adamant that he was not a javascript developer, but I thought he did a great job at putting together his demo and modifying his code on the fly during the demo.  I am not sure how difficult it will be to deploy WCF Data Services on a SharePoint server, but I would recommend users who are not strong in javascript to look into this technology.  If you are already strong in javascript, then there will be less benefit at leveraging this new, but powerful technology from Microsoft.

Thanks, Lee, for a great presentation.  Well done.

Lee Richardson’s Twitter ID: @lprichar

Lee Richardson’s blog: http://rapidapplicationdevelopment.blogspot.com/

LeeNicSmall

SPSDC and jPoint Presentation Wrap-up including How to pre-populate SharePoint form fields from URL parameters with just 3 lines of code. December 9, 2009

Posted by willhlaw in jPoint, jQuery, SharePoint, SPSDC.
Tags: , , , , , ,
2 comments

SharePointSatDC

It started off a cold and rainy morning on 12/5/09 for the SharePoint Saturday DC conference.  I had a car full of about 7 bags of donated clothes for the events clothing drive thanks to the Harris, Lawrence, and Wallenhorst families.  The clothes were dropped off after my 8:30-9:40 session and by that time, there was a nice white blanket on the ground and snowing heavily!  I hope the clothes from the event will provide warmth to several cold persons sometime soon.

I kicked off my presentation with a “Taste of jPoint” video to wake up the audience and grab their attention.  Tell me what what you think of the video.  Ken from the jPoint team created it from some program on his new laptop.  If you are prompted, username is demouser and password is sharejPoint!

The presentation, entitled “jPoint: jQuery Based Library for Creating Web 2.0 Apps in SharePoint” had 4 parts.

  1. Web 2.0 App: Demo
  2. jPoint: Unleashed
  3. jParts: Plug and Play Web Parts
  4. jParts: Live Demo

For the Web 2.0 App Demo, I gave a quick background and showed while describing another jPoint team member’s pre-recorded demo.

I then talked through parts 2 and 3 with just a couple of on-the-fly questions from the audience.

For the jParts: Live Demo, I was pretty confident I could do it live without trouble, as long as the website connection worked, since I had run through similar steps when I created a screencast earlier.  Well, I was a little bit wrong.  There were, of course, a few glitches, but I was able to smooth them out.  In one case, I touted how Firefox with Firebug is such a useful tool for client-side developing on SharePoint.  A few seconds later, I had to switch to IE so that I could inspect the contents of a form [editor] web part.

Nevertheless, I was able to demonstrate live, how to add the GoogleChartsAPI jPart from the Web Parts Gallery.  Then, I demonstrated how to take the new jPart_Template.js and paste in 3 lines of code and a function called querySt to read query string parameters to create a jPart to pre-populate a SharePoint form page with values from URL parameters.  Those 3 lines of code are:

$.each(jP.Form.readForm().Items, function(idx,formjQueryItem){
if(querySt(formjQueryItem.Name) != null)
jP.Form[formjQueryItem.Name].val(querySt(formjQueryItem.Name));
Let’s go over it quickly.

The first line uses jQuery’s $.each function which iterates through the form items and uses an anonymous callback function with two parameters. idx for the index and formjQueryItem which represents the Form item object (in other words, the cell that contains the Title, Assigned To, or Priority field.

jP.Form.readForm() is called which reads the page’s html to extract the SharePoint columns or “fields”.  readForm() returns a Form item object so that you can daisy chain this into one line to get the items, jP.Form.readForm().Items.

The next line checks to see if the current name of the field (i.e. Title, Assigned To, or Priority), matches an existing URL parameter.  If it does, then the last line is executed.  The last line uses the powerful .val() function.  To reference a particular field in jPoint, the array notation, jP.Form[“field name”] can be used or the dot notation, jP.Form.fieldname can be used.  When using the dot notation, it is not recommended to use a field that has special characters or a whitespace.  In jPoint you can, you just need to remove those before using it (i.e. Assigned To becomes AssignedTo).  So back to the last line.

jP.Form[formjQueryItem.Name] gives you a reference to the field item object.  Passing a parameter to the .val() function acts like a setter.  No parameters acts like a getter, just like jQuery’s val() function.  Thus, passing the value of the URL parameter to the field item’s val function sets it.  Thus, you can pre-populate any form field.

To run the code, remember, you need to have both jQuery and jPoint loaded on the page.  Below is the entire script.

<script type=”text/javascript”
src=”http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js”&gt;</script><script type=”text/javascript”
src=”http://sharejpoint.googlecode.com/files/jPoint-latest-expanded.js”&gt;</script><script type=”text/javascript”>
$(document).ready(function() { //Wait page to load and then apply webpart logic
$.each(jP.Form.readForm().Items, function (idx, formjQueryItem) {


if(querySt(formjQueryItem.Name) != null)
jP.Form[formjQueryItem.Name].val(querySt(formjQueryItem.Name));

});
});
function querySt(ji)


{
hu = window.location.search.substring(1);
gy = hu.split(“&”);
for (i=0;i<gy.length;i++)
{
ft = gy[i].split(“=”);
if (ft[0].toUpperCase() == ji.toUpperCase()) //Fixed query so it is case insensitive
{
return unescape(ft[1]);
}
}
return null;
}
</script>

So, when I was finished with the live demo, I was at the 50 minutes mark.  I had ten more minutes before the 10 minutes Q & A.  After asking the audience, we decided more examples would be good.  Rather than going off script and risk the few embarrassing glitches of the live demo, I explained a few of the jPart examples on the http://sharejPoint.com/examples website.  I showed off the chatterbox solution as a pure client-side jPart.  After that, I discussed the Bing Maps API and the story behind it.

After ten minutes of that, it was finally ready for the Q & A.  Oh, and before the Q & A was over, my laptop died.  The camstudio session that I was recording…gone!  Oh no.

There were a few interesting questions like, “If I use jPoint in the enterprise, who is going to support it and for how long”.  I answered “With jPoint being a good platform for developing scripts for 2007 that work when upgraded to 2010, it’s going to be around for a while.  Plus, it is open source.  You can look at the comments in the code and maintain it yourself.  I really think that this project has legs and the more people I talk to, the more excitement and enthusiasm is generated and the word spreads”.

One audience member summarized the session, “It was not as clear at first, but the demos at the end really helped to make it more clear.”  I think there are lot of advanced concepts with jPoint, especially jParts and the deployment framework.  There is a lot of documentation to be done.  At the very end of Q & A, a bunch of audience members came up to talk to me one and one.  One member was extremely excited about learning jPoint and has offered to contribute to the project, particularly in the documentation area.  It is always great to bring on new volunteers to the project.

Since I had a wedding all the way down in Raleigh, I had to leave right after Q & A.  At 8:00am it was raining.  At 9:45am it was snowing.  This was not going to be a fun trip.  Well, after making it to the wedding on time, we found out that we were actually late, because the wedding started EARLY!  Who does that?

I want to conclude with a big thank you to Dan Usher and Dux Sy Raymond and the other organizers for helping to make this event happen.  And thanks again to everyone who contributed clothes!

If you want to take a look at the slide deck, I have converted it into a PDF and made it available here.

SharePoint Designer 2010 – Building Composite Apps: From SPC09 Las Vegas October 21, 2009

Posted by willhlaw in jQuery, SharePoint, Sharepoint Designer, SPC09.
Tags: , , , , ,
1 comment so far

I am here at the SharePoint Conference 2010 (SPC09) at Las Vegas. There were not a plethora of interesting sessions this afternoon, so I stuck to what I have been good at; live blogging on SharePoint Designer 2010. See my other blog posts:

Here are the interesting points from the session.

Enterprise Mashups with SharePoint Designer 2010, Bing map services, and Restful web services: From SPC09 Las Vegas October 21, 2009

Posted by willhlaw in jQuery, SharePoint, Sharepoint Designer, SPC09.
Tags: , , , , ,
5 comments

Enterprise Mashups with SharePoint Designer 2010, Bing map services, and Restful web services

This is an overview during a live presentation at SPC09, the biggest SharePoint Conference of the year, possibly ever. The session is quite good. There were good examples of the different web parts and interaction in Shareponit Desinger 2010, bringing in RSS feeds from Twitter and MSN Weather, stylesheets to turn a list into a Bing map, and the underlying code to render the pushpins. Great job Microsoft.

[Update] The jPoint team is creating a Bing script solution. Check back later this evening to get the hyperlink to the example!

[Update #2] The jPoint team, within hours, has created the Bing solution at http://sharejPoint.com/examples.

[Update #3] Hector Ruiz has blogged about Experimenting with jPoint and Bing Maps here.

Demo 1, connecting with recruits using Twitter and MSN Weather

  • In SharePoint Designer 2010 (SPD2010), data sources can be RSS, Rest, Server Scripts. That is how Twitter and MSN Weather were added as data sources. From each website, the RSS feed URL was grabbed.
    • Twitter’s feed is /show.xml?…
  • RecruitDetails.aspx
    • MSN Weather feed was added into a new ASPX page as a DataFormWebPart by selecting Data View -> MSN Weather.
    • Twitter feed was using Twitter’s API, which is not reliable, and it did not work. But presenter prepared the audience for this failure.
    • For MSN Weather DFWP, a web connection was created to get parameters from the query string.
    • After establishing the TwitterID as a query string parameter, the presenter tried to drag in the Twitter DFWP again. It worked!
    • An XsltListViewWebPart that is hooked up to a recruiter’s list is connected to the Twitter web part.
  • RecruitMap.aspx
    • Recruits list is added to the page without any formatting.
    • The recruit list is added again to the page. Hmmm…where are they going with this?
    • The presenter turns the second webpart, an XsltListViewWebPart, and adds a reference to an XSL stylesheet called g11.xsl. This stylesheet magically turns the XLVWP into a Bing map! Pretty cool, but I’d like to see that g11.xsl! This gets the audience’s first clappter!
    • Wow, they go into the XSL stylesheet. There is a little bit of javascript to send the addresses to the map services. Actually, they have code placeholders, so I have no idea how much work was involved. I have done this with Google Maps, OpenLayers, and Google Earth Enterprise (which has a slightly different API than Google Maps public, which is always a slight pain).

Demo 2, rentals mashup

  • Same pattern is going to be followed as the first demo, by starting with creating a RentalDetails.aspx page.
  • RentalDetails.aspx
    • First step is to go into code and define the layouts
    • Presenter pops over to view the list. It is standard information about a rental unit (bedrooms, baths, etc)
    • Back to the code view in SP2010, a rentals-gallery div and rentals-detail div is created.
    • To show just one list item, change the DataFormWebPart of the rentals list to only show 1 item, a nice way to style a detailed view.
    • The attachment column is at the top of the list. These attachments are going to be pictures attached to each rental item. Since this will be useful later, it is tagged in the content by typing “@Marker” in the field next to the label “Attachment” for the DFWP.
    • The DFWP control inserts a table with id of idAttachmentTable which will be used later to show the pictures.
    • A filter is added to only show the rental item whose “title = Title” where Title is a query string parameter.
    • The page refresh did not filter properly. Somebody in the audience helped the presenter out by telling him he made the variable a server variable rather than a query string param.
    • The page still did not filter properly. It is still showing the first item in alphabetical order. The presenter tried to pull the file from a saved location, but that did not seem to work. So now, he is rebuilding the solution from scratch. This rebuild is fast! Uh-oh. Still a problem. Somehow, it is just magically NOT working. So, the presenter pulls up a totally new “backup” page so that the demo can move on.
    • This brd.aspx page uses jQuery to show an image slide show. That’s what I’m talking about. I see several people in the audience skoot to the edge of their seats.
    • In the brd.aspx page, he references a local jquery.min.js and a jquery.slideshow.js as well as a jquery.slidshow.css file.
    • Within the page itself, there is some more custom script that clones the idAttachmentTable and prepends the rentals-gallery.
    • Then, $(“#rentals-gallery”).slideshow() creates the slideshow with parameters dictating the speed and location of the images. He glanced over these details because the code will be provided “later”. I have always wondered how much later and how will we be notified? Well, once I find out, I will update each pertinent blog entry on my site.
  • To create the map, _spBodyOnLoadfunctionNames.push(“Initialize”)
  • And several variables to define; var mapDivId, mapZoom, mapListName, mapPinTitle, maplistQueryFields (columns from list), maptargetDetailsPage=”brd.aspx”, mapTargetDetailsPageParam, mapTargetDetailsPageValue = mapPinTitle;
  • Functions include:
    • mapGetItemaddress(i)
    • mapGettemHTML(i)
    • Initialize -> this calls mapInitialize() and then spGetData();
    • mapListQuery() -> builds the fields in CAML query.
    • mapInitialize()
      • mapTheMap = new VEMap(mapDivId);
      • maptheMap.LoadMap();
      • mapResetCenterCalculation();
    • spGetData()
      • This function uses the Javascript Client Object Model. Again, the presenter touts the consistency across client side models (.NET, Silverlight, and Javascript). For more information on the Client Object Model, see my blog post.
      • A context is created and then ctx.get_web().get_lists().getByTitle(mapListName);
      • Then, a CAML query is created.
      • After some more setup calls, then ctx.executeQueryAsync(mapAsyncQueryWorks(mapListItems))
        • He starts talking about javascript closures. Wow, this is the first time I’ve HEARD someone talk about closure, as opposed to just writing about it. However, he skims over this topic and really does not explain it. Too bad. I thought he would be able to educate the audience since closures is a really tough topic for people to grasp.
      • mapAsyncQueryWorks(mapListItems)
      • mapCallback(title, photo_url, shareHTML)
        • A VEShape is created for the pushpin and latlong location.

Roadblocks to Mashups in the Enterprise

  • Technical roadblocks
    • Security, authorization, authentication
    • Identity Management
    • Single Sign-On
    • Credential propagation
    • Data trustworthiness -> Research has shown when users see data on a map (or in a report), they believe it to be TRUE.
    • Web services readiness
  • Management roadblocks
    • Web services changes
    • Data source dependencies
    • Mashup lifecycle
    • Component lifecycle
    • Policy Management and Governance
    • Privacy
    • Compliance

That’s it. The session ended with an apology for the failed demo, but a reminder that they had a backup ready. Unfortunately, there was no time for questions. If you find my live blogging useful, let me know. Also, add my blog as a feed as I will update it once I find out when the code samples are available.

Working with the new Client Object Model: From SPC09 Las Vegas October 20, 2009

Posted by willhlaw in jQuery, SharePoint, Sharepoint Designer, SPC09.
Tags: , , , ,
9 comments

Live from Las Vegas at Mandalay Bay. I am at the SharePoint Conference 2009 and listening to a presentation on the new SharePoint 2010 Client Object Model. Presenter was Paul Stubbs from Microsoft.

Client Object Model

  • Simple API to Add, Retrieve, Update and Manage Date in Shareponit.
  • 1st goal – consistency
    • Between client and server API
    • As well as between the three different clients, Client side (.NET), Silverlight, and Javascript.
  • 2nd goal – efficiency
    • In use of server resources
    • In use of network resources
    • Uses a SQL model. Batch up client calls, call server, server processes query, server turns results as a result set
    • Only return data the exact data that I need. i.e. When calling a list, only retrieve data for the specific columns that are needed.
  • Code example
    • Today:
      • SPWeb site = SPContext.Current.Web;
      • String title = site.Title;
      • Site.Title = title + ” and Client OM”;
      • Site.AllowUnssafeUpdates = true;
      • Site.Update();
    • Now with Client Object Model:
      • ClientContext = clientContext = new ClientContext(http://intranet.contoso.com);
      • Web site = clientContext.Web;
      • clientContext.Loadsite);
      • clientContext.ExecuteQuery(); //synchronous call
      • site.Title += ” and Client OM”;
      • site.Update((); //second call because as a rule, can’t use a property to set the value of another property.
      • clientContext.ExecuteQuery();
    • Another example:
      • Web site;
      • ClientContext ctx;
      • Void MainPage_Loaded(object sender, RoutedEventArgs e)
      • { contexzt = new ClientContext(http://mysite);
      • Site = context.Web;
      • Context.Load(site);
      • //Call the Sharepoint Server
      • Context.ExecuteQueryAsync(succeededCB, failedCB);}
    • Javascript example:
      • _spBodyOnLoadfunctionNames.push(“Initialize”);
      • Var site;
      • Var Context;
      • Function Initialize()
      • { contexst = SP{.Clientcontext.get_current();
      • Site = Context.get_web();
      • Context.load(site, “Title”);
      • //Call the Sharepoint Server
      • Context.executeQueryAsync(Suceeded, Failed);}
  • Retrieve Data
    • Context.Load(object, params LinqExpre3ssion)
      • Fills out the objects in the context; in-place
      • ‘method syntax’ linq only
  • Context.Loadquery(iQueryable)
    • Use linq query to return custom objects
    • Not filled into the client context
    • Both ‘query syntax’ and ‘method syntax’ linq
  • Query Syntax
    • More natural Linq query that is familiar
    • Var query = from list in clientContext.Web.Lists where list.Title != null select list;
  • Method Syntax
    • More technical
    • clientContext.Load(oList, list => list.Fields.Where( field => field.hidden === false && field.Filterable == true));
    • Harder, but more powerful.
  • How does this all work? How to access data with Client OM?
    • A new service called Client.svc is a proxy to WCF service.
    • When .ExecuteQuery occurs, block of XML gets sent to server, it unwinds it, and returns JSON object to client.
    • Use fiddler to see the payload to understand how it works, but once you do, can ignore the traffic details.
  • Demo 1, change site title “Hello World”:
    • Shows an example of client.svc runtime being used in a windows application to change the title of a site.
  • Client Object Model using .NET is synchronous, but Silverlight and Javascript are asynchronous.
  • Demo 2, a WPF example:
    • Purpose is to fill a list box with a List of Lists.
    • There are some namespace collisions when building the WPF app.
    • So, you must write: Using SP = Microsoft.Sharepoint.Client again to prevent namespace conflict.
    • Object model will turn query syntax into method syntax before sending it to the server. Remember, query syntax is easier to write.
  • Demo 3, showing .NET CLR in Word
    • Drop .NET controls on the canvas onto the design surface within Visual Studio.
    • Purpose is to fill a task pane (Action Pane, uses ElementHost control because it needs to be Winforms based) on the right-hand side of customer data.
    • Also showing grabbing fields from a list.
  • Demo 4, javascript and jQuery
    • In visual studio, starting a new OMJavascriptApplication
    • <SharePoint:scriptLink> name=”sp.js”. -> Name of javascript client object model
    • <script src = js/jquery-ui-1.7.1.custom.min.js and other jquery files. Presenter mentions that trontastic is a great css to use. I have to check it out.
    • Bui8lding a dynamic jQuery Accoridion on the page by setting a div id=”accordion”
    • Has a separate MyJScode.js file
      • Inside the file, uses _spBodyOnLoadfunction to push Initialize function with familiar code that gets context, etc.
      • LoadListBox is pure jQuery code to populate listbox with a change event.
      • Var listEnumerator = lists.getenumerator();
      • While listEnumerator.moveNext()) {
      • }
      • Then listbox1.append using standard jquery.
      • BuildTable(ListName) is pure jQuery code.
    • Purpose of example is to show List of Lists inside the accordion! Really cool. This caused the audience to clap for the first time in the entire demo!
  • Javascript Client OM
    • Javascript files are in the 14 bin folder on the server.
    • There is a debug version (SP.debug.js)
    • SP.Core.js and SP.Core.debug.js
    • SP.Runtime.js (SP.Runtime.debug.js)
    • Debug versions are only slighter larger.
  • Next demo, Silverlight example
    • In visual studio, starting a new OMSilverlightApplication in Visual Studio
    • Starts with a simple grid with listbox
    • Using SP = Microsoft.Sharepoint.Client again to prevent namespace conflict.
    • Can build using standard Silverlight code to run in browser or inline, which I think means stand alone on the client machine.
    • It is easy to go from WPF code to Silverlight using this.Dispatcher.BeginInvoke and using a lambda expression.
      • i.e. this.Dispatcher.BeginInvoke ( ()=> {messageBox.Show(string.Forma(“failed – msg”); })
    • There are lot of steps to publish the Silverlightproject. Seems like several options for outputting the project. Grant it, I am not familiar with Silverlight at all.
    • (uh-oh, big clapping from next session over!) Yeah Microsoft.
    • When deploying Silverlight app to Sharepoint, a Silverlight.xap file is published to a Silverlight folder located at
    • The project does not exist on the SharePoint server, it is deployed as a sandbox solution.
    • In site settings -> solutions -> OMSilverlightApplicatinoDeploy exists for a site collection administrator to deploy.
    • Since deployment option was checked to allow Silverlight webapp to be installed on client, you can right-click the Silverlight listbox app, and can install the app on the client!
    • (This got the second clap of the session from the audience!)
  • No reason to deploy in WPF (if you are not doing full trust or 3D). To have updates, click once, security, and to have offline capability, build apps in Silverlight!    
  • #SPC09Buzzword for this session, “Super Powerful. Super Powerful”
  • Silverlight CLR Client OM
    • Located in 14 bin on server.
    • Microsoft.SharePoiht.Client.Silverlight (262KB)
    • Microsoft.SharePoint.Client.Silverlight.Runtime (138KB)
  • Q & A
    • I asked what recommended methods does Microsoft have for deloying jQuery and script libraries to Sharepoint Pages. There was no real recommendation other than including it in masterpage globablly or referencing it in a single .aspx file, but Scott was the second time I heard to talk with Mike Amerland.

My first YouTube video is an intro to jPoint October 18, 2009

Posted by willhlaw in jPoint, jQuery, sharejPoint, SharePoint.
Tags: , , , , , , , , , ,
2 comments

The sharejPoint blog, managed by The jPoint Project, has a post over at http://bit.ly/blog_jPoint_YouTube and the video is at http://bit.ly/3C3bab. The video has me introducing jPoint and going through a quick demonstration.


(Video Screenshot is an image hyperlinked to YouTube video)

This video says it is 9:33 long, but the intro and demo really only lasts until 5:59. The rest of the video is a silent intro that I added in order to re-upload the video with enough of a checksum difference for YouYube not to reject it as a duplicate. The first video that was created did not have the correct zoom points at places. The silent part which is a couple of minutes at the end is not necessarily a waste of time. It shows the jPInspector example which shows the power of jPoint.Form. This acts as a preview of the next video. So, how did I do for my first video screencast? What can I do to improve the next one?

Kung-fu jQuery Solution to Bill Simser’s Post on Changing the Home tab in Multipage Meeting Workspaces October 14, 2009

Posted by willhlaw in jPoint, jQuery.
Tags: , , , , ,
4 comments

Bill Simser posted a blog article two days ago that I wanted to reply to. The title was “Changing the Home tab in Multipage Meeting Workspaces with jQuery”. However, when I posted my comment, it did not show up. I know that sometimes, it takes a while. I waited, reposted my comments in Chrome rather than in IE7 and waited some more. But after an entire day and Bill tweeeting he did not see any comments, I am resorting to responding with a blog post.

Thus, here is a re-hash of the problem Bill was trying to solve. On a Multipage meeting workspace, you can change the name of each meeting tab except for the “Home” one. Bill came up with a jQuery solution for changing the “Home” to “Zombieland”, or whatever you wish. However, he needed two separate script solutions on the “Home” page and the other pages because the structure of the tab changed whenever it was the current selected page (no link is necessary to click on the tab that you are already on).

Here were Bill’s two solutions.

To change the Home Page tab name we’ll need two Content Editor Web Parts (CEWP). One when the Home tab is active and one when it’s not. Using jQuery we simply find the tab and change the text. Seriously it’s this easy:

<script type=”text/javascript”>

$(document).ready(function(){

$(‘.ms-tabselected:contains(“Home”)’).text(“Zombieland”);

});

</script>

And here’s the code when the tab is inactive (it has a different classname):

<script type=”text/javascript”>

$(document).ready(function(){

$(‘.ms-tabinactive:contains(“Home”) a’).text(“Zombieland”);

});

</script>

And here is Bill’s problem:

I thought I would be smart and use the className^=”ms-tab” wildcard so it would work on any page but the content changes if the page is active. Even with the class selector when the page is active, there’s no hyperlink to the page (which makes sense) so no ‘a’ selector to find. When the tab isn’t active it’s there. My JavaScript kung-fu prevents me from figuring out something that works for both situations but feel free to post a snippet in the comments and I’ll update the post.

This is my answer to Bill and it would have been a comment on his blog but for some reason, my 4 attempts to comment did not work. (Don’t worry, I tried everything, including just writing about the first part of the solution and leaving out the whole configurable script part.)

[metadata would have looked something like this] Monday, October 12, 2009 3:55 PM by willhlaw

Okay, I am not sure if you need your code on one line, but the following ninja code should work.

<script type=”text/javascript”>

$(document).ready(function(){

var homeTab = $(“span .ms-tabinactive, .ms-tabselected”).find(“:contains(‘Home’)”);

homeTab.html(homeTab.html().replace(“Home”,”ZombieLand”));

});

</script>

Basically, I use find to search the children. And so as not to affect the structure, I do a string replace.

I created a quick configurable script using jPoint so a user with edit page permissions can change the new tab name from “Zombieland” to something else. It uses the jPoint configuration model, so if you are familiar with it, it should be simple. If you are not, just drop the script onto a content editor webpart and you will see a yellow config screen with an edit button.  Click that edit button to change the NewTabName from “Zombieland” to anything else. After the page refreshes, you’ll see your changes. No need for power users to mess with code.

Here is the configurable script with the script tags replaced with [script] to make sure it will appear:

<script type=”text/javascript”>

var myjLocalOptions={NewTabName:’ZombieLand’};

</script>

<script type=”text/javascript” src=”//sharejpoint.googlecode.com/files/jPart-0.4-template-expanded.js“></script>

<script src=”/src/jPoint_dev/webparts/jPart.replaceMeetingHomeTab.js”></script>

Here are the pictures to help explain the configurable script for Changing the Home Tab of a Multipage Meeting Workspace.

A close up.

When you click the Edit button, you will see the following configuration screen for the script webpart.

A close-up.

So now, without having to be a developer, a power user or site admin could change the name of the “Home” tab to ZombieFire.

Click Update and you will see the changes.

.