martes, 20 de diciembre de 2011

Filtrar contenido de un combobox (dropdown list) con jquery

Hace poco me encontre con este problema.

Tenia una lista de unos 6000 elementos y necesitaba que los usuario pudieran buscar rapidamente el elemento que necesitaban seleciionar.

Lo primero que pensé hacer fue usar la opción de combobox del autocomplete de Jquery UI sin muy buenos resultados. No sé que hice mal pero no me renderizaba la lista  ni siquiera pude hacer funcionar el ejemplo. asi que decidí tomar un poco de tiempo y hacer un scirpt para esto. El resultado fue más o menos el siguiente:
 <input type="text" id="input"> </input>
 <select name="datoaenviar" id="RemisionEquipoId">
<option value=""></option>
</select>
<select name="datosreferencia" class="hidden" id="RemisionEquipos">
<option value="1">Dato 1</option>
 <option value="2">otro dato</option>
<option value="3">un dato mas</option>
<option value="n">y asi sucesivamente</option>
</select>
  $("#input").bind('keyup', function(){
        $("#RemisionEquipoId").empty();
        var palabra = $(this).val().toUpperCase();
        $("#RemisionEquipos option")
        .filter(function(index){
            return $(this).text().toUpperCase().indexOf(palabra) >= 0 ;
        }).show()
        .clone()
        .appendTo('#RemisionEquipoId');
     
        $('#RemisionEquiposId option:eq(0)').attr("selected", "selected");
    });
El select "datosreferencia" está oculto y contiene todos los datos a filtrar. A medida que en "input" se escribe se van seleccionando los "options" que contengan el texto que se escribe en "input". Cada vez que se presiona una tecla se vacian los datos del select "datosenviar" y se agregan los que cumplan con el criterio.

No es una solución muy elegante pero es sencilla y eficaz.

jueves, 20 de octubre de 2011

Sumar campos en Cakephp y retornar la suma

