Webcognoscere

Hi, welcome to Webcognoscere, the digital home of Eliana and Miguel Ribeiro.

The Bridal Obsessions Journey - Part 2 (Development)

Development of Bridal Obsessions started around December 2008. Filled with excitement and dreams of having this massive product out there on the web, helping brides and grooms everywhere, we worked on our little pet project at a frantic pace.

We couldn’t wait to get home after our day jobs to get coding, designing and talking about our little pet project. I was applying my experience as a software architect and developer to its fullest, writing the most efficient C# code I’d ever done while Eliana was designing and coding the UI to be as responsive and standards compliant as ever.

Unit tests were coded, refactoring was done, refactoring was re-done, classes where being created and repurposed at a pace, CSS was being refactored and HTML was being tidied constantly. We both actually had quite a time doing this. Since we both had full time jobs, we weren’t coding this for a living so we could afford to take our time on it, and we did.

The first half of 2009 had our product development going steady, then a couple of major projects at our respective jobs put it on hold for a while and we were back on it towards the end of 2009. The final push was almost done and we started getting so amped we actually lost sleep thinking about the 1000’s of users we were going to have using our site.

Our big launch in January 2010

Our big launch happened in January 2010, we weren’t sure how to do a launch and really did this by the seat of our pants. Our only (known) option at the time to launch, Google AdWords.

I setup an AdWords Campaign and pumped some money into it. Then we sat back and waited for our servers to reach capacity J

They never did L

The initial response to Bridal Obsessions was abysmal, to say the least, we had maybe a single new user per day (if we were lucky). And of those that we managed to get, about 10% of them used more than 2 of our tools. Most of them tried out our Budget Planner and then left.

It was a hard and bitter pill to swallow, we had spent almost a full year developing what we thought people wanted only to find they didn’t want what we were offering.

It seemed of the 8 or so tools we developed, users only wanted 2 of them. And those 2 weren’t good enough to keep them coming back. We had failed.

We had built the Ferrari, when all they wanted was a way to get from A to B

Lessons Learnt

Hack it, sticky tape it and glue it together

Your first release of any software (with some exceptions) should be hacked and glued together with sticky tape and glue. This for me is extremely difficult, even now knowing what I know at this stage of my career.

As a software engineer at heart, it’s very difficult for me to ‘not go full retard’ with software development. I like unit testing the crap out of my software, and enjoy all those little ‘green’ lights indicating passed tests, sometimes obsessively soJ. Refactoring and building out frameworks is core to why I enjoy software development. But all this is rarely necessary for a first release of a product. Let me explain:

Your first release is actually your first opportunity to gather ‘real’ feedback from your end-user (and hopefully customer) on how effective/useful your product really is. It makes sense then that:-

a)      You want to get your software out there as soon as possible

b)      You can make changes and release these updates quickly to gather yet more feedback etc.

This applies to both product developers and corporate developers equally, since your goal is to have happy end-users. For Product Developers, these end users end up being your customers and for Corporate Developers your end-users ultimately determine the success/failure of your project.

With your first release out there in the wild you are now able to gather real feedback from real customers/users. You are able to make changes based on what they actually want and it will quickly highlight features that aren’t being used while showing you flaws with those that are being used. This is one of the best tips I can give you to build a highly usable software/product.

Hack it, release it, gather feedback, react, repeat!

 

In my next post, I’ll show you that these failures are actually lessons that push you forwards and upwards. Stay Tuned!

Tags:

Growth Hacking

The Bridal Obsessions Journey

In this multi-part series, I'll be taking you guys through the Journey of our Online Wedding Planner, Bridal Obsessions. From inception through development, marketing and finally release and hopefully ASTOUNDING SUCCESS!

This series is also a means of me documenting our lessons learnt which will hopefully help you guys learn from our mistakes, of which there have been many.

Part 1 - The Idea

