CascadingDropDown extender

The time has come for me to write an opinionated post. In today’s post I will not explain anything, although I was going to…

Being so madly obsessed with drop down lists lately (you’ve had a chance to follow my obsession thorough the posts on this blog), I’ve decided to give a try to CascadingDropDown extender. After all, it seemed as a really nice and easy way to get around all the javascript / xml-script and still have client side data binding.

So, I’ve studied it a bit, watched the video, opened the examples, then read the documentation again… It was quite confusing, I’d even say mysterious. This extender is more designed as a puzzle game than something that should improve our (developers) productivity.

Nevertheless, I’ve started to play around with it, but than bang! One needs to use xml as data source to be able to use this extender. Ok, I will allow that I have misunderstood something, but take a look at this screenshot yourself. Intellisense does no suggest any other solution than xml.

What a ...?

Don’t get me wrong, xml is cool and I have nothing in particularly against it, but was it really that hard to enable this extender for data set, data table or even a simple string array for that matter? Do I really need to write the code to get data out of sql server, make an xml document out of that data, then bind this extender to this xml document, because if so I’ll just stick with the xml-script and javascript.

If you managed to understand how to use CacadingDropDown extender with data tables, please let me know. Leave a comment or just drop me an email (it’s on the “about” page).


This blog is being delivered to you by
reBlogger.com
“Do you know what your employees are blogging about?”


Master / Detail drop down lists – client side data binding

Master Detail Drop Down Lists
Today’s post is a response to a comment I’ve got from Rajesh. Before I go on with the post, I’d like to thank Rajesh for being one of my readers and giving a feedback. So, first the comment:

“I have a scenario of client binding where I’m facing problems. I have two select boxes which will be loaded on load using client side data binding. On selecting data of one select box, data in the second select box needs to be re-binded accordingly. (like selecting ASIA in one selectbox should only load Asian counties in the second select box).”

So, in today’s post I’ll make a following example : we’ll have two select elements. First one will have the names of countries, the second one will display the names of cities, based on which country we’ve chosen in the first select element. I’m not going to use Rajesh’s example with continents and countries, because I’ve already have this web service done (countries/cities) so I can reuse it. However, the principle is identical.

The list of countries we will load as soon as the page loads, but the list of cities we will load once user chooses the country.

For getting data we’ll need a web service. It is the same web service I’ve used in Master / Detail post with ListView, only this time we’ll use two select elements. We’ll name the web service geography.asmx. This is how this file looks like:

OPEN CODE IN NEW WINDOW

The code behind for this file looks like this:

OPEN CODE IN NEW WINDOW

As you can see the GetCountries Function has DataObjectMethodType.Select attribute, and that is because we want the countries to load as soon as page loads, so we’ll use dataSource component in xml-script. As you can see, here I’ve simply created manually a DataTable and return it. You would probably retrieve data from SQLServere here.

Next method you can see is GetCities. This is a simple WebMethod, because we will call it from javascript (we won’t use it with dataSource component). It takes one parameter, namely IDCountry, and returns the cities located in that country. Last function in this class, simple creates and fills DataTable with cities.

Now, let’s go to the default.aspx page, where we are going to set up our select elements. First make sure you register ScriptManager. You’ll also need here a reference to geography.asmx web service so that we can call its methods from java script. This part of code should look like this:

OPEN CODE IN NEW WINDOW

Now, we need to create two html select elements. One we’ll name selCountries and other selCities. For selCountries, we’ll define onchange event to call “selCountries_Change” function in javacript (this function will be called every time user changes the selected index > in our case every time user chooses different country). For selCities we’ll define onchange event to call “selCities_Change”. This function will simply show user a message that says something like “You have selected New York as your favourite city!” > obviously the name of the city is actually variable and depends on which city user chose. This part of code looks like this:

OPEN CODE IN NEW WINDOW

Now let’s see our xml-script. Take a look at the code first and I’ll explain it then:

OPEN CODE IN NEW WINDOW

First we set up the dataSource. I’ve explained this many times, so just briefly. We want it to load as soon as page loads, and use the geography.asmx as its web service. Then we’ll declare selCountries select element and bind it to this data source. If in doubt about this part of code, please read first Drop Down List – Client Side Data Binding Post.

Next thing we do, is declare our selCities select element. You will see that the process is pretty much the same as for the selCountries select element with one important change. We did not define dataContext for it, nor did we define bindings. This is because we are going to bind data to this select element through javascript (in the selCountries_Change function; remember how we set that event in html!).

