Monday, March 9, 2009

Uploading Images from URL using Paperclip

I was searching for a way inside paperclip that uploads image from Url instead of File which is the normal behavior handled by Paperclip but I didn't find that

After too much search and trials, I reached to a solution that is easy to be implemented and handle all cases you can expect in this process

I am applying the solution inside my model but it is preferred to add a patch to Paperclip version to use so that the same logic be applied everywhere but this exercise is left for you to do

To check the code and how it evolved to handle all special cases, Please review my gist here

Cascaded HTML SELECT elements using JQuery V2

This is a small update i made to the code, This code fixes a bug detected and also get rid of some duplicated code

his is an update to the JS function

eSpace.HTML = {
cascadeLists: function(parentId, childId, callbackFunction){
$("body").append('');
var childOptions = $('#' + childId + ' option');
$('#' + parentId + childId).html(childOptions);

$('#' + parentId).change(function(){
var parent = $('#' + parentId)[0];

var selectedOptionValue = '';
if (parent.selectedIndex > -1)
selectedOptionValue = parent.options[parent.selectedIndex].value;

if (selectedOptionValue == '')
$('#' + childId).html($('#' + parentId + childId + ' option[value=""]').clone());
else {
var childs = $('#' + parentId + childId + ' option[parent="'+selectedOptionValue+'"]');
if(childs.size() == 0)
$('#' + childId).html($('#' + parentId + childId + ' option[value=""]').clone());
else
$('#' + childId).html($('#' + parentId + childId + ' option[parent="' + selectedOptionValue + '"]').clone());
}

$('#' + childId).trigger("change");

if(callbackFunction != null) callbackFunction(parent.options[parent.selectedIndex]);
});

$('#' + parentId).trigger("change");
}
}

Saturday, March 7, 2009

GMarks vs Foxmarks

I have found some many friends of mine interested so much in GMarks extension to sync their bookmarks from one pc to another.

As i am also interested in bookmarks sync across computers, and as i also respect google extensions and was a frequent user of Google Browser Sync until they stopped supporting such extension. I said to myself that i have to see what this extension gives

Frankly speaking, using GMarks is very ugly, yes you bookmark and tag your bookmarks but the way of retrieving tagged bookmarks is very old fashioned. It takes us back to the era of Firefox 2 of adding bookmarks in folders and then whenever you look for something, you open your bookmarks and look for what you want. SO UGLY AND OLD FASHIONED way

To understand why GMarks is a bad choice, lets have a look at what Firefox 3 introduced which became a de facto and also is going to be there later on in other browsers even google chrome

With the arrival of Firefox3, we got rid completely of two main stupid things
  • searching for bookmarks in folders, they introduced tags
  • searching bookmarks then if not there, google using one of the search engines beside navigation bar
Firefox 3 focused on value, simply we should deal only with one entity whenever we open a new tab, this entity is the location bar

Since you write keywords on you search engine to get you results, and since now you tag your bookmarks with keywords then we all agree that it is only keywords that matter. The new scenario became open a new tab, you are already on the location bar, write the keywords you are searching for, Firefox will list you tagged bookmarks and some other results from history.

Satisified then fine take any like from this collection. if not satisified then simply hit the enter key and you will be taken to search results from the search engine you prefer

Very lovely way, focusing on one position and having everything in hand for you. let's see what this GMarks did for our lovely neat scenario

Now, if you want something, you go to Gmarks tab beside tools and you will find your tags, you search for the tag you want then you find your bookmarks there. Not satisfied then google and write again the same tags you were about to use. SIMPLE WASTING YOUR TIME AND DON'T EXPLOIT MULTIPLE TAGS SEARCH NOR HISTORY SEARCH

simply guys, it is very stupid. Please get rid of this ugly extension right now. you are brainwashed with it. Simply use Foxmarks

it don't interfere in your cycle at all. It just sync on shutdown or from time to time as you configure it and whenever you add it from any other browser on same pc or another pc you get your bookmarks ready for you

it also has this features
  • compatabile on many browsers, i think safari and opera
  • has web interface to use from anywhere
  • sync passwords also encrypted if you wish to
  • has a new fancy feature added which is suggesting tags from other people to you whenever you tag your bookmark
To be also honest, i must say that Foxmarks is great but you need to disable its sync from time to time and make it on shutdown because it has currently a bug that causes a slowdown to firefox on synchronizarion