It all started when my wife Eliana and I got engaged, back in 2007 (I think, don't kill me Eliana!). Eliana and I started the huge task of planning our wedding. I wasn't that involved initially with all the magazine collecting and article reading on wedding decor, colors etc. Eliana, however, was so totally into it and watching her get excited every time she would come to my place and talk about the wedding was just so cool for me.
She would literally glow every time she pulled out her little diary, her scrap books and files. It was really awesome to see her having so much fun and be that into it.

Fast forward a couple of months and the initial excitement started wearing off as the wedding started becoming 'real'. The planning side of it started to become a bit overwhelming. Remembering what to do, who to pay, when to do what etc. added huge amounts of pressure on us. This all began causing stress as tracking and managing it all become more of a chore than a 'hobby'.

Seeing Elaina’s demeanour changing over the weeks started worrying me as I could see she wasn’t having as much fun as in the beginning. She started worrying more about ‘managing’ this wedding and less about enjoying this once-in-a-lifetime experience of getting married.

This is when I got involved. Right off the bat I could see there was a ton of things that needed doing, remembering, checking, following up on etc. It was crazy, and I believe anyone who has gotten married will know just what I mean.

The pressure a bride is under is immense, I couldn’t actually believe Eliana was doing this on her own and immediately felt guilty about not helping her.

You see, I didn’t initially ‘help’ her as I thought this was more of a girl’s thing and that this is what girls grew up dreaming of and I didn’t want to ‘interfere’ as I feared I would be taking the joy out of it. I really wanted it to be her choices and decisions so that she would have her ultimate dream wedding. But seeing the pressure she was under, I decided to get involved.

Right off the bat, I saw that Eliana had done an amazing job of organizing everything, so much so that I felt I would be ‘slowing her down’ more than helping her. But she insisted, which was sweet J. With both of us coming from IT backgrounds it just made sense to approach this with a ‘system’ in mind that would help us stay on top of this MAMOTH task that is Planning A Wedding.

The result was a really cool excel, word and outlook based ‘solution’. We’d use excel for the budget, guest lists, seating arrangements and RSVP’s, then Outlook to keep all our appointments in its calendar. Word was then used as a checklist of what we had done and what we had left to do. It actually worked really well and, as we went along we refined it, moved the checklist into outlook tasks for a while then back into Word etc. All basically to establish what we actually used vs. what seemed like a good idea. This way, we were consciously ‘trimming the fat’ from our system. In the end we had a really useful manual system for managing our wedding. All our documents were free of clutter, it was all very organized and it worked really well. 

On 26th October, 2008 Eliana and I got married. The wedding went off perfectly, it really did. I was really amazed at how particular Eliana was about everything and how she managed to get every detail to flow into the next. I was really impressed with her ability to organize this amazing event down to the tee and more importantly, get it to actually work out how she envisioned it.

Wedding over, honeymoon done we arrived at our new home and immediately started reminiscing about the event. It was at that moment that Eliana said: “You know something, I bet our ‘system’ could help other brides….”

Thus, Bridal Obsessions was born!

 

In my next post, see why you should hack together your first release.

Tags:

LINQ Basic Projection

Author: Miguel Posted 5. May 2013

Here is a basic example of LINQ Projection.

I'm using it to build up a SelectList used in a dropdown for my ASP.NET MVC View.

In this particular case, I want to display all the administrators in my system in a dropdown for the user to select. I have a class that holds a particular users' information as well as a stored procedure that retrieves all the users in the database.
I then load these users into a List of my [User] class and convert it to a SelectList using LINQ.
The LINQ that I use makes easy work of creating and joining the [FirstName] and [LastName] fields to create a composite field to display in my dropdown.

My User class looks like this:

public class User
        {
            public int UserId { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public string RoleName { get; set; }
        }
 

And I want my dropdown to look like this:

Here's the LINQ to project (read transform) my List<User> to a new list of a custom type where the FirstName and LastName properties are merged into a single Username property.

var userList =
                from u in users
                where u.RoleName == "Administrator"
                select new { Id = u.UserId, Username = string.Format("{0} {1}", u.FirstName, u.LastName) };

Next, I create a new SelectList passing in the my List, set the Value field (within the list) and the Display field and pass it to my view. Voila! :)

SelectList list = new SelectList(userList, "Id", "Username");

In LINQ, the process of transforming the results of a query is called projection. It is achieved using LINQ's select operator and can be applied in two 'styles', LINQ query syntax or LINQ method syntax. If I had've done this using method syntax it would've looked like this:

var userList = users.Where(u => u.RoleName == "Administrator")
                                .Select(u => new { Id = u.UserId, Username = string.Format("{0} {1}", u.FirstName, u.LastName) });

It all depends on your personal preference and the complexity of what you're trying to do. But in essence it's doing the same thing. I threw in the where operator so you could see how you could filter your items as well.

Hope this helps.

Tags:

In this post I'll show you how to send a JSON object to your MVC Action Method and have your Action Method return you a JSON result.

The code for this article can be downloaded from here.

Why do you want this?

Firstly I'd like to give you some examples as to why you would want to do this and how it can enhance your web applications/sites:-

  1. You want a web page to save some data to a database without having to redirect the user to another page or have the user leave the current page they are on.
  2. You want to perform some or other function on the server side without having the user leave the current page.
  3. You want to keep the UI responsive
  4. You want to minimize the amount of postbacks on your website.

 

Understanding the scenario

My scenario is a simple one:-
We have a website that sells various items online. Our store currently has only three items. To keep this page responsive I want to keep items that the user opts to add to his cart in a client side object, until such time that they want to actually check out and pay for these items.
I want to code it this way as the alternative is to save these items each time the user clicks the 'Add to Cart' button. This would then post back each and every time the user clicks the 'Add to Cart' button and could prove slow and frustrating for the user. So to keep our users engaged with our site we must provide them with a responsive and efficient UI and storing his/her cart items in a client-side JSON object is the perfect mechanism for doing this. Adding and removing items from his/her cart will be quick and when they are ready to purchase they can click the 'checkout' option.

 

First things first, defining the Shopping Cart Objects

For this article I specifically wanted a semi-complex object as the mapping of JSON objects to C# objects in previous versions of MVC worked only for what I call 1 tier objects. Objects without child objects inside them. Things like arrays were a hassle to get working and you had to write your own custom binding helpers to get them to map properly. With the advent of MVC 3, this is much easier, but I still wanted to show you what a real life object may look like and how it would map into your C# objects.

So here below you can see what my Shopping Cart objects look like:

C# Objects

public class ShoppingCartModel
{
	public int UserId { get; set; }
	public string DeliveryInstructions { get; set; }
	public List<CartItemModel> CartItems { get; set; }
}

public class CartItemModel
{
	public int Id { get; set; }
	public string ItemName { get; set; }
	public decimal Price { get; set; }
	public int Quantity { get; set; }
}

ShoppingCartModel is the 'parent' object that holds a list of the Items that the user wants to purchase.

Now in our scenario we need a JSON representation of our C# objects so we can use them on the UI when the user is adding/removing items from his/her cart.

JSON Object

var m_ShoppingCart = {
	UserId: 10,
	DeliveryInstructions: "Leave at front desk",
	CartItems: []
};

I've just put random values inside this object to show you what data would typically be there.

Next we need to create a simple UI so that we can add items to our JSON object (m_ShoppingCart) to pass through to our Controller Action Method. I'll just show you the output of what the UI looks like below and you can just grab the code here.

So the idea here is to click on the 'Add to Cart' button, have this add the item to the JSON object called m_ShoppingCart, then have that get added to the Shopping Cart UI List (which calculates the total) and finally have the user click the Checkout.
When the user clicks the 'Proceed to Checkout' link, we post this JSON object to the Controller Action Method, which converts our JSON object into our C# object where we can then save it to the database and return a success status indicator. 

The JavaScript

Adding to the Cart

Calling the AddToCart function

<input type="button" value="Add to Cart" onclick="javascript:AddToCart(1, 'Book A', 14.95, 1);$(this).attr('disabled',true);" />

You'll notice that I call two Javascript functions in the 'onclick' event of the button. The first is the function that actually adds the item to the shopping cart, the second merely disables the button so that the user cannot click it again.
Next, the function itself

function AddToCart(id, itemName, price, quantity) {

	//  Add the item to the shopping cart object
	m_ShoppingCart.CartItems.push({
		"Id": id,
		"ItemName": itemName,
		"Price": price.toFixed(2), //   Issue here if you don't specify the decimal place
		"Quantity": quantity
	});

	//  Render the shopping cart object
	RenderShoppingCart();
}

On the face of it, AddToCart() is a pretty straight forward method, however, there's two items of interest inside it.
Firstly, there's the JavaScript 'push' method, which is a native JavaScript method for adding items to an array. This method is especially useful when adding complex objects to an array.
Secondly, you may have noticed that I specifically call the 'toFixed()' method when assigning the price to the m_ShoppingCart.Price property. This is because the toFixed() method preserves the number of decimals in the price that I'm passing through. Without it, my JSON object would store the number 11 as opposed to 11.00 and, when it got passed through to my controller action method, the mapping into the C# discarded the actual number and merely retained the trailing zeros, resulting in a price of $0, not $11.00. (if anyone can explain this to me, that'd be great)