Last thing we have to do is write the javascript to handle the change events of our select elements. Take a look at the code first :

OPEN CODE IN NEW WINDOW

First function is the selCountries_Change() function, which is invoked every time user chooses a different country. We don’t want to do anything if selectedIndex is 0, because first item in our select element is simply an instruction (“Choose a country”). If user selected something else, we find the value of that choice (that is the IDCountry value) and call BindCities function with that value as a parameter.

The BindCities function will call GetCities function on our webservice and send it the IDCountry parameter, so that GetCities functions knows which cities to return. The second parameter is the name of the callback function. Callback function is the function that web service will call once it has the data and to which it will send the data.

The BindCities_Callback function is called by web service and receives data table with list of cities for chosen country in results parameter. You see how we first get reference to the atlas representation of our selCities select element (we do that with dollar sign). Then we call selCities.control.set_data(results) function. This is something similar to asp.net’s data source property (e.g. in asp.net with drop down list you would do selCities.DataSource = results). Last thing we do here is call evaluateIn method on selCities (in asp.net that would be selCities.DataBind()). So to wrap it all up, we get the reference to select element, set it’s data source with set_data method and finally bind the data to the control.

At the end there is just a simple selCities_Change function. This function is called every time user selects different city. Here we just find which city user chose and give an alert message telling him that he chose that particular city. Obviously, you would replace this code with something more useful.

The whole project you can download from reBlogger lab.


This blog is being delivered to you by
reBlogger.com
“Do you know what your employees are blogging about?”


Always visible loading image

Loading image
In the new version of reBlogger due to come out some time this week, I’ve realized that I need some way to position update progress image so it’s always visible. Because, depending on how many keywords user enters in reBlogger, the page may become quite long and need scrolling, so having an update progress being fixed at one position was not an option. Basically, I wanted the little “loading…” animated gif to appear in the top left corner every time there was a asynchronous postback (via update panel).

So, here is the idea: I decided I’ll combine the atlas:UpdateProgress control and AtlasControlTookit AlwaysVisibleControlExtender. So the UpdateProgress control would make sure the animated gif is displayed only when there is a partial update (via UpdatePanel) and AlwaysVisibleControlExtender would make sure that, when displayed, animated gif is visible on top of everything in the top left corner of the screen.

This is how I’ve set up the code for displaying the animated gif :

OPEN CODE IN NEW WINDOW

You’ll notice that <asp:Panel surrounds the <atlas:UpdataProgress control. This is because, it is not possible to use AlwaysVisibleControlExtender directly on <atlas:UpdateProgress control. The UpdateProgress control itself is very simple. All you do is declare the ProgressTemplate, which will be displayed whenever there is a partial update.

The AlwaysVisibleControlExtender has several properties that I’ll explain here: TargetControlID is the id of the control that we are going to extend with this extender (in our case it’s the surrounding panel “pnlLoading”), VerticalSide can be top or bottom, allowing positioning this element on top or the bottom. Now, it would be really cool if we could set this to middle, but we can’t! The HorizontalSide property sets the element left or right. The VerticalOffset and HorizontallOffset properties set the margin between the end of screen and your element vertically and horizontally.

Last property is ScrollEffectDuration. Here I’ve 0.1 seconds, the larger this number is it will take longer time for our loading element to keep up with scrolling.

The whole project you can download from reBlogger lab.


This blog is being delivered to you by
reBlogger.com
“Do you know what your employees are blogging about?”


Master / Detail – client side data binding

Master detail client side data binding
In two previous posts about client side data binding I have demonstrated how to bind data to drop down list and list view (atlas equivalent of DataList, resembles GridView as well). Now, since we know how to these two, let’s combine that knowledge to solve classic master detail task.

In our example we want to bind list of countries to drop down list. Then when user chooses any of these countries we will cities that are located in that country in a ListView. Very simple, but will prove the point.

First thing we need to do is to add a WebService. Add new item to your project (Web Service), name it geography.asmx and check “Place code in separate file”. We will need to change the Class attribute from “geography” to “Reblogger.Samples.Data.Geography” (we need the namespace attribute in order to call the functions from javascript). Here is how the geography.asmx file will look like :

OPEN CODE IN NEW WINDOW

Now, let’s go to our web service code-behind file, namely geography.vb. We need to add a namespace declaration here (Namespace Reblogger.Samples.Data – you could name this namespace anyway you wish). Second thing to change is the inheritance of our Geography class : instead of WebService, make it inherit from Microsoft.Web.Services.DataService. Anyway, take a look at the whole class :

