Spring naar inhoud
30 juni 2011

Personal project called MessyBrain

Yesterday I launched my own little project on CodePlex called MessyBrain!
This way I hope to improve my coding skills and learn some new things. I never worked with ASP.NET MVC so this is the first hurdle to get over…

An extra pair of brain cells is always welcome!

 

MessyBrain

Project Description
Organize your tasks in an efficient way. Assign tasks to members of your team. Create workflows for your team.
Written in C# and ASP.NET MVC.

Why did I start this project?
Making mistakes is part of the learning process. They can be painful especially when they are made at work; there’s a cost attached to it.

Why not start a project on my own? Mistakes will be less painful (only my ego will be damaged), I learn something new and there isn’t a cost attached to it. I can share the code with the world and hopefully people will optimize my code so I will learn something new! But what sort of application should I develop?

Because I’m having some trouble to find an efficient and organized way to manage my tasks I was thinking to create a planning tool. It’s not only for my messy brain but I also noticed that some people are using Excel to manage their tasks.

Why not use a special developed application for this purpose? Or wouldn’t it be easier if the head of the department could centralize this data? He can assign tasks to specific people in his team and see how much of the task has been completed so far.

The people in the team will have a nice overview of all the assigned tasks and can see which tasks are more important… Maybe each task could contain multiple steps and maybe each step must be completed by a different department. This way the person who created the task can see which department is currently working on the task. Some sort of workflow…

26 november 2010

Telerik AsyncUpload: InvalidFiles-property

I’ve upgraded the Telerik ASP.NET AJAX-controls to the latest version this week (2010.3.1109) and experienced some problems with the AsyncUpload-control.
I always check the release notes of the newly released versions but nothing indicated breaking changes:

  • Added: Silverlight Module
  • Added: Inline Progress indicator

What’s Fixed

  • Fixed: RadAsyncUpload now works with Forms/Windows authentication and Anonymous Authentication disabled as long as there is Silvelright installed on the client’s browser
  • Fixed: RadAsyncUpload manual server-side validation not working

However when compiling our project I got the error that the property InvalidFiles didn’t exist for the AsyncUpload-control. I used this property to check if any file was selected with the wrong extension and show the appropiate error message.

I’ve contacted the Telerik support for this with the following answer:

With RadAsyncUpload we wanted to undertake a different approach in handling files. In RadAsyncUpload the FileUploaded event is fired for each and every uploaded file and the event argument object of that event contains IsValid property, which specifies whether the uploaded file is valid or not.  You can use that event in order to perform actions regarding invalid files. Despite that, I believe that it might be a good idea to bring back the InvalidFiles collection, or at least a property to RadAsyncUpload specifying whether there are invalid files or not.

So they will include the property again in one of the following releases. When trying to implement a fix I noticed that the browse control is now filtering automatically on the allowed extensions set on the AsyncUpload-control.

Telerik AsyncUpload-control

Automatically filter the files on the allowed extensions

A nice upgrade! No need to validate this myself anymore!
At first I was a little bit frustrated about the breaking change (without mentioning it in the release notes) but the new implementation is actually much better!

Thank you Telerik!

26 augustus 2010

Contact Form 7: digit module

I’m currently in the progress to migrate our current website (www.smashforfun.be) to WordPress.
Because it will be used primarly as CMS, I’m using a lot of plugins and one of them is Contact Form 7.

A great plugin to rapidly create a form on your website/Wordpress but… I was lacking one functionality. Numeric validation.
Because Contact Form 7 uses modules it was fairly easy to create a module (right-click and Save as) myself.

The only thing you need to do is add a error message in includes/functions.php (in the folder of Contact Form 7).
And that should do the trick… well… there was a problem when I added a new element to the messages array. My WordPress didn’t work anymore. When I add a new element something terrible happens I guess :)

For now, I just replaced an existing error message (which I don’t use right now) but if someone knows what causing this issue… please do tell!

22 mei 2010

Photography: The Antwerp Zoo

Last week I’ve been to the Antwerp Zoo (I think it has been 6 years that I’ve been to the zoo) and took my camera with me (a Canon 1000D)…
These are the first two pictures I’ve choosen from the ones I’ve shot there:

okapi - antwerp zoo

Okapi

Monkey - Antwerp Zoo

A monkey at the Antwerp Zoo

18 mei 2010

Create a website intro with jQuery

A couple of days ago I was asked if I could create a little intro for a website.
The person, who asked the question, showed me some examples… in Flash…

I’ve never been a fan of Flash websites so I was thinking if it would be possible to create an intro in jQuery?
Well let’s get started! Example of the jQuery intro

HTML

The HTML-code is quite straightforward:

