DCSIMG
February 2009 - Posts - IronShay

February 2009 - Posts

A BAD of Roses - JQuery UI Dialog and ASP.Net AJAX

You see, all I wanted was to integrate JQuery’s dialog into my ASP.Net application. The JQuery guys really did an amazing job there and it’s a shame no to take advantage of it.

So I did.

The outcome: 5 days trying to figure out what’s wrong (that includes the weekend!) and eventually, a fragile solution that made me abandon the whole thing.

In this post I’m going to briefly introduce you with the JQuery UI dialog, explain the problem I had, the cause to the problem and my frail solution suggestion.

The JQuery UI Dialog

The JQuery UI Dialog is a great little component. It gives you everything you need from a dialog – title, body, buttons, resizing, dragging… it’s an all-in-one pack. You can put whole forms inside, change themes, choose opening and closing effects, make it modal, bind to events and more and more.

All you have to do is - create a DIV, put the dialog content inside, and call the dialog method with the needed properties:

<div id="myDialogDiv" title="Dialog's title">
    The content of the dialog
</div>

<script type="text/javascript">
    $("#myDialogDiv").dialog({
        modal: true,
        overlay: {
            backgroundColor: '#000',
            opacity: 0.5
        },
        buttons: { Close: function() { $(this).dialog('close'); } }
    });
</script>

And this is how it looks like (for example):

JQuery UI  Dialog Screenshot 1
JQuery UI  Dialog Screenshot 2

 

The Problem

The problem starts when you want to have a form inside the dialog. And not just that, you put the dialog div (with the form elements) inside an UpdatePanel.

I’ve made a screencast to demonstrate the problem. The upper  part is an update panel that contains a div with a textbox. The div is hidden. The left lower button opens the dialog with the div and the right lower button alerts the textbox value. Look what happens, especially after a callback is generated:

Download the video 

The Cause

In short - The way JQuery’s dialog and ASP.Net’s UpdatePanel work collide.

In details – UpdatePanel is translated into a DIV element. When you generate a callback in it, the div content is being sent to the server. So if you have a textbox there, it will be sent as part of the server request.
The JQuery UI dialog, in order to avoid, I guess, z-index hell and other happy-happy-joy-joy stuff, takes the DIV that you want to present in the dialog and moves it to the end of the body element.

So… one side needs its elements in a certain place, and the other one takes them out of there.

This is the time when all hell breaks loose. You may start running for your life now.

The Solution

The exact line, where JQuery takes the div away is on the dialog’s init function:
(this is from the 1.6rc6 version but the exact thing appears in the 1.5.3 version)

uiDialog = (this.uiDialog = $('<div/>'))
    .appendTo(document.body)
...

This line constructs a new div for the dialog (it will contain the title and buttons as well). This isn’t our div yet. The next line actually takes our div and adds it to this new div:

uiDialogContent = this.element
    ...
    .appendTo(uiDialog),

So the obvious solution is to remove the .appendTo(document.body) line. This doesn’t work. If you try that, you’ll see the dialog fine on the first click, but from the second click and on you won’t see the dialog at all, only the overlay background…

What I eventually did, was commenting out the appendTo(document.body) line and registering to the dialog close event, where I moved my div to its initial parent:

function showDialog()
{
    // Save the dialog div parent
    parentContainer = $("#myDialogDiv").parents().get(0);
    
    // On close, take the div back to where it belongs
    $("#myDialogDiv").bind('dialogclose', function(event, ui)
    {
        var myDiv = $("#myDialogDiv");
        myDiv.css("visibility", "hidden");
        myDiv.css("display", "none");
        myDiv.appendTo(parentContainer);
    });
    
    // Show the dialog
    $("#myDialogDiv").css("visibility", "visible");
    $("#myDialogDiv").css("display", "block");
    $("#myDialogDiv").dialog({
        modal: true,
        overlay: {
            backgroundColor: '#000',
            opacity: 0.5
        },
        buttons: { Close: function() { $(this).dialog('close'); } }
    });
}

This actually works but I’m scared of its consequences. It just doesn’t feel right… This is why I ended up not using it, even though I like it very much.

If you have a solution, please comment!

All the best,
Shay.

Share it: kick it! | shout it! | dzone it!

Posted by shayf | 14 comment(s)
תגים:, ,

IronPython 2.0.1 Has Just Been Released!

IronPython 2.0.1!

Great news for all IronPythonists! a new version is available!
This minor update fixes some bugs and improves performance.

Go and get it: http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=12481

All the best,
Shay.

Posted by shayf | with no comments
תגים:,

Suicidal Programming

Hey you! yes, you! you’re sitting there, coding in your nice little chair with a few silly games surrounding you, think again!
Your programming language has many integrated abilities to hurt you!

Suicidal Programming

Do NOT take anything in this post seriously. Thank you.

Commit suicide:

Ruby: undef self
C#: this.Dispose();

Jump From The Window:

BLOCKED SCRIPT window.open(); throw self;
(Credits to NadavE)

Seppuku (AKA Hara-kiri)

