Dins del desenvolupament web, hi ha la part més fàcil que és muntar en HTML el formulari que es farà servir per editar dades. L'HTML pertany al que s'anomena part client. Quan es genera l'HTML que dóna estructura a la part client no es posen estils (excepte casos concrets), ni events, ni dades. El que obtenim és un HTML senzill d'entendre i de mantenir, sense barrejar conceptes.
Normalment, tota l'aplicació web fa servir els mateixos fitxers de Javascript i els mateixos CSS, això juntament amb la validació de seguretat ho poso en una MasterPage.
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Blog.Master.cs" Inherits="Blog.Master.Blog" %>
<%
if (Session["IdLogin"] == null) Response.Redirect("login.htm");
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<headrunat="server">
<meta http-equiv="X-UA-Compatible" content="IE=8" />
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<link rel="icon"href="~/img/favicon.gif"type="image/x-icon" />
<!-- CSS UI/Grid -->
<link rel="stylesheet"type="text/css"href="~/css/blitzer/jquery-ui-1.8.14.custom.css" />
<link rel="stylesheet"type="text/css"href="~/css/grid/ui.jqgrid.css" />
<!-- CSS Autocomplete-->
<link rel="stylesheet"type="text/css"href="~/css/jquery.autocomplete.css" />
<link rel="stylesheet"type="text/css"href="~/css/thickbox.css" />
<!-- CSS Menu-->
<link rel="stylesheet"type="text/css"href="~/css/ddsmoothmenu.css" />
<!-- CSS general -->
<link rel="stylesheet"type="text/css"href="~/css/Manteniment.css" />
<!-- CSS dateTime picker addon -->
<link rel="stylesheet"type="text/css"href="~/css/jquery-ui-timepicker-addon.css" />
<!-- jQuery Base -->
<scripttype="text/javascript"src="<%=ResolveUrl("~/js/jquery-1.6.2.js")%>"></script>
<!-- Scripts del UI -->
<scripttype="text/javascript"src="<%=ResolveUrl("~/js/jquery-ui-1.8.14.custom.min.js")%>"></script>
<scripttype="text/javascript"src="<%=ResolveUrl("~/js/ui.datepicker-ca.js")%>"></script>
<!-- Scripts del Autocomplete -->
<scripttype="text/javascript"src="<%=ResolveUrl("~/js/jquery.bgiframe.min.js")%>"></script>
<scripttype="text/javascript"src="<%=ResolveUrl("~/js/jquery.ajaxQueue.js")%>"></script>
<scripttype="text/javascript"src="<%=ResolveUrl("~/js/thickbox-compressed.js")%>"></script>
<scripttype="text/javascript"src="<%=ResolveUrl("~/js/jquery.autocomplete.js")%>"></script>
<!-- Scripts del grid -->
<scripttype="text/javascript"src="<%=ResolveUrl("~/js/grid/i18n/grid.locale-cat.js")%>"></script>
<scripttype="text/javascript"src="<%=ResolveUrl("~/js/grid/jquery.jqGrid.min.js")%>"></script>
<!-- Script del Menu -->
<scripttype="text/javascript"src="<%=ResolveUrl("~/js/ddsmoothmenu.js")%>"></script>
<!-- Script de Deserialitzacio -->
<scripttype="text/javascript"src="<%=ResolveUrl("~/js/deserialize.js")%>"></script>
<!-- Script del Validador -->
<scripttype="text/javascript"src="<%=ResolveUrl("~/js/jquery-validate/jquery.validate.js")%>"></script>
<scripttype="text/javascript"src="<%=ResolveUrl("~/js/jquery-validate/localization/messages_ca.js")%>"></script>
<!-- Script del DateTime picker addon -->
<scripttype="text/javascript"src="<%=ResolveUrl("~/js/jquery-ui-timepicker-addon.js")%>"></script>
<!-- Script del Helper -->
<scripttype="text/javascript"src="<%=ResolveUrl("~/js/helper.js")%>"></script>
<styletype="text/css">
#capcalera td
{
padding: 5px 5px 5px 5px;
}
</style>
<!-- PLACEHOLDER DEL HEAD --><asp:ContentPlaceHolder ID="head"runat="server"></asp:ContentPlaceHolder>
</head>
<body>
<tableid="capcalera"border="0"cellspacing="0"style="width: 100%;">
<tr>
<td><ahref="<%=ResolveUrl("~/Blog.aspx")%>">
<imgsrc="~/img/laughing_man_p.jpg"alt="Manteniment del blog"runat="server" /></a></td>
<tdid="logout">Manteniment del Blog (<ahref="<%=ResolveUrl("~/login.ashx")%>?action=logout">Sortir</a>)</td>
</tr>
</table>
<!-- PLACEHOLDER DEL BODY --><asp:ContentPlaceHolder ID="Contingut"runat="server"></asp:ContentPlaceHolder>
</body>
</html>
Aquesta MasterPage permet que tota l'aplicació tingui la mateixa política de seguretat (excepte la pantalla de login) i també tingui una estructura uniforme. Si l'aplicació té un menú també es posa a la MasterPage. Hi ha dos "placeholders" (en negreta al codi), un pel cap ("head") i una altra pel cos ("body"). Les pàgines filles ompliran aquests dos "forats" amb el seu propi contingut, es a dir cada pàgina farà servir la MasterPage i només tindrà un apartat "head" i un "body", sense declarar res més. Això facilita molt el manteniment, per exemple si es vol canviar una versió d'un component només fent la substitució a la MasterPage hi ha prou. Veiem un exemple del head:
En el head va ben poca cosa, però important. El titol de la pàgina, el seu fitxer Javascript particular que gestionarà la pàgina, i la crida a la funció que crea els events. Aquesta funció que crea els events només es crida quan la pàgina ja està carregada. Ara toca un exemple del body, que és força net:
Hi ha detalls MOLT importants que comentar sobre un HTML que sembla tan inofensiu. La forma de maquetar amb taules o div, això ja va a gust del consumidor, donat que les empreses no són donades a fer servir navegadors moderns amb taules és més quadrat, però això ja és una discusió que queda fora d'aquest post.
Els detalls rellevants a comentar són:
Perque la deserialització funcioni el camp ha de tenir el mateix nom que a la BBDD. Bé, de fet no és obligatori però sí recomanable. Si no acaba sent un galimaties.
És important que tots els camps dins d'un formulari tinguin un camp id únic.
Els checkbox han de tenir value=True, així es deserialitzen correctament.
Els combos no tenen dades, es carreguen amb el comboloader.ashx a la part servidora i el LoadCombos al Javascript.
Els grids a l'HTML venen representats per una taula i un div. Queda petit en temps de disseny però és un grid ben gran.
Els calendaris no apareixen aquí, es creen per javascript.
Els botons es defineixen sense events, es fan per javascript.
#27/01/2014 12:11 Programació HTML/CSS Autor: Alex Canalda
Dins del desenvolupament d'aplicacions web, ja hem tractat la part de BBDD, la part servidora amb els ASHX i la clsDades. Ara cal començar amb la part client.
Sempre m'ha molestat la barreja que es fa en la part client entre les diferents parts d'una pàgina web. Tal com ho he muntat he aconseguit separar la presentació (HTML+CSS), els events (jQuery i Javascript) i les dades (Ajax pel transport i JSON).
Amb aquesta separació m'he simplificat la vida i millorat la eficiència (per la xarxa no viatja HTML amb dades empotrades, només JSON), el HTML només viatja el primer cop que es carrega. Si cal canviar colors, tocar HTML o CSS, que cal modificar el comportament, tocar Javascript, que cal tocar dades, aleshores ja depen, però normalment JSON, ASHX i llestos.
Pel que fa a components de .NET, per mi estan morts. Són una castanya, suposo que amb el temps han millorat però recordo que eren difícils de fer servir... Així que faig servir uns altres:
El autocomplete, encara que està deprecat al principi el de jQuery no limitava els resultats i per això el vaig mantenir un temps. Ara ja sí es poden limitar els resultats del autocomplete als de la llista (similar un combobox) i faig servir el de jQueryUI.
Un menú horitzontal (encara que admet un setup vertical)
Un deserialitzador fet en jQuery
El validador de formularis del jQuery
Al fer servir aquests components també té una altra avantatja. És que si algun dia la part servidora deixa de ser .NET i és PHP o qualsevol altra tecnologia, mentre es respecti l'estructura del JSON, almenys la part client seguirà funcionant.
Un petit formulari quedaria com la següent imatge:
Aquest és un formulari tipus, poden variar moltes coses, per exemple que el detall sigui molt gran i necessiti una pantalla apart, que el filtre enlloc d'un camp tingui 19, que el grid el vulguin molt gran, que hagin combos depenents, grids depenents un de l'altra, etc... Tot es pot fer. També té una avantatja que és que no necessita mantenir el ViewState de .NET, estalviant molt tràfic de dades, només viatja el JSON de les poques dades del formulari, el JSON del grid, etc... Així que ara el que cal es veure les parts que he comentat en els seus corresponents posts.
No sóc dissenyador, però a vegades faig veure que ho sóc amb més o menys encert. I ja se que es poden fer servir fonts als CSS desde fa "temps" (en termes informàtics el temps és relatiu).
L'altra dia em vaig animar a posar fonts diferents al blog. I he vist que no és sencill. El primer pas és aconseguir les fonts, m'agrada fer-me les coses jo mateix però a les fonts encara no arriba el meu masoquisme. Per això les he agafat de Google.
He fet servir la lobster pel títol del blog i la nunito pel títol dels posts.
La forma de posar al CSS també és curiosa. Quan descarregues les fonts tens un munt de fitxers amb la font "regular" (normal), "bold" (negreta), "italic", "thin"... Els navegadors si poses la regular però després dius que la vols negreta fan un "faux" bold (o una negreta falsa). I el mateix per la itàlica, tens la regular i li dius que la vols itàlica i et fa una itàlica falsa. El que cal fer és incloure el fitxer "bold" i el fitxer de la "italic". Però enlloc de fer una font NunitoRegular, una altra NunitoBold i una NunitoItalic en el CSS s'ha de fer amb el mateix nom però modificant les propietats "font-weight" (normal o bold) i "font-style" (normal o italic). Aquí trobareu un article que ho explica millor que jo. Jo no ho he tingut que fer per que només faig servir la "regular" de la font Nunito i la font "lobster" només té regular, però poso el codi com sempre:
M'agrada citar el que diuen en altres llocs, però a vegades posar un enllaç no és gaire útil perque has d'anar a l'altra pàgina (que amb els anys ves a saber si funciona) i clar, fer un copy&paste del text d'altres dins del teu sense que es distingeixi doncs queda lleig. Sembla que estiguis atribuint-te l'autoria del text quan en realitat no és així.
Per això existeix el tag blockquote, ja existia en HTML4 però ara han refinat i ajustat millor el seu us. Juntament amb CSS3 s'aconsegueix un efecte que està força bé (almenys ho he vist en FFox i IE10). També han fet que s'hagi d'afegir el tag <footer> (peu) i dins del peu posar un tag <cite> per posar un enllaç a l'autor de la cita.
Veiem les definicions actuals dels elements i aprofitarem per posar uns exemples.
The
blockquote
element represents content that is quoted from another source,
optionally
with a citation which
must
be within a
footer
or
cite
element, and
optionally
with in-line changes such as annotations and abbreviations.
Content inside a
blockquote
other than citations and in-line changes
must
be quoted from another source, whose address, if it has one,
may
be cited in the
cite
attribute.
The cite element represents a reference to a creative work. It must include the title of the work or the name of the author (person, people or organization) or an URL reference, which may be in an abbreviated form as per the conventions used for the addition of citation metadata.
#13/11/2013 11:18 Programació HTML/CSS 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
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)
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