The onkeyup problem of del.icio.us

Overview

In Japan, people need to use input managers to input Kanji characters like "宮".

On del.icio.us's edit form, they cannot input Kanji characters appropriately. Because keyup events will post the form immediately.

For this reason, please DO NOT post on keyup events. Please use keypress events instead. This is known as common technique in Japan.

Greasemonkey Script

A Greasemonkey user script to fix this problem is here:

In Depth

(1) To input a Kanji "宮", at first they will type "miya".

editting

(2) And hit the space key to line up candidates for "miya".

editting

(3) And then, hit the enter key to select a word they want to input.

editting

(4) Hitting the enter key occurs onkeyup event, and then the form will be posted immediately though they want to continue editting the form.

Note that no keypress events occur in (1) and (2), while keydown and keyup events occur. And just one keypress event will occur after (3). If you pick up the enter key event in the onkeyup handler to post the form, the form will be posted even if they want to input more characters. That's the current problem of del.icio.us.

The Fix

This fix works on IE6/7, Firefox2, Safari2, Opera9 at least.

Updated version of the makePostForm function: http://limechat.net/sample/delicious_keyup_fix/delicious.js

--- ui/static/delicious.js  2007-08-01 15:16:44.000000000 +0900
+++ ui/static/fix_delicious.js  2007-08-01 18:35:08.000000000 +0900
@@ -288,21 +288,21 @@
        var flickrThumbFactor = data.isFlickrThumb ? 0.8 : 1.0;
        var inputStyle = $id('fp-recent') ? { width: parseInt($id('fp-recent').offsetWidth * 0.8 * flickrThumbFactor) + 'px' }  : { width: parseInt($id('main').offsetWidth * 0.75 * flickrThumbFactor) + 'px' }

-       var fields = {
-               description: create('input', { value: data.desc, style: inputStyle, css: 'desc', attr:{maxlength:255}, onkeyup: keysubmit}),
-               url: create('input', { value: data.url, style: inputStyle, css: 'url', onkeyup: keysubmit }),
-               oldurl: create('input', { value: data.url, type: 'hidden' }),
-               privacy: create('input', { type: 'checkbox', checked: (data.privacy ? true : false), defaultChecked: (data.privacy ? true : false) }), 
-               date: create('input', {value: data.isoDate, type: 'hidden' }),
-               notes: create('input', { value: data.notes, style: inputStyle, css: 'notes', attr:{maxlength:255}, onkeyup: keysubmit }),
-               tags: create('input', {value: data.tags, style: inputStyle, autocomplete: 'off', css: 'tags',
-               onfocus: showSuggest, onblur: hideSuggest, onkeypress: keypress, onkeyup: keyup, onkeydown: keydown }),
-               save: create('button', { html: 'save', css:'save', style: { fontWeight: 'bold', cssFloat: 'left' }, onclick: save }),
-               cancel: create('button', { html: 'cancel', onclick: cancel, css:'cancel', style:{marginLeft: '10px', clear:'none', cssFloat: 'left'} }),
-               full: create('a', { html: 'full-screen edit', attr:{href: data.editUrl || data.copyUrl}, style: {marginLeft: '10px', cssFloat: 'right'} }),
-               dont: create('label', {html: 'do not share', onclick: function(){ fields.privacy.checked = !fields.privacy.checked }})
-       }
-   
+       var fields = {
+               description: create('input', { value: data.desc, style: inputStyle, css: 'desc', attr:{maxlength:255}, onkeypress: keysubmit}),
+               url: create('input', { value: data.url, style: inputStyle, css: 'url', onkeypress: keysubmit }),
+               oldurl: create('input', { value: data.url, type: 'hidden' }),
+               privacy: create('input', { type: 'checkbox', checked: (data.privacy ? true : false), defaultChecked: (data.privacy ? true : false) }), 
+               date: create('input', {value: data.isoDate, type: 'hidden' }),
+               notes: create('input', { value: data.notes, style: inputStyle, css: 'notes', attr:{maxlength:255}, onkeypress: keysubmit }),
+               tags: create('input', {value: data.tags, style: inputStyle, autocomplete: 'off', css: 'tags',
+               onfocus: showSuggest, onblur: hideSuggest, onkeypress: keypress, onkeyup: keyup, onkeydown: keydown }),
+               save: create('button', { html: 'save', css:'save', style: { fontWeight: 'bold', cssFloat: 'left' }, onclick: save }),
+               cancel: create('button', { html: 'cancel', onclick: cancel, css:'cancel', style:{marginLeft: '10px', clear:'none', cssFloat: 'left'} }),
+               full: create('a', { html: 'full-screen edit', attr:{href: data.editUrl || data.copyUrl}, style: {marginLeft: '10px', cssFloat: 'right'} }),
+               dont: create('label', {html: 'do not share', onclick: function(){ fields.privacy.checked = !fields.privacy.checked }})
+       }
+ 
        var table = TABLE([
                ROW(['title', fields.description]),
                ROW(['url', fields.url]),
@@ -334,6 +334,7 @@
                                break
                        case 13:
                                if(Suggestions.parent && Suggestions.list.picked > 0) prevent(e)
+                               else save()
                                break
                        default: Suggestions.lastValue = this.value
                }
@@ -354,7 +355,7 @@
                                if(Suggestions.parent && Suggestions.list.picked > 0) {
                                        Suggestions.complete()
                                        prevent(e)
-                               } else save()
+                               }
                                break
                        case 35: //end
                        case 36: //home
Satoshi Nakagawa /