Fiddler – super web debugging proxy

Postato da ROb | nella categoria Sviluppo web, Utilità | giovedì, 5 maggio 2011

0

Ieri, cercando di risolvere un problema di un sito che si verificava con il browser Safari su Windows, navigando qua e là in cerca di risposte, ho trovato qualcuno che consigliava di installare Fiddler, un web debugging proxy freeware per Windows.

Chi già utilizza l’estensione LiveHttpHeaders per Firefox o Firebug sa già quanto siano importanti tali strumenti per lo sviluppatore web. Essi infatti permettono non solamente di analizzare il codice di una pagina web (html, css, javascript) ma anche di visualizzare tutte le chiamate http effettuate dal browser, con le relative risposte, e di fare debugging del codice Javascript presente nella pagina stessa.

Alcuni browser come Safari, Chrome e altri, pur avendo i propri strumenti di sviluppo, non permettono di scendere  anche nel dettaglio delle singole chiamate http, inoltre non sempre il client delle chiamate web è un browser, in alcuni casi potrebbero essere un software stesso che prova a connettersi a un servizio web per scaricare, ad esempio, gli aggiornamenti.

Per tutti questi casi, ma sicuramente anche per molti altri, Fiddler si offre come valido strumento di analisi, frapponendosi in modo trasparente tra client e server e intercettando tutte le richieste e le risposte http del nostro PC.

Per funzionare ha bisogno del framework .NET che installa autonomamente nel caso non sia già presente. Una volta installato è sufficiente avviarlo e iniziare a navigare con un browser per vedere tutte le nostre chiamate (e anche i nostri dati :-D ) apparire nelle schermate del programma.

Il sito del software è il seguente: http://www.fiddler2.com/

Per il download fate riferimento a quest’altro indirizzo: http://www.fiddler2.com/fiddler2/version.asp

Happy debugging!

Sencha Touch: un breve articolo di IBM developerWorks

Postato da ROb | nella categoria Android, Sviluppo web | mercoledì, 26 gennaio 2011

2

Ecco un interessante articolo su Sencha Touch pubblicato sul canale degli articoli tecnici di IBM, developerWorks.

Sencha Touch è un framework Javascript, nato dall’evoluzione del potente e popolarissimo ExtJS, e orientato al mondo mobile, principalmente Android e iOS.
Il suo obiettivo è quello di costruire interfacce web evolute per tali dispositivi che assomigliano a delle vere e proprie applicazioni native.
Il framework si basa su Javascript e sul potere espressivo del nuovo linguaggio di markup HTML5.

sencha touch

L’articolo, scritto da Michael Galpin, Software Architect presso eBay, presenta una semplice applicazione testata sia in un dispositivo Android che in un iPhone.

Ecco il link diretto all’articolo per chi volesse approfondire.

Pulire codice HTML eccetto alcuni tag in Java sfruttando Jsoup

Postato da ROb | nella categoria Java, Sviluppo web | venerdì, 24 settembre 2010

4

Abbiamo già parlato di Jsoup in questo precedente post.
In due parole Jsoup è una potente libreria di parsing html/xml che permette di leggere e manipolare facilmente stringhe e porzioni anche grandi di codice html/xml.

Oggi voglio farvi vedere come possiamo sfruttarla per pulire del codice html (proveniente ad esempio dal campo di un web form) mantenendo solamente i tag che vogliamo.

Questa opzione è infatti molto utile nel caso in cui si voglia permettere agli utenti di arricchire il dato con la formattazione classica dei testi: bold, italico, … senza però rischiare di esporci al pericoloso XSS attack che consiste nell’inserire codice Javascript malevolo che punta verso qualche altro sito.

Con poche righe di codice Jsoup ci permette di definire la nostro lista di tag partendo da alcuni set predefiniti.

        ...
        String unsafe = "<p><a href='http://www.bits4beats.com/' onclick='stealCookies()'>Benvenuto <b>Roberto Rossi</b></a> lo so che che sei di Macerata! <br/>... sei proprio un <i>impiastro</i>!</p>";

		Whitelist myWL = Whitelist.simpleText();
		myWL.addTags("br", "hr");

		String safe = Jsoup.clean(unsafe, myWL);
		System.out.println("stringa sicura: " + safe);
        ...