C#: this.ToString().Split();

Heart Transplant

C#: this.ToString().Replace(“Heart”, “hmmm”);

Murder

C#: System.Diagnostics.Process.Kill(someone);

Execute at Town Centre

BLOCKED SCRIPT
InTownCentre = New RegExp
InTownCentre.Execute(resisters)

Just a Stomach Ache

VB.Net:
Dim cookie = New System.Net.Cookie()
cookie.Expires = New DateTime(1950, 1, 1)

Thinking of another way I haven’t mentioned? add a comment!
And next time you’re calm and relaxed while your IDE is open, beware!

Enjoy!
Shay.

Like this post? Share it! Ninja? Kick it! Heavy rocker? Shout it! Don’t like C-Zone? DZone it!

Posted by shayf | 2 comment(s)
תגים:

SVN Error “Can't open C:\WINDOWS\TEMP\report.tmp Access is denied” on Update

The Problem
You try to execute an Update operation and you get an error: “Can't open C:\WINDOWS\TEMP\report.tmp Access is denied”.

The Solution
This is a server problem. In order to fix it, do the following:

  1. Go to your SubVersion server
  2. Open the services console (Start->Run->Services.msc)
  3. Find the SubVersion service
  4. Restart it.

Enjoy!
Shay.

Posted by shayf | 1 comment(s)
תגים:,

Moving my old blog posts here

Hey, just letting you know that in the next couple of weeks I’ll be posting here articles from my old blog (which is officially going down in the end of the month). Sorry for the “spam”.

Happy Elections Day!
Shay.

Posted by shayf | 1 comment(s)
תגים:

Make Your Application Extendable Using the DLR

It’s very common for applications to have a way to extend them. Extensibility comes in various ways and have multiple names too – plug-ins, add-ins, addons, etc. It seems, though, that one kind of extensibility was left to the very few – application macros.
The concept is very simple – You don’t need to create a special Dll, implement a specific interface and register it somehow, you don’t even have to install an IDE. All you have to do is to open the relevant window, write some code and voila – you’ve extended the application.

What is this post about?

I’ll start with the result.
I built a simple application – it has a textbox, a “Send” button and a larger textbox for the application output. The flow is very simple – the user writes text in the textbox, hits “Send” and a “Hello” message appears in the larger textbox:

Extending Applications using the DLR - Sample #1

The power lies in the button on the bottom of the form - “Extensions”. Clicking there will open the extensions dialog, where you can write a macro which will be run after the user clicks “Send”. The users can choose the language for their macro, which will be one of the DLR’s languages – IronRuby or IronPython. After the user writes the code and hits “Save”, the application is extended!

Extending Applications using the DLR - Sample #2

 

Now when the user clicks send, look what happens:

Extending Applications using the DLR - Sample #3

This sample is very simple but it took me about 20 minutes to get it done. It’s just magic!

How was it done?

Well, all the credit goes to the DLR. This amazing little thing, makes it soooo easy to integrate dynamic languages into the .Net environment, that it’s a shame not to do so.

The heart of this application is the ExtensionRunner class and its Run method:


public static bool Run(Form1 frm, string code, bool rubyCode)

The method receives 3 parameters – the form object to pass to the executed code, the code that the user has written and a boolean value indicating whether it’s ruby or python code.

Firstly, I declare a ScriptScope and a ScriptEngine variables and fill them with the chosen language implementation. Because all DLR languages implement the same interfaces and classes, this is the only language-related code here. After that, the code will fit every DLR language. This means that adding IronScheme and Nua here, for instance, will be a matter of seconds:


ScriptScope
scope = null; ScriptEngine engine = null; if (rubyCode) { engine = Ruby.CreateEngine(); scope = Ruby.CreateRuntime().CreateScope(); } else { engine = Python.CreateEngine(); scope = Python.CreateRuntime().CreateScope(); }

Now we declare variables that the macro code will be able to use. We declare 2 variables:

  • frm – which is the form object. you wouldn’t want to do that in your application, the right way will be to pass a class with targeted functionality for the extensions.
  • return_value – the extension will put a value here. It’s a boolean value which indicates whether we should continue with the regular flow of the application after the extension has been executed or stop.

scope.SetVariable(
"frm",frm); scope.SetVariable("return_value", false);

The rest of the code is pretty straight forward – I create a ScriptSource object from the given code and execute it. Then I get the return_value value and return it to my main application.


// Run the code!
ScriptSource source = engine.CreateScriptSourceFromString(code, SourceCodeKind.Statements); source.Execute(scope); // Get the return value bool retVal = scope.GetVariable<bool>("return_value"); return retVal;


This is it. The other code of the application is just a regular WinForms code so I won’t deep dive into it.

Conclusion

In conclusion, the DLR makes it very simple to run dynamic languages from your .Net code. I showed you here only one of the possibilities that are made available with this kind of integration.

Go ahead and try!

Download the source code

All the best,
Shay.

Like it? Share it: Loves soccer? Kick it  | Angry? Shout it  | In DA ZONE? DZone it