OPEN CODE IN NEW WINDOW

As you can see the GetCountries Function has DataObjectMethodType.Select attribute, and that is because we want the countries to load as soon as page loads, so we’ll use dataSource component in xml-script. As you can see, here I’ve simply created manually a DataTable and return it. You would probably retrieve data from SQLServere here.

Next method you can see is GetCities. This is a simple WebMethod, because we will call it from javascript (we won’t use it with dataSource component). It takes one parameter, namely IDCountry, and returns the cities located in that country. Last function in this class, simple creates and fills DataTable with cities.

Ok, now we are going to default.aspx page. We need to set up drop down list and listView in code (take a look at previous posts about client side data binding if in doubt how to do this).

OPEN CODE IN NEW WINDOW

Now in xml-script we make DataSource for countries and bind it to the drop down list :

OPEN CODE IN NEW WINDOW

Next thing we do is define our listView. Everything is same as in this POST, but notice that we are not binding the listView itself to no dataSource. This is because we will do it dynamically based on the selected value of our drop down list :

OPEN CODE IN NEW WINDOW

Last this we have to do, is provide javascript code that will bind listView with the list of appropriate cities every time user changes the country.

OPEN CODE IN NEW WINDOW

As you can see here, first we have function that get’s the selected value of drop down every time selected index changes and calls BindCities function with that value. Note that selected index must be greater than 0, because first item in our drop down is not a name of a country, but “Choose a country…” text.

Next we have BindCities function. This function calls the Reblogger.Samples.Data.Geography.GetCities() function and sends it id_country as a parameter. The second parameter is the name of the so called callback function. Basically we are telling the web service that once it has data, it should send that data to that callback function.

And at the end the BindCities_Callback(results) function. Notice how it has parameter “results” > that parameter holds the data that server returned. First we need to find our listView (we do it with the $ sign), then we set it’s data source and at last call evaluateIn method on it. As I’ve already said before, evaluateIn is atlas equivalent of asp.net’s DataBind().

The whole project you can download from reBlogger lab. This project you should really download, because even though I’ve explained most of the things in the post, I think it’ll be much more easier to understand it if you can look at the working example. Just a thought :).

p.s. Do not forget to add service reference to your ScriptManager tag. It should look something like this :

OPEN CODE IN NEW WINDOW


This blog is being delivered to you by
reBlogger.com
“Do you know what your employees are blogging about?”


Tooltip on steroids


I know I’ve promised a little series on client side data binding, but here is one quick and dirty post just to break the monotony.

As I’ve been developing reBlogger for past year or so, many times I needed a quick and simple way to explain some of the features to the user. reBlogger is, what we beleive to be, a very unique application and here and there we simple need to provide users with some instructions to understand some of our revolutionary (I never claimed I’m humble!) concepts. We’ve tried using builtin tooltips (atl attribute) on images, but they are very limited (they only represent text and in some browsers the length of text is severely limited).

So, here is an atlas way of making your own tooltip and I will creatively call it : “tool tip on steroids” (I bet you haven’t heard that one before).

We’ll set up just a small form with two input fields, and two tooltips next to the textboxes. When user hovers over the image, our super tooltip will appear.

For the tooltip image we’ll use <asp:Image control, and the image should be something suggestive, like a question mark. Here is the complete code for the tooltip, because it’s very simple and I’ve wrote already about something similar:

OPEN CODE IN NEW WINDOW

So first we have the <asp:image control. Nothing special here. Next control is the <asp:panel control, which represents our tooltip. Feel free to go nuts here, whatever crazy HTML you put in there it’s ok. The last thing and the one actually making it all happen is Hover Menu Extender (part of AtlasControlToolkit).

Several things that we need to set up here : PopupControlID (the id of our tooltip, in our case the id of the <asp:panel control), TargetControlID (the id of our <asp:image control, in our case the little question mark gif). Basically we say, when user hovers over the TargetControl show PopupControl. There are two optional properties that we’ll set here. First is PopupPosition (I’ve put it right, so popup doesn’t display over the form) which determines at which side in respect to the TargetControl should PopupControl appear. Second property is OffsetX – I’ve set this to 20, which basically means that TargetControl and PopupControls should be 20px apart horizontally.

And that’s it.

You can download the whole project from reBlogger lab.


This blog is being delivered to you by
reBlogger.com
“Do you know what your employees are blogging about?”