Se lo eseguiamo otterremo la seguente stringa:

stringa sicura: Benvenuto <b>Roberto Rossi</b> lo sei che sei di Macerata! <br /> sei proprio un <i>impiastro</i>!

In pratica abbiamo detto a Jsoup di partire dalla lista accettata simpleText() che contiene i tag essenziali della formattazione a cui abbiamo aggiunto il tag br e il tag hr.

Come caricare un file sul server in AJAX

Postato da ROb | nella categoria Sviluppo web | martedì, 2 marzo 2010

2

I form html tradizionali negli anni hanno dimostrato numerosi limiti. Quelli più notevoli erano impossibilità di effettuare validazione server side, impossibilità di gestire dei campi autopopolati durante la digitazione, post completo del form senza possibilità di parzializzazione.

Ajax file upload

Tutte queste cose hanno reso il web uno strumento difficilmente utilizzabile per applicazioni che richiedessero un’elevata interazione con l’utente.
Negli ultimi anni AJAX ha rivoluzionato i tradizionali form html permettendo ai programmatori di poter dialogare agilmente con il loro backend e permettendo agli utenti di godere una più dinamica esperienza web.

Recentemente ho avuto la necessità di gestire un campo file in un form ajax. Per form ajax intendo un form che invia i suoi dati serializzati al server e non fa il post dell’intera pagina.
La tecnologia utilizzata era jQuery così ho cercato un plugin che si integrasse bene con tale tecnologia e ho trovato AJAX Upload.

Inseriamo innanzitutto gli script javascript nell’header necessari alla definizione di jQuery e del plugin AJAX Upload:

...
<head>
...
<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="js/ajaxupload.js"></script>
...
</head>
...

A questo punto bisogna creare il div che cliccato avvierà la procedura di caricamento file:

<div id="upload_button">Upload</div>

Infine dobbiamo inizializzare i campi di tipo file all’interno del nostro form:

