Sliding Task Lists project (day 5) – Reorder Lists and client side update panel refresh

Yesterday, I have added the ability to save new tasks without postbacks to database. Today, I’m going to bring the lists to life. So far, you could have notice that lists with the tasks were simple html lists (mock up functionality), however today I’ll convert those lists to atlas control toolkit ReorderList control, because I want to allow user to order the tasks in list by the priority.

I will explain the code only for the first list („Big Tasks“) since the rest of the code (for other lists) is pretty much same. So, here is how the code for Big Tasks list looks now:

OPEN CODE IN NEW WINDOW

You notice that I’ve wrapped the whole code in UpdatePanel. This is so because I want to refresh this list when user adds new task (NOTE: If you don’t intend to allow users to add new items or edit existing items, you don’t need Update Panel. Reordering works well without it as well).

I’ve already written the post on ReorderList (you can read it here), so I won’t repeat myself. However, this time I’m using SqlDataSource, and in that data source I make sure that only the big, uncompleted tasks for the currently logged in user are pulled out. The update command simply changes the priority (hmm… I must admit I’m not sure do I need this update command here… maybe it would work without it as well?!).

Anyway, I’ve made a textbox where I put the user name when page loads so I can use it here in this select statement (in case you wonder what is ‘txtUserName’).

The last thing I have in this update panel is the hidden link button. I use this so that I can call the click event on it from javascript and in doing so refresh the update panel. Now, you may wonder why I haven’t simply added trigger for control event and hook it up to the save button in ModalPopup. I’ve tried, but it doesn’t work. Seems like this button is losing it’s ability to do postbacks when inside of the ModalPopup. I’m not really sure on why is this not working, but for the time being, I’ll just let it be at that. I’m sure there is some theoretical explanation for this, but I thought a little mystery could bring some more readers :) … hmmm maybe some violence would help as well… ok, back to atlas.

The change in javascript file (tasks.js) is following:

OPEN CODE IN NEW WINDOW

You’ll notice that in AddBigTask_Callback function, just before I tell user that “new big task has been added”, I call __doPostBack(‘lnkRefreshBigTasks’,’’). This is the very same function that would be called if that hidden link button inside of the update panel would be clicked. I’m pretty sure this is not the best / intended way to refresh the update panel from javascript, since it is obviously looks like a hack. However, up to now, I have not found a more appropriate method of doing this.

Tomorrow, I’ll be polishing the application… styling the look and feel, adding update progress images and making sure it works in IE and FF as well.

The working version of STL can be found here : www.reblogger.com/lab/STL


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


Sliding Task Lists project (day 4) – database tables and saving new tasks with atlas

After the most of UI has been created, in order to get this application to actually do something, I needed to add one database table and one stored procedure. The ‘tblTasks’ table will hold all the tasks, regardless of their type and who do they belong to. Here is how the table looks like:

IDTask – int
UserName – varchar(100)
TaskTitle – varchar(500)
StartDate – datetime
CompletedDate – datetime
IsBigTask – bit
IsQuickTask – bit
IsEverydayTask – bit
IsCompleted – int

If you’d like the SQL script to create this table, open the following link:

OPEN CODE IN NEW WINDOW

In addition to this, I’ve also created a ‘pr_AddTask’ stored procedure that will add any kind of task to ‘tblTasks’. Take a look at the stored procedure:

OPEN CODE IN NEW WINDOW

Now, let’s go back to the application. In previous post I’ve created the three ModalPopups, each of them designed to add different kind of task to the lists. I will explain here the code logic for the “Big tasks”, since the rest of code is pretty much identical. First one little update from the last post. We don’t actually need UpdatePanel there, so I’ve just removed it. The three panels representing the ModalPopups are created by following code:

OPEN CODE IN NEW WINDOW

Next update from the last post happened in the ModalPopupExtender. Open the code and I’ll discuss it then:

OPEN CODE IN NEW WINDOW

You can see that I’ve added OnOkScript property to the each one of the extenders. This property holds the name of the javascript function to be called, when user clicks the “Save” button in our “add task” panels. Since you can see that we are going to use javascript, naturally next thing we need to do is link our external javascript file to the default.aspx. so that looks like this :

OPEN CODE IN NEW WINDOW

To add tasks we’ll need to do two more things. First is javascript code that will call methods on web service and second the web service methods to actually add data to database. Let’s start with web service. Add new web service to your project and name it ws_tasks.asmx. Select option “Place code in separate file”. The code behind for this web service should look like this:

OPEN CODE IN NEW WINDOW

Notice that there are three methods; each one takes care of adding one type of tasks to the database. The methods receive task title and user name (of the current user logged in) as two parameters. The rest is pretty easy, so I won’t explain it here. Maybe just to note that @is_big_task, @is_quick_task and @is_everyday_task are optional parameters of ‘pr_AddTask’ stored procedure with the default value of false, so we don’t need to add all the parameters in each of the methods.

Before I forget, make sure to add the reference to this web service in your script manage tag. It should look like this :

OPEN CODE IN NEW WINDOW

And finally, the last thing we have here is writing javascripts that will call the methods on web service and send them the two needed parameters when user clicks ‘Save’. Let’s take Big Tasks for example. First we have ‘AddBigTask()’ function (remember that we set OnOkScript property of ModalPopup for BigTasks to this function). This function gets the value of the task title and the username of the user currently logged in. You’ll notice that I’m getting a userLoginName value here. That is nothing else then the value of <asp:LoginName control. Lastly we call the STL.Tasks.AddBigTask method on our web service. We send the two required parameters and add at the end the name of the function we want to be called back when task is saved in database. In the ‘AddBigTask_Callback(result)’ function I empty the textbox (reset it…) and simply give a user alert message that her task has been added.

OPEN CODE IN NEW WINDOW

Ok, that’s it for today. Tomorrow we are going to bind the data from the database to the lists, so after all this application will look like it works :) !


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


Sliding Task Lists project (day 3) – using ModalPopup extender to create panels for adding new tasks

ModalPopup extender
For people that read this blog for some time now, you may remember the post “Darken the page and set focus on the user input”. Ok here is a better/quicker solution and it’s called ModalPopup extender. Like the saying goes: live and learn!

Today, I’ve added panels (only the UI, the save button is not functional yet) that open when user chooses to add a task to one of the lists. Since, the application is designed to have three different categories of tasks (big, quick and everyday) I have three link buttons (“Add Big Task”, “Add Quick Task” and “Add Everyday Task”).

The code for link buttons looks like this:

OPEN CODE IN NEW WINDOW

Next thing I’ve done is added three panels, each representing my modal popup window, where I’ll let users enter the task. One panel holds the modal popup for “Big Tasks”, one for “Quick Tasks” and one of course for the “Everyday Tasks”. You’ll notice I’ve wrapped the code inside the panel in UpdatePanel control, so that I can later perform saving to database without a full postback. The code for these three panels looks like this:

OPEN CODE IN NEW WINDOW

The last thing I’ve done today was adding the ModalPopupExtender, so that I can convert those panels into modal popup windows. Take a look at the code first and I’ll explain then the ModalPopupProperties for the first panel:

OPEN CODE IN NEW WINDOW

TargetControlId property determines which control will fire up the modal popup. In my case those are the link buttons I’ve added at the top in the action bar. Next property is PopupControlID. This property indicates which control will act as modal popup window. In my case those are the three panels. Next property is the BackgroundCssClass, which is really interesting feature. It lets you set the css class for the whole background screen behind your popup. Keep reading, because I’ll show you the CSS I’ve used to make background blurred and transparent. Next property is OkControlID. This is simply the id of the control that represents confirmation or ok (hehe) button of your popup. You’ll notice I have a save button in each of the panels, and those are my OkControls. Following control is cancel control and similar to the ok control, this one represents cancellation (closes popup with no actions/consequences).

Now we are only left with the css and few tricks there. First of all, here is the css for the transparent blurred background (remember the BackgroundCssClass property we set to modal_bg) :

OPEN CODE IN NEW WINDOW

You need to use filter and opacity properties both, because one works in IE and not in FF and vice versa. However the 70 and 0.7 both represent 70% transparency.

And finally the last thing. I’ve noticed that I need to set to my panels position:absolute, otherwise they all show when page loads. Try leaving that out and you’ll see what I mean.

OPEN CODE IN NEW WINDOW

The working (take that working with reserve. Only the things explained on this blog are working.) application can be found here :

http://www.reblogger.com/lab/STL

Tomorrow we’ll create the database tables and add code for adding/saving new tasks, so drop by if you get a chance.


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


Thanks Shawn – CascadingDropDown extender (explained)

Several days ago I wrote a post on CascadingDropDown extender. I was a bit frustrated and blog about it, because I have thought it is only possible to use this extender
in conjunction with xml document. Turns out, you can use it with datatables indeed.

Thanks to Shawn Burke from Microsoft (that’s a world class support,ehh? I ask question on my blog and they answer it on my blog :) here is the solution :