<div id="intro">
 <ul>
 <li>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</li>
 <li>Phasellus id enim ut turpis dictum tincidunt.</li>
 </ul>
 <ul>
 <li>In tincidunt metus ut arcu ultricies a tempus est pretium.</li>
 <li>Nam tristique ultricies nunc, at ultrices nulla fringilla quis.</li>
 </ul>
 <ul>
 <li>Sed sit amet ante ut enim aliquam pulvinar a sed eros.</li>
 </ul>
 </div>

CSS

Nothing special here; the only important thing is the position: absolute so the text will always come from the same spot.

#intro { margin-top: 25px; }
 #intro ul { position: absolute; }
 #intro li {
 font-size: 28px;
 margin-bottom: 15px;
 }

Javascript

if(jQuery) {
    var listItems = new Array();
    var next_index = 0;

    $(document).ready(function() {
        // hide each list in the div intro
        $("#intro ul").each(function() {
            // add each list to a global array
            listItems.push($(this));
            // position each list outside the screen
            $(this).children().css("margin-left", -700);
        });

        // start the intro
        animateList(listItems);
 });

function animateElement(elements, index) {
      if(!index) index = 0;

      var next_childIndex = index + 1;
       if(next_childIndex > elements.length) {
           // all listitems of the list has been animated; hide the complete list
           $(elements[0]).parent().animate({
                opacity: 0
            }, 1000, function() {
                // start animating the next list
                animateList(listItems, next_index);
            });

           return;
       }

       var element = elements[index];
       // start animating the current listitem
       $(element).animate({
           marginLeft: 10
       }, 3000, function() {
           // start animating the next listitem
           animateElement(elements, next_childIndex);
       });
 }

function animateList(elements, index) {
      if(!index) index = 0;

      next_index = index + 1;
      if(next_index > elements.length) { return; }

      var element = elements[index];

      var itemChildren = new Array();
      $(element).children().each(function() {
          // get each listitem from the current list and add them to an array
          itemChildren.push($(this));
      });

      // start the animation of the listitems of the current list
      animateElement(itemChildren);
 }
 }

Credits for most of the code: wait for each jQuery on StackOverflow

22 maart 2010

Telerik RadGrid: filter column on date range

Het filteren van een Telerik RadGrid is doodeenvoudig. Je zet de property AllowFilteringByColumn op true en dat is het eigenlijk. Nu is er een probleem als je niet wil filteren op tekst maar op datum en niet louter op 1 datum maar tussen bepaalde datums…

Daarom moeten we een eigen filter gaan maken; wat vrij eenvoudig is.
In plaats van

<telerik:GridBoundColumn HeaderText="Datum" UniqueName="Datum" DataField="EventDate" AutoPostBackOnFilter="true" />

moeten we nu gebruik maken van

<telerik:GridBoundColumn HeaderText="Date" UniqueName="EventDate" DataField="eventdate">
 <FilterTemplate>
 <telerik:RadDatePicker ID="dateFrom" runat="server" ClientEvents-OnDateSelected="FromDateSelected" SelectedDate='<%# fromDate %>'  />
 <telerik:RadDatePicker ID="dateTo" runat="server" ClientEvents-OnDateSelected="ToDateSelected" SelectedDate='<%# toDate %>' />
<telerik:RadScriptBlock ID="scriptFilterEventDate" runat="server">
 <script type="text/javascript">
 function FromDateSelected(sender, args) {
 var tableView = $find("<%# ((GridItem)Container).OwnerTableView.ClientID %>");
 var ToPicker = $find('<%# ((GridItem)Container).FindControl("dateTo").ClientID %>');

 var fromDate = FormatSelectedDate(sender);
 var toDate = FormatSelectedDate(ToPicker);

 if (toDate != '') {
 tableView.filter("EventDate", fromDate + " " + toDate, "Between");
 }
 }
function ToDateSelected(sender, args) {
 var tableView = $find("<%# ((GridItem)Container).OwnerTableView.ClientID %>");
 var FromPicker = $find('<%# ((GridItem)Container).FindControl("dateFrom").ClientID %>');

 var fromDate = FormatSelectedDate(FromPicker);
 var toDate = FormatSelectedDate(sender);

 if (fromDate != '') {
 tableView.filter("EventDate", fromDate + " " + toDate, "Between");
 }
 }
function FormatSelectedDate(picker) {
 var date = picker.get_selectedDate();
 var dateInput = picker.get_dateInput();
 var formattedDate = dateInput.get_dateFormatInfo().FormatDate(date, dateInput.get_displayDateFormat());

 return formattedDate;
 }
 </script>
 </telerik:RadScriptBlock>
 </FilterTemplate>
</telerik:GridBoundColumn>

Ok, het is een aardig stukje code meer maar als je het eens rustig bekijkt, is er eigenlijk niets aan.

