Using del.icio.us to track my blog comments
Saturday, January 7, 2006I've worked out I can use del.icio.us to track where I have left comments on other blogs. It's sometimes hard to keep up with all these conversations and I hate email alerts. It's quite simple really. All I do is post the blog entry link to del.icio.us and tag it with 'self'. I can add my comment text in the del.icio.us comment field too. I've also modified the del.icio.us bookmarklet to make it easier. Here's what I use: Post 'self' to del.icio.us .
Just modify the standard bookmarklet by adding &tags=self
like this:
<a href="javascript:location.href='http://del.icio.us/YOURUSERNAME?v=3&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)+'&tags=self'">Post 'self' to del.icio.us</a> Easy! Of course you can add any tag you like if you don't like 'self'. Del.icio.us is such a flexible tool. I also use it to indicate which links I might like to post about with the tag '*for_post'. The * makes it rise to the top of any alphabetical list. Tagging is an awsome concept. I really don't think we've scratched the surface of what it can do.
14 Comments
So are you going to embed a list of 'My comments elsewhere' on your blog? Cause that would be awsome!
wow, pretty cool idea, that relay solves my problem of remembering places to come back to. @adrian this sounds like a foaf for plogposts
@Adrian, yeah that was the original intention, but I just never got around to it. It'd be dead easy to add via the standard del.icio.us javascript linkroll.
Clever thing!
Andrew, clever idea, thank you, now to make use of the basic tools available on del.ico.us
I translated the messages of output to spanish. Maybe u could put a "spanish version" to download. Sure some will use that ;).
Greetings and congratulations for this work Andrew!
Nicolas.
HERE IS THE CODE:
Validation.addAllThese([
['required', 'Este campo es obligatorio.', function(v) {
return !Validation.get('IsEmpty').test(v);
}],
['validate-number', 'Por favor ingrese un numero valido.', function(v) {
return Validation.get('IsEmpty').test(v) || (!isNaN(v) && !/^s+$/.test(v));
}],
['validate-digits', 'Por favor ingrese solo números en este campo. Evite espacios u otros caracteres como puntos o comas.', function(v) {
return Validation.get('IsEmpty').test(v) || !/[^d]/.test(v);
}],
['validate-alpha', 'Por favor ingrese solo letras (a-z) en este campo.', function (v) {
return Validation.get('IsEmpty').test(v) || /^[a-zA-Z]+$/.test(v)
}],
['validate-alphanum', 'Por favor ingrese solo letras (a-z) o números (0-9) en este campo. Espacios u otros caracteres no están permitidos.', function(v) {
return Validation.get('IsEmpty').test(v) || !/W/.test(v)
}],
['validate-date', 'Por favor ingrese una fecha valida.', function(v) {
var test = new Date(v);
return Validation.get('IsEmpty').test(v) || !isNaN(test);
}],
['validate-email', 'Por favor ingrese una dirección de E-mail valida. Por ejemplo fred@domain.com .', function (v) {
return Validation.get('IsEmpty').test(v) || /w{1,}[@][w-]{1,}([.]([w-]{1,})){1,3}$/.test(v)
}],
['validate-url', 'Por favor ingrese una URL valida.', function (v) {
return Validation.get('IsEmpty').test(v) || /^(http|https|ftp)://(([A-Z0-9][A-Z0-9_-]*)(.[A-Z0-9][A-Z0-9_-]*)+)(:(d+))?/?/i.test(v)
}],
['validate-date-au', 'Por favor use este formato de fecha: dd/mm/yyyy. Por ejemplo 17/03/2006 Para el 17 de Marzo de 2006.', function(v) {
if(Validation.get('IsEmpty').test(v)) return true;
var regex = /^(d{2})/(d{2})/(d{4})$/;
if(!regex.test(v)) return false;
var d = new Date(v.replace(regex, '$2/$1/$3'));
return ( parseInt(RegExp.$2, 10) == (1+d.getMonth()) ) &&
(parseInt(RegExp.$1, 10) == d.getDate()) &&
(parseInt(RegExp.$3, 10) == d.getFullYear() );
}],
['validate-currency-dollar', 'Por favor ingrese un monto valido de $. Por ejemplo $100.00 .', function(v) {
// [$]1[##][,###]+[.##]
// [$]1###+[.##]
// [$]0.##
// [$].##
return Validation.get('IsEmpty').test(v) || /^$?-?([1-9]{1}[0-9]{0,2}(,[0-9]{3})*(.[0-9]{0,2})?|[1-9]{1}d*(.[0-9]{0,2})?|0(.[0-9]{0,2})?|(.[0-9]{1,2})?)$/.test(v)
}],
['validate-selection', 'Por favor haga una selección.', function(v,elm){
return elm.options ? elm.selectedIndex > 0 : !Validation.get('IsEmpty').test(v);
}],
['validate-one-required', 'Por favor seleccione algún ítem.', function (v,elm) {
var p = elm.parentNode;
var options = p.getElementsByTagName('INPUT');
return $A(options).any(function(elm) {
return $F(elm);
});
}]
]);
I needed to localize the validation library so this is what I've done (look at the sections enclosed with ////// ADDED ///////////// and ///// CHANGED /////////)
Luca
/*
* Really easy field validation with Prototype
* http://tetlaw.id.au/view/javascript/really-easy-field-validation
* Andrew Tetlaw
* Version 1.5.4.1 (2007-01-05)
*
* Copyright (c) 2007 Andrew Tetlaw
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
var Validator = Class.create();
Validator.prototype = {
initialize : function(className, error, test, options) {
if(typeof test == 'function'){
this.options = $H(options);
this._test = test;
} else {
this.options = $H(test);
this._test = function(){return true};
}
this.error = error || 'Validation failed.';
this.className = className;
},
test : function(v, elm) {
return (this._test(v,elm) && this.options.all(function(p){
return Validator.methods[p.key] ? Validator.methods[p.key](v,elm,p.value) : true;
}));
}
}
Validator.methods = {
pattern : function(v,elm,opt) {return Validation.get('IsEmpty').test(v) || opt.test(v)},
minLength : function(v,elm,opt) {return v.length >= opt},
maxLength : function(v,elm,opt) {return v.length <= opt},
min : function(v,elm,opt) {return v >= parseFloat(opt)},
max : function(v,elm,opt) {return v <= parseFloat(opt)},
notOneOf : function(v,elm,opt) {return $A(opt).all(function(value) {
return v != value;
})},
oneOf : function(v,elm,opt) {return $A(opt).any(function(value) {
return v == value;
})},
is : function(v,elm,opt) {return v == opt},
isNot : function(v,elm,opt) {return v != opt},
equalToField : function(v,elm,opt) {return v == $F(opt)},
notEqualToField : function(v,elm,opt) {return v != $F(opt)},
include : function(v,elm,opt) {return $A(opt).all(function(value) {
return Validation.get(value).test(v,elm);
})}
}
var Validation = Class.create();
Validation.prototype = {
initialize : function(form, options){
this.options = Object.extend({
onSubmit : true,
stopOnFirst : false,
immediate : false,
focusOnError : true,
useTitles : false,
onFormValidate : function(result, form) {},
onElementValidate : function(result, elm) {}
}, options || {});
this.form = $(form);
if(this.options.onSubmit) Event.observe(this.form,'submit',this.onSubmit.bind(this),false);
if(this.options.immediate) {
var useTitles = this.options.useTitles;
var callback = this.options.onElementValidate;
Form.getElements(this.form).each(function(input) { // Thanks Mike!
Event.observe(input, 'blur', function(ev) { Validation.validate(Event.element(ev),{useTitle : useTitles, onElementValidate : callback}); });
});
}
},
onSubmit : function(ev){
if(!this.validate()) Event.stop(ev);
},
validate : function() {
var result = false;
var useTitles = this.options.useTitles;
var callback = this.options.onElementValidate;
if(this.options.stopOnFirst) {
result = Form.getElements(this.form).all(function(elm) { return Validation.validate(elm,{useTitle : useTitles, onElementValidate : callback}); });
} else {
result = Form.getElements(this.form).collect(function(elm) { return Validation.validate(elm,{useTitle : useTitles, onElementValidate : callback}); }).all();
}
if(!result && this.options.focusOnError) {
Form.getElements(this.form).findAll(function(elm){return $(elm).hasClassName('validation-failed')}).first().focus()
}
this.options.onFormValidate(result, this.form);
return result;
},
reset : function() {
Form.getElements(this.form).each(Validation.reset);
}
}
Object.extend(Validation, {
validate : function(elm, options){
options = Object.extend({
useTitle : false,
onElementValidate : function(result, elm) {}
}, options || {});
elm = $(elm);Validation.getLocalizedError
var cn = elm.classNames();
return result = cn.all(function(value) {
var test = Validation.test(value,elm,options.useTitle);
options.onElementValidate(test, elm);
return test;
});
},
test : function(name, elm, useTitle) {
var v = Validation.get(name);
var prop = '__advice'+name.camelize();
try {
if(Validation.isVisible(elm) && !v.test($F(elm), elm)) {
if(!elm[prop]) {
var advice = Validation.getAdvice(name, elm);
if(advice == null) {
///// CHANGED /////////
error = Validation.getLocalizedError? Validation.getLocalizedError (v.error) : v.error;
var errorMsg = useTitle ? ((elm && elm.title) ? elm.title : error) : error;
///////////////////////
advice = '<div class="validation-advice" id="advice-' + name + '-' + Validation.getElmID(elm) +'" style="display:none">' + errorMsg + '</div>'
switch (elm.type.toLowerCase()) {
case 'checkbox':
case 'radio':
var p = elm.parentNode;
if(p) {
new Insertion.Bottom(p, advice);
} else {
new Insertion.After(elm, advice);
}
break;
default:
new Insertion.After(elm, advice);
}
advice = Validation.getAdvice(name, elm);
}
if(typeof Effect == 'undefined') {
advice.style.display = 'block';
} else {
new Effect.Appear(advice, {duration : 1 });
}
}
elm[prop] = true;
elm.removeClassName('validation-passed');
elm.addClassName('validation-failed');
return false;
} else {
var advice = Validation.getAdvice(name, elm);
if(advice != null) advice.hide();
elm[prop] = '';
elm.removeClassName('validation-failed');
elm.addClassName('validation-passed');
return true;
}
} catch(e) {
throw(e)
}
},
isVisible : function(elm) {
while(elm.tagName != 'BODY') {
if(!$(elm).visible()) return false;
elm = elm.parentNode;
}
return true;
},
getAdvice : function(name, elm) {
return $('advice-' + name + '-' + Validation.getElmID(elm)) || $('advice-' + Validation.getElmID(elm));
},
getElmID : function(elm) {
return elm.id ? elm.id : elm.name;
},
reset : function(elm) {
elm = $(elm);
var cn = elm.classNames();
cn.each(function(value) {
var prop = '__advice'+value.camelize();
if(elm[prop]) {
var advice = Validation.getAdvice(value, elm);
advice.hide();
elm[prop] = '';
}
elm.removeClassName('validation-failed');
elm.removeClassName('validation-passed');
});
},
add : function(className, error, test, options) {
var nv = {};
nv[className] = new Validator(className, error, test, options);
Object.extend(Validation.methods, nv);
},
addAllThese : function(validators) {
var nv = {};
$A(validators).each(function(value) {
nv[value[0]] = new Validator(value[0], value[1], value[2], (value.length > 3 ? value[3] : {}));
});
Object.extend(Validation.methods, nv);
},
get : function(name) {
return Validation.methods[name] ? Validation.methods[name] : Validation.methods['_LikeNoIDIEverSaw_'];
},
methods : {
'_LikeNoIDIEverSaw_' : new Validator('_LikeNoIDIEverSaw_','',{})
}
});
////// ADDED /////////////
Object.extend (Validation, {
i18n: {
default: 'EN',
EN: {
'REQUIRED': 'This is a required field.',
'VALID_NUMBER': 'Please enter a valid number in this field.',
'NUMBERS_ONLY': 'Please use numbers only in this field. please avoid spaces or other characters such as dots or commas.',
'ALPHA_ONLY': 'Please use letters only (a-z) in this field.',
'ALPHANUMERIC_ONLY': 'Please use only letters (a-z) or numbers (0-9) only in this field. No spaces or other characters are allowed.',
'VALID_DATE': 'Please enter a valid date.',
'VALID_EMAIL': 'Please enter a valid email address. For example fred@domain.com .',
'VALID_URL': 'Please enter a valid URL.',
'DATE_FORMAT': 'Please use this date format: dd/mm/yyyy. For example 17/03/2006 for the 17th of March, 2006.',
'VALID_CURRENCY': 'Please enter a valid $ amount. For example $100.00 .',
'SELECT': 'Please make a selection.',
'SELECT_OPTION': 'Please select one of the above options.',
'VALIDATION_FAILED': 'Validation failed.'
},
IT: {
'REQUIRED': 'Questo è un campo obbligatorio.',
'VALID_NUMBER': 'Inserire un numero valido in questo campo.',
'NUMBERS_ONLY': 'Usare solo numeri in questo campo. Si evitino gli spazi e altri caratteri come punti e virgole.',
'ALPHA_ONLY': 'Usare solo lettere (a-z) in questo campo.',
'ALPHANUMERIC_ONLY': 'Usare solo lettere (a-z) o numeri (0-9) in questo campo. Non sono ammessi spazi o altri caratteri.',
'VALID_DATE': 'Inserire una data valida.',
'VALID_EMAIL': 'Inserire un indirizzo email valido. Per esempio fred@domain.com .',
'VALID_URL': 'Inserire un URL valido.',
'DATE_FORMAT': 'Per la data si usi questo formato: gg/mm/aaaa. Per esempio 17/03/2006 per il 17 marzo 2006.',
'VALID_CURRENCY': 'Please enter a valid $ amount. For example $100.00 .',
'SELECT': 'Effettuare una selezione.',
'SELECT_OPTION': 'Selezionare una delle opzioni riportate sopra.',
'VALIDATION_FAILED': 'Validazione fallita.'
}
},
getLocalizedError : function (error) {
var lang = (Validation.i18n.lang && Validation.i18n[lang]) || Validation.i18n.default;
var msg = '';
if (typeof error == 'string') { // error is a key in Validation.i18n.<language>
error = error || 'VALIDATION_FAILED';
// if there is not a localization for the error try the default language; if this also fails write the error string as is
msg = Validation.i18n[lang][error] || Validation.i18n[Validation.i18n.default][error] || error;
}
else if (typeof error == 'object') {
// error is an object with all the localizations, like this: {lang1: error message, lang2: error message, ...}
msg = error[lang] || error[Validation.i18n.default] || 'No localization available for language '' + lang + ''';
}
return msg;
}
});
/////////////////////////////////
Validation.add('IsEmpty', '', function(v) {
return ((v == null) || (v.length == 0)); // || /^s+$/.test(v));
});
Validation.addAllThese([
['required', 'REQUIRED', function(v) {
return !Validation.get('IsEmpty').test(v);
}],
['validate-number', 'VALID_NUMBER', function(v) {
return Validation.get('IsEmpty').test(v) || (!isNaN(v) && !/^s+$/.test(v));
}],
['validate-digits', 'NUMBERS_ONLY', function(v) {
return Validation.get('IsEmpty').test(v) || !/[^d]/.test(v);
}],
['validate-alpha', 'ALPHA_ONLY', function (v) {
return Validation.get('IsEmpty').test(v) || /^[a-zA-Z]+$/.test(v)
}],
['validate-alphanum', 'ALPHANUMERIC_ONLY', function(v) {
return Validation.get('IsEmpty').test(v) || !/W/.test(v)
}],
['validate-date', 'VALID_DATE', function(v) {
var test = new Date(v);
return Validation.get('IsEmpty').test(v) || !isNaN(test);
}],
['validate-email', 'VALID_EMAIL', function (v) {
return Validation.get('IsEmpty').test(v) || /w{1,}[@][w-]{1,}([.]([w-]{1,})){1,3}$/.test(v)
}],
['validate-url', 'VALID_URL', function (v) {
return Validation.get('IsEmpty').test(v) || /^(http|https|ftp)://(([A-Z0-9][A-Z0-9_-]*)(.[A-Z0-9][A-Z0-9_-]*)+)(:(d+))?/?/i.test(v)
}],
['validate-date-au', 'DATE_FORMAT', function(v) {
if(Validation.get('IsEmpty').test(v)) return true;
var regex = /^(d{2})/(d{2})/(d{4})$/;
if(!regex.test(v)) return false;
var d = new Date(v.replace(regex, '$2/$1/$3'));
return ( parseInt(RegExp.$2, 10) == (1+d.getMonth()) ) &&
(parseInt(RegExp.$1, 10) == d.getDate()) &&
(parseInt(RegExp.$3, 10) == d.getFullYear() );
}],
['validate-currency-dollar', 'VALID_CURRENCY', function(v) {
// [$]1[##][,###]+[.##]
// [$]1###+[.##]
// [$]0.##
// [$].##
return Validation.get('IsEmpty').test(v) || /^$?-?([1-9]{1}[0-9]{0,2}(,[0-9]{3})*(.[0-9]{0,2})?|[1-9]{1}d*(.[0-9]{0,2})?|0(.[0-9]{0,2})?|(.[0-9]{1,2})?)$/.test(v)
}],
['validate-selection', 'SELECT', function(v,elm){
return elm.options ? elm.selectedIndex > 0 : !Validation.get('IsEmpty').test(v);
}],
['validate-one-required', 'SELECT_OPTION', function (v,elm) {
var p = elm.parentNode;
var options = p.getElementsByTagName('INPUT');
return $A(options).any(function(elm) {
return $F(elm);
});
}]
]);
And these are the changes to the HTML.
Luca
var valid = new Validation('test', {immediate : true, onFormValidate : formCallback});
Validation.i18n.lang = 'IT';
Validation.addAllThese([
['validate-password',
{
IT: 'La password deve essere più lunga di 6 caratteri e non deve essere 'password' oppure uguale al tuo nome',
EN: 'Your password must be more than 6 characters and not be 'password' or the same as your name',
},
{
minLength : 7,
notOneOf : ['password','PASSWORD','1234567','0123456'],
notEqualToField : 'field1'
}],
['validate-password-confirm', 'Your confirmation password does not match your first password, please try again.', {
equalToField : 'field8'
}]
]);
Thanks for the post. One side note, the current bookmarklet is v4 and doesn't pay attention to the tags variable. The only way I got it to work was to change v3.
Are you a big fan of movies and all the new releases on the big screen? Do you like to watch all the latest movies as soon as they are released? If the answer is yes, and you not only love to watch movies but you also like to get loads of other movie related products as well then there is a web site that is perfectly suited to you. The web site that you should consider taking a look at is called. The Films gives its visitors the chance to down load many of the latest movie releases as well as offering loads of news about all that is going on with in the movie industry and the actors in and around Hollywood. From this web sites well designed menu system you can also access movie sound tracks, and down load wall papers of you favorite movies and movie stars.
Of course, but what do you think about that?,
Magnificent collection of prayers - and I haven't begun to explore the rest of the website!
very best job http://google.us/group/wticket cheap international airline tickets 013175 http://google.us/group/qticket first class cheap international airfare >:)))
I praise God for answering my prayers. God, you are so wonderful, majestic. Jesus Christ, I adore Your Sacred Heart.