A vegades faig programes complicats i sembla que "sàpiga" molt, però no. Avui en dia cal saber unes bases però la resta no cal recordar-ho de memòria, cal saber on trobar-ho i com buscar-ho. Per això hem trobo buscant el mateix de forma repetitiva certs temes. Un d'ells és com recuperar el valor d'un control radiobutton en un formulari des de Javascript (fent servir jQuery). Tenim l'HTML:
Observar en l'HTML cada radiobutton té un value i un id diferent, el que els lliga i fa que estiguin relacionats és el name. El codi javascript per recollir el valor del radiobutton seleccionat és:
var OrderBy = $('input[name="ordenarpor"]:checked').val();
Job done!
#09/09/2020 18:43 Programació Javascript HTML/CSS Autor: Alex Canalda
Aquests dies de coronavirus i de quedar-se a casa, intentant sobreviure a conviure tots junts en un espai reduït, aprofito per programar coses. Una d'aquestes vaig pensar: ¿I si enlloc de fer servir un tag input type="button", faig servir el tag button directament? I així estava jo molt content d'aquesta idea inspiradora quan de sobte, un cop posat el tag button, li dono i "ups!" la pàgina navega a un altra lloc.
Els formularis que faig en HTML acostumen a funcionar amb AJAX, tant per recuperar dades com per guardar-les i no "naveguen" a cap lloc, la URL no acostuma a canviar, i en el meu codi javascript no hi havia res que modifiqui la URL. Per això em va estranyar que amb el nou tag button sí. Vaig trigar una bona estona fins trobar el que passava. Resulta que la URL on navegava la pàgina era el "action" del formulari (vaig trigar a adonar-me perque els meus formularis tenen el action="/", no tenen). I el que estava fent el botó era un submit del formulari. I com és que el tag button fa un submit si jo no li dic per javascript? Aaaaah...
submit: envia el formulari mitjançant un HTTP Post a l'action del formulari.
reset: neteja el formulari.
button: no fa res, només executa el javascript quan es fa l'event click
La punyeteta està en la següent frase de l'especificació:
The missing value default is the Submit Button state.
Es a dir, que si al tag button no li poses un atribut type, aquell botó fa submit. I jo que tinc un munt de buttons en el formulari... no crec que aquest comportament per defecte sigui el millor i que de sobte tots facin submit. Per defecte hauria de ser "button", així ens estalviaríem coses del capità "obvious" al tenir que posar molts tags "button type="button" ...." tu escrius un button no cal dir-li que a més a més és de tipus... mmmmm... deixam pensar... mmmmmm... a sí, tipus button.
#16/03/2020 16:28 Programació HTML/CSS Autor: Alex Canalda
Amb el canvi de servidor he posat Windows Server 2016, IIS 10, SQL Server 2016 per veure que hi ha de nou. La migració del software d'un a l'altra ha anat prou bé. Copiar fitxers, permisos NTFS, moure BBDDs, canviar cadenes de connexió... fins que al cap d'un temps m'he fixat que en una de les meves webs, un control jQuery, el Grid, no es veia bé.
Resulta que els texts del control mostraven caràcters estranys en els accents. Típics errors de joc de caràcters. Si obria el fitxer JS en l'Editplus veia el text correctament, l'editor em deia que el fitxer està codificat amb ANSI, encara que en realitat per filar prim és Windows-1252. En HTML5 la codificació Windows 1252 es pot servir com ISO-8859-1 ja que les considera la mateixa.
També és curiós veure com el Firefox, en el Network monitor veu correctament el fitxer, en canvi en el Javascript Debugger el mostra amb els caràcters estranys. Suposo que ara han adoptat el UTF-8 com codificació per defecte si no s'indica res.
Hi ha varies solucions, poso les que he trobat més "assequibles".
Passar el fitxer a UTF-8, s'ha de fer fent un "Guardar como...", no un canvi a sac de codificació ja que el canvi directe perd els caràcters, mentre que el "Guardar como..." fa la transformació.
No modificar el fitxer JS i indicar en tag HTML que importa l'script la codificació que fa servir:
Quan es deserialitzen valors que venen d'un JSON contra un formulari normalment tots els controls del formulari reben correctament els valors del JSON. Tots? No! Un grup d'irreductibles controls es resisteixen a l'invasor. Els "checkboxes"!
En el JSON es poden passar els booleans de dues formes diferents, el serialitzador genera el JSON de forma diferent segons l'origen. Es poden serialitzar de forma nativa ja que el JSON suporta el tipus booleà, llavors es troba algo com: "Camp_boolea": true. En canvi també es pot serialitzar com un "string", i queda així: "Camp_boolea": "True", cal fixar-se en les cometes...
Quan es declara un control checkbox s'ha de fer de les següents maneres, si al JSON arriba un booleà:
Canvia el value, i el que no és tan intuïtiu és que surti un value="1" pel JSON booleà. També cal tenir en compte el deserialitzador javascript que es fa servir...
#05/11/2014 11:33 Programació Javascript HTML/CSS Autor: Alex Canalda
Amb HTML5 es pot carregar un fitxer de l'ordinador local on està el navegador directament a una pàgina web, sense passar pel servidor web. Antigament per fer això calia pujar el XML al servidor, aquest processar-lo i enviar-te el HTML amb els controls degudament informats. Això s'ha acabat, al menys en Firefox. Cal fer un HTML com el següent:
Un cop fet això cal fer el següent script (té el document.ready del jQuery, així que s'ha de posar el jQuery també):
<script>
var reader = new FileReader();
reader.onload = function (e) {
var text = reader.result;
if (window.DOMParser) {
parser = new DOMParser();
xmlDoc = parser.parseFromString(text, "text/xml");
$("#test").val(xmlDoc.getElementsByTagName("SOAPAction")[0].childNodes[0].nodeValue);
}
else {
alert("No hi ha parser!");
}
}
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object// files is a FileList of File objects. List some properties.var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
f.size, ' bytes, last modified: ',
f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a',
'</li>');
reader.readAsText(f);
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}
$(document).ready(function () {
// Check for the various File API support.if (window.File && window.FileReader && window.FileList && window.Blob) {
document.getElementById('files').addEventListener('change', handleFileSelect, false);
} else {
alert('The File APIs are not fully supported in this browser.');
}
});
</script>
Com es pot veure a l'exemple, el XML ha de tenir el tag "SOAPAction" i el seu valor es posa al control "test", i llestos!
#26/05/2014 16:06 Programació Javascript HTML/CSS Autor: Alex Canalda
Segueixo veient cosetes del HTML5, aquest cop és un atribut dels camps input que es diu placeholder. Consisteix en posar un text dins d'un input de tipus text que quan l'usuari comenci a escriure desapareix. Abans això es feia amb Javascript, ara està en el llenguatge. Millor un exemple, el codi seria:
<inputname="valor"id="valor"type="text"placeholder="Entra aqui el valor" />
I quedaria algo com:
També és curiós que el comportament no és exactament igual en tots els navegadors. En IE11 tot just el input rep el focus el text desapareix. En Firefox no, desapareix quan l'usuari comença a escriure. El valor del placeholder no s'envia mai al servidor, es a dir, si es fa un HTTP POST d'un camp buit amb placeholder aquest valor no forma part del que s'envia al servidor.
#20/03/2014 16:51 Programació HTML/CSS Autor: Alex Canalda
He provat diferents formes de posar els SVG dins del HTML. He fet servir dues, la primera fent servir el tag HTML <svg>, i dins del tag posar tot el text SVG que un editor com Inkscape ha generat, fent copiar / enganxar. L'altra es fer servir un tag img i en l'atribut src posar el fitxer svg tal qual surt de l'editor. El resultat visualment és el mateix però, almenys en Firefox, el que fa servir el tag svg permet seleccionar els texts de dins del svg, mentre que el que està com atribut d'un img es comporta com un block, sense poder seleccionar res. Curiós.
#21/02/2014 11:34 Programació HTML/CSS Autor: Alex Canalda
Gràcies al meu nou monitor estic descobrint coses lletges de la programació, i coses lletges de la navegació. Gràcies a que el nou monitor té High DPI veig les coses més nítides, però també descobreixo que no tot està preparat per funcionar amb High DPI. Ja he vist que les aplicacions d'escriptori en Winforms no van bé, però ara resulta que al navegar també hi ha defectes.
Normalment quan el navegador carrega una imatge, la mostra a 1px de la imatge 1px de la pantalla, però jo estic al 125% d'augment, els píxels són més petits, i clar, cal fer un estirament del 25%. Quan les imatges són suficientment grosses, i són fotos aquest 25% no es nota. El problema ve quan les imatges no són tan grosses i contenen text, llavors el text es torna borrós. I jo per fer uns pocs dibuixos per explicar quatre coses sobre programació faig servir text, i clar, al meu xupimonitor es veuen malament, i això és en quatre paraules in-to-lera-ble, inclús afegiria inacceptable.
Remenant pel Internets he trobat una forma de generar imatges i que es vegin bé a qualsevol resolució. Primer he vist l'element HTML5 canvas, però el "canvas" no deixa de ser un bitmap on es dibuixa (normalment amb Javascript) i depenent del navegador pateix de problemes d'escalat a HighDPI. Després he vist el format bo, el SVG, que guarda la imatge com un conjunt de vectors. Clar com són vectors si cal estirar un 25% la figura no hi ha problema, es torna a calcular el resultat i llestos. El problema està en editar els SVG ja que és un llenguatge força espès, cal fer servir un editor de SVG. He trobat el InkScape que és un editor gratuït que he pogut fer servir. No és que sigui la meravella de l'usabilitat però és força acceptable per ser de codi lliure.
Un cop es té el SVG hi ha varies possibilitats per posar-lo a la pàgina. Els navegadors entenen el tag svg, per tant es pot posar dins del HTML directament (obrir amb editor de texts el SVG i copiar i enganxar), és el que s'anomena "inline". O bé fer servir el tag img, especificant en l'atribut src el fitxer .svg. De moment he provat la versió "inline", aquí amb molts bons resultats.
Cal tenir en compte que ara vindrà una onada de dispositius HighDPI, els nous monitors 4K. Als que cal sumar els dispositius que ja són HighDPI, com els nous SmartPhones i Tablets. Per això amb paciència aniré modificant els meus dibuixos per fer-los amb SVG... Si es que se m'acumula la feina.
#20/02/2014 11:42 Software HTML/CSS Autor: Alex Canalda
Al principi de fer el blog em vaig plantejar en quin idioma escriure. Vaig escollir el català per comoditat, ja que és el que parlo i penso. Però després vaig pensar que també en anglès, ja que quina millor forma de demostrar algo que fer-ho. Sempre penso en els currículums inflats que veig de tant en tant i que Einstein era un mindundi al costat, però que després alhora de fer algo fan llufa. Així que alehop! Blog multiidioma.
Això a nivell de software suposa varies coses, primer afegir a tots els posts un camp idioma, a les categories també. I després a la part de manteniment del blog cal afegir el corresponent combo amb l'idioma i que carregui en cascada les categories del idioma sel·leccionat. Dins de la pàgina que mostra el blog hi ha un switch-case on posa a tots els texts del blog el que toca segons l'idioma.
A nivell d'HTML5 l'idioma es pot definir a diferents nivells, jo l'he posat a nivell de pàgina on queda així:
<!DOCTYPE html>
<html lang="ca">
[.....]
Com a última cosa és que tinc que re-escriure els posts amb anglés, en HTML serà lang="en"... Yummi! Això ja dependrà de les ganes i el temps disponible.
#19/02/2014 11:34 Programació HTML/CSS Autor: Alex Canalda
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