Rendering the Cart

Rendering the cart is straight forward, however, I'll list it here for those of you that would like to see how I built up the html using javascript and jQuery:

function RenderShoppingCart() {

	$("#CartItemList").html("");

	var totalAmount = 0;

	$.each(m_ShoppingCart.CartItems, function (index, cartItem) {

	    var itemTotal = Number(cartItem.Price) * Number(cartItem.Quantity);
	    totalAmount += itemTotal;

	    $("#CartItemList").append("<li>" + cartItem.ItemName + " - $" + itemTotal.toFixed(2) + "</li>");
	});

	$("#TotalAmount").html("$" + totalAmount.toFixed(2));
}


The Meat and Potatoes

Next we have what I like to call the 'Meat and Potatoes' of the post :) the actual Posting of the JSON object to our MVC Controller Action Method:

The JavaScript

function PostData() {
		$.ajax({
			url: '@Url.Content("~/Store/Checkout")',
			async: false,
			type: "POST",
			data: JSON.stringify(m_ShoppingCart), 
			dataType: "json", 
			contentType: "application/json; charset=utf-8",
			error: function (jqXHR, textStatus, errorThrown) {
				alert(jqXHR + "-" + textStatus + "-" + errorThrown);
			},
			success: function (data, textStatus, jqXHR) {
				$("#Results").show();
				$("#ResultMessage").html(data.Message);
			}
		});
}