ListView – client side data binding

As I continue to write my series on client side data binding, the next obvious choice was the listView. ListView is in my opinion as close as Atlas gets to Asp.Net’s GridView or DataList.

So anyway, basically what we want to do here is bind the very same datatable from our previous post (list of names and emails) to listView control. We’ll create the webservice file first. To add webservice file, you’ll right click on your project (in solution explorer), then click “Add new item”, then you’ll select WebService, name it dsNames.asmx and check “place code in separate file”.

The dsNames.asmx file will look like this :

OPEN CODE IN NEW WINDOW

As you can see it’s only one line of code. It’s code behind file, dsNames.vb should look like this:

OPEN CODE IN NEW WINDOW

Read the previous posts for the explanation of this class if you need it.

Now we’ll turn to the default.aspx file, the asp.net page that will hold our listView and xml-script that will bind the data from web service to the listView.

First thing we need to do is to define our listView but with html (remember that’s how client side atlas works!). To do that, we’ll put an empty <div element with id=”namesList”. So it will look like this:

OPEN CODE IN NEW WINDOW

Next thing we need to do is define the template look for this listView. Take a look at the html and I’ll explain it then:

OPEN CODE IN NEW WINDOW

First of all you can see we wrapped everything into a div that with set to be invisible. That’s been done because this is just like an instruction to xml-script how to make our listView look like, it’s not something we want to show the user. Next you see there is ListTemplate div, which represents the layoutTemplate for our listView. This div contains all the other templates in our case it’s only ListItemTemplate. The div that represents the ListItemTemplate you can think of as ItemTemplate in DataList (or in TemplateColumn of GridView). Inside the ListItemTemplate we declared how we want each item to look like… notice only that we have two spans with ids _name and _email. Those obviously we’ll be bound to the data.

At the end we have a button that will bind the listView to dataSource once when clicked. If you are wondering how to bind it automatically, check out the previous post.

The last thing we need to do is, write our xml-script. Take a look first at how it looks like and then I’ll explain it:

OPEN CODE IN NEW WINDOW

First we have dataSource component. We set it’s id to dsNames (we need this to be able to reference it), serviceURL is dsNames.asmx (our web service).

Next you see is our listView. Now, as I’ve said all the controls in client side atlas need html elements to represent them. In our case listView is represented by an empty <div element with the id=”namesList”. We set it’s itemTemplateParentElementId=”ListTemplate” (take a look at the template html that’s invisible to find and element with same id).

Now, we need to set up the binding for the listView to our dataSource. So we set dataContext=”dsNames” (our dataSource id), dataPath=”data” and property=”data” (remember that this is always data when we are returning datatable, dataset or that kind of data).

Following this, we declare our layoutTemplate. This is simply our ListTemplate <div element.

Now last thing in listView we need to set up is the itemTemplate. As you can see we first set the layoutElement to the “ListItemTemplate” <div element (take a look at the hidden html part we wrote to find the element with such id). Then we have two labels, representing those spans in our hidden html. One is _name and one is _email. Two each of these we need to set the binding. We bind its text property to the Name/Email column (those are the column names in our datatable) from the dataSource that we bound in the first place to our listView.

At the end we have only one more thing to do. When we press the btnLoad button, we want the dsNames dataSource to load and bind the data to listView. So we invoke load method on the dsNames target.

And that’s it.

You can download the whole project from reBlogger lab.


This blog is being delivered to you by
reBlogger.com
“Do you know what your employees are blogging about?”


Drop down list – client side data binding

What's the deal with the peas?As I was trying today to find an example of how to bind data to the drop down list on the client side with xml-script (and refresh my memory), I was surprised just how few of those kind of examples are there on the internet. So, I’ve decided that in next several days I’ll write a little series with examples how to perform client side data binding with different kinds of controls. So, to kick it off with something simple I’ve chose drop down list.

There are two files that we need for this. First we need our good old default.aspx. On that page we will put the drop down list and the binding code (xml-script). The second file we need is a web service file, in my case named dsTest.asmx. That fill will give us the data that we are about to bind to the drop down. So let’s get the web service out of our way first.

We’ll add a new file to our project. From the list of files we’ll choose the “Web service”, we’ll name it dsTest.asmx and we’ll check the “Place code in separate file” checkbox.

The dsTest.asmx file has one line only and it looks like this :

OPEN CODE IN NEW WINDOW

The dsTest.vb file however, has the code that will give us our data when we request it. Take a look at this class first :

