Hint: Use 'j' and 'k' keys
to move up and down

Yaz's Blog

I am a php developer. I am a geek. I am a fiction reader. A movie and tv addict.
An XBOX360 player. A snowboarder. A cyclist. A Softball player. A Venezuelan-Canadian.

Scriptaculous Sortable.create option: overlap horizontal

Seven months ago I ran into some issues with a legacy sortable list (I didn’t code it, just copied and pasted it).

It was working okay enough, except when you needed to move the first item down (say from point A to B), you had to drag the last item up, forcing the first item to move down on its own (so forcing B to go to A).

And every time you just wanted to move an item (say from point B to C) you had to dance around with the draggable to try to find where you could drop it so that it would work.

The only way it would work for sure, was if you dragged the item to the area 33% from the right-side edge of the ‘dropable’ container.

Let me illustrate.

This of course was not acceptable. But I didnt know better (and the scriptaculous  documentation was no help).

So I went through the draggable.js file, and found the section in Sortables. This is where I saw the part in the code where it implements “overlay”.

If your sortable needs to move up/down, set the overlap option to “vertical”. Mine was set to “horizontal” which is why it was acting whishy-washy.

So now its fixed. Yay for learning.

Javascript + prototype new object/class definition

john = new Person(); 
var susan = new Person();

function load_div() 
      $('random_div').show();
      john.say("Hello"); // doesn't work
      susan.say("Yo"); // works!
}
Huh.

Prototype 1.5 to 1.6 upgrade nightmare.

The issue: in prototype 1.5, there are some Ajax.Request calls that return onComplete, the response, and then a second variable passed through with json from php. Prototype 1.5 handled this perfectly fine.

But on the new prototype (1.6.1), Ajax.Request doesn’t handle that second variable. So the there are some chunks of code not executing because the variable is null.

This has taken me 2 days to figure out. Two whole days of researching, reading random people’s code, reading documentation, and when none of those panned out, reading the prototype file side by side to find what changed.

So, on to the practical example of what happened.

For prototype 1.5..

// In the php file that handles the ajax request
if( $_POST['ajax_request'] ) {
        $arrSomeStuff['name'] = "John Smith";
        $arrSomeStuff['city'] = "Toronto";
        echo json_encode( $arrSomeStuff );
}
//and the javascript request: 
new Ajax.Request('some_url.php', {
       parameters  : { 'ajax_request' = 1 },
       onComplete: function(response, arrSomeStuff){
               $('name_div').update(arrSomeStuff.name);
       },
       onFailure: function(response){
               // handle errors
       }
});
// assumes all the other defauls from Ajax.Options

The above code, processed just fine… until Prototype 1.6, where you can’t do that because the second parameter is the response.headerJSON. Something completely unnecessarily for my use. I need it to be the response.responseJSON option!

So if you want to get this to work with 1.6, you have to send along the right header in the php file.. otherwise javascript will read responseJSON as null

// NEW: send the content type 
header('Content-type: application/json');
echo json_encode( $arrSomeStuff );
// And the javascript request has to be modified like so: 
onComplete: function(response){
	var arrSiteVariable = response.responseJSON;
	// do whatever
}
There is another method of course, you could just forget about sending the json header, and parse the response.responseText string, which contains everything sent back from the server. (This might be a good thing because responseJSON only works for “small ammounts of text”, the limit is not specified. So trial and error friends)

The reason for this change? Well, the Ajax class now wraps xmlHttpRequest in this: Ajax.Response class/object/whatever thing. For more info: http://www.prototypejs.org/api/ajax/response

Now if you excuse me I have to go shoot myself, as there are about 20 or so Ajax.Request per javascript files, and there are about 50ish files.

[tech] submitting forms with javascript

I keep running into these stupid small issues with javascript and prototype. Sometimes they seem so simple, so easy, but somehow you can’t figure them out. This next thing should have been logical, I should have known.. and still, I spent 20 minutes figuring out why it didn’t work.

The goal: a mass action button. On the php side, I use the name of the button to process the form. On the html side, I have a form with a bunch of radio buttons and one submit button. On the javascript side, a simple confirm function.

Here’s the code for the button:


input name="DeleteItems" id="DeleteItems" type="submit" value="Delete Item(s)" onclick="fncConfirmForm()"
I simple want that onclick to do a confirm, if you press yes, go ahead and submit form, otherwise, stay where you are. The confirm code uses a prototype window plugin. The javascript function, returns true if you press yes, and it does a form.submit(). Like so:


function fncConfirmForm() {
Dialog.confirm("Are you sure you want to delete these items?", {
windowParameters : {width:200},
okLabel : "Delete",
cancelLabel : "Cancel",
onOk : function(){ $('ItemsFormName').submit(); return true; },
onCancel: function(){return false;}
});
}

But that didn’t work.

First, the button I used kept submitting as soon as I pressed it. It didnt even wait for me to click Yes/Delete. So I changed the button type to “button” instead of “submit”. That stopped the form from submitting.

But it still didn’t work.

Turns out when you make it a type button, that input element doesn’t actually get submitted with the form. So the page was submitting after I pressed Yes/Delete, but it wasn’t going in the php part.

I had to add a hidden field with the name I needed, and make the button that has the onclick a fake button. Like this:


input name="DeleteItems" id="DeleteItems" type="hidden" value="true"

input name=”DeleteItemsFake” id=”DeleteItemsFake” type=”button” value=”true” onclick=”fncConfirmForm()”

Should have been simple huh?

PS: I cannot figure out how to show code here without tumblr going bonkers… anyone have any ideas?