http://atlas.asp.net/atlastoolkit/Walkthrough/CCDWithDB.aspx

The walkthrough is written in C# however, so I’ll write a VB version of it pretty soon.Anyway, I’d like to thank Shawn once again. Very nice gesture.


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


Sliding Task Lists project (day 2) – implementing Asp.NET 2 membership provider

Sliding Task Lists project - login page
Today I’ve protected the Sliding Task Lists application with Asp.NET 2 membership provider. Since we are using SQL Server 2005 (remotely) and not SQL Express we needed to do several things in order to complete this step.

I will not go in details here, since Membership provider is way out of scope of this blog, but for starters here are few links : This is a quick start for Membership provider and here is the blog post on how to get membership provider working on full blown SQL Server 2005.

So, basically today I’ve created the login page. You’ll notice some degree of atlas being used there. When you click the “Register!” button, CreateUserWizard appears without postback. This was done very simply with using two UpdatePanel controls. I have noticed that standard Login control has issues with UpdatePanel, so I left that out. The CreateUserWizard on the other hand works fine inside of UpdatePanel.

I’ve also used the little processing image there, which I’ve explained in detail how to create in this post : Always visible loading image.

I have not zipped the whole project yet, since there is not so much to be seen. However, tomorrow or day after tomorrow when I get into more exciting atlas stuff, I’ll provide you with daily updated project files.

Till then, feel free to visit the Sliding Task Lists project and register. Keep in mind that I’ve just laid down the html interface, nothing is functional yet, but we are getting there :)


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


Sliding Task Lists project (day 1) – building a user interface

I like to start web applications by making the user interface first. That way it’s much easier for me to understand the scope of the project and even define it. The design itself, I’ve done in the very first part of this series. Today I’ve done the HTML/CSS part of this application (you will notice that links don’t do anything… it’s pure HTML/CSS – no atlas yet).

You can check out how it looks like on reblogger lab :
http://www.reblogger.com/lab/STL

I’m working on getting this folder to be an asp.net application, so that I can provide you with a live functioning example every day.

There is really not too much to be said about the today’s work, except that it needed to be done. I haven’t used tables for design, and basically I’ve just laid the groundwork.

Tomorrow, I will add the Asp.NET membership provider so we can all use our own lists :).


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


Sliding Task Lists project – building an atlas application from a scratch

Sliding Task Lists project
After explaining numerous Atlas functionalities on this blog, I’ve decided it would be a good idea to put all these concepts into practice. So, over the period of next 10 days or so, I’ll build a small, but completely Atlas based application. Along the way, I’ll write regular blog posts about everything being done and how I did it.

The “sliding task lists” application is a kind of to do list, that I practice every day for my work, but I’m using notepad for it (not so web 2.0, ehh?). Basically, I’m going to build this application for myself and show you the process. There is a possibility, the actual application will be hosted somewhere on reblogger lab, but I’m not 100% sure just yet.

So, here is what I need. All my tasks are divided into three different lists.

  1. “Big tasks” – when I’m developing reblogger, adding a new feature to it represents the big task, since it can anywhere from several days to several weeks to get it done.
  2. “Quick tasks” – this is for example adding a contact page on reblogger.com. Something that takes at most 1-2 hours. I decided I will do every day one item of this list, so that I don’t get buried in those little things.
  3. “Everyday tasks” – this is something that I need to do everyday, no matter what else pops out. Writing a post on this blog is one of these everyday tasks.

The idea is following. I have to do ALL the tasks from my “everyday tasks” list every day. Pretty obvious. I have to do 1 (but I may change this in future) of “quick tasks” every day. The rest of the day I spend on working on big tasks. I always work on the first item in the list, so the order is important since it indicates priority.

Some other requirements: I want to be able to add tasks, edit them, and delete them. I want to be able to reorder tasks when my priorities change. I want an easy way to mark task finished. And finally I want to have a way to see what I’ve done so far this day and what I still need to do.

I’m going to use atlas to build this application. So obviously, you can imagine there will be no postbacks, but there will be a lot of drag-and-dropping and stuff like that.

I’ll work for about 2 hours a day on this project and every day I’ll blog on this. Feel free to ask questions, give suggestions or simply criticize me when I do something that could be done much better.

I hope you’ll have fun with this series and maybe even learn a thing or two.

I’ve opened the flickr set with the GUI mock up, so you can go there and check it out.


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


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?”


Follow

Get every new post delivered to your Inbox.