Tuesday, June 24, 2008

jQuery form plugin data manipulation

jQuery form plugin is a great piece of code, and if you are working with ajax forms its your best friend. The basic usage of it is excellently explained of their site.

It happens from time to time that you have to serialize/create some values into a hidden form field and extract the data on the server side. I came up with a solution to avoid this unnecessary serialization/deserialization.

You can provide your custom code in beforeSubmit callback. It works like this:

beforeSubmit: function(formData, jqForm, options) {
jqForm.find('select[@name=listItems]')
.children()
.each(function(){
formData.push({
name: 'aListItems['+$(this).attr('value')+']',
value: $(this).text()
});
});
}


This code snippet would find a select field named 'listItems' within the posted form and convert all of its options into an array that gets posted to server side (and there easily accessible trough $_POST from PHP).

formData parameter of beforeSubmit callback is an JS array that contains all the fields of the form, and as it is passed by reference you can add your custom fields to it, and form plugin will see them as parts of the form. jqForm parameter is a reference to jQuery ajaxForm object, so you can use it to extract data.

This solution should work for any type of data manipulation before the form submit.

Saturday, June 14, 2008

Moving select options with jQuery

I wanted to move select options up/down on a click of a button. The following jQuery snippet does exactly that, if you want to put in some moveby variable (delta) execute this stuff within a for loop

#UPDATE My implementation was valid ages & jQueries ago, thanks to imants.horsts for updated solution

$.fn.moveSelectedUp = function() {
var selectedOptions = $(this).selectedOptions();
var prev = $(selectedOptions).first().prev();
$(selectedOptions).insertBefore(prev);
}

$.fn.moveSelectedTop = function() {
var selectedOptions = $(this).selectedOptions();
var first = $(this).children("option").not(":selected").first();
$(selectedOptions).insertBefore(first);
}

$.fn.moveSelectedBottom = function() {
var selectedOptions = $(this).selectedOptions();
var last = $(this).children("option").not(":selected").last();
$(selectedOptions).insertAfter(last);
}


This solution is tested in FF3 & IE6/7, should work elsewhere as well

Thursday, June 12, 2008

My Grandmother

My Grandmother (aged 83) today gave me a call. Nothing special, from her mobile phone (she prefers large letters, and better display because she sends SMS`s daily). The interesting thing is the she saw the german army occupying Serbia from her workplace, the time when only few of them had radios and tv sets (with sometimes watchable single demo channel) were a rarity. She called to alert me on a new virus on the Internet?! I wonder about what is left for us to see

Saturday, June 7, 2008

indexOf function JavaScript arrays & IE6/7

Here is a hidden gem : Javascript in IE6 & IE7 DOESNT support Array.indexOf function

So if you are getting some "unknown property or method", open the script debugger (a joke for itself :)) and it hangs on a line with call to indexOf dont despare here is the fix (even better joke that is comes from Mozilla :)

add Array.indexOf for IE6 & IE7

Wednesday, June 4, 2008

JSON embedded HTML in TBODY

This is a short one but really odd.

Scenario:

Have a table with tbody element, have an ajax provider that dynamically generates rows for this tbody, pretty simple.

Ajax request (jquery), expecting JSON result with embedded HTML in an array. If there is comment in HTML, jQuery produces unexpected behaviour (strip some unnecessary tags like tr`s, td`s which is really really ugly). Solution is to remove comments from HTML that you plan to deliver this way.
The optimistic programmer thinks the hidden traps are found, but IE6 produces 'unknown error on line 11' with code

$('#id_of_tbody').html(ajax_response);

After some desperation found out that according to msdn some elements are read-only for IE, among them tbody (nice DYNAMIC Object Model), so .innerHTML is not usable, my guess is that jQuery`s .html() function uses it in background.

The solution is

$('#id_of_tbody').empty().append(ajax_response);


What a nice day to be a programmer :) My mother told me I should be a fisherman, but they have to wake up early (and protest on the streets against high prices of fuel)...