OPEN CODE IN NEW WINDOW

There are two very important things here. A) your class needs to inherit from the DataService class, which is a member of Microsoft.Web.Services namespace. And B) the GetMyData function that returns datatable needs to have it’s DataObjectMethodType attribute set to Select. You would do the same for update, delete or insert, but that exceeds the scope of this post.

Inside the GetMyData function you would typically substitute my code with some code that would return a table from SQL Server database or something like that. To make it simpler, I’ve just created a DataTable and populate it there in the code. I think I may have explained this part of the code, a while back in one of the other posts, but oh well… repetition is the mother of wisdom 🙂

Now, let’s go back to the default.aspx file. First we’ll set up our drop down list, which will contain the names of some people as its text property and email addresses of those people as its value property. When we change the name in the drop down list, we want the email address for that person to appear in a label. Now, all you Asp.NET freaks… we need to use html elements here, not your typical <asp: … kind of thing. So, the drop down list we represent with html <select> element, and label we represent with <span> element. If you ever looked at the source code Asp.NET generates you’ll see that indeed those are html equivalents of Asp.NET controls. So that would look something like this:

OPEN CODE IN NEW WINDOW

And now, last thing we have to do is add some xml-script code so these elements actually do something. The Atlas stuff. Take a peek at the code first and I’ll explain it then:

OPEN CODE IN NEW WINDOW

You’ll notice all the code is located between the components tags. First we have the dataSource component.

DataSource component will get our data. It’s rather similar to the SqlDataSource or ObjectDataSource controls from Asp.NET. First we set the id of this control (I’ve put dsNames). Then we set autoLoad=”true”, meaning that data will be loaded as soon page loads. And last property we set is the serviceURL. The serviceURL property we set to the dsTest.asmx – the web service file we’ve created in the first part of this post. Now, you may wonder how will this dataSource component know which function to call in our web service. Well it will call the one that has DataObjectMethodType.Select attribute, so that explains why was that very important.

Second component we want to declare here is our drop down list. Now, notice that for each html element we’ve created we need to make an atlas representation (so to say) of it inside the xml-script if we want to do anything with it. So we declare select component. We give it the exactly same id as we have to our html select element (this is very important, since that’s how it knows which element it represents). We then set dataContext=”dsNames”. You’ll notice that we named our dataSource “dsNames”, so this is like giving a datasource to this control. The firstItemText property sets the text of drop down for the first item, which is usually some kind of an instruction (like “Please select a name…” or something like that. And lastly, the two very important properties: textProperty should be set to the column name of your datatable that you want to act as text of your drop down item (in Asp.NET that would equal to DataTextField). valueProperty should be set to the column name of your datatable that you want to act as a value of your drop down item (in Asp.NET that would equal to DataValueField).

Next thing we need to define for our select (drop down list) element is the bindings. We set and id of binding that we may need later if we want to rebind this for some reason. dataContext is again the id of our dataSource. dataPath and property properties are set to data. Those two are always “data” if we are binding to some kind of datatable, dataset, array or that kind of thing.

And at the end of this element we’ll define a selectionChanged event. So basically what we do here is tell our select element that whenever selection changes it should invoke the “evaluateIn” method on bndEmail binding. We’ll get later to bndEmail element, so don’t worry about that. The “evaluateIn” method is roughly the same thing as DataBind is in Asp.NET, so whenever you want to rebind some binding you would typically call the evaluateIn method on that binding. And that’s exactly what we are doing here, rebinding every time selection changes.

The last element we have is label (the one that will display the email of the selected person). As you can see the id of this label is set to lblEmail, the very same id as we have set on our span html element (remember, we need to represent label in html elements, so that’s why we use span). We have declared the binding for this label and named it “bndEmail” (we need this id, so we can call “evaluateIn” on this binding every time selection in drop down changes). The dataContext this time is not our dataSource, but rather the selNames – our drop down list. Now, here it gets interesting. We have bound the text property (property=”text”) of our label to the selectedValue property (dataPath=”selectedValue”) of the selNames drop down list (dataContext=”selNames”). As you can see, data binding in xml-script can do a lot’s of things, not only get data from database.

I’m tired now. My mouth is dry. I hope it was worth it and you’ve got at least something out of this post.

Ahh yes, the whole project you can download from reBlogger lab.

p.s. What’s the deal with the peas? Well, I hate posts without images…


This blog is being delivered to you by
reBlogger.com
“Do you know what your employees are blogging about?”