Lo primero que se me ocurrió para resolver este problema era hacer una consulta find('list), y luego recorrer el arreglo sumando en una variable acumuladora y devolver el resultado.
Esto es sencillo pero resulta poco elegante.

Una mejor solución es incluir en la búsqueda una función de MySQL  y tumar los resultados directamente desde la búsqueda.
Y ya que únicamente necesito un valor, en lugar de find, uso la función field que devuelve un único valor en lugar de un array.

para resumir la cosa quedaría así.


$params = array('equipo_id'=>$equipo_id, 'numero_equipo'=>$numero, 'obra_id'=>$obra_id, 'fecha >'=>$fecha_ini, 'fecha <'=>$fecha_fin);
        $datos = $this->field('SUM(total)', $params  );
return $datos;
Aquí el truco es poner SUM('campo') ya que si la consulta, según las condiciones retorna varios campos, se suman y se devuelve únicamente el resultado.
Si se pone como parámetro de field, simplemente el nombre del campo, retornará la primera coincidencia si alguna.

lunes, 15 de agosto de 2011

Easy print genera problemas para imprimir, como deshabilitar easy print de terminal server


Si ha usado sesiones de terminal server o escritorio remoto, debe saber que es posible ejecutar una aplicacion en el servidor remoto e imprimir enla impresora local gracias al redireccionamiento de impresora.

Para esto debe estar el controlador correspondiente a la impresora tanto el el servidor como en el equipo cliente.  (este controlador debe ser el indicado para cada sistema operativo.)

Aún así es posible que presente problemas de impresión. Una de las razones más comunes para esto es que antes que nada el servidor intenta usar el driver: Terminal Server Easy Print que no siempre es compatible con la impresoras. 



Generalmente esta predeterminado y un usuario sin privilegios no puede cambiar esta configuración.
¿Qué hacer entonces?

La forma mas sencilla es precisamente deshabilitar este comportamiento desde las directivas de grupo de los usuarios en el servidor, justo como se ve en la imagen inferior.
(Entrar a la consola de políticas de equipo: Ejecutar: "gpedit.msc")
"Configuración del Equipo -> Plantillas Administrativas -> Componentes de windows ->"Terminal  services -> Terminal Server.



Después de esto ejecute el comando "gpupdate". Cierre la sesión del cliente he ingrese nuevamemte y si todo quedo bien, en las propiedades de la impresora ya debe aparecer el driver de la impresora tal cual debería estar y podrá imprimir sin dificultades-

miércoles, 15 de junio de 2011

Es mejor usar funciones de mysql para calcular un cunpleaños

El problema es sencillo:
Se desea mostrar de una lista de empleados el empleado que cumpla años el día de hoy.

Como primera opción se pensó en recorrer toda la lista de empleados en la vista haciendo explode() de la fecha y comparando el día y mes. Pero esta opción además de ser tediosa agregaría mucho código en la vista que no seria solo para mostrar los datos sino para calcular un resultado lo caual iría en contra de la filosofía MVC.

Asi que la mejor opción, al menos para mi, fue obtener desde el controlador un arrglo con los empledos que cumplieran años en el día actual.

El código seria más o menos asi:

$this->set('cumplen', $this->Empleado->find('all', array('conditions'=>array('date_format(fecha_nacimiento,\'%m%d\') = date_format(now(),\'%m%d\')'))));
De esta manera se estrían comparando cadenas como '0615' para junio 15 de cualquier año.

También podrían combinarse con opciones como field o containable para traer solo los datos que sean necearios.

sábado, 4 de junio de 2011

Para instalar una genius tvgo A03 iptv en windows 7 64bits

 De hecho ya existe una solucion oficial en la direccion:
http://download.geniusnet.com/2007/Video/How_to_install_TVGo_A03_MCE_%20under%20WinVista.pdf

En resumidas cuentas te dice que debes escoger el controlador para que el dispositivo quede como TV box y no como TV tuner u otra casa.

El controlador para Windows 7 se puede descargar desde aca:
http://download.geniusnet.com/video/TVGo-A03-IPTV_W7.zip

¿Ahora bien donde están los controladores? Esta pregunta viene a lugar porque el archivo solo contiene un ejecutable que no es extraible.

Los controladores en cuestión deberian estar en la ruta:
C:\Program Files (x86)\TVGo A03-IPTV\Drivers\vista64bit

notese que son los de Vista ya que no están oficialmente los de Windows 7

miércoles, 11 de mayo de 2011

Para cada nueva caracteristica en un desarrollo de software debria...

Por cada nueva característica nesecito (en el siguiente orden):
1. Decir que no. 2. Fuerzar  a la nueva característica a de demostrar su valor. 3. Si lo anterior resulta en "no" nuevamente, termino aquí. Si "sí", continúo ... 4. Bosquejo de la pantalla (s) / ui.  (papel o balsamiq mockup).5. Diseño de la pantalla (s) / ui.  (html o en lo que este programando)6. Codificar la característica. 7-15. Probar, ajustar, probar, ajustar, probar, ajustar, probar, ajustar ... 

16. Compruebe si el texto de ayuda tiene que ser modificado. (manuales, ayuda en linea, sitio web.)17. Actualizar el tour del producto (si es necesario). 18. Actualizar la copia de la comercialización (si es necesario). 19. Actualización de los términos del servicio (si es necesario). 20. Comprobar si las promesas se rompieron. 21. Comprobar si la estructura de precios se ve afectada. 22. Lanzamiento. 23. Aguantar la respiración.


Lo anterior lo tome de "Getting Real de 37 Signals". Aunque especificamente aplica para aplicaciones web como productos , tiene sentido para cualquier otro desarrollo.



viernes, 6 de mayo de 2011

Excel tiene la opcion de filtro avanzado (y es una maravilla)

En general Excel y demás aplicaciones de hoja de calculo, tienen un montón de funciones que no usamos, si acaso un 5% se usa habitualmente y el otro 95% no se usa no porque no se necesite si no por desconocimiento..

Seguramente muchos saben usar la opción de auto filtro que está bajo el menú dialogo. Opción muy util para organizar los datos y por supuesto filtrarlos según lo que se requiera.

Pero que onda Con filtro Avanzado? su uso no es muy intuitivo. Y si les paso como a mi, que me da pereza leer la documentación de ayuda, quizá lo hayan dejado de lado.

Hace poco me pidieron la lista de los datos de los clientes que saldrían en la facturación del mes. Un trabajo sencllo bajo el administrador de base de dados, si tuviera acceso a el; pero lo único que disponía era 2 libros de excel: uno con 2000 clientes y otro con 220.

¿"select * FROM Libro1 WHERE Libro1.cliente = Libro2.cliente"?
Una solución genial si tan solo se pudiera hacer en Excel. (o si se puede que alguien me diga cómo).

Mmmm, quizá importando los libros como tablas de SQL, ejecutar la consulta y exportar nuevamente a Excel. Factible pero debería haber una solución mas elegante: "Filtro avanzado".

Para no repetir como se usa dejo el link de un completísimo y claro tutorial de como hacerlo.
Por cierto hecar a una vista a los demás artículos de ese blog seguro le salvará la vida a más de uno que use Excel en su trbajo.

http://jldexcelsp.blogspot.com/2007/03/usando-filtro-avanzado-en-excel.html

martes, 3 de mayo de 2011

UNa impresora de red puede conectarse con linea de comandos

PAra añadir una impresora de red por medio de linea de comando se usa el script prnmngr.vbs: que viene con Windows.

Digamos que se quiere instalar la impresora HP laser jet p1005 que previamente se compartió con el nombre de HP1005. (Aunque pudo ser un mejor nombre como: "Impresora facturación primer piso"), que esta conectada al equipo FACTURACION.  Entonces usaríamos la siguiente linea:

CSCRIPT %windir%\system32\prnmngr.vbs -ac -p "\\FACTURACION\HP1005"
Lo anterior aplica apra Windows XP, en windows vista, 7 y server 2008, la ubicación del prnmngr.vbs cambia y se encuentra en: C:\Windows\System32\Printing_Admin_Scripts\es-Es
por lo cual el comando cambiaría a:
CSCRIPT %windir%\system32\Printing_Admin_Scripts\es-Es\prnmngr.vbs -ac -p "\\FACTURACION\HP1005"
Ahora bien es posible que el equipo que tiene la impresora exija algún tipo de autenticación. Si dispone de un usaurio y contraseña, puede especificarlos añadiendo al final de la linea:

-u nombredeusuario -w contraseña
Para mayor informcaion pueden consultar el sitio de Microsoft

http://technet.microsoft.com/es-mx/library/cc725868(WS.10).aspx

sábado, 16 de abril de 2011

cómo buscar los registros que empiecen por un número

Hasta ahora no he encontrado ningún metodo directo en Cakephp,  asi que la mejor solucion es usar una funcion de my sql por ejemplo:


SUBSTRING(LOWER(Modelo.campo),1,1) BETWEEN '0' AND '9'

Ahora bien simplemente se pasa la cadena completa como un array entre comillas dobles como argumento de paginate. Esto es importante ya que no se pueden escapar las comillas sencillas ya que la cadena es pasada tal cual a la clausula WHERE de la consulta SQL.


                      $this->set('modelo',$this->paginate(array("SUBSTRING(LOWER(Tercero.razon_social),1,1) BETWEEN '0' AND '9'")));
 y Voila! Muy útil para usar cualquier función MySQL.
                     

El símbolo # no es un parámetro valido como argumento en Cakephp

Y de hecho en ninguna otro framework php o aplicación web ya que es el símbolo que hace referencia a la misma pagina o a algún marcador en la misma.

Así que: el código:

$this->Html->link('#', array('action'=>'index'));

Realmente no dispara la acción index del controlador sino que te lleva a inicio de la pagina, nada más.

martes, 12 de abril de 2011

No debo cambiar los nombre de un archivo bajo subversion

Bueno realmente los nombres si se pueden cambiar si son diferentes.

El problema radica en que si por ejemplo cambias un archivo, digamos: Opcion.php a opcion.php,
Subversion asumirá que se borro Opcion.php y se creo opcion.php, realmente no habria problema con esto a menos que este en Windows pues como el S.O. no es caso sensitivo asumira que se trata del mismo archivo y generara un error al tratar de hacer update o commit al proyecto.

Yo tuve que borrar alguna de las copias directamente en el repositorio y quitar el directorio que las contenía y hacer nuevamente check out.

sábado, 2 de abril de 2011

De las primeras cosas a revisar cunado fala un servicio en linux es el espacio en disco.

Ya varias veces me ha ocurrido que cuando servicios  como el squid, apache o mySQL fallan, se trata de poco espacio en disco que impide que se modifique o creen archivos temporales que se requieren para el funcionamiento.

Y aunque uno supondria que al tratar de ejecutar la aplicación esta debería avisar con algo como: "Error tal y tal, me quedé sin espacio en disco, Pilas! muchas veces simplemente sale un "Error".

Verificar lo es fácil en sistemas Linux. (y en Windows si que más).

# df -h

Donde df viene de disk-free y el -h viene de "human" es decir que los tamaños puedan ser leídos por humano, osea en Kb, Mb y Gb según el caso.

miércoles, 23 de marzo de 2011

Los inputs maracados como "disabled" no son enviados con el formulario.

Hoy estuve dando vueltas un par de horas tratando de averiguar porqué no se me estaba guardado correctamente la información de un formulario que recién el día de ayer parecía funcionar a las mil maravillas.

La repuesta, muy sencilla: había marcado una etiqueta html input tipo texto con la propiedad disabled="disabled", lo que hace que esta no pueda ser editada por el usuario, pero tampoco sea enviado como datos del formulario.

Desde la perspectiva del HTML tiene sentido este comportamiento, ya que si el valor no puede der modificado por el usuario, yo ya sé el contenido y no tiene sentido enbviarlo conlos datos del formulario; pero desde un punto "dinámico" del asunto es posible que ese valor sea generado por el servidor y quiero mostrarlo o bien quiero bloquearlos después de hacer cálculos en el Cliente.

¿Solución? Crear un campo tipo "hidden" que copie el valor del campo deshabilitado y procesarlo en lugar de este.

Asi de sencillo.

martes, 22 de marzo de 2011

Para validar indices únicos de 2 campos

Generalmente es fácil hacer la comprobación si un valor que se va a insertar en una columna es único, es decir no será un valor repetido en esa columna.

Pero cuando el indice único esta compuesto por 2 campos digamos nombre y apellido y no quiero que se repita esa combinación, CakePHP, no cuenta son una regla isUnique explicita para estos indices compuestos.

¿La solución?

Crear una función de validación  propia que haga esto por nosotros.
Cómo no soy un experto en CakePHP y menos en PHP, depues de dar tratar de construirla yo mismo por un par de horas, decidi buscar alguna solución ya probada pues segurament eno soy el unico con ese problema. He aqui la solución:

Agregar la siguiente función el el modelo que contiene la combinación de campos a validar.


function checkUnique($data, $fields) {
    if (!is_array($fields)) {
            $fields = array($fields);
        }
        foreach($fields as $key) {
            $tmp[$key] = $this->data[$this->name][$key];
        }
    if (isset($this->data[$this->name][$this->primaryKey]) && $this->data[$this->name][$this->primaryKey] > 0) {
            $tmp[$this->primaryKey." !="] = $this->data[$this->name][$this->primaryKey];
        }
    //return false;
        return $this->isUnique($tmp, false); 
    }

LUego en el mismo modelo en la variable $validate, llamar esta función de validación par AMBOS campos:


'field1' => array(
                'checkUnique' => array(
                    'rule' => array('checkUnique', array('field1', 'field2')),
                    'message' => 'This field need to be non-empty and the row need to be unique'
                ),
            ),
'field2' => array(
                'checkUnique' => array(
                    'rule' => array('checkUnique', array('field1', 'field2')),
                    'message' => 'This field need to be non-empty and the row need to be unique'
                ),
            ),


Y hago énfasis en AMBOS capos pues en algún blog indicaban lo mismo pero omitían el segundo campo y así parece no funcionar, al menos para mi.

Fuente original:
http://stackoverflow.com/questions/3445483/validation-rule-for-a-composite-unique-index-non-primary