$(document).ready(function() {
    new AjaxUpload('upload_button_id', {action: 'uploadServletPath'});
}

Al rendering della pagina cliccando sul div upload_button si aprirà la finestra di dialogo per la scelta del file e il file sarà direttamente inviato via POST (senza però il POST dell’intera pagina) alla servlet di upload che abbiamo specificato nell’inizializzazione del componente.

Nel costruttore di inizializzazione possiamo anche passare altri parametri di configurazione e gestire alcuni eventi precedenti (o successivi) al caricamento utili per valorizzare altre variabili del form o per visualizzare la progressione del caricamento o il nome del file caricato sul server.
E’ anche possibile stabilire il tipo di risposta ricevuta dal server: html, xml o json.

Per chi fosse interessato ecco il codice Java necessario al salvataggio del file:

/*
 *	author: Roberto Rossi
 */
package it.bits4beats.servlets;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.*;
import java.util.Iterator;
import java.util.List;

public class UploadServlet extends HttpServlet {
	private static Log log = LogFactory.getLog(UploadServlet.class);
	public static final String DEFAULT_UPLOAD_DIR_INIT_PARAM = "DefaultUploadDir";

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * This is a default constructor for UploadServlet class.
	 *
	 */
	public UploadServlet(){
	}

	public void init() throws ServletException {
		super.init();
	}

	/**
	 * Receive a file to be uploaded and save it into filesystem
	 */
	public void doGet(HttpServletRequest request,
			HttpServletResponse response)
	throws ServletException,java.io.IOException {
		log.info("method not supported!");
	}

	public void doPost(HttpServletRequest request,
			HttpServletResponse response)
	throws ServletException,java.io.IOException {

		String defaultUploadDir = getServletConfig().getInitParameter(DEFAULT_UPLOAD_DIR_INIT_PARAM);
		if (defaultUploadDir != null && !defaultUploadDir.equals("")) {
			log.debug("> default upload dir: " + defaultUploadDir);
		}

		/* the uploading user */
		String username = request.getParameter("username");
		/* max size of file upload */
		String sizeParam = request.getParameter("sz");
		Long maxBytes = null;
		if (sizeParam != null && !sizeParam.isEmpty()) {
			try {
				/* max 5Mb file uploaded */
				maxBytes = new Long(5242880);
			}
			catch (NumberFormatException nfe) {
				/* do nothing */
			}
		}

		log.debug("remote user: " + request.getRemoteUser());
		log.debug("user principal: " + (request.getUserPrincipal() == null ? "" : request.getUserPrincipal().getName()) );
		log.debug("username: " + username);

		String status = "true";
		String message = "";
		String savedfilename = "";
		String attachmentname = "";
		String originalFilename = "";

		/* reading file streams */
		boolean isMultipart = ServletFileUpload.isMultipartContent(request);

		if (isMultipart) {

			FileItemFactory factory = new DiskFileItemFactory();
			ServletFileUpload upload = new ServletFileUpload(factory);
			List items = null;
			try {
				items = upload.parseRequest(request);

				if (items != null && items.size() > 0) {

					File uploadDirFile = null;
					String uploadDirFileRelativePath = null;

					uploadDirFile = new File(getServletContext().getRealPath(defaultUploadDir));
					uploadDirFileRelativePath = defaultUploadDir;

					Iterator itr = items.iterator();

					FileItem fileItem = null;
					FileItem filenameItem = null;

					while(itr.hasNext()) {
						FileItem item = (FileItem) itr.next();

						if (!item.isFormField()) {
							fileItem = item;
						}
						else {
							if (item.getFieldName().equals("attachmentFilename")) {
								filenameItem = item;
								log.debug("filenameItem name: " + filenameItem.getFieldName() + " valore: " + filenameItem.getString());
							}
						}
					}

					if (fileItem != null) {
						/* there is a file item in the request */
						String fileName = fileItem.getName();
						log.debug("fileItem name: " + fileName);

						if (fileItem.getName().contains("\\")) {
							log.debug("Windows file");

							/* windows file path */
							fileName = fileItem.getName().substring(fileItem.getName().lastIndexOf("\\") +1);
							log.debug("fileItem name: " + fileName);
						}

						File fullFile  = new File(fileName);
						File savedFile = new File(uploadDirFile, fileName);

						if (savedFile != null) {

							/* check file size */
							if (maxBytes != null) {
								if (fileItem.getSize() > maxBytes.longValue()) {
									FileTooBigException ftbe = new FileTooBigException();
									ftbe.setMaxSize(new Long(maxBytes.longValue()/1024/1024).toString());
									throw ftbe;
								}
							}

							if (savedFile.exists()) {
								/* we need to create a file variant, save it and send it to the user */
								String fileNameWithoutExtension = savedFile.getName().substring(0, savedFile.getName().lastIndexOf("."));
								originalFilename = fileNameWithoutExtension;
								String suffix = savedFile.getName().substring(savedFile.getName().lastIndexOf(".") + 1);

								File newFile = File.createTempFile(fileNameWithoutExtension + "_", "." + suffix, uploadDirFile);
								fileItem.write(newFile);

								log.debug("newFile: " + newFile.getAbsolutePath());
								status = "true";
								message = "OK " + newFile.length() + " byte salvati";

								/* relative file path */
								savedfilename = uploadDirFileRelativePath + newFile.getName();
								String filenameWithExt =  extractFilenameWithExtensionFromPath(savedfilename);
								attachmentname = extractFilename(filenameWithExt);
							}
							else {
								log.debug("writing file to: " + savedFile.getAbsolutePath());
								originalFilename = extractFilename(extractFilenameWithExtensionFromPath(savedFile.getAbsolutePath()));
								fileItem.write(savedFile);

								status = "true";
								message = "OK " + savedFile.length() + " byte salvati";

								/* relative file path */
								savedfilename = uploadDirFileRelativePath + fullFile.getName();
								String filenameWithExt =  extractFilenameWithExtensionFromPath(savedfilename);
								attachmentname = extractFilename(filenameWithExt);
							}
						}
						else {
							log.error("cannot create file");
							status = "false";
							message = "Errore generico di salvataggio";
						}
					}

				}
				else {
					log.debug("no item to be saved");
				}
			}
			catch (FileTooBigException ftbe) {
				status = "false";
				message = "File troppo grande, dimensione massima (Mb): " + ftbe.getMaxSize();
			}
			catch (Exception e1) {
				e1.printStackTrace();
				log.error("error in uploading");

				status = "false";
				message = "Errore generico di salvataggio";
			}
		}

		PrintWriter out = response.getWriter();

		String responseMessage = "{\"success\":" + status + ",\"message\":\"" + message + "\",\"savedfilename\":\"" + savedfilename + "\",\"attachmentname\":\"" + attachmentname + "\",\"originalfilename\":\"" + originalFilename + "\"}";
		log.debug("responseMessage: " + responseMessage);
	    out.println(responseMessage);
	}

	/**
	 * This method extract filename (with extension) from filepath
	 *
	 * @param filepath
	 * @return filename without extension
	 */
	public static String extractFilenameWithExtensionFromPath(String filepath) {
		if (filepath != null) {
			int index = filepath.lastIndexOf("/");

			if (index > 0 && index < (filepath.length() -1)) {
				return filepath.substring(index + 1);
			}
			else return null;
		}
		else {
			return null;
		}
	}

	/**
	 * This method extract filename (without extension) from filename with extension
	 *
	 * @param filepath
	 * @return filename without extension
	 */
	public static String extractFilename(String filenameWithExtension) {
		if (filenameWithExtension != null) {
			int index = filenameWithExtension.lastIndexOf(".");

			if (index > 0) {
				return filenameWithExtension.substring(0, index);
			}
			else return filenameWithExtension;
		}
		else {
			return null;
		}
	}

	class FileTooBigException extends Exception {
		private static final long serialVersionUID = 1L;

		private String maxSize = null;

		public String getMaxSize() {
			return maxSize;
		}

		public void setMaxSize(String maxSize) {
			this.maxSize = maxSize;
		}

		public FileTooBigException() {
			super();
		}

		public FileTooBigException(String message) {
			super(message);
		}
	}

}

Nel sito del plugin trovate anche una demo completa e funzionante di AJAX upload.

Comprimere il codice Javascript con YUI Compressor

Postato da ROb | nella categoria Sviluppo web | mercoledì, 17 febbraio 2010

0

Molte librerie javascript vengono distribuite in un formato compresso (o minimizzato).

Se aprite i file in questo formato non riuscirete a leggere granché per via del fatto che tutti gli spazi e gli a capo sono stati sacrificati per risparmiare byte preziosi.

Compressione librerie Javascript

Mi sono sempre chiesto come fossero riusciti a realizzare tali file.
Beh la risposta è molto semplice: ci sono programmi appositi per farlo.

Uno di questi è YUI Compressor, un tool sviluppato dal YUI Team.
YUI Compressor è stato scritto in java e il suo utilizzo è veramente immediato.

Dopo aver scaricato la distribuzione (la versione attuale è la 2.4.2) e ipotizzando di averla scompattata nella directory /opt/ , potete avviare la minimizzazione del vostro codice attraverso questo comando:

java -jar /opt/yuicompressor-2.4.2/yuicompressor-2.4.2.jar --type js vostrofilejavascript.js

Il codice minimizzato verrà stampato a video. A questo punto potete salvarlo in un file.

Se volete invece salvarlo in un file minimizzato potete redirezionare direttamente lo standard output in questo modo:

java -jar /opt/yuicompressor-2.4.2/yuicompressor-2.4.2.jar --type js vostrofilejavascript.js > vostrofilejavascript.min.js

Utilizzare il date picker jQuery UI per i nostri campi data

Postato da ROb | nella categoria Sviluppo web | martedì, 16 febbraio 2010

39

Far inserire manualmente una data nei form è una cosa ormai poco utilizzata.
E’ buona abitudine fornire agli utenti degli strumenti che aiutano nella compilazione di tali campi.

logo jQuery UI

Ogni buon framework che si rispetti mette ormai a disposizione questi oggetti (ExtJS di cui vi parlavo qualche giorno fa non è da meno).

Oggi voglio proporvi un esempio con il datepicker del framework jQuery UI, un framework javascript nato per costruire widget e oggetti di interfaccia sfruttando solamente la libreria jQuery.

In questo esempio ho isolato dalla distribuzione di jQuery UI solamente il componente datepicker (con i suoi file javascript e i suoi fogli di stile) e l’ho utilizzato di una pagina web minimale.
Le comodità di questo componente sono il multilinguismo e la possibilità di modificarne facilmente il tema rimpiazzando alcuni file, cose che lo rendono molto appetibile nel caso di siti o applicazioni internazionalizzati e in cui l’integrazione con l’aspetto grafico dell’applicazione è fondamentale.

Per ulteriori informazioni sul componente fate riferimento direttamente al sito web oppure alla pagina specifica con la demo del componente.

esempio jQuery UI Datepicker

Ecco il codice necessario per l’integrazione del componente in una pagina web:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>bits4beats - esempio jQuery UI Datepicker</title>
	 <meta name="Description" content="Utilizzare jQuery UI Datepicker come widget per la scelta della data" />

    <script language="javascript" type="text/javascript" src="jquery.min.js"></script>
	 <script type="text/javascript" src="jquery.ui.core.js"></script>
	 <script type="text/javascript" src="jquery.ui.datepicker.js"></script>
	 <!-- INCLUDERE LA SEGUENTE LINEA PER LA TRADUZIONE DEL WIDGET IN ITALIANO -->
    <script type="text/javascript" src="ui.datepicker-it.js"></script>

    <link href="jquery-ui.css" rel="stylesheet" type="text/css" />
    <!-- SCEGLIERE IL FOGLIO DI STILE DEL TEMA PREFERITO -->
    <link href="ui.datepicker.css" rel="stylesheet" type="text/css" />

 </head>
 <body>

	<div id="datepicker">
		<label>clicca sul campo per aprire il widget</label>
		<input
			name="datepicker"
			id="datepickerId"
			type="text"
			maxlength="10"
			size="10"
		/>
   </div>

	<script type="text/javascript">
		$(document).ready(function(){
			$('#datepickerId').datepicker({ dateFormat: 'dd/mm/yy' });
		});
	</script>

 </body>
</html>

Per vedere l’effetto dal vivo potete cliccare qui, con il focus all’interno del campo data si aprirà il pannello per la selezione della data.

In questo caso il componente è stato usato in lingua italiana (linkando opportunamente il codice javascript per la traduzione).

Ecco il file zip con il codice completo dell’esempio.

ExtJS: il framework di sviluppo Javascript per eccellenza

Postato da ROb | nella categoria Sviluppo web | venerdì, 12 febbraio 2010

2

Recentemente ho avuto il bisogno di riscrivere completamente un’applicazione web.
Penso di conoscere bene html, css e javascript ma, nonostante questo, nella scrittura di applicazioni web ho dovuto spesso risolvere gli stessi problemi, rispondere alle stesse esigenze e scrivere in diverse occasioni lo stesso codice.

ExtJS logo

Per questi motivi mi sono guardato un pochino attorno cercando una libreria Javascript che mettesse in mano dello sviluppatore un ambiente con oggetti pronti all’uso, semplici da configurare, carini da vedere e potenti allo stesso tempo.
Mi sono concentrato sulla ricerca di toolkit Javascript e non su altro perché avevo necessità di sfruttare tale libreria con differenti tecnologie server side.
Ovviamente un aspetto fondamentale di valutazione è che il toolkit funzioni con tutti i browser web più diffusi (Firefox, Safari e Chrome, Internet Explorer … IE è volutamente stato messo per ultimo).

Indubbiamente anche in questo caso il panorama non è assolutamente deludente e il mondo open source offre come al solito le sue superbe soluzioni.
I più famosi in quest’ambito sono: Dojo, Prototype, Scriptaculous, jQuery (anche se più che un toolkit è un nuovo approccio Javascript alla selezione degli oggetti) , SmartClient, ed ExtJS (anche nella sua variante Yui).

Dopo aver visto gli esempi proposti nel sito e aver fatto alcuni test ho provato a svilupparla con ExtJS.

Rotte le prime iniziali difficoltà per impostare l’ambiente con tutte le opportune dipendenze, mi sono subito accorto di avere a che fare con una libreria veramente matura, flessibile e molto performante.
Il forum della comunità è attivissimo, la documentazione (presentata anch’essa tramite un’applicazione web ExtJS) è comodissima da navigare e ben scritta, i bug sono pochi e di poco rilievo, perlomeno nella versione che ho provato e che sto ancora usando, cioè la 2.2.1 (il ramo attuale è alla major release 3.x).

Essendo una libreria già molto famosa, numerosi sono i tool di contorno alla libreria stessa. C’è chi l’ha usata per generare un template wordpress (http://extjswordpress.net/), chi l’ha sfruttata per generare un desktop virtual su web, chi ci ha scritto un software di collaborazione.

ExtJS desktop example

Lo showcase dimostrativo è veramente molto ricco e ci sono oggetti già pronti per qualsiasi situazione.
Gli widget che sto usando più di tutti sono le griglie (con la possibilità di caricare i dati in modo asincrono via JSON), i form, le finestre flottanti, i tab e gli accordion.
Con ExtJS è anche semplicissimo implementare caricamenti e callback via AJAX mettendo infatti a disposizione degli oggetti statici per l’invio e la ricezione dei dati serializzati.

Per gli amanti del Google Web Toolkit c’è anche una versione di ExtJS integrata con GWT chiamata GXT. Il suo sviluppo, pur se con qualche ritardo dovuto a una partenza successiva, sta procedendo bene e contano a breve di allineare le funzionalità ExtJS con GXT.

Dal punto di vista della licenza ExtJS ha adottato una coercizione “forte” di chi la utilizza verso l’open source basata sul principio del Quid Pro Quo.
Chi vuole utilizzare ExtJS per progetti open source è liberissimo di farlo chi invece intende utilizzarla per progetti non “open” deve acquistare una licenza commerciale.
In realtà fino alla versione 2.x la politica di licenza era leggermente diversa (LGPL) e permetteva di utilizzare la libreria anche in progetti closed source.

L’insetto di fuoco (Firebug) invade anche Chrome!

Postato da ROb | nella categoria Sviluppo web | lunedì, 8 febbraio 2010

0

Parlare di Firebug è ormai inutile, lo conoscono tutti.

Nuovo logo Firebug

E’ invece di qualche giorno fa (esattamente il 4 febbraio) la notizia della versione 1.3 Lite di Firebug per Chrome.
La versione Lite consente agilmente di fare debugging del codice css e html della pagina web (ma non di quello Javascript) ma senza poter intervenire direttamente e modificarla al volo.

Qui sotto potete vedere lo screenshot dell’estensione appena installata e funzionante sul mio Chrome per Linux.

Firebug in azione su Chrome per Linux

JQuery sticky toolbar, una barra in evidenza nel vostro sito

Postato da ROb | nella categoria Sviluppo web | martedì, 26 gennaio 2010

0

Ieri mi sono dilettato nella realizzazione di una toolbar di servizio per il software CMS a cui sto lavorando da oltre un anno.

Alcuni anni fa, lavorando con Symfony, avevo trovato geniale l’idea degli sviluppatori di arricchire il framework di una debug toolbar che aiutasse il webmaster nella realizzazione e nel troubleshooting del sito stesso. Ecco un’immagine di questa toolbar presa direttamente dal sito ufficiale di Symfony.

Symfony debug toolbar

La comodità di questa barra è quella di poter essere minimizzata o rimossa e contiene tutte le informazioni principali di cui un webmaster può avere bisogno durante il ciclo di sviluppo del sito stesso.

Così, spinto dalla necessità di averne una anche nel nostro CMS, mi sono cimentato nelle funzioni di animazione di JQuery e in qualche proprietà CSS. Il mio intento non era quello di replicare la barra di Symfony ma almeno di emularne i comportamenti base.

Ecco qui il risultato.

In realtà, dopo aver incluso correttamente la libreria jquery nell’head del vostro documento html e aver scelto una posizione per le immagini utilizzate nei link di chiusura e apertura della toolbar, il codice Javascript necessario al suo funzionamento si riduce a queste poche righe:

	<style>

		#toolbar {
			position: fixed;
			width: 100%;
			height: 60px;
			top: -40px;
			display: block;
			border-bottom: 2px solid black;
			opacity:0.9;
			background-color: #E5E5E5;
		}

		#toolbar #close {
			position:absolute;
			top: 40px;
			display:none;
		}

		#toolbar #open {
			position:absolute;
			top: 40px;
		}

		#toolbar #remove {
			position:absolute;
			top: 40px;
			left: 20px;
		}

		#toolbar img {
			border: 0px;
		}

		#toolbar #toolbar_text {
			font-size: 10px;
			font-family: 'Verdana',sans-serif;
			position:absolute;
			top: 2px;
			left: 2px;
			width: 100%;
		}

		#toolbar #toolbar_links {
			font-size: 10px;
			font-family: 'Verdana',sans-serif;
			position:absolute;
			top: 42px;
			left: 40px;
			width: 100%;
		}

	</style> 

	<div id="toolbar">
		<a href="javascript:;;" id="close" title="close"><img src="arrow_up.png"/></a>
		<a href="javascript:;;" id="open" title="open"><img src="arrow_down.png"/></a>
		<a href="javascript:;;" id="remove"  title="remove"><img src="delete.png"/></a>

		<div id="toolbar_text">
			A text <strong>inside</strong> the toolbar
		</div>

		<div id="toolbar_links">
			| <a href="javascript:;;">just a simple link</a>
		</div>
    	</div>

	<script type="text/javascript">
		$(document).ready(function(){
			$('#close').bind('click', function() {
				$('#toolbar').animate({top:"-40px"}, 400 );
				$('#close').hide();
				$('#open').show();
			});

			$('#open').bind('click', function() {
				$('#toolbar').animate({top:"0px"}, 400 );
				$('#close').show();
				$('#open').hide();
			});

			$('#remove').bind('click', function() {
				$('#toolbar').hide();
			});
		});
	</script>