Wat willen we nu juist doen?

Aangezien we gaan filteren tussen bepaalde datums, moeten we dus eerst en vooral de standaard tekstvelden gaan vervangen door twee kalenders.
Dit kunnen we eenvoudig doen door een <FilterTemplate></FilterTemplate> te gaan definïeren voor onze kolom en tussen deze tags onze twee kalenders te gaan plaatsen.

<telerik:GridBoundColumn HeaderText="Date" UniqueName="EventDate" DataField="eventdate">
     <FilterTemplate>
         <telerik:RadDatePicker ID="dateFrom" runat="server" />
         <telerik:RadDatePicker ID="dateTo" runat="server" />
     </FilterTemplate>
</telerik:GridBoundColumn>

Mooi zo! We hebben nu twee kalenders bovenaan onze kolom.
filter Telerik ASP.NET grid met kalender

Nu moeten we nog de code voorzien om de grid te gaan filteren als we een datum hebben gekozen. We mogen pas dit event gaan uitvoeren als zowel de begin- als de einddatum is gekozen.
De events gaan we gaan uitvoeren via Javascript; daarom voegen we aan onze twee kalenders de methodes toe die worden uitgevoerd wanneer er een datum wordt geselecteerd.

<telerik:GridBoundColumn HeaderText="Date" UniqueName="EventDate" DataField="eventdate">
     <FilterTemplate>
         <telerik:RadDatePicker ID="dateFrom" ClientEvents-OnDateSelected="FromDateSelected" runat="server" />
         <telerik:RadDatePicker ID="dateTo" ClientEvents-OnDateSelected="ToDateSelected" runat="server" />
     </FilterTemplate>
</telerik:GridBoundColumn>

Goed, nu de Javascript-methodes zelf:

<telerik:RadScriptBlock ID="scriptFilterEventDate" runat="server">
<script type="text/javascript">
    function FromDateSelected(sender, args) {
        var tableView = $find("<%# ((GridItem)Container).OwnerTableView.ClientID %>");
        var ToPicker = $find('<%# ((GridItem)Container).FindControl("dateTo").ClientID %>');

        var fromDate = FormatSelectedDate(sender);
        var toDate = FormatSelectedDate(ToPicker);

        // filter alleen de tabel als we de andere datum al gekozen hebben
        if (toDate != '') {
            tableView.filter("EventDate", fromDate + " " + toDate, "Between");
        }
    }

    function ToDateSelected(sender, args) {
        var tableView = $find("<%# ((GridItem)Container).OwnerTableView.ClientID %>");
        var FromPicker = $find('<%# ((GridItem)Container).FindControl("dateFrom").ClientID %>');

        var fromDate = FormatSelectedDate(FromPicker);
        var toDate = FormatSelectedDate(sender);

        // filter alleen de tabel als we de andere datum al gekozen hebben
        if (fromDate != '') {
            tableView.filter("EventDate", fromDate + " " + toDate, "Between");
        }
    }

    function FormatSelectedDate(picker) {
        var date = picker.get_selectedDate();
        var dateInput = picker.get_dateInput();

        var formattedDate = dateInput.get_dateFormatInfo().FormatDate(date, dateInput.get_displayDateFormat()
        return formattedDate;
    }
</script>
</telerik:RadScriptBlock>

Voilà! We kunnen onze grid nu filteren en tot nu toe niet echt grote problemen. Maar je zal zien dat de gekozen datums niet worden bewaard tussen de postbacks…
En dit is de reden waarom ik eigenlijk deze blogpost ben begonnnen. Ik vond niet direct de methode om de waardes tussen de postbacks te gaan bewaren…

Het is de bedoeling om aan de kalenders volgende code toe te voegen:

SelectedDate='<%# fromDate %>'

Allemaal goed en wel maar vanwaar komt deze variabele nu?! Ik vond het niet direct terug in de documentatie tot ik bij de demo’s van Telerik kwam.
Blijkbaar moet je in je code-behind twee properties gaan declareren die de waarde gaan bewaren in de ASP.NET ViewState.

Rustig rustig! De code komt er zo aan:

protected DateTime? fromDate {
   set {
       ViewState["fromDate"] = value;
   }

   get {
       if ( ViewState["fromDate"] != null ) {
           return ( DateTime )ViewState["fromDate"];
       }

       return null;
   }
 }

 protected DateTime? toDate {
    set {
        ViewState["toDate"] = value;
     }

     get {
         if ( ViewState["toDate"] != null ) {
             return ( DateTime )ViewState["toDate"];
         }

         return null;
     }
 }

Ziezo! Nu blijven je gekozen waardes bewaard tussen de postbacks en is onze filter volledig!

Follow

Get every new post delivered to your Inbox.