lunes, febrero 09, 2015
Validaciones con HTML5 sin necesidad de form.submit
Ahora bien pongamos en contexto, tengo un formulario como este:
<form name="managerForm" id="managerForm">
<p>
Name:
<input id="managerNameText" required="required" placeholder="Write here the new manager name" size="40"/>
</p>
<p>
Email:
<input id="emailText" required="required" placeholder="[email protected]" type="email" />
</p>
<br/>
<a href="#" id="addManagerLink">Add a new Manager to the List</a>
</form>
Si presta atención al markup, podrá ver que se cuenta con dos inputs; un text normal y un email, el text es requerido al igual que el email, adicionalmente el email precisa que el texto introducido sea acorde a una dirección de correo.
Si hiciéramos submit al formulario con algún campo vacío veríamos como el browser se encarga de hacer las validaciones y mostrar los popups con los mensajes de errores.
Ahora bien, el tema es; que sucede si el requerimiento es que el formulario no se envié pero que los errores continúen funcionando de la misma forma. Para ello debemos usar las siguientes funciones en javascript:
var managerForm =
document.getElementById("managerForm");
if (managerForm.checkValidity()) {
// hacer algo
} else {
managerForm.reportValidity();
}
checkValidity retorna true si no existe ningún error en el formulario, de lo contrario retorna false.
reportValidity muestra los mensajes de error en los popups sobre los inputs correspondientes en caso que existan, similar a cuando hacemos submit.
JavaScript: Removiendo hijos
// Bajo parent Id los elementos que deseo eliminar tienen un className en común.
var nodes =
document.getElementsByClassName(className);
var parentNode =
document.getElementById(parentId);
if (nodes) {
for (var i = 0; i < nodes.length; ++i) {
var node = nodes[i];
if (node) {
if (parentNode.contains(node)) {
parentNode.removeChild(node);
}
}
}
}
El problema con el código anterior es que no se eliminan todos los elementos, si no alrededor de la mitad y esto sucede porque el valor nodes.length es alterado cada vez que eliminamos un nodo (o al menos es lo que creo, tampoco me detuve mucho tiempo a comprobar mi teoría), el cambio siguiente me funciono bien (simplemente cambie el siglo del for para que decremente en lugar de incrementar)
for (var i = nodes.length - 1; i >= 0; --i)
domingo, enero 12, 2014
Cache y estrategias, parte 1
lunes, diciembre 09, 2013
Ordenamiento de numeros flotantes en sistemas de persistencia
Necesidad de almacenar numeros flotantes en un sistema de persistencia java (en el caso particular es para Lucene/Solr, pero podria bien ser para MySql, Mongo o cualquier otro sistema de persistencia)
Una vez almacenados esos flotantes, debemos hacer ordenamientos por ellos y a su vez obtenerlos y formatearlos de tal manera que se muestren en una presicion de 2 decimales.
Es decir un numero como 12.542323
Debera ser presentado como 12.54
Lo normal sería almacenar el valor tal cual en el sistema de persistencia y despues con un objeto Decimal Format darle formato con precisión 2.
Sin embargo con numeros flotantes, Java no asegurá total exactitud en este calculo y fue constatado pues a la hora de pasar un flotante cuya mantiza se encuentra cerca de .99 se redonde al siguiente numero, lo cual resultaba en un comportamiento perjudicial.
Una solución sería cambiar todo por numero double, estos funcionan bastante bien y el Decimal Format también funciona de forma decente, sin embargo existe una solución un poco mas estable y segura que comentamos acontinuación.
Pasar el numero flotante a un entero cuyos ultimos dos digitos serían los dos decimales de precisión que se requieren desplegar.
Veamos como sería el asunto:
Si se tienen numeros como:
12.546676
12.073847
guardariamos numeros tales como:
1254
1207
A la hora de formatear estos numeros, simplemente sacariamos los ultimos de digitos y se mostrarían como:
12.54
12.07
La solución es muy segura, y para los flotantes de 30 bits o menos funciona bien (pues se ocupan dos para los decimales) así que si no tienes numeros muy grandes una buena solución.
jueves, junio 13, 2013
Canvas - Dibujando poligonos con Javascript (Herencia y pseudo polimorfismo)
Lo primero el HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Figure Example</title>
</head>
<body>
<canvas id="myCanvas" width="300" height="300" style="border: solid 1px black"></canvas>
<script type="text/javascript" src="figure.js"></script>
</body>
</html>
Note q al javascript le hemos dado el nombre de figure.js
Seguidamente el codigo con el canvas, es bastante sencillo para mas detalles busque la documentacion de cada metodo.
/**
* User: jsanca
* Date: 6/12/13
* Time: 11:10 PM
*/
// Defines a point
function Point (x, y) {
this.x = x;
this.y = y;
} // Point
// Basic definition of a Figure, just a point in nowhere.
function Figure (point, name) {
this.point = point;
this.name = name;
this.render = function (context) {
console.log("figure: " + this.name + " " +this.point);
}
} // Figure.
// the points defines some of the sides
function Square (point1, point2, name) {
Figure.call(this, point1, name);
this.point2 = point2;
this.side = function () {
var side =
(this.point2.x == this.point.x)?
this.point2.y - this.point.y:
this.point2.x - this.point.x;
return Math.abs(side);
}
this.area = function () {
var side = this.side();
return Math.pow(side, 2);
}
this.render = function (context) {
// render out the square.
var side = this.side();
context.fillStyle = "rgb(0,0,255)";
context.fillRect (this.point.x, this.point.y, side, side);
console.log("square: " + this.name + ", area = " + this.area());
}
} // Square.
Square.prototype.parent = Figure.prototype;
Square.prototype.constructor = Square;
// the points defines the point angles
function Triangle (point1, point2, point3, name) {
Figure.call(this, point1, name);
this.point2 = point2;
this.point3 = point3;
this.area = function () {
var base = 0;
var verticalHeight = 0;
if (this.point2.x == this.point.x) {
base = this.point2.y - this.point.y;
verticalHeight = this.point.x - this.point3.x;
} else {
base = this.point2.x - this.point.x;
verticalHeight = this.point.y - this.point3.y;
}
return 0.5 * Math.abs(base) * Math.abs(verticalHeight);
}
this.render = function (context) {
console.log("triangle: " + this.name + ", area = " + this.area());
// the triangle tooks a base point and them move to the rest of the angle point
context.fillStyle = "rgb(255,0,0)";
context.beginPath();
context.moveTo(this.point.x,this.point.y);
context.lineTo(this.point2.x,this.point2.y);
context.lineTo(this.point3.x,this.point3.y);
context.fill();
}
} // Triangle.
Triangle.prototype.parent = Figure.prototype;
Triangle.prototype.constructor = Triangle;
// the points you pass are the diagonal of the rectangle.
function Rectangle (point1, point2, name) {
Figure.call(this, point1, name);
this.point2 = point2;
this.width = function () {
return Math.abs(this.point2.x - this.point.x);
}
this.height = function () {
return Math.abs(this.point2.y - this.point.y);
}
this.area = function () {
return this.width() * this.height();
}
this.render = function (context) {
console.log("rectangle: " + this.name + ", area = " + this.area());
context.fillStyle = "rgb(0,255, 0)";
context.fillRect (this.point.x, this.point.y, this.width(), this.height());
}
} // Rectangle.
Rectangle.prototype.parent = Figure.prototype;
Rectangle.prototype.constructor = Rectangle;
// the points defines the radius
function Circle (point1, point2, name) {
Figure.call(this, point1, name);
this.point2 = point2;
this.radius = function () {
var radius =
(this.point2.x == this.point.x)?
this.point2.y - this.point.y:
this.point2.x - this.point.x;
return Math.abs(radius);
}
this.circumference = function () {
var radius = this.radius();
return 2 * Math.PI * radius;
}
this.area = function () {
var radius = this.radius();
return Math.PI * Math.pow(radius, 2);
}
this.render = function (context) {
var radius = this.radius();
console.log("circle: " + this.name + ", area = " + this.area() + ", circumference = " + this.circumference() + ", radius = " + radius);
context.fillStyle = "rgb(255,255, 0)";
context.beginPath();
context.arc(this.point.x, this.point.y, radius , 0,2 * Math.PI);
context.stroke();
}
} // Circle.
Circle.prototype.parent = Figure.prototype;
Circle.prototype.constructor = Circle;
console.log("Running");
var figuresArray = new Array(
new Square (new Point(10,10), new Point(10,30), "Cuadrado 1"),
new Square (new Point(10,50), new Point(20,50), "Cuadrado 2"),
new Triangle(new Point(10,10), new Point(10,20), new Point(0,15), "Mi Triangulito"),
new Triangle(new Point(100,100), new Point(60,160), new Point(160,160), "Triangulo grande"),
new Rectangle(new Point(80,50), new Point(90,80), "Mi Rectangulo"),
new Circle(new Point(200,200), new Point(200,225), "Mi Circulo")
);
var canvas = document.getElementById('myCanvas');
var context = (canvas.getContext)?
canvas.getContext('2d'):null;
figuresArray.forEach(
function(entry) {
console.log(entry);
entry.render(context);
}
);
Ejecutalo para ver el resultado :) cada figura tiene un color diferente