Il codice completo è disponibile a questo indirizzo per il download.

Happy Javascript a tutti!

P.S: tale toolbar è stata testata con Firefox 3.0 e Chrom 4.0 per Linux (ma ci sono buone possibilità che funzioni con quasi tutti i browser viste le caratteristiche cross-browser del framework JQuery).

FCKEditor come tipo campo per ExtJS 2.x

Postato da ROb | nella categoria Sviluppo web | martedì, 19 gennaio 2010

2

In questo post voglio presentare gli step necessari per l’utilizzo di FCKEditor come tipo campo per il web toolkit javascript ExtJS 2.x.

Quasi tutte le informazioni sono state ricavate da questo preziosissimo thread nel forum di ExtJS e dal contributo congiunto di molti utenti e sviluppatori.

  1. Prima di tutto bisogna procurarsi l’editor fckeditor nella precedente versione stabile (io ho usato la 2.6.5), scaricare il file zip e scompattarlo all’interno di una directory all’interno della web application.
  2. Poi bisogna copiare il file all’interno della cartella fckeditor chiamato fckconfig.js in una directory a vostra scelta e rinominarlo: fckcustomconfig.js.
  3. Quindi bisogna creare il file dell’estensione per ExtJS. Potete scaricare la mia versione da qui e inserirlo nella stessa directory in cui si trova il file fckcustomconfig.js.
  4. A questo punto bisogna fare in modo che il nostro documento html contenga tutte le definizioni necessarie per caricare l’estensione in questione.
    Inserire quindi nell’head html del documento tali dichiarazioni.

    <script type="text/javascript" src="<percorso>/fckeditor/fckeditor.js"></script>
    
    	<script type="text/javascript" >
    		//change the config with the correct dirs
    		var oFCKeditorOptions = {
    		    BasePath : '<percorso>/fckeditor/'
    		    ,Config : {
    		    	BaseHref 	: window.location.href
    		        ,SkinPath	: '<percorso>/fckeditor/editor/skins/office2003/'
    		        ,CustomConfigurationsPath	: '<percorso>/fckcustomconfig.js'
    		        ,ProcessHTMLEntities 		: true
    		        ,ProcessNumericEntities 	: false
    		    }
    		    ,AllowQueryStringDebug 			: false
    		};
    	</script>
    
    	<script type="text/javascript" src="<percorso>/Ext.ux.FCKEditor.js"></script>
    

    Dove <percorso> e’ il percorso in cui si trovano fckeditor, il file Ext.ux.FCKEditor.js e il file fckcustomconfig.js.

  5. Come ultimo passo, inserire il codice javascript per la gestione del campo di tipo fckeditor:
    			{
    			    xtype:'fckeditor',
    			    name:'body',
    			    id:'body',
    			    fieldLabel: 'label',
    			    height: 400,
    			    editorWidth: 650,
    			    toolbarSet: 'Default',
    			    value: 'some text...'
    			}