- Posted by mateid on April 1, 2009
A little while back I was looking for a nice convenient way of calling ASP .Net web services from JavaScript. I looked at the MS Ajax implementation, however I’m a little uncomfortable with the Script Manager and all the related plumbing. It’s just a little heavy for my taste, and I’m not a big fan of the auto generated web service proxy. I also wanted to keep the door open for porting my project to Mono and I wasn’t sure if those features have been ported yet (if they have, ping me). I looked at jQuery, Prototype and Scriptaculous and of those three I liked jQuery the best for the additional features the package offers. Right off the bat jQuery was pretty simple to use and set up, but a little too much typing for my taste. Here’s what I came up with:
1: (function($) { $.proxy = function(options) {
2:
3: /* Default .Net web service proxy options. */
4: var defaults = {
5: mode: "POST",
6: contentType: "application/json;charset=utf-8",
7: dataType: "json",
8: endPoint: "",
9: data: "",
10: success: {},
11: failure: {}
12: };
13:
14: /* Extend (or override) the defaults with any passed in options. I really like this extend feature. */
15: var options = $.extend(defaults, options);
16:
17: /* Make the ajax call using $.ajax() */
18: return $.ajax({
19: url: options.endPoint,
20: type: options.mode,
21: contentType: options.contentType,
22: dataType: options.dataType,
23: data: options.data,
24: success: options.success,
25: error: options.failure
26: });
27: };
28: })(jQuery);
This is a simple jQuery plug-in that encapsulate the details of calling ASP .Net web services. This is pretty sweet since now I can do something like this and avoid all that set-up work every time I need to call into the back-end:
1: Zanzibar = {}
2: Zanzibar.Web = {
3: LocationService: {
4: Get: function(options) {
5: $.extend(options, { endPoint: "http://localhost:60088/RPC/GeoLocation.asmx/Get" });
6:
7: return $.proxy(options);
8: }
9: }
10: }
This becomes my proxy now. I’m extending the options with the specific end point for the web method I need to call and the usage pattern for this becomes something like the following:
1: Zanzibar.Web.LocationService.Get({
2: data: "{ userId: 10001 }",
3: success: successCallback,
4: failure: errorCallback
5: });
This is great, because now all I need to worry about is the actual parameters I want to call my web service with, none of the setup work is needed up front anymore. Clearly other methods can be added and you can provide a really nice, rich wrapper for a web service this way. No complex inheritance, just some simple composition and extension of passed in parameters with some default settings. I really like the $.extend() function, comes in very handy for defaulting parameters and helping cut down on verbosity somewhat. Using that cool feature I can trim the code down but I still retain the power of customizing every aspect of my web service call if I need to.
- Posted by mateid on March 25, 2008
We all know the "debugger" JavaScript statement will cause your script to break in the debugger. You can use this statement with like if {} else {} and conditionally break into the debugger in your script. See an example below.
1: function ConditionalBreakPoint()
2: {
3: debugger;
4:
5: for(i=0;i<20;i++)
6: {
7: if(i==10)
8: {
9: debugger;
10: Sys.Debug.trace("Debugger " + i);
11: }
12: Sys.Debug.trace(i);
13: }
14: }
- Posted by mateid on January 10, 2008
Very good list of Javascript and HTML resources over at MooTools site.
MooTools Help! I Don't Know JavaScript!
- Posted by mateid on September 7, 2007
Closing the window from JavaScript should be easy. However if the window was not opened using script the user will be prompted for permission to close the window. This can be irritating for the user end so a request you frequently encounter is to close the window without prompting for permission. I came across two interesting articles today, one that provides a technique for IE 6 and the other for IE 7. So here are the two posts:
IE 6 and IE 7
I've tested the IE 7 and it seems to work well.
- Posted by mateid on June 17, 2007
In this article I will show what I've learned while building a Silverlight Javascript driven custom control. The technique I will be discussing is simple and provides good end results. If you'd like to write a control of your own you will need a copy of Expressions Blend 2 Beta - May preview, ASP .Net AJAX with the latest drop of Futures and of course Visual Studio.
To begin, I will show how I've developed a custom Silverlight button that looks cool and acts like a button. The basic ideea is that I create a Javascript object prototype and the XAML is contained within as a property. So in essence it's just a Javascript object with a graphical representation that happens to be XAML in a Silverlight host. You can see this in action in Joe Stegman's MIX '07 video here.
You can start by creating a new Silverlight (Javascript) project in Expressions Blend. This will create the basic project for you with little fuss. What you end up with can be seen in the screen shot at the right. Scene.xaml.js contains the prototype for your scene. Default.html.js contains code to initialize the scene and wireup the onLoad event. I will be using this event to instantiate the button and wire up its events to do some useful work.
The XAML to define the button is pretty simple. It is a Canvas with three children, the button background, the button text and the button higlight that displays on mouse overs. The end result is displayed on the right. The javascript code for the full button can be found below.
Type.registerNamespace("ControlsDemo");ControlsDemo.Button = function(parent, text, name, left, top) { this.$parent = parent; this.$buttontext = text; this.$name = name; this.create(name, text, left, top); ControlsDemo.Button.initializeBase(this);}// This function initializes the button into the given canvas.ControlsDemo.Button.prototype.create = function(name, text, left, top) {
this.$xaml = String.format(this.$xaml, name);
this.$root = this.$cfx(this.$xaml); this.$parent.children.add(this.$root); this.$root["Canvas.Left"] = left; this.$root["Canvas.Top"] = top; this.$main = this.$f("btnFace"); this.$text = this.$f("btnText"); this.$text.Text = this.$buttontext; this.$highlight = this.$f("btnHighlight"); // Set event handlers for the button clicks and mouse overs this.$main.addEventListener("MouseEnter", this.onMouseEnter); this.$main.addEventListener("MouseLeave", this.onMouseLeave); this.$main.addEventListener("MouseLeftButtonUp", Sys.Silverlight.createDelegate(this, this.click));}ControlsDemo.Button.prototype.$xaml = '<Canvas xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"\ x:Name="{0}" Width="60" Height="20" Cursor="Hand" >\ <Rectangle Fill="#FF595959" Stroke="#FF323232" StrokeThickness="1"\ RadiusX="2" RadiusY="2" Cursor="Hand" Width="60" Height="20" />\ <Rectangle x:Name="btnHighlight" Fill="#FF6B6B6B" Stroke="#FF303030"\ StrokeThickness="0" RadiusX="2" RadiusY="2" Cursor="Hand" Width="56"\ Height="8" Canvas.Top="2" Canvas.Left="2" Visibility="hidden"/>\ <TextBlock x:Name="btnText" Foreground="#FFFFFFFF" Cursor="Hand"\ Width="29" Height="17" Canvas.Left="10" Canvas.Top="2" FontSize="12" Text="OK" />\ </Canvas>';//Creates the visual representation of the control on the canvasControlsDemo.Button.prototype.$cfx = function(xaml) { return this.$parent.getHost().content.createFromXaml(xaml, true);}//Removes the control from the XAML treeControlsDemo.Button.prototype.remove = function() { this.$parent.children.remove(this.$root);}//Finds subordinate controlsControlsDemo.Button.prototype.$f = function(name) { return this.$root.findName(name);}//Add a listener to the click eventControlsDemo.Button.prototype.add_click = function(handler) { this.get_events().addHandler('click', handler);}//Add a listener to the click eventControlsDemo.Button.prototype.remove_click = function(handler) { this.get_events().removeHandler('click', handler);}//Notify listeners of the click eventControlsDemo.Button.prototype.click = function() { var handler = this.get_events().getHandler("click"); if(handler) handler(this, Sys.EventArgs.Empty);}//Handle the MouseEnter eventControlsDemo.Button.prototype.onMouseEnter = function(sender) { var highlight = sender.findName("btnHighlight"); highlight.Visibility = "visible";}//Handle the MouseLeave eventControlsDemo.Button.prototype.onMouseLeave = function(sender) { var highlight = sender.findName("btnHighlight"); highlight.Visibility = "hidden";}ControlsDemo.Button.registerClass('ControlsDemo.Button', Sys.Component);// Notify ScriptManager that this is the end of the script.if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
To create an instance of the button simply pass the following parameters to the constructor: parent, text, name, left, top where parent is the canvas you want to create the button on, text is the text that will appear on the button, name is the name you can refer to the main button canvas in the XAML tree and left,top are the coordinates the button will be created at on the parent canvas. Notice the name gets replaced with the name you supply to the constructor. The reason for this is that once the name of an element is set is read-only from there on. The other thig to keep in mind is that the name of the child elments of the button canvas are scoped to the canvas to avoid name collision with other buttons' children.
Once you have all this set up you can create an .aspx (or simply rename Default.html to Default.aspx) page and take your new control for a test drive. Include a ScriptManager on the page and add the Button.js file as a script reference. In the onLoad event handler you can create the button and hook the event listeners. I've added two button for the purpose of the demo, btnOk and btnCancel. Here is the code:
handleLoad: function(control, userContext, rootElement) { this.control = control; //Instantiate a new button control and wire up the click event var btnOk = new ControlsDemo.Button(rootElement, "Ok", "btnOk", 20, 20); btnOk.add_click(button_Click); //Instantiate another new button control and wire up the click event var btnCancel = new ControlsDemo.Button(rootElement, "Cancel", "btnCancel", 100, 20); btnCancel.add_click(button_Click); }
When the button is clicked the button_Click event handler will be notified and the name of the button iwll be displayed.
//Handle the click event and display the sender.$namefunction button_Click(sender, args){ alert(String.format("You clicked {0}!", sender.$name));}
And that's all there is to it. Of course the button can be improved by adding animations, better look and feel, centering the text and so on. Maybe I will polish this up a little and talk about those things in another post. You can find the code for this post here.