Ok, so this is the crux of this post and certainly took me some time to figure out the right combination of the parameters.

So, what are the parameters and what values should I give them:

  • async
    • set this to 'true' (without the apostrophes) to prevent the page for 'waiting' for this method to return. I've set it to false as I wanted my page to wait till the post completed.
  • data (with JSON.stringify)
    • this is where you specify the data that is going to be sent to our Action Method
    • WHAT IS JSON.stringify
      • If you leave the JSON.stringify method out, your object (m_ShoppingCart) will be sent to your Action Method as a Key/Value pair object, i.e. a series of objects that have a string representing the name of your property and the value thereof, e.g.:
        • UserId=10
        • DeliveryInstructions=Leave+at+front+desk
        • CartItems[0][Id]=1&CartItems[0][ItemName]=Book A&CartItems[0][Price]=14.95&CartItems[0][Quantity]=1&CartItems[1][Id]=2 ........etc...
      • Using the JSON.stringify method ensures that your object is sent as a JSON object to your Action Method (a string representation thereof)
      • It is a native Javascript method (as of JavaScript 1.7 afaik) that converts a value (object) to the JSON string representation of that object
      • Must work in conjunction with the contentType parameter below
  • dataType
    • This specifies the type of data you are expecting from the server. (i.e. not the datatype that you are sending to the server :) )
    • Our example sees us receiving a JSON object, so you specify "json" as the dataType
  • contentType
    • This gave me pains in my side as you must set this to 'application/json' to inform the server what data type you are sending to the server. If you don't set this, the default is 'application/x-www.form-urlencoded' and the server will interpret the data you are sending it as key/value pairs.
    • Why did I set "charset=utf-8". By default it should be UTF-8 (at least as per jQuery.ajax documentation), but just in case ;)

The C#

My controller doesn't do much, it accepts the ShoppingCart object that you send through from the JavaScript, compiles a nice 'success message' and returns this to the caller.

[HttpPost]
public JsonResult Checkout(ShoppingCartModel model)
{
	string message = string.Format("Successfully processed {0} item(s).", model.CartItems.Count.ToString());
	return Json(new { Success = true, Message = message });
}

So what you may notice here is there is no visible code converting our JSON object to our ShoppingCartModel object.
This is because, in ASP.NET MVC 3, there's a 'value provider' factory that is doing this for us automatically. This factory attaches to our Controllers' Action Method and converts our JSON object into our ShoppingCartModel. It uses our Action Methods Signature to determine what Type we are expecting and it attempts to convert the input it received (from our POST) into that Type. This all happens inside MVC's binding logic. In MVC 2, you had to write your own 'Value Provider Factory' and enable it so it could run when the data posted to an Action was about to be bound to the type specified on the Actions input parameter(s).

The next thing you'll notice is how I send a JSON object back to the caller. Here I use what's known as an anonymous type, basically defining an object on the fly, and pass this back through the Json method. This method takes in your object and serializes it into JSON format and returns this to the caller.

Now on the UI I can simply access this object as follows inside the success method of my ajax post:

function PostData() {
		$.ajax({
			url: '@Url.Content("~/Store/Checkout")',
			async: false,
			type: "POST",
			data: JSON.stringify(m_ShoppingCart),
			dataType: "json",
			contentType: "application/json; charset=utf-8",
			error: function (jqXHR, textStatus, errorThrown) {
				alert(jqXHR + "-" + textStatus + "-" + errorThrown);
			},
			success: function (data, textStatus, jqXHR) { $("#Results").show(); $("#ResultMessage").html(data.Message); }
		});
}

The returned JSON object comes back as the object named [data] as seen in the success callback above. [data] then maps directly to my anonymous object which has the properties, [Success] and [Message]. So if I wanted to access the message property, I would simply type data.Message;

Conclusion

So there you have it, oh and before I go, just remember the gotchas:

  1. Make sure your parameters on the jQuery Ajax post are set correctly
  2. The automatic JSON binding only works from ASP.NET MVC 3 and up, for MVC 2 you'd have to write your own.
  3. Don't forget that the decimal numbers you send through must be formatted with the correct decimal places before you send it to the Controllers Action Method (the toFixed() method)
  4. And most importantly, YOUR JSON OBJECT PROPERTY NAMES MUST BE EXACTLY THE SAME AS YOUR C# OBJECT NAMES, if they are not, it will not be able to map properly and from what I've seen it is case sensitive.

I really hope this post helps you guys create really usable, responsive and efficient sites/applications and please, let me know your thoughts and comments.

I'd really love to hear what you guys think.

 

The code for this article can be downloaded from here.

Tags: , , , , , ,

Microsoft Unity - Configuration and Aliases

Author: Miguel Posted 30. November 2011

Should I Use Aliases in my Configuration File?

It's a good idea to use aliases for the following two reasons:

  1. User Friendly
    1. It allows you to keep all your assembly references at the top and easily viewable, so you don't have to sift through all the registration tags to search for the references you need to add to the project, and
  2. Better Error Display
    1. You will get more useful errors should you reference the incorrect assembly or if you don't reference the assembly you are specifying in the configuration.

If you are using the registration tags to specify the full type names and assemblies, and one of them happens to be misspelt or you haven't referenced that project in your assembly, Unity will throw a very obscure message that will look like this: "FileLoadException was unhandled by user code. The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)"

This particular error sent me on a wild goose chase for a good few hours until I decided to use the alias tags. After which it broke immediately and indicated exactly the type that was giving the issues. It was coincidence in fact, since I wanted to clean up my code so that I could easily see all the references that I was using at the top as opposed to sifting through my reference tags. It was after I added in the references that the error it gave me was actually quite descriptive and not obscure like the previous one. In my case, it was a silly misspelling of the reference which would've taking me ages to figure out had I have persisted based on the current error message. In fact, in one post I read the guy actually downloaded the source code for unity and debugged it this way, obviously causing a huge delay in his project.

So it makes sense then to use aliases, as it cleans up your config file quite a bit and due to Unity appearing to resolve the aliases first, will give you a better error message should the type you referenced be unavailable/misspelt etc.

Hope this saves you guys some time. Let me know your thoughts.

Tags:

What is SEO?

Author: Miguel Posted 20. August 2011

Exactly what is SEO and SEM, and why should I worry about them?

Think of your site as a retail store, as more people visit your store, your chance of making a sale increases. It makes sense then that you want as many people entering your store as possible, or does it? If you get people that are not interested in your products, coming into your store, you aren’t likely to make too many sales. However, if you are able to attract people that are interested in your products, your potential for selling to them is huge.

But how do you get that potential customer into your store and not your competitors? Well, that’s the million dollar question. Now if you owned a physical retail store, the factors in attracting the right kind of customer are many, factors such as location, reputation and shop fitting come into play. Do you have a franchise? Are you in a mall? Is your store visually appealing and appropriate to your product offering?

Owning a website isn’t that dissimilar. The primary difference being that you have a virtual presence as opposed to a physical one. Adjusting the parameters and factors to build your online credibility to attract more potential, and targeted, visitors is the arena that SEO (Search Engine Optimization) and SEM (Search Engine Marketing) are focussed on.

In short, SEO and SEM are more than the basic marketing you would do for a physical store to get business. Since you have a physical presence, by default you can be found by people passing by your store. On the net, however, there’s just no ways anyone can find you unless you actively work to get found.

Search Engine Optimization deals with actually making your site 'presentable' to the search engines whilst Search Engine Marketing deals with actively marketing your site using the major search engines marketing programs.

I'll be doing a series of articles on each of these to try and help you gain the most out of your SEO and SEM and avoid the common pitfalls that the average webmaster/business owner makes when trying to do this themselves.

Tags: ,

Communication - The key to successful projects

Author: Miguel Posted 28. October 2010

Imagine this scenario:

You are a project manager. You have a team of 5 developers working on an uber cool web portal and it’s D-Day. You and your team need to demo the software to your client.

You have been busy the whole week with other projects, chasing clients for payment, managing other projects and you are slightly stressed about this particular one as you walk over to the team. You ask them: “So are we all ready to go for the demo this afternoon?”

An eerie silence creeps over all 5 team members. You know what’s next; you’ve experienced this feeling before, your heart sinks, and your mind races as to what you are going to tell the client.

One lonely developer steps up and tells you what you already know: “There is a problem. Some functionality doesn’t work due to ‘x’, ’y’ and ‘z’”.

You know your next steps aren’t going to be easy; the call to the client is going to be an unpleasant one, your reputation is going to take a bruising, the company’s reputation is going to take a knock. This is not good.

You take the next steps; you phone the client, empathize with his frustration, take his slack and re-assure him when he can actually expect the demo. You put down the phone and your blood starts boiling.

  1. Why did this happen?
  2. Why did no-one communicate this to me earlier?
  3. Why didn’t the team test that particular piece of functionality at the beginning of the week?
  4. Who is to blame?

Now these are all reasonable questions to ask. But they all have one thing in common; their answer has nothing to do with you.

Unfortunately, this is the real problem. ‘You’ are the answer to these questions. It’s a harsh reality that you have to deal with, and the sooner you do, the sooner these sort of issues go away.

As a project manager, the ownership should be on you to ensure these sorts of things don’t happen. You need to ensure that at minute 59 things blow up and go pear shaped.

Now before the worlds project managers get defensive and block out the message in this article, let me explain why I think this is a project manager’s failure.

You see this scenario happens so often in the software/web development industry because of some very simple and core issues. The most fundamental of them all is communication. Communication in a team environment is key to the delivery of a successful project. Yet everyone on the team thinks that it is the next person’s responsibility to instantiate the communication. As a project manager, in my opinion, it is up to you to get the communication between the team flowing. You are seen as the project leader and therefore you need to make the environment a suitable and comfortable one to communicate in.

If you find that you never receive any feedback or communication, you need to analyze and address this immediately and not at the end of the project. You need to honestly assess whether the lack of communication is actually your fault or the developers fault. If the developer perceives you to be unapproachable then you cannot reasonably expect the developer to be open with his communication to you.

Developers need to know that their project managers are there to assist them, they need to really believe that the project managers have their best interests at heart. They need their leaders to take an interest in what they are doing as opposed to just the results of what they are doing. If they do not receive this type of support they are less inclined to take the project managers on the ‘journey’ of the project and this is where all communication begins deteriorating.

If the project manager is not willing to take the journey with the developers on the project, they will inevitably fall out of touch with what is actually going on with the project. And the scenario indicated above will happen time and time again.

So in closing, as a project manager, your role is not only the schedule and budget of the project, but the project itself. The person who dictates the timelines is usually the person that drives the project. You cannot drive a project at arm’s length; you cannot lead a project by sitting at your desk and merely tracking everyone’s’ progress. You need to get involved. You need to force communication if it is not happening. This is your role; it’s an important one and key to the success of any project.

Great leaders make greater project managers as they want both the project and everyone in the project to succeed. A project is not just a task they have to get done, it’s a journey that they want to be on, a journey that will allow them to meet new people and build new relationships through hard work and team effort. This is what drives good project managers; a personal interest in every person on the team, and having this interest will motivate and drive your team to success after success.

Project managers need to be leaders. They need compassion and a strong sense of self motivation to effectively drive a team to be successful.

Tags:

Effort vs. Usability

Author: Miguel Posted 19. October 2010

This weekend, my wife and I worked on I'm See You and Bridal Obsessions.
I was busy getting our public event model going while she was busy on the registration process in Bridal Obsessions.

It was at this point, the point after she had gotten the site to send the validation email (after registration), that she started getting frustrated with the amount of usability work she actually had left to do.

You see, when you write down a task that says "Create Registration Process for Bridal Obsessions" and you think about what it involves, you very rarely think that there is much 'usability' work to do around it. I mean, surely you just capture the users details and send them a validation email and that's it right? WRONG!

You see there's a whole 'workflow' that goes around a simple registration process that may go something like this:

  1. User enters details and clicks 'Register'
  2. Save user details
  3. Generate validation key
  4. Email the validation key to the user
  5. User opens email
  6. User clicks on link in email to validate
  7. Link redirects user to a page that accepts the email address and the validation key
  8. System validates this key against email and approves/declines user
  9. Log user in if validation key and email match

Now besides these 'basic' steps there's a whole bunch of new questions that you must ask yourself to close this 'loop' off.

  • What happens if the email never reaches the user?
  • What happens if the user registers again when the email doesn't arrive
  • What happens if the email goes into the users spam folder? How will you validate them then?
  • What happens if the email address doesn't exist?
  • Do you trace if the user has been to your site before and store their email address in a cookie, then check if they have validated and prompt them etc.

Answering these kinds of questions will force you to think from a user perspective and cover a lot more angles that you would initially have. Just imagine you were the one registering and you didn't get that email. Wouldn't you want an opportunity to have that validation email resent? What happens if you didn't get the validation email and you register again thinking it will resend it? What would you expect the system to do?

Now if you are doing this work for a client, these are the kinds of questions you must ask them to put some perspective in their heads around "Why the registration process will take 4 days and not 1?". It will also 'close the loop' around your 'Registration' task.

Remember: Don't underestimate the time you need on a task. Walk through the entire process you are about to code in detail and in your head, write down these steps as you go, you might just save yourself a lot of pain and prevent project burn in the end.

Tags:

So today I wanted to have an image that redirected the user to one of my actions on a controller upon clicking it. Just like an 'a' tag wrapped around an image.
Up until now I've been merely using links, or more specifically the Html.ActionLink method to generate my links.

After a quick search I found this method which is very straight forward:

The Url.Action() view helper method. This method generates a 'raw' url given the appropriate parameters.

Syntax (for one of its 8 overloaded methods):

Url.Action(string actionName, string controllerName);

Usage:

<a href='<%= Url.Action("Index","Home") %>'> <img src="image source here" /></a>

So using it to generate the raw url, pumping this url into an 'a' tag then wrapping the 'a' tag around an image achieved my goal.

Tags:

To convert a string to lower case in JavaScript we use the following steps:

var sometext=”This is some text.”;
var casechanged=sometext.toLowerCase();

Now the variable casechanged contains “this is some text.”. For upper case in JavaScript:

var sometext=”This is some text.”;
var casechanged=sometext.toUpperCase();

Now the variable casechanged contains “THIS IS SOME TEXT.”.

Tags:

Meet the team

Eliana Ribeiro

Designer, Coder and Usability Fundi
View Profile

Miguel Ribeiro

Architect, Coder and Online Fundi
View Profile

Some of our work

Email Newsletters, Email Marketing, Web Design, Web Development Solution Architecture, Software Development, User Experience, Usability, Search Engine Optimization, Search Engine Marketing

Html, Xhtml, Html 5, CSS, jQuery, JavaScript, ASP.NET MVC, C#.NET, Web Services, ASP.NET (1-4), AJAX, ASP.NET AJAX, Transact-SQL

View more