views:

3417

answers:

6

I want to use Thickbox (or one of the varieties) on our site to display information messages returned from the server. Examples include warning messages returned from biz logic, etc.

The first place to need this functionality will be the navigation buttons on an asp:wizard control. When the user tries to move forward, we validate their product selections and may have messages we need to display.

For testing, since I'm new to JQuery and Thickbox, I created a test page. The relevant part is below:

<asp:Panel runat="server" ID="pnl" Visible="false" style="display:none;background-color:Black;">
<div style="background-color:Black; width=300; height=200; ">
    <asp:Label runat="server" ID="lblMessage" ForeColor="White" />

    <script language="javascript" type="text/javascript">

        function showMessage()
        {
            tb_show("Message", "#TB_inline?height=200&width=300&inlineId=<%# me.pnl.ClientID %>", null);
        }

        $(document).ready(function() { showMessage(); });

    </script>
</div>

Currently, I get the Thickbox to display in IE7, but it's doubled. I get two vertical Thickboxes stacked together, both with title and close buttons, only the top one has my content.

In Chrome, the window gets the grayed out background, but no thickbox window is visible.

When I wrap the whole thing inside an AJAX UpdatePanel, I get nothing.

What am I doing wrong?

Kevin

OK, so more info. I've gotten both Thickbox and another one called LightView to sort of work. The following script block is static in the page (Thickbox version):

<script type="text/javascript" language="javascript">
        function showMessage(sender, args)
        {
            tb_show("Message", "#TB_inline?height=200&width=300&inlineId=ctl00_ctl00_cph1_cphMain_pnl", null);

     }
     function StartWatch() {
         var prm = Sys.WebForms.PageRequestManager.getInstance();
         prm.add_endRequest(showMessage);
     }

The postback sets the text of the label, which is inside the div specified in the call to tb_show. I get that the prm.add_endRequest call needs to be invoked before the postback fires.

There's several problems. First, entirely too much of this is hardwired -- an asp:panel and label in the page, the ID of the div spelled out, etc.

What we really want is to be able to invoke this from any code behind in some fashion like:

Page.ShowMessage("Hello lightbox!")

I'm thinking I could have some script and a DIV contained in the master page file. It would be hidden until invoked.

However, I need to be able to:

a) control when this happens. Not every AJAX request (in fact, most will not) need to have a message displayed when it returns. So, I would either not have to invoke the endRequest method, or have the endRequest method check something that comes back from the AJAX call to determine whether it really needs to call showMessage().

b) I'll need to find a way to have the UpdatePanel contain something with the message. If I could execute a line of JavaScript that would update a hidden or set the content of the hidden message DIV BEFORE the call to showMessage(), I think we'd be good to go.

The thickbox addin uses JQuery, the Lightview uses prototype and scriptalicous. Lightview is much fancier -- better images, animation, etc. I don't really care which.

I'm using the AJAX (Atlas) framework built into .NET.

Any advice on how to proceed would be appreciated.

A: 

One thing i've often encountered is that when you return javascript from an AJAX request, it won't get executed by default, for security reasons, and you have to enable it in your ajax request. Sorry to be a pain, but i only know the setting in Prototype, not Asp.Net AJAX - however at least it's something to check?

Chris
A: 

If you want to control when the message is displayed with endRequest, one really simple method is to use a variable. Set a hidden input field as a flag (should be in the update panel as otherwise it would not be updated). Then, in your ShowMessage function, always read the value of the hidden input. If set, then popup the Thickbox. Else, do nothing.

As for the item b, you could go the same route (but this might just pepper the view with lots of unnecessary hidden fields). Any thoughts of using page methods or web services? It's lot more flexible for interaction.

Dhana
+1  A: 

Late answer, but maybe not too late. I'm a litte bit confused by your question, I will just answer this part :

What we really want is to be able to invoke this from any code behind in some fashion like:

Page.ShowMessage("Hello lightbox!")

Let's do it with Thickbox and jQuery, that's what I'm familiar with, but this will give you the general idea to reproduce it with Lightview. First, you'll need a client script to convert the "Hello lightbox!" message into a html element and then use it as an inline content with TB. To do that, we will create a div with id myTBInline:

function showMessage(message)
{
    var divId = "myTBInline"; // You can change this id...

    var div = $("#" + divId); // try to retrieve the div if it exists

    if (div.length > 0) // if div already exists (previous call)
        div.empty();    // then remove its content
    else
        div = $('<div id="' + divId + '"/>'); // else create it

    // add the message to the div
    div.append(message);

    // display Thickbox using the div as inline element
    tb_show("Message", "#TB_inline?height=200&width=300&inlineId=" + divId, null);
}

This was the hard part. Now comes the easy part, being able to call that from the code behind. You'll have to add a method, where you want as it can be static/shared. I normally use C#, but I'll try to write it with VB Syntax for you (the last time I used VB.Net was back in 2005 ;)

Public Shared Class Thickbox
    Public Shared Sub ShowMessage(Type type, string message)
        Dim script as String = "showMessage('" + message.Replace("'", "\'") + "');";
        ClientScriptManager.RegisterStartupScript(type, "Thickbox", script, true);
    End Sub
End Class

Here you go. From within your page, you can use the method this way :

Thickbox.ShowMessage(GetType(), "Hello Thickbox!");

Check out this other question on SO. The implementation uses jqModal and is very small (no need for a client script).

ybo
A: 

I have has the problem that using lightbox in conjection with the jQuery library can cause some issues, where lightbox just wont load properly due to a conflict somewhere.

The way round this I have found is to use a jQuery version of lightbox. http://plugins.jquery.com/project/jquerylightbox_bal.

TheAlbear
A: 

Another method is to overwrite JS's built in alert() and confirm() functions with your modal of choice (instead of displaying what you might think of as the browser's default modal).

http://dev.iceburg.net/jquery/jqModal/#examples and scroll down to "overrides" for an example. you can try it out in the firebug console while on this page. run: alert('zomg!'); in there.

function alert(msg) { //your modal js here. }

Don't know much about asp.net but I'm assuming sending alerts is something it'll help you do by default. This will just override the default action.

Will Moore
A: 
Lawk Salih