Does anyone know how one would write a jquery plugin with scriptsharp

175 views
Skip to first unread message

rekna

unread,
Nov 5, 2009, 5:24:41 PM11/5/09
to Scriptsharp
The code to be generated should be something like (following the
recommend way to create an extension)

$.fn.myextension = function() {
...
};

or another example would be

(function($) {

$.fn.extend({

custommethod : function( ) {

},

anothercustommethod : function() {

},
}) (jQuery);

rekna

unread,
Nov 6, 2009, 11:28:38 AM11/6/09
to Scriptsharp
My first attempt at a working plugin , using ScriptSharp.
Feel free to comment, improve the code...
Added comments inside code explaining the different parts.


using System;
using System.DHTML;

namespace Framework
{
// plugin options using a [Record] structure
[Record]
public sealed class SimplePluginOptions
{
public string cssproperty;
public string cssvalue;
}

// this static class will extend jQuery with
// an instance of our class using the jQuery.fn.extend function
// following common jQuery plugin practices
// (probably, it could be moved to the Simple class, will try it
later)
public static class SimplePlugin
{
public static void Initialize()
{
jQuery.fn.extend( new Simple() );
}
}

// this is the class, that contains the definition of our
extension
// each public method will become another method on jQuery
public class Simple : jQuery
{
// this will hold the default options
private SimplePluginOptions _options;

// this will create the default options
public Simple()
{
_options = new SimplePluginOptions();
_options.cssproperty = "border";
_options.cssvalue = "1px solid red";

}

// this method will be available for all jQuery objects
public jQuery DoSimple(SimplePluginOptions options)
{
// extending the default options with custom options
_options = (SimplePluginOptions)jQuery.extend(_options,
options);

// for each DOMElmement, we'll apply the css property
// as jQuery selector can return multiple objects
return this.each((EachCallback)delegate(int index,
DOMElement elm)
{
jqProxy.jQuery(elm).css(_options.cssproperty,
_options.cssvalue);
});
}
}


// just to test our little extension, we write a static class with
a static constructor
// this will translate to only the code in the InitAll method
being executed
[IgnoreNamespace]
public static class InitAll
{
static InitAll()
{
SimplePlugin.Initialize(); // intialize our plugin, to add
extent jQuery

// when document ready, change color of border of all
div's
// using our Simple extension
jqProxy.jQuery(typeof(Document)).ready((Callback)delegate
()
{

// just wait, so we can see the changes
Script.Alert("wait");

// the result of jQuery selection has to be cast to
our Simple class
// otherwise the DoSimple method will not be visible
(only necessary
// when calling from c#, in javascript you could just
write
// $("div").DoSimple(null);
Simple test = (Simple)jqProxy.jQuery("div");

// we pass null, to see if the default options are
being used
test.DoSimple(null);
});
}
}

}

to test this you will need an html document, with following script
references:

<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="sscompat.debug.js"></script> //
compatibility for firefox
<script type="text/javascript" src="sscorlib.debug.js"></script>
<script type="text/javascript" src="TestPlugin.debug.js"></script>

and some div's so you can see the result:

<div style="width:100px;height:200px;border:1px solid black;">
</div>

<div style="width:200px;height:100px;border:1px solid black;">
</div>

Greatz ..Rekna

rekna

unread,
Nov 6, 2009, 7:24:49 PM11/6/09
to Scriptsharp
First update : removed static class SimplePlugin, and moved static
Initialize inside plugin class (changes are marked in comment with
***)

public class Simple : jQuery
{

//** added static method to plugin itself
public static void Initialize()
{
jQuery.fn.extend(new Simple());
}
...
}

[IgnoreNamespace]
public static class InitAll
{
static InitAll()
{
Simple.Initialize(); //*** call static method on plugin
class ***

jqProxy.jQuery(typeof(Document)).ready((Callback)delegate
()
{
Script.Alert("wait");

Simple test = (Simple)jqProxy.jQuery("div");
SimplePluginOptions opt = new SimplePluginOptions();
opt.cssvalue = "1px solid blue"; //*** test for
overiding defaults ***
test.DoSimple(opt).css("backgroundColor", "red") ; //
*** test for chaining **
});
}
}

Remarks:
- I still have a feeling, that the plugins options are not defined the
way it should.
- The this keyword in javascript has different behaviour than this in
c#, sometimes it is not possible to write the code like you would in
javascript, eg inside the this.each construct, I am not sure what this
will refer to, as ScriptSharp translates

return this.each((EachCallback)delegate(int index, DOMElement elm)
{
jqProxy.jQuery(elm).css(opt.cssproperty,
opt.cssvalue);
});

into
return this.each(Delegate.create(this, function(index, elm) {
jQuery(elm).css(opt.cssproperty, opt.cssvalue);
}));

If I am not mistaken:
jQquery states that this inside the each delegate, refers to the
DOMelement being processed.
ScriptScharp Delegate.Create binds this inside the delegate to the
instance of the class

So I suspect they are not the same....

rekna

unread,
Nov 8, 2009, 12:29:23 PM11/8/09
to Scriptsharp
Getting the options to work properly is proving more difficult than
anticipated.

There are fundamental differences between jquery plugins and
scriptSharp's class structure, which make it difficult (if not
impossible for now) to implement a plugin with ScriptSharp, specially
when you want to make a plugin with options, which can be set / get
after the plugin was created.

I tried using the widget plugin structure of jquery ui. This plugin
structure seems to be more robust than standard jquery plugin
structure, in terms of memory management and plugin data storage, but
I can not get it translated to ScriptSharp.

Maybe the error I make is that I try to mimic jquery's way of
implementing plugins.

Finding a good tutorial for making a jquery plugin (at least one that
goes beyond the basics and is not too complex either) is not easy.
Basically I couldn't find any good one using the standard plugin
structure (one that eg implements a getter for options after the
plugin is created).

So finally I looked at jquery UI examples, like the progressbar, which
is fairly simple and which seems to have a getter for the value
property of the progressbar. Unfortunately, this plugin contains an
error. When you want to retrieve the current value for the
progressbar, it returns an object instead of the integer value. Seems
to be a confirmed bug in the plugin.

Looking at the slider plugin (which is somewhat more complex), gave
insight what was wrong in the progressbar plugin.

jQuery ui plugins do have a disadvantage however. Retrieving
properties is done by using a string to specify which property value
you want to retrieve (key value pairs). Eg. to retrieve the
progressbar's value you have to write :

$('#myProgressbar').progressbar('option','value').

So there goes codecompletion and strong typed code...

Not very promising altogether. But I do not completely understand the
way javascript, jquery and jquery ui widgets work, I only touched the
surface of it.
Reply all
Reply to author
Forward
0 new messages