Doncs no existeix, només hi el datetime picker, que com el seu nom indica només permet escollir la data, sense hora (notis la ironia).
Per sort en Trent Richardson ha creat un "addon" molt aconseguit que aconsegueix gestionar l'hora en el datetime picker. Cal afegir als CSSs un fitxer, i un altra al javascript del projecte i llestos. Per invocar-lo es fa així
Com es pot veure amb uns sliders permet escollir l'hora [0-23] i els minuts [0-59], com sempre el calendari permet editar el seu valor directament (i s'actualitza el control) i a la inversa.
#12/11/2013 10:00 Programació Javascript Autor: Alex Canalda
Arrel del comentari d'un amic on em feia constar que les imatges al blog estaven una mica mancades de disseny (tipic de mi), m'he posat a investigar com centrar, posar un peu amb una mica de text a la imatge i donar-lis una mica de format. És aquí on he trobat una nova característica d'HTML5 que desconeixia. És el tag <figure>.
The figure element represents a unit of content, optionally with a caption, that is self-contained, that is typically referenced as a single unit from the main flow of the document, and that can be moved away from the main flow of the document without affecting the document’s meaning.
Es fa servir en conjunció amb el tag <figcaption>, dins del figcaption es posa el text que es vol que vagi acompanyant la imatge. Si es posa a sota apareix com a peu de imatge, si es posa a sobre... Millor un exemple:
<figure>
<imgsrc="img_pulpit.jpg"alt="The Pulpit Rock" >
<figcaption>Fig.1 - A view of the pulpit rock in Norway.</figcaption>
</figure>
#12/11/2013 00:45 Programació HTML/CSS Autor: Alex Canalda
El següent pas en el upload de fitxers, després de posar un input de tipus file amb l'atribut "multiple" és posar els fitxers en una estructura que permeti el seu enviament al servidor. És aquí on entra el FormData.
El FormData és un interface que s'ha afegit a l'objecte XMLHttpRequest nivell 2 i és una estructura formada per un conjunt de valors organitzats en clau/valor (i en el cas dels fitxers a més a més un nom de fitxer).
El suport del FormData es molt ampli en tots els navegadors actuals, desde el IE10, el FFox, etc...
La funció següent té un bucle per afegir els fitxers i una crida Ajax de jQuery. S'assigna a l'event clic del botó upload. L'únic especial que té aquesta crida Ajax és que s'especifiquen dos parametres que normalment no es posen:
processData: false, fa que el jQuery no transformi les dades que enviem a string, per defecte és true, cal posar-lo a false ja que enviarem dades binàries.
contentType: false, per defecte és 'application/x-www-form-urlencoded; charset=UTF-8', aquest encoding no ens va bé ja volem algo del tipus: "multipart/form-data"
En el "success", es a dir quan va bé, el que es fa és verificar el que respon el servidor i mostrar els quadres de diàleg corresponents (són del jQuery UI). També es crida a refrescar imatges, el que fa aquesta funció és consultar al servidor quines imatges hi ha associades al post i mostrar-les. Genera dos botons, un per eliminar la imatge i un altra per afegir un enllaç a la textarea on s'editen els posts. IdImatge i PathImatge són les propietats del JSON que arriba del servidor.
S'ha de tenir en compte que per defecte la mida màxima d'un enviament a un IIS és 4MByte. Per tant si la suma de les mides de les imatges supera aquest valor caldrà configurar el IIS perque accepti valors més grans. Un altra punt que no he posat és el tema de la barra de progres. Tal com ho he muntat només es fa un enviament per tots els fitxers, es a dir s'empaqueten totes les imatges juntes i s'envien, només podria posar una sola barra de progres. Si es volen barres de progres individuals s'han d'enviar els fitxers per separat. De totes maneres per posar una barra de progres a una crida Ajax cal fer servir l'object XMLHttpRequest directament, això jQuery ho fa exposant-lo en la propietat "xhr" del seu object $.ajax. Queda algo així:
$.ajax({
[....]
xhr: function() {
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){
myXhr.upload.addEventListener('progress',showProgress, false);
} else {
console.log("Upload progress is not supported.");
}
return myXhr;
}
});
[...]
///En una altra funciofunction showProgress(evt) {
if (evt.lengthComputable) {
var percentComplete = (evt.loaded / evt.total) * 100;
$('#progressbar').progressbar("option", "value", percentComplete );
}
}
#10/11/2013 23:41 Programació Javascript Autor: Alex Canalda
Després d'anys d'espera, finalment no cal fer servir un component Flash ni res exòtic perque un miserable "input" d'HTML de tipus "file" pugui sel·leccionar més d'un fitxer per fer l'upload. I ho han fet la mar de senzill, felicitats als que fan l'HTML5
Ja està, afegint l'atribut múltiple i llestos. El suport en navegadors normals i en IE del 10 en endevant (el 10 és el del Windows 8, però està disponible en el Windows 7 com una actualització, de fet acabo de mirar-ho i tinc el 10). Aquest post forma part del Upload múltiple d'imatges amb Ajax.
#06/11/2013 23:51 Programació HTML/CSS Autor: Alex Canalda
Sembla que l'upload d'imatges via Ajax sigui el sant grial o la pedra filosofal d'internet. Algo que hauria de ser senzill es complica sobremanera, troves múltiples opcions i solucions. I quan enlloc d'un únic fitxer es volen pujar uns quants alhora ja és la bomba, si afegim barres de progrés UUUAHHH!!!
Sembla que les queixes continues dels desenvolupadors ha aconseguit que aquest tema es vagi posant en l'HTML5, aleshores el que passa és que el suport en diferents navegadors varia. Jo faig servir Firefox, així que per mi que funcioni en FF ja hi ha prou.
He triat una solució que fa servir jQuery i FormData (és una característica de HTML5 i sembla que IE10 la suporta i FF també). De fet disposar d'aquesta eina fa que sigui senzill. El procés consta de varies fases:
Un processat previ en Javascript per omplir l'objecte FormData
Fer una crida ajax amb jQuery configurada d'una forma especial que no causi errors al contenir fitxers (aqui m'he saltat el tema de les barres de progres, posaré com es fa però no ho he implementat)
Fent proves i més proves he trobat que el resaltador de sintaxis en el seu estat original no troba correctament algunes paraules. Per exemple les paraules reservades "get" o "set", o String i StringBuilder.
Estic muntant aquesta pàgina, poc a poc vaig afegint coses que em semblen interessants.
Tinc pensat afegir codi que trobi interessant al blog, com eina de consulta, per aquelles vegades que passa allò de: "això ho tenia fet en algun lloc". I clar si afegeixo codi queda una mica lleig que estigui com text pla. I és aquí on entra el resaltador de sintaxis, per donar-li un xic de color.
Això mateix passa en la demo de jquery que tinc muntada, que en la documentació vaig afegir trossos de codi. Aleshores vaig posar una llibreria javascript que fa aquesta tasca, i funciona prou bé. Com a avantatge té que no es modifica el codi original (es a dir que a la BBDD on està el text del post, el codi està sense modificacions, tal com estava a l'editor), i aleshores desde el manteniment per moltes vegades que s'editi el contingut no es fa cap embolic al guardar (es a dir, quan es guarda des de el manteniment no torna a recalcular la coloració del codi). Com inconvenient té que és javascript, no tots els navegadors van igual, no tothom té el javascript en marxa, començant per un servidor.
Per això m'he decidit a fer un resaltador de sintaxis, però l'he fet en Winforms (sí, sí, la tecnologia en teoria morta), té un "textbox" i un botó. El resultat va a a parar al clipboard i després ho puc engaxar aquí. El blog l'únic que ha de tenir en compte és afegir uns estils al CSS i llestos. Haig de conservar el codi original en fitxers de text per si haig de retocar el codi colorejat.
I que millor que fer servir d'exemple que el propi codi del colorejador...
//////////////////////////////////////////////////////////////////////////////// This source code and all associated files and resources are copyrighted by// the author(s). This source code and all associated files and resources may// be used as long as they are used according to the terms and conditions set// forth in The Code Project Open License (CPOL).//// Copyright (c) 2013 Jonathan Wood// http://www.blackbeltcoder.com//using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
namespace Colorizer
{
/// <summary>/// Class to colorize source code by inserting HTML markup around language tokens./// </summary>publicclass clsColorizer
{
// Language rules collectionpublic LanguageRulesCollection Languages { get; set; }
// Token class namespublicstring CssClassKeyword { get; set; }
publicstring CssClassSymbol { get; set; }
publicstring CssClassString { get; set; }
publicstring CssClassOperator { get; set; }
publicstring CssClassComment { get; set; }
/// <summary>/// Colorizer construction/// </summary>/// <param name="languageRulesFile">Name of XML file that contains all language rules</param>public clsColorizer(string languageRulesFile)
{
// Load language rules
Languages = new LanguageRulesCollection(languageRulesFile);
}
/// <summary>/// Color codes a block of source code using the specified language/// </summary>/// <param name="code">Source code to format</param>/// <param name="language">Language to use for formatting</param>/// <returns></returns>publicstring ColorizeCode(string code, string language)
{
// Load rules for the specified language
LanguageRules rules = Languages.GetLanguageRules(language);
if (rules == null)
thrownewException(String.Format("Undefined language \"{0}\" was specified", language));
// CSS class lookup tableDictionary<TokenClass, string> cssClasses = newDictionary<TokenClass, string>()
{
{ TokenClass.Keyword, CssClassKeyword },
{ TokenClass.Symbol, CssClassSymbol },
{ TokenClass.String, CssClassString },
{ TokenClass.Operator, CssClassOperator },
{ TokenClass.Comment, CssClassComment },
};
// Tokenize source code according to specified language rulesStringBuilder builder = newStringBuilder();
LanguageTokenizer tokenizer = new LanguageTokenizer(rules, code);
for (Token token = tokenizer.ParseNext(); token.Class != TokenClass.Null; token = tokenizer.ParseNext())
{
token.Value = WebUtility.HtmlEncode(token.Value);
string style;
if (cssClasses.TryGetValue(token.Class, out style) && !String.IsNullOrWhiteSpace(style))
builder.AppendFormat("<span class=\"{0}\">{1}</span>", style, token.Value);
else
builder.Append(token.Value);
}
return builder.ToString();
}
}
}
El més difícil alhora de fer un resaltat de sintaxis és trobar els identificadors de tipus, no he trobat cap resaltador que ho faci bé. Bé això no és del tot cert, hi ha un que sí ho fa però gairebé et compila l'aplicació (per saber quins tipus hi ha, i no és capaç de trobar-los en trossos de codi petits o aillats). També hi ha unes "productivity tools" del VisualStudio que et permeten guardar el codi com HTML, però al final m'he decidit per una cosa senzilleta i que no tingui que afegir res al VisualStudio, encara que no troba gaire bé els identificadors de tipus, he afegit els més comuns StringBuilder, DataTable etc...
#30/10/2013 23:05 Programació C# HTML/CSS Autor: Alex Canalda