i wish this post can help you getting rid of your slavery to GMarks. see the light with Foxmarks instead

Friday, March 6, 2009

Software Update Mess

Nowadays, every software application has its own update program that is run in the background waiting for any new update to occur and notify you with it.

I see this is leading to more processes being run without any reason and taking time on startup and even bandwidth and cpu clocks

I got rid of all these after using
Filehippo software update program

this program is very nice one, it do this update idea but all these update programs are now in one place only, i stopped firefox update, apple update and so many and whenever something new exists this update program just tell me

I suggest it for anyone who hated such update programs, one for java, one for adobe reader, another for open office and so many others

Hope this may be useful small tip for Windows users like me

Thursday, March 5, 2009

Cascaded HTML SELECT elements using JQuery

Many web applications at least from which i worked in demanded the existance of many select boxes stacked over each other. These HTML select boxes are used for filtering data underneath them.

But the idea is that in some cases, these ones are dependent on each other. One case can be a filter for cars that starts with types, then makes then trims and so on. In some of these filters the amount of overall filters data are not so large that they can all be retrieved with page once and then JS manipulation can be used to propagate between them.

I used to make this myself until i found myself fed up of doing things that should be generic. I looked for a plugin for JQUERY which i use as a JS framework in my application. Lucky me. i found one that does this cascading on two levels and then you can repeat on others until all get cascaded together.

The solution i found was that blog post
the solution proposed here was very nice but i found that i need to modify it somehow to be much more elegent and complete from my opinion. You may disagree with me in some modifications and it's your right to do so. Take the code and modify it as you wish

Before looking at my code, you can have a look at the post in order to be familiar with my solution.

Here is the code

cascadeLists: function(parentId, childId, callbackFunction){
$("body").append('');
var childOptions = $('#' + childId + ' option');
$('#' + parentId + childId).html(childOptions);

var parent = $('#' + parentId)[0];
if(parent.options[parent.selectedIndex].value == '')
$('#' + childId).html(childOptions.filter('[value=""]').clone());

$('#' + parentId).change(function(){
var parent = $('#' + parentId)[0];

var selectedOptionValue = '';
if (parent.selectedIndex > -1)
selectedOptionValue = parent.options[parent.selectedIndex].value;

if (selectedOptionValue == '')
$('#' + childId).html($('#' + parentId + childId + ' option[value=""]').clone());
else {
var childs = $('#' + parentId + childId + ' option[parent="'+selectedOptionValue+'"]');
if(childs.size() == 0)
$('#' + childId).html($('#' + parentId + childId + ' option[value=""]').clone());
else
$('#' + childId).html($('#' + parentId + childId + ' option[parent="' + selectedOptionValue + '"]').clone());
}

$('#' + childId).trigger("change");

if(callbackFunction != null) callbackFunction(selectedOptionValue);
});
}

In order to use this function, you will do as this example

<select id="parent"> <option value="1">xxx</option> <option value="2">xxx</option></select>

<select id="child"> <option parent="1" value="1">xxx</option> <option parent="1" value="2">xxx</option> <option parent="2" value="3">xxx</option></select>


just as your normal select boxes, but with additional IDs for each one of them and for the select box that have parent, each option state in its parent attribute the value of its parent

One Question will be: What if i want to add dummy option such as --select-- for both selects and whenever i choose this option in parent, child should be also this dummy one. Don't worry code handles this for you. If available this will be done. As for the dummy one, don't add to it a parent and let its value = ''

Now, just call the function and pass parameters:
  • parent select id
  • child select id
  • callbackFunction (optional) if you wish certain function to be called on any change to parent select, this function is called and pass to this function, the value of the option which was selected. Use this value to make any extra manipulation you want to do in the HTML page

Modification made are:
  • this method depend on option sent to it in order to show empty option on child, this isn't very nice in all cases, especially when dealing with internationalizations, in this case the data added here will have different text from a language to another. That's why i give you the ability to add empty option at the top of options and use it instead of generating one myself. that way you can choose what to write in this without changing in the JS Code The new logic is if there is an empty value option in child
  • Another option is needed is to call certain function whenever a change occurs on parent level and this function takes the new value, this way you can do any changes that was waiting such change like loading in Ajax some changes in page
  • One last change is that i see adding a parent attribute will be better than using sub_ and parent value