Category Archives: Usability
Hi,
i just saw this on my twitter TL and i think it worth a mini-post. All those who develop some application that require user authentication, deal with the password problem. is not only a problem to store passwords (BTW, i wrote another post about it recently) but also the problem is the user, trying to encourage him to use stronger ones, using uppercase, lowercase letters, number and symbols is not easy. usually most of the app’s have a bar that measure the strength of the password. is nice and useful, but most of the users just don’t pay attention to it. in this cases is where naked password take action and i will not say anything else, just go to the site and try it, is a twist in usability to say it in some way
Regards,
Shadow.
Related Post
Hi,
today i have a reflexive post for all of you
those who know me, can say that my design skills are in a level of a developer. i’m not a designer, i do not pretend to be one really, i like coding more than doing anything else but when you are not only a developer, but also in charge of make improvements or decide about a product in their general aspect (functionality, aspect, usability etc..) you need to have basic/advanced knowledge about the design process. when you try to develop a product, you are talking about a whole thing that involves all this things, not only the code. the people who will use will not care about how you code it (except if the product is a code itself that will be used by devs or a product that can be extended by the client). is something seamless when you see a game developer talk about a incredible piece of code or algorithm that make something awesome, but still the game is shit
i have learned based in experience how to “look” at a product. is something that can be taught and studied but is really useful just doing it. the process is simple, but hard to take it in action. is simply ask you several questions and look in a objective at the product.
Did this really meet the purpose of the product?
Is easy for the user to use and accomplish what is trying to do with it?
The secondary functions are not bothering the use of the product?
I like it when i see it?
How i feel when i see it?
How i feel using it?
Can be more simple?
there are several process to answer this questions. first of all, you, the person on charge of the product need to be objectively answer this questions. after this, you need to put someone that never used it and target the audience that will use it and observe how they react. just in silence, do not give them any help, just observe and see the user reactions. is a iteration process and hard to do, but is the only way to make it. also, there are some gold rules that you should follow to make it in less iteration possible.
Simple is better
my boss always say that you need to make it idiot proof, and he is right. you need to simplify the process of do something in less steps as possible first, even if it require to delete some secondary feature. after that, you need to make it visually easy and obvious to fin the steps necessaries to make the action. again, is a iteration process that could take several revisions to optimize it accordingly.
The call-to-action elements are essential
call-to-action is something used always on the sales sites and marketing stuff, but is something that can be applied to almost anything. if you intent that the user to buy a product, you need to push that user that is already interested to make the deal with you. in case of sales, this is used explaining the features of the product, showing demos, etc.. but if you look in detail, the most important part is that the user have always a button close to buy the product, and the process to buy it is easy, fast and obvious. the page make the user experience less painful as possible, to avoid the regret feelings or the buying feeling. you should apply this for anything that have contact with the user. the experience need to bring joy and make it easy, put the action itself easy to find and use (of course with moderation in the qty, you don’t want to flood the user either), this will push the user to make the action, together with all the other elements.
The emotions are importants
The humans are emotional things, we do things drive by the emotions. we want to be better, so for that reason we study, we want to be stronger, for that reason we train our body etc.. be sure that the functionality, design and usability can transmit the correct emotions to your user. if you want the user enjoy the app, transmit joy, reward him, be sure that is not too frustrated (i think the frustration is always there on the human self) to leave or stop using your app. the use of your app should be not painful in any aspect. this can be achieved choosing a good selection of colors (light colors transmit peace etc..) and a flowing usability, where the user is guided to the options and not forced or need to think too much to do something that wants.
Support the users
This is maybe more on a advanced phase of the product, but design a easy and friendly support is also essential. there is no worse thing that a angry user for bad support, or even one that can’t even find it. sometimes the user get lost, for bad design or sometimes for no reason, they should be able to contact you fast, easy and you need to answer them fast too.
Flexible code is the best
When you develop a product, the code need to be flexible, is possible that in terms of usability or aspect, you need to change radically the aspect, positions and process that your product does, and it can be really painful if you don’t plan accordingly. the MVC pattern is a good option here, even you can morph to something that will suit you better in some aspects, but try to maintain the base of it separating the process from the views. by the way, the same questions i say earlier, should be applied to the code design, always remember, simple is better.
and here we finish folks, this is something that cost me to express in words, i have tried to be plain and straight as possible on my explanations, i hope you get what i mean and help you in your tasks
Regards,
Shadow.
Related Post
Hi,
in any web app (or desktop app) the security and store of password is a critical subject. there is a lot of solution out there for desktop and if you are around in the web development you will know the usual solutions as well. the hashing of the password is *usually* the most popular option (is discarded any attempt to store the password in plain text of course) and even that mysql have in-built functions as AES_ENCRYPT and AES_DECRYPT, i still think is insecure have any option to get the encrypted password in some way.
for the hash of the password, there are lot of popular functions, as md5(), sha1() etc.. and the big problem with all this functions is the advance of the processing units of our computers have made easier for the cracker to figure out the real password behind the hash.
recently, with the attacks that pletyoffish.com and other important webs have suffered i started looking for the strongest hash encryption i could find (in the past i used a combination of sha2 with a unique salt and a second pass of sha2). in this search, i realized that bcrypt was the best option here. knowing that, i looked for a class that could wrap that process and make it easier. then is when i found phpass.
phpass is a wrapper, that will use the strongest hash function available (in this case bcrypt) and if not, will go down with a combination of functions. is really easy to use, as you will see in the following examples:
Encrypt password:
$hasher = new PasswordHash(8, FALSE); $hash = $hasher->HashPassword($pass);
Check password at login
if ($hasher->CheckPassword($pass, $hash))
in this example, you need to provide the plain password and the hashed password that is keep on the DB.
if you have already a hashed password system for login, the transition should be painless, if not, i recommend you do it as soon as possible. this is better to any system you could make, really will make you sleep better at night and don’t wake up at night with the notice that your site has been hacked.
you will find more info in their tutorials and in their home page
i hope it help you in some way
Regards,
Shadow.
Related Post
Hi,
for the past days i have been playing with selenium, coding test’s for the application we are developing. in my journey with this great tool i have found some interesting tips that could be handy to you in my own situation.
Handle ajax calls
there are 2 ways to handle ajax calls, one is making the actions that will trigger the ajax call (like a click or something) and set a pause for XXXX quantity of miliseconds and then check that the actions has been made. the other is the waitForCondition command, that will execute the script till the condition is true. the second is the best,you can check a condition by setting up a variable or checking for some stat on the page after the ajax call is made. be sure to measure how much time the ajax call take action on a normal environment so you can set up a correct timeout.
Access to content in the page for a conditional or a script
there are commands that require you write some conditional sentence or minimal script to verify an action. in some of this cases is probably you need to get some value for a element in the page. in this case you can use this function:
this.page().findElement('locator');
this will return you the object like a getElementById will, and support the use of locators.
Store the result of a script
maybe you need to save the result of a script for later, so, you can use storeEval for that purpose. will store the result of the last line of the script on a variable you define.
later you can access to it like this:
storedVars['foo'];
i hope it help you in some way
Regards,
Shadow.
Related Post
Hi,
i’m still with the images stuff
now i needed to integrate a crop image script using js. so i started to look for a premade solution. you can find several of them here, here and here. i was looking for a mootools based solution and i found 4. for my surprise,one didn’t exist anymore, one of them didn’t worked with mootools 1.2, the others was too complicated and not flexible and none offer what i really needed, that was able to offer “mirrors” as preview of the crop in 2 different sizes. in my adventure, i tried to fix the first one (MooCrop) porting it to 1.2 but i leave it why it would take me too much work, then i tried to modify cwCrop but the code structure seems to be less flexible, and finally i decided to go with uvumiCrop, as it already have a mirror function and just need to be converted into a multi-div function.
so for those who want the mirror feature in the uvumiCrop script, here are the functions and code you need to replace:
Add this to the class var declaration
previewImageArray:new Array(),
On some place around line 102, paste this
this.previewImageArray = new Array();
replace with this from lines 285 to 354
if(this.options.preview){
if(isArray(this.options.preview)){
var previewImgObjArray=new Array();
this.options.preview.each(function (item,index){
var initWidth= $(item).getStyle('width');
var initHeight= $(item).getStyle('height');
//we put the preview in a wrapper div with a fixed height, because preview height and width may change.
var previewWrapperObj = new Element('div',{
styles:{
height:initHeight
}
}).wraps($(item));
//Setting the preview container
$(item).setStyles({
display:'block',
position:'relative',
width:initWidth,
height:initHeight,
overflow:'hidden',
margin:'auto',
fontSize:0,
lineHeight:0,
opacity:1,
visibility: 'visible'
});
//cloning the original image for the preview
var previewImageObJ = this.target.clone();
previewImageObJ.set('id','imgObj_'+index);
previewImageObJ.removeProperties('width','height').setStyle('position','absolute').inject($(item));
previewImgObjArray.push(new Array('imgObj_'+index,item,initWidth,initHeight));
}.bind(this));
this.previewImageArray=previewImgObjArray;
}else{
if($(this.options.preview)){
this.preview = $(this.options.preview);
//we put the preview in a wrapper div with a fixed height, because preview height and width may change.
this.previewWrapper = new Element('div',{
styles:{
height:this.previewSize.y+2*this.preview.getStyle('border-width').toInt()+this.preview.getStyle('margin-top').toInt()+this.preview.getStyle('margin-bottom').toInt()
}
}).wraps(this.preview);
}else{
var previewWrapper = new Element('div',{
'class':'preview'
}).inject(this.toolBox,'top');
this.preview = new Element('div').inject(previewWrapper)
}
//Setting the preview container
this.preview.setStyles({
display:'block',
position:'relative',
width:this.previewSize.x,
height:this.previewSize.y,
overflow:'hidden',
margin:'auto',
fontSize:0,
lineHeight:0,
opacity:0
});
//cloning the original image for the preview
this.previewImage = this.target.clone();
this.previewImage.removeProperties('width','height').setStyle('position','absolute').inject(this.preview);
// this.addEvent('onPreview',this.updatePreview.bind(this));
}
this.addEvent('onPreview',this.updatePreview.bind(this));
}
replace updatePreview function with this code below:
//Function to update the preview
updatePreview: function(top,left,width,height){
if(this.previewImageArray.length>0){
this.previewImageArray.each(function (item,index){
if(height*item[2].toInt()/width<item[3]){
$(item[1]).setStyles({
width:item[2],
height:(item[3].toInt()*height/width).toInt()
});
$(item[0]).setStyles({
width:(this.target_coord.width*item[2].toInt()*this.scaleRatio/width).toInt(),
height:'auto',
top:-(top*item[2].toInt()/width).toInt(),
left:-(left*item[2].toInt()/width).toInt()
});
}else{
$(item[1]).setStyles({
height:item[3],
width:item[3]
});
$(item[0]).setStyles({
height:(this.target_coord.height*item[3].toInt()*this.scaleRatio/height).toInt(),
width:'auto',
top:-(top*item[3].toInt()/height).toInt(),
left:-(left*item[3].toInt()/height).toInt()
});
}
}.bind(this));
}else{
if(height*this.previewSize.x/width<this.previewSize.y){
this.preview.setStyles({
width:this.previewSize.x,
height:(this.previewSize.x*height/width).toInt()
});
this.previewImage.setStyles({
width:(this.target_coord.width*this.previewSize.x*this.scaleRatio/width).toInt(),
height:'auto',
top:-(top*this.previewSize.x/width).toInt(),
left:-(left*this.previewSize.x/width).toInt()
});
}else{
this.preview.setStyles({
height:this.previewSize.y,
width:(this.previewSize.y*width/height).toInt()
});
this.previewImage.setStyles({
height:(this.target_coord.height*this.previewSize.y*this.scaleRatio/height).toInt(),
width:'auto',
top:-(top*this.previewSize.y/height).toInt(),
left:-(left*this.previewSize.y/height).toInt()
});
}
}
},
and the isArray() function used at the beginning of the code:
function isArray(obj) {
return obj.constructor == Array;
}
so, now in the initialization of the uvumiCrop object, you set the preview property as a array ( new Array(‘id1′,’id2′) ) with the id’s of the divs that will be used as mirrors. is important that you set the width and height of each div before you create the uvumiCrop object. this code will maintain the original behavior of the original script, you can still have the floating mirror and the unique mirror.
is also important to mention that i changed the code so the container don’t get the width and height deformed and work as a container hiding the rest of the image. is done like this so the user can know really how it will look after the crop process.
i have sent this post to the developer, so maybe he include it on the next release
i hope you find this useful and save you some time
Regards,
Shadow.
Related Post
Hi,
long time since my last post right? sorry about that, too much work and things happening lately
.
this time i’m here to share the discover of a great tool that a friend of mine told me some days ago. is called selenium IDE. this tools comes in several formats, but what i’m interested in the FF addon version. this addon let you record user actions in a website, as login into a site, submit a form, click a link etc.. all of this can be recorded and reproduced anytime. this is useful why you can create a test suite of diferent’s actions for your app, and after you added some change or feature, you can run the test’s and know if something is not working.
selenium also accept scripting,in a markup language like xml where you can manually define actions, as waiting for some DOM object to show up, or some value to get set to launch an action.
i recommend you to take a look at it, will save you time and headaches in the future
you can download it from here.
Regards,
Shadow.
Related Post
Hi,
today i was playing with inkscape, and i created some shiny balls to share with my readers
are not a big deal, but could be useful for some project that you maybe have. the good thing about this shiny balls, is that you can just change the color of the ball itself (not of the white half transparent ellipses) , and you will have balls of any color
the file is on SVG format and the license of this is free for any purpose, commercial or not.
you can download it from here.
i hope you enjoy it.
Regards,
Shadow.
Related Post
Hi,
yesterday, i got the invitation from rockmeit to test their new browser, so, here i bring you a review from my experience with it.
What is RockMeIt?
RockMeIt is a browser, based on chrome, focused in the social networks. different from the normal browser, their interface has been changed integrating services as facebook and twitter, to get/set update to those social networks. the purpose of this browser is to make the share of content more easy for the user.
Installation
RockMeIt comes in a small installer of 500kb (windows version, there is also a mac version available), that after you open it, start downloading the browser itself and install it.
after the normal installation process you get a facebook login form. this is why rockmeit depends from a facebook app to make work their addons, so you need to login into your account and allow the access of the app to your personal data. after that, the browser start normally and you are ready to use it.
Related Post
Hi,
i’m trying to put some effort maintaining the blog, and today looking at it, i didn’t like it how it was, so i looked for some free template and i tweaked it a little to my taste and this is the result
i added the tweet button so is more easy to share the content and categories so is more easy to navigate the blog.
i hope you like it and any feedback about it is welcome
Related Post
Hi,
recently i saw several new linux powered distributions come up oriented for the end-user, so i wanted to test them to see if the linux OS made some progress in the way to get closer to the common user, those users that just know how to turn on the computer, send a email and check their facebook. between those new distributions, are the ubuntu netbook with the unity interface, meego and jolicloud, that has been a while with us and i wanted to make a test today. i tried to test the other 2 this days but none of them worked on a virtual machine, so when i have some time to try it in a real computer, i get it tested.
What is jolicloud
Jolicloud is a linux based operating system, oriented to the web services. the aim of the os is to make the use of a computer painless and easy to use, and also make it full integrated to the web, with integration with facebook, twitter, google, dropbox etc..
after the jump can see the rest









