Silverlight

Just Quickly: jQuery and Silverlight

I love Silverlight and I love JavaScript. A very important part of any new technology is making sure it plays nice with existing technologies.

Silverlight has some great features when it comes to integration with the DOM and JavaScript. The ScriptObject and the way Silverlight proxies out POCOs (Plain Old CLR Objects) to JavaScript are a couple of my favourites.

Across the divide, JavaScript is also very cool, but lacks some power and compatibility when used in its bare form (well, compared to JS with a library over the top anyway).

This leads to a lot of web developers choosing to add a JavaScript library to add extra functionality and compatability to their sites. A common choice these days is jQuery.

Over the years a lot of code has been written against these various JS libraries. This means that Silverlight needs to play nice with existing code so that integration with existing sites is quick and pain free (and to reduce re-writes of existing code). Client code is client code and in .NET or not, it can still be very useful.

Nobody wants to re-write an entire site just to add some new existing tech. You want to reuse as much of your existing code as is possible.

jQuery rocks. It’s got some great features, like the jQuery object’s fluent interface, plugins and importantly the implementation of CSS style selectors. CSS selectors allow you do some cool stuff when searching the DOM based on CSS syntax. You can do stuff like “find me all the LI elements that are in UL elements that are in an element with a CSS class name of menuPanel -> “.menuPanel UL LI”. Check out the full power of jQuery selectors here.

jQuery is so cool and so powerful there is a case for using it even if you *don’t* have existing code based on it.

A potential case – CMS

I talked briefly about Silverlight playing nice with existing sites. It’s probably even more important that Silverlight plays nice with existing back end systems such as CMS. When Silverlight is used with a library like jQuery it becomes very easy to integrate.

Your new application can source data from the existing CMS without the CMS needing to know a single thing about Silverlight. And we’re not talking about integrating Silverlight with some existing API or web service.

You can use jQuery selectors with Silverlight to scrape the page both elegantly and simply.

Nitty gritty – jQuery in Silverlight

<Sample Code>

jQuery and Silverlight sample code

</Sample Code>

Using jQuery from Silverlight is very easy as jQuery (in all it’s awesomeness) has a single object to perform most operations -> the “jQuery Object”. Most people use jQuery by using the $ shortcut, but it’s also available on the JS global object (window) as a property called jQuery.

public class jQueryManager
{
	ScriptObject jQuery = null;
	void init()
	{
		//get the jQuery object from the JavaScript global object
		jQuery = HtmlPage.Window.GetProperty("jQuery") as ScriptObject;

		...


	}

}

Now the code is ready to chain up some jQuery operations.

public List GetElements(string selector)
{
	List result = new List();

	//this is like saying $(selector) in jQuery
	ScriptObject select = jQuery.InvokeSelf(selector) as ScriptObject;

	//Check the length property to see if there are any elements in the array
	//Keep in mind JavaScript objects are arrays
	int length = Convert.ToInt32(select.GetProperty("length"));

	if (length > 0)
	{
		for (int i = 0; i < length; i++)
		{
			//As I said, all objects are arrays, so you can call GetProperty like an indexer
			HtmlElement selElement = select.GetProperty(i) as HtmlElement;
			result.Add(selElement);
		}
	}

	return result;
}

The magic happens when the code calls InvokeSelf on the jQuery object. Keep in mind that objects in JavaScript can be functions (it's a functional language). Once the selector has been passed in to the jQuery "function" a ScriptObject is returned. Also keep in mind that objects in JavaScript can be functions *and* arrays. So the ScriptObject in this case can be treated like an array and an object that has properties (like length etc).

The array is looped through and the elements are retrieved using the GetProperty(i) call… is like saying select[i] (remember that the calls are proxied back to JavaScript so that's probably why raw indexers don't work).

This code packages up the elements in to a List and returns the result.

List eleList = jQueryManager.Instance.GetElements(“#someDataDiv ul li a”);

List result = (from e in eleList
select new SomeDataObject()
{
Link = e.GetAttribute(“href”),
Text = e.GetAttribute(“innerHTML”)
}).ToList();

return result;

The SomeDataManager class uses the jQuery helper class to find all the anchor tags that are in LI tags that are in UL tags that are in an element called “someDataDiv”. It does this by calling the jQuery selector “#someDataDiv ul li a”. Cool hey.

Once it gets the list of HtmlElements back it parses them out to get their Link and Text values and populates a simple business object class called SomeDataObject.

The SomeDataManager class also implements INotifyPropertyChanged so that it may raise an event when the data is ready. This means the class can be bound to using Silverlight DataBinding.

id x:Name="LayoutRoot" Background="White">

	
		
	

An ItemsControl in Page.xaml shows the result.

Finally – the HTML that this reads: a simple un-ordered list.

 <div id="someDataDiv">
	<ul>
		<li>
			<a href="http://www.sddn.org.au" title="SDDN Site">SDDN Site</a>
		</li>
		<li>
			<a href="http://blog.webjak.net" title="My Blog">My Blog</a>
		</li>
		<li>
			<a href="http://www.theage.com.au" title="The Age Website">The Age Site</a>
		</li>
	</ul>
</div>

There is something else cool about this

As you well know there are a lot of different browser and “plugin levels” out there. Someone might be on Safari 2 with no Silverlight, someone else might not have JavaScript enabled and the other person may have anything and everything installed.

It’s good practice to design your site in such a way to support all these groups -> a gracefully degrading site.

Build the site so that it works with HTML, JavaScript only and the full works Silverlight version. Using the techniques in this article and some extra sprinkles of ingenuity you can quite easily make your site work in all browser types and plugin installs. Stay tuned for more on this important aspect of web development!

11 thoughts on “Just Quickly: jQuery and Silverlight

  1. Excellent post Jordan!

    I’m working on a blog post using this technique to achieve SEO in Silverlight, so this will be a great post to point to as an introduction to jQuerySilverlight integration!

    Excellent idea to use the power of CSS selectors to grab data from the hosting HTML page.

    – Jonas

  2. Hey Jonas,

    It’s been a while – Hope the MSDN tour was awesome!

    I completely forgot to mention SEO! Oops πŸ™‚

    Always happy to provide some base material for one of your awesome articles πŸ˜› Looking forward to it.

    Cheers,

    Jordan.

  3. Good one!

    We already have jQuery goodness in our site and I am currently adding some silverlight icing on the cake. My primary concerns in using Silverlight at the moment are:

    1. SEO
    2. Graceful degradation
    3. Leveraging existing investments (like jQuery) instead of re-inventing the wheel.

    And your post is spot on.

    Looking forward to your and Jonas’ posts…

    Cheers

    Soni

  4. Hey Asheesh,

    On graceful degradation, the Readify.net site is about to be updated with a new home page that has some concepts… It starts out with plain html, then adds a JS version, and finally a “Silverlight, scraped with jQuery” version. It was sooo easy to do πŸ™‚

    I plan to blog a little more on this, and Damian Edwards and myself are going to build a presentation on graceful degredation in Silverlight and how symantic web helps with this.

    I too am waiting eagerly for Jonas’ post… hurry up!

    Cheers,

    Jordan

  5. Awesome!

    html->JS->SL is what I’d like to do… but given the tight deadline I am working on, its on the back burner for now.

    Please record and post your presentation here.

    Cheers

  6. Awesome post..!! Clever use of ScriptObject and its InvokeSelf() method to integrate jQuery and Silverlight. It will be very useful to manipulate HTML DOM elements from Silverlight.

    But what if one need to use jQuery for Silverlight elements itself, instead of HTML elements. I found a good post to solve this here.

    http://xamlquery.codeplex.com

    This can be used for Silverlight elements (similar to jQuery)

Comments are closed.