Me lo contaron y lo olvidé, lo leí y lo entendí, lo hice y lo aprendí.





viernes, 22 de septiembre de 2017

[JavaScript] Usar checkbox en Kendo Grid con valores booleanos

Introducción

El grid de KendoUI soporta datos del tipo booleano, pero su funcionalidad de edición para el usuario se representa en forma de un campo "select" (DropDown) con las opciones de "verdadero" y "falso". De forma nativa no permite poner un "CheckBox" que realice esta función y si se quiere hacer uso del template para poner el "CheckBox" éste no actualiza por sí solo la información del campo en el grid.
Para términos de la explicación

En los ejemplos de esta explicación se tiene el siguiente ambiente:

  • Un grid con ID: "div-monitor-data-grid"
  • El grid tiene como "DataSource" un arreglo llamado "resultadoFlujo".
  • Los objetos del DataSource tienen un atributo llamado "Seleccionada", el cual es el "booleano" que se quiere manipular con el checkbox; éste deberá ser sustituido por el atributo que se desea manipular en sus propios casos.
  • Los objetos del DataSource tienen un atributo que les sirve de llave primaria: IdDetalle; éste deberá ser reemplazado por el o los atributos que identifiquen de manera única los objetos en sus propios casos.

Solución

Debido a que la única forma (Hasta ahora conocida) de agregar un campo tipo CheckBox a un GRID en kendo es mediante del Template se hará uso de éste, poniendo una condición para que cuando el campo tenga el valor "true" el input esté seleccionado y deseleccionado para el caso contrario:

{
    title: "Seleccionar",
    field: "Seleccionada",
    template: "#if(Seleccionada){#<div class='text-center'><input  type='checkbox'  class='chkSeleccionada' checked/></div>#}else{#<div class='text-center'><input  type='checkbox'  class='chkSeleccionada'/></div>#}#",
},

Como se aprecia, el checkbox contiene una clase (En este caso: "chkSeleccionada"), la cual servirá para capturar el evento de éste al ser "clickeado" por el usuario; ésta función se "amarrará" al grid donde se encuentre el input, además de que se realizará en una función "anónima" para que se ejecute en cada momento:

$(function () {
  $('#id-del-grid').on('click', '.chkSeleccionada', function () { //Como se ve, el evento se da a la clase "chkSeleccionada"
    .......
  });
});

La lógica dentro del evento debe ser la siguiente:
Obtener el valor del checkbox (Si está o no seleccionado).
Recuperar el objeto del grid del cual obtendremos el objeto de la tupla que corresponde al checkbox clickeado.
Recorremos la lista que funge de "DataSource" para el "Grid". En cada iteración se compara con el objeto de la tupla seleccionada; y de ser ésta la tupla, al objeto del arreglo se le da el valor del checkbox (True o false).
Se refresca el grid al terminar de iterar.
El código final de ésta función quedaría así:

$(function () {
  $('#div-monitor-data-grid').on('click', '.chkSeleccionada', function () {
     var checked = $(this).is(':checked'); //Se obtiene el valor del checkbox
     var grid = $('#div-monitor-data-grid').data().kendoGrid; //Se obtiene el objeto del grid
     var dataItem = grid.dataItem($(this).closest('tr')); //Se obtiene la tupla que corresponde al checkbox
     for (var i = 0; i < vm.resultadoFlujo.length; i++)
    { //Se itera el datasource
       if (vm.resultadoFlujo[i].IdDetalle == dataItem.IdDetalle)
      { //Se pregunta si es el mismo objeto del checkbox
         vm.resultadoFlujo[i].Seleccionada = checked; //Se edita el valor del atributo por el del checkbox
      }
    }
    grid.dataSource.read(); // Se vuelve a "leer" el dataSource del grid.
    grid.refresh(); //Se refresca el GRID.
  });
});

martes, 3 de enero de 2017

[JavaScript][Jquery] Convertir todas las cadenas de un objeto (O cualquier variable) a mayúsculas

Como anécdota personal, en mi trabajo se hacen llamados a servicios web desde JavaScript enviando objetos con los cuales se interactuará en la base de datos; la norma es que toda cadena que se envía a la base de datos debe de estar formateada a mayúsculas, y es un gran lío pasar atributo por atributo (o campo por campo) a mayúsculas de forma manual.
Ante ésto me di la ligera tarea de crear una función que usando la recursividad, y testeando el tipo de datos con el cual trabaja en cada iteración, recorra todos los elementos del objeto y, cada cadena con la que se interactua es convertida a mayúsculas.
Ahora les comparto tal función para su uso personal, aunque eso sí, se ha de incluir la librería de JQuery al sitio donde trabajan, debido a que se hace uso de su función "type()" para saber con qué tipo de dato se está trabajando.

Les presento el código:



function objectUpperCase(objeto)
{
if(jQuery.type(objeto) == "string")
{
return objeto.toUpperCase();
}
if(jQuery.type( objeto ) == "array")
{
var arreglo = [];
for(var i=0;i<objeto.length;i++)
{
arreglo.push(objectUpperCase(objeto[i]));
}
return arreglo;
}
if(jQuery.type( objeto )=="object" || jQuery.type( objeto )=="function")
{
for (var atributo in objeto) {
objeto[atributo] = objectUpperCase(objeto[atributo]);
}
}
return objeto;
}



Como mencioné anteriormente, se testea el tipo de dato con el que se trabaja y dependiendo de ésto (cadena, array, objeto, función...) se hace uso de la recursividad para interactuar con sus elementos (en caso de que sea un objeto o arreglo), se convierte a mayúsculas (En caso de que sea directamente una cadena) o se ignora en cualquier caso que no requiera interacción. De esta forma se garantiza que aún usando objeto "complejos", todos las cadenas que se manejen serán convertidas a mayúsculas estén en la profundidad que estén.

La única desventaja de este método es la recursividad misma en JavaScript, debido a que los navegadores limitan el uso de memoria así como de llamadas recursivas de forma interna. Lo que nos limita a una profundidad no mayor de 8 o  10 (dependiendo del navegador a utilizar).

[JavaScript] Llenar cadena de ceros (o cualquier caracter) a la izquierda

En ocasiones se requiere formatear a una cadena con una longitud estática, rellenando con un carácter (Comúnmente ceros 0s) a la izquierda las posiciones faltantes; por ejemplo, si se requiere tener una cadena de longitud 6 y se tiene la cadena "123", será necesario convertirla a "000123".

JavaScript no cuenta con una función nativa para "rellenar" una cadena con un carácter específico para que ésta tenga una longitud determinada; y las mayorías de las soluciones a este problema consiste en bucles y condicionales que se extienden más allá de la simpleza del problema. La solución que propongo en esta ocasión consiste en un método que genera una cadena tal que, al concatenarla con el texto que ya se tiene, se obtenga un "String" con la longitud determinada.

La solución sería la siguiente:


caracter.repeat(longitud- String(cadena).length).concat(cadena);



O, expresado a una función:


function llenarCadena(cadena,longitud,caracter)
{
        //Siendo "cadena" el texto a completar
        //"longitud" el largo de la cadena deseada
        //"caracter" el símbolo con el cual se llenarán los espacios faltantes
return caracter.repeat(longitud- String(cadena).length).concat(cadena);
}



La lógica es sencilla; como expliqué arriba, consiste en crear una cadena de caracteres (caracter.repeat) con la longitud necesaria (longitud- String(cadena).length), tal que al concatenarla con la cadena original, nos dé un texto con la longitud deseada.
En pocas palabras, usando el ejemplo inicial; la parte del código "caracter.repeat(longitud- String(cadena).length)" generará la cadena "000" el cual, al concatenarse con la cadena original, dará un texto de longitud 6.

Pues bien, sería todo. Espero les sea de utilidad

domingo, 22 de mayo de 2016

Agregar AdFly a los enlaces de tu web [y monetizarlos]

AdFly es esencialmente un acortador de URL cuyo funcionamiento es simple: pasa por una página intermedia (Del dominio de AdFly) antes de redirigir a la página original, pero que da la opción de crearse una cuenta y obtener dinero cada vez que alguien utiliza uno de tus enlaces personalizados.
La forma más sencilla de hacer esto es crear una cuenta (Obviamente) y usar la herramienta de "acortar", la cual siempre se situará en la parte superior de la página de AdFly; pegas en "link" que quieres personalizar y le das en "Acortar", se te generará el nuevo enlace el cual podrás colocar en tu página y, al ser usado, se te abonará una pequeña cantidad de dinero.


Eso implicaría que a cada enlace que quieras utilizar para obtener ganancias de él tendrás que hacerlo pasar por este proceso; más tenemos la opción de afectar, automáticamente, a todos los enlaces de nuestra página, a los enlaces en nuestra página con excepción de ciertos dominios o sólo a los enlaces de nuestra página que contengan algunos dominios determinados.

Para realizar ello, una vez teniendo creada la cuenta en AdFly (Inicialmente no es necesario introducir datos bancarios, sino hasta el momento de cobrar las ganancias) ir a la sección de Herramientas: 
Y, en el panel izquierdo, elegir la opción Documentación de la API, se nos mostrará la información que utilizaremos para implementar AdFly en nuestra web, más precisamente el "ID de usuario" y la "llave pública de API"; únicamente necesitaremos el "ID de Usuario":


Ahora procederemos a insertar un código en JavaScript en nuestra web, preferentemente entre las etiquetas "<head>" y "</head>".
Para que todos los enlaces se vean afectados por el Script solo es cuestión de poner el siguiente código:

<script type='text/javascript'>
var adfly_id = {Tu ID de usuario}
var adfly_advert = 'int'; 
var popunder = false; 
</script>
<script src='https://cdn.adf.ly/js/link-converter.js'/> 

Sólo es cuestión de reemplazar el valor "{Tu ID de usuario}" por el Id que se te mostró en la opción "Documentación de la API"; ahora bien, para que la API no afecte a los enlaces de determinado dominio (Como el de nuestra propia web) se debe agregar una variable extra: "exclude_domains" la cual obtendrá una lista de los dominios que deben ser excluídos, por ejemplo: ['blogspot','youtube','plus.google','youtu.be','wikimapia.org'].
Quedando el ejemplo de la siguiente forma:

<script type='text/javascript'>
var adfly_id = {Tu ID de usuario}
var adfly_advert = 'int'; 
var popunder = false; 
var exclude_domains = ['blogspot','youtube','plus.google','youtu.be','wikimapia.org']; 
</script>
<script src='https://cdn.adf.ly/js/link-converter.js'/> 

O bien, si se quiere hacer lo contrario: que el Script sólo afecte a los enlaces de cierto dominio, en lugar de agregar la variable "exclude_domains" se agrega una simplemente llamada "domains" con la lista de los dominios que se quiere que afecte; por ejemplo: ['depositfiles.com','rapidshare.com','vip-file.com'].
Quedando el ejemplo así:

<script type='text/javascript'>
var adfly_id = {Tu ID de usuario}; 
var adfly_advert = 'int'; 
var popunder = false; 
var domains = ['depositfiles.com','rapidshare.com','vip-file.com'];
</script>
<script src='https://cdn.adf.ly/js/link-converter.js'/> 

Ahora sólo unas aclaraciones de configuración:

  • Se pueden agregar banner publicitarios extra nuestras páginas por medio del mismo script (Agrega la publicidad en la parte inferior de la pantalla y genera unas ganancias extra) cambiando el valor de "var popunder = false;" por "var popunder = true;".
  • También se puede cambiar el tipo de publicidad en el momento de redirección; originalmente se muestra en toda la pantalla, más se puede cambiar a que solo sea un simple banner (Menos intrusivo pero también menos dinero) cambiando la variable "var adfly_advert = 'int';" por el valor "banner".

También en las opciones de cuenta:


En la parte inferior se encuentran las siguientes tres opciones:


  • Anuncios de aplicaciones móviles: Habilita y deshabilita la publicidad en los dispositivos móviles al momento de redireccionar. Se puede deshabilitar para minimizar la cantidad de megas que se consumen.
  • "Skip Ad" adverts: da la opción (De estar activada) de saltarse la publicidad en la redicción de forma instantánea; normalmente hay que esperar de 5 a 10 segundos para que el usuario tenga esa opción (Habilitarla puede minimizar los ingresos obtenidos).
  • Stop Adblock user: De estar habilitada, la aplicación detecta si el navegador tiene el plugin "AdBlock" activado y, de estar activado, solicita al usuario desactivarlo para poder continuar a la página destino.
La cantidad de ganancias obtenidas varían dependiendo de la configuración que se tenga: una configuración más intrusiva (y agresiva) generará más ganancias, pero sin duda resultará más molesto para el usuario, cosa que bien hay que tener en cuenta

viernes, 20 de mayo de 2016

Obtener arreglo desde una lista de "CheckBox" con AngularJs

AngularJs es un Framework de JavaScript de código abierto, mantenido por google. Su existencia es más que una simple curiosidad, ya que permite a desarrolladores crear aplicaciones web de "una sola página" (Single Page Applications). Este framework nos da la facilidad de manipular datos entre el "DOOM" de HTML y las variables en JavaScript sin tener que usar código intermedio para mantener este "puenteo" (binding) que siempre nos ha costado líneas de código adicionales y, sobre todo, extensas en nuestros ficheros de JavaScript.
Aunque, por muy hermoso que sugiere ser la herramienta, siempre existirán casos específicos los cuales tendremos que resolver por nuestra propia cuenta; tal es el caso del tema que abordo en esta publicación y que, seguramente, te habrás topado (o te toparás): querer obtener un arreglo de una lista de "CheckBox", usando AngularJs claro.
Aunque varios programadores han creado sus propias directivas que el framework permite configurar, la propuesta que presento se destaca por su simpleza en el código.

Para esta función me base en tres elementos técnicos:

  1. AngularJs crea (Y elimina) elementos de JavaScript según sea necesario. Aunque no declares un objeto o atributo en el controlador de Angular, si lo utilizas en la vista HTML el framework automáticamente lo creará en cuando el usuario interactue con él.
  2. En un campo de formulario declarado como Requerido (REQUIRED) no existen o se eliminan si éste no contiene un valor (O uno inválido).
  3. La función "$.map" de JQuery que interactúa con varios items y devuelve un arreglo de éstos (En este caso, se interactúa con los atributos de un objeto).

Primero vamos a preparar el archivo HTML de nuestro ejemplo:

<html >
<head>
<meta charset="UTF-8">
<title>Checkbox array list AngularJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="controller.js"></script>
</head>
<body>

</body>
</html>

Como ven, importo las librerías de Jquery y Angular (desde las apis de Google). Además de que haré uso de un archivo de JavaScript llamado controller.js el cual tendrá el código de AngularJs.

Justo en el archivo controller.js pondré el siguiente código de prueba:

var app = angular.module('myApp', []);
app.controller('indexController', function($scope) {
        var vm = this;
vm.lista = [
{id:1,valor:"Juanito Alcachofa"},
{id:2,valor:"Padro Alcántara"},
{id:3,valor:"María Mercedez"},
{id:4,valor:"Romero Romerío"},
{id:5,valor:"Susana Nollores"},
];
vm.seleccionados={};
});

Creo la App: "myApp", y en controller: "indexController".
Aquí declaro dos variables que formarán parte del controller:
  • vm.lista: nos servirá para desplegar la lista de los checkbox.
  • vm.seleccionados: Será el objeto donde se "almacenarán" los checkbox seleccionados y que, posteriormente, convertiremos en un arreglo.
Quiero aclarar que para cuestiones de espacio, declaro la variable "vm = this" para hacer referencia al "$scope" de una forma más corta, nada más.

Ahora, volveremos al archivo HTML para desplegar la Interfaz; dentro del "BODY":

<div ng-app="myApp" ng-controller="indexController as vm">
<p ng-repeat="elemento in vm.lista" > 
<input type="checkbox" ng-model="vm.seleccionados[elemento.id]" required/>{{elemento.valor}} 
</p>
<p>{{vm.seleccionados}}</p>
<p><button ng-click="vm.obtenerSeleccionados();">Mostrar arreglo</button></p>
</div>

  • Creo un "DIV" en el cual hago instancia de la app y del controller (A este último le vuelvo a dar un alias: vm, para hacer una referencia corta al controlador).
  • Creo una etiqueta "P" en la cual uso la directiva "ng-repeat" para iterar la lista que declaramos en el controlador "indexController. 
  • Dentro de la etiqueta "P" creo los "checkbox"; note que en la directiva "ng-model" le indico "vm.seleccionados[elemento.id]" lo que quiere decir que al objeto "vm.seleccionados" le estaremos modificando el atributo dado por "elemento.id" el cual, aunque nosotros no lo hayamos declarado, el mismo AngularJs lo irá creando o destruyendo conforme se vaya necesitando.
  • Por último, observe que los "checkbox" tiene el atributo "required", o sea que la variable indicada por "ng-model" (En este caso "vm.seleccionados[elemento.id]") existirá sólo si se marca el imput.
  • Tenemos un párrafo con la directiva {{vm.selccionados}} únicamente con fines de "debugeo" en tiempo real.
  • Finalmente, tenemos un botón que, al ser presionado, llama a la función "obtenerSeleccionados()" la cual declararemos hasta el final.
¿Qué nos da eso como resultado? muy simple, el objeto "vm.seleccionado" se le añadirá el atributo "elemento.id" si y solo si se marca el checkbox correspondiente. Por ejemplo, si están seleccionados los checkbox cuyo Id sean "1,4 y 5" entonces el objeto vm.seleccionados tendrá los atributos: {1:true,4:true,5:true}. Se le asigna el valor "true" debido a que por defecto los "checkbox" trabajan con valores booleanos.

Por último, crearemos la función obtenerSeleccionados() la cual nos regresará el arreglo de con los valores de los "checkbox" seleccionados; la función contendrá lo siguiente:

return $.map(
vm.seleccionados, function (value, index) { if(value){ return [index];}  }
);


Como ven, es una simple línea que regresa el resultado de $.map; a esta función se le pasa como primer parámetro el objeto o arreglo que iterará, en el segundo parámetro se le pasa la función (con dos argumentos de valor e índice que representa cada elemento del objeto) la cual indicará qué nos regresará en cada índice del arreglo resultante, en este caso sólo nos regresará el índice (Que será el Id de cada elemento de la lista). Así pues, el archivo JS termina de la siguiente forma:

"use strict";

var app = angular.module('myApp', []);
app.controller('indexController', function($scope) {
    var vm = this;
vm.lista = [
{id:1,valor:"Juanito Alcachofa"},
{id:2,valor:"Padro Alcántara"},
{id:3,valor:"María Mercedez"},
{id:4,valor:"Romero Romerío"},
{id:5,valor:"Susana Nollores"},
];
vm.seleccionados={};
vm.obtenerSeleccionados = function()
{
return $.map(
vm.seleccionados, function (value, index) {  return [index];  }
);
}
});


El ejemplo funcional sería el siguiente (La función "obtenerSeleccionados" fue modificada para que lanzara un "alert" con el contenido del arreglo resultante):


Y el enlace de descarga directa desde Google Drive

miércoles, 4 de mayo de 2016

Consejos para escribir historias cortas [Por hobby]

Hola.
Justamente quiero compartir varios de los puntos que, de forma indirecta, me sirven de guía para cuando escribo algo. Hago énfasis en "historias cortas" debido a que para mí escribir una historia larga y completa es una hazaña que no me atrevo a realizar (No por que no pueda, sino por que soy muy "dejado" en proyectos a tan largo plazo); también el "mecanismo" y los puntos a considerar son muy diferentes. Y lo de "por hobby"... lo explicaré (tal vez) en algún punto más adelante.

Eso sí, antes de empezar con los consejos mencionaré dos normas obligatorias a la hora de escribir.

  • Correcta ortografía

Una mala ortografía no es simplemente algo molesto e incorrecto, una incorrecta forma de escribir invalida cualquier cosa que expreses.Este punto no es nada difícil; usar un editor de texto como Word, o el mismo navegador "Google Chrome" ayudará a corregir los HORRORES de escritura. En cuestión de dudas o desconocimiento de la correcta escritura de una palabra (Por su significado, por parentesco a otras palabras o la razón que sea) tal vez les sea anticuado consultar un diccionario, pero al menos se tiene al "mágico" buscador Google, sólo escriben una palabra seguida de "significado" y les arrojará como resultado cientos de páginas que sirven como diccionarios. 

  • Aprendan a redactar

Otro punto fácil y necesario para que, aquello que desean expresar, sea entendido lo más fielmente en la medida de lo posible. La redacción es el acto de estructurar un texto de la forma adecuada, así sin más. No es lo mismo: 

Citar
Escribir algo que se este usando de mal los signos esos de puntuación o que no se usen.
Comparado con
Citar
Un uso adecuado de los signos de puntuación y el manejo correcto de las palabras en el lugar y tiempo adecuado.

De momento dejen a un lado si quieren parecer o no expertos, ésto es para lograr que los lectores entiendan el mensaje correcto y sigan el "hilo" de la historia. Manejar una redacción decente es muy sencillo: lean; claro, no basta con leer lo que cualquiera escribe: lean libros, revistas, blogs profesionales, lean las instrucciones de cómo programar su reloj despertador; en fin, lean textos escritos por personas que saben escribir (Dentro de la medida de la decencia, no es necesario leer a Cervantes o Edgar Allan Poe).



Ahora sí, mis consejos para escribir historias (Consejos aplicables para mí; cada quién, y a medida que se va desarrollando en la escritura, aplicará sus propias reglas):

  • Primero tengan la idea y después deseen escribirla
Un error es querer escribir y forzarse en captar cualquier idea para hacerlo; la llamada "inspiración" es necesaria para convencerte de lo que quieres escribir: si te esfuerzas por una idea ésta no terminará de convencerte y vagarás mucho en tu historia, la irás alterando y desviándote del punto de partida y tu historia no tendrá coherencia consigo misma. En cambio, tener una idea que te haya convencido te mantendrá enfocado en la esencia de tu historia y, aunque los detalles vayan cambiando conforme escribes, sabrás cómo quieres que fluya tu relato, el impacto que deseas tener e incluso el final. La inspiración puede ser cualquier cosa: Un personaje que te agradaría crear, una escena que te parecería interesante relatar y creas toda una historia que conlleve a esa escena, un sentimiento que te gustaría provocar en el lector, describir un lugar o una mitología que te llegó a la mente... cualquier cosa puede ser una inspiración, pero debe de surgir de forma natural.

  • Define los detalles sobre los cuales se fundamentará tu historia, la lógica del por qué empieza/ocurre
Éste es un punto muy importante y, para varios, muy tedioso. Se tiene ya la inspiración: se quiere describir una escena entre guerreros espaciales con rayos láser enfrentándose a dinosaurios con armadura de adamantium. Bien pero ¿por qué ocurre ésto? Responder esta pregunta universal resolverá la lógica de tu relato, ya que tal vez en tu mente esa escena sea majestuosa, pero un lector que llegue sin preparación a tal idea que te inspiró podrá rechazarla al no encontrarle lógica, si no hay un reto, un castigo, un ser inteligente detrás de todo o algún capricho que justifique el suceso simplemente será una idea hecha a medias. Para resolver la pregunta se deberán plantear otras preguntas más "pequeñas" que fomenten la base de tu idea y, por desgracia, para cada idea se necesitan resolver diferentes preguntas:
Si pretendes relatar las aventuras de un grupo de amigos en una mazmorra deberás responder preguntas como ¿por qué están allí? ¿por qué simplemente no salen de allí? ¿ocurrirá algo si fallan? ¿Qué es lo que aumenta la tensión como para que sea interesante el que estén en la mazmorra?
Si pretendes narrar el cómo un cazador murió intentando atrapar a su presa las preguntas podrían ser ¿y por qué quiere cazar justamente a esa presa? ¿de qué forma explicarías la obsesión o necesidad selectiva sobre esa presa? ¿cómo justificarías que, aún pasados tantos sucesos, el cazador siga persiguiendo a la criatura? ¿qué ventajas y/o desventajas tiene cada quién y cómo las usarías para que el relato dure lo que dure y no termine en 5 minutos?
En fin, el lector debe entender por qué está ocurriendo lo que ocurre y por qué no sucede lo contrario. Se pueden usar todo tipo de recursos: miedo, locura, orgullo, ambición, etc; siempre y cuando logres expresarlo durante tu relato y en el tiempo justo (Explicar que el cazador era un orgulloso hasta el final de la historia no es oportuno).

  • No uses palabras rebuscadas/rimbombante/poco conocidas
Principalmente debes de entender que, en esta situación, no eres un maestro del idioma y tampoco un escritor profesional, mantenerse al usar palabras simples y que la mayoría entienda es mejor que querer adornar los textos con palabras exageradas. No solo puede limitar la cantidad de gente que lea el texto, sino que algo tan rebuscado llega a perder el sentido y resulta más complicado de usar: Las palabras "elegantes" llegan a ser muy específicas y un mal uso de ellas (por más mínimo que sea) puede deformar el significado del texto o, peor aún, enfurecer al lector cuando éste entienda, en primera instancia, una idea diferente a la que deba.

  • Evita repetir la misma palabra de manera consecutiva
Una norma muy recurrente en la escritura: en la medida de lo posible no repitas la misma palabra de manera consecutiva dentro de una oración. No es algo muy sencillo, claro está, pero por algún motivo cuando se lee un texto y una palabra se menciona muy seguido resulta de gran disgusto para el lector, más aún si el texto se narra el voz alta. Una guía general propone separar una misma palabra por lo menos cada tercera oración; claro está, no siempre es posible hacer ésto, pero en la mayoría de los casos ésta regla se puede cumplir incluso con una separación de un párrafo o más. 
No todas las palabras aplican a esta norma, sino las más importantes y que destacan (Artículos, monosílabas y demás quedan descartados).
Pondré de ejemplo éste mismo texto, las palabras que destacan son:
Idea, texto, historia y (para este punto) palabra.
La palabra "PALABRA" es difícil de sustituir por un sinónimo que aplique, así que lo que opté fue tratar de separar una de otra cambiando la estructura de las oraciones.
Para "texto" e "historia" busqué otras palabras y rotarlas, como "relato" y "escrito".
En un punto la palabra "inspiración" me sirvió como sustituto de "idea".

  • Define tus recursos literarios y estandarízalos
Algo muy importante para que el lector sepa qué está leyendo. Los recursos se usan para hacer énfasis sobre algo y que se sepa sobre qué se está enfatizando. Por ejemplo, los diálogos son muy importantes en las historias. Cuando hablamos de "estandarizar" nos referimos a que durante todo el relato el mismo recursos se muestre igual y, del mismo modo, ningún otro recurso comparta la misma representación. Con el ejemplo de los diálogos, se acostumbran a que éstos empiecen en un renglón aparte y que se encuentren dentro de guiones medios ("-"). Para ejemplificar:
Citar
-Alto allí.- Gritó maría.
-No, para nada.- Pedro respondió y siguió corriendo; ante tal evento María no tuvo de otra más que decir:
-Ya verás cuando te atrape.-

También se pueden usar los pensamientos de los personajes como recursos, y aquí podemos ser creativos. Hay quienes suelen usar las comillas dobles para dar a conocer ésto: 

Citar
Se encontraba en un pasillo largo y escaso de luz, "Si no hubiera visto tantas películas de terror ésto no me parecería tal difícil" fue lo que pensó nuestro personaje al empezar a avanzar.
Como ven, no sólo se encerró el pensamiento del personaje entre comillas dobles (" " ), sino que también el mismo texto explicó que se trataba de un pensamiento; ésto es útil para ir "domesticando" al lector que debe de aprender que tal recurso se verá representado de ésta forma, además de que se llegan a usar las comillas dobles para otros recursos literarios (Como dar un sentido figurado a las palabras). 
Los sonidos/onomatopeyas, descripciones de las sensaciones, citas o referencias a otras obras pueden ser un recurso literario y el escritor es libre de representarlos como guste.
Un ejemplo real fue de "Cassandra Clare" quien en los primeros libros de su serie "Cazadores de sombras" hacía uso de estilos de pintores y músicos para describir las escenas, tales comparaciones las solía poner entre comillas dobles "" o en letras cursivas para educar al lector de que tales expresiones no son literales sino que subjetivas a lo que transmitían esas obras.
 

  • Revisa tu texto
Muy importante, una vez terminada tu historia léela no una ni dos ni tres veces: las veces que sean necesarias hasta que ya no encuentres un solo error. Además de que no es recomendable leerla únicamente al terminar de escribirla, lo correcto es finalizarla, leer un par de veces, hacer las correcciones, esperar un par de horas y volver a leer. Ésto debido a que, mientras escribimos solemos retener la historia y los detalles en mente así que, a la hora de leer de forma inmediata, seguimos teniendo tales imágenes y sentimos que la idea se expresa correctamente (Así como pasamos por alto algunas expresiones que damos por sentado están bien escritas). Al dejar pasar un tiempo olvidamos los detalles importantes, así que al volver a leer estaremos reconstruyendo la historia conforme a lo que leemos y no a lo que creemos que escribimos. (Por ejemplo, doy por sentado que hay varios errores de expresión en este artículo y, debido a que es media noche, no lo leeré y tendrán que leer un párrafo varias veces para entender qué quería decir :P ).

  • Respeten la naturaleza de su historia y sus personajes
Un error muy común es tener una buena idea, empezar a plasmarla en escrito y justo a medio relato querer cambiar los acontecimiento simplemente por que parece más "cool" algún otro final. Debido a que has estado encaminando la historia, los personajes, su carácter y las decisiones a una vertiente obvia, el cambiar por completo el rumbo llega a dar esa sensación de "falsedad" o incoherencia que se da en varias publicaciones incluso profesionales.
Si un personaje está destinado a morir, éste deberá morir. Si el villano debe ganar, entonces ha de ganar; te has esforzado en que cada paso de tu historia desemboque en un punto y dejarlo a un lado es mandar todo tu trabajo a la basura y tener que rehacer todo de nuevo (Encaminar tu historia al nuevo rumbo y pensar en los detalles de la nueva vertiente); recuerden el tercer punto: "no eres un maestro del idioma y tampoco un escritor profesional".

  • Mantente en el formato de Historia corta
Una historia corta no es un relato: un relato contiene pocos detalles y es muy breve, generalmente conciso y no requiere muchas explicaciones del por qué ocurre cada evento; una historia, en cambio, requiere ser justificada en los eventos importantes (Por lo menos). Además de que requiere más recursos literarios. Pero recuerda también que es breve, de 3 a 20 páginas es un rango aceptable (Aunque realmente no hay un estándar de duración de una historia corta).

  • Lo haces por hobby
Esto implica dos cosas:
  • No te debes apegar a las tendencias actuales. Generalmente estamos rodeados de mercadotecnia "genérica" sobre los temas de moda, así que lo normal es que busquemos ideas sobre las cosas que están de moda: anime, vídeo-juegos, películas actuales, etc. Sin embargo, al ser temas forzados (primer punto) fallamos en el compromiso que tenemos con nuestra historia y terminamos haciendo un revoltijo de elementos ensamblados a la fuerza.
  • Haz un compromiso. Si es por hobby entonces te deberá agradar terminarla ¿no? Así que otro motivo de que sean historias cortas el tema de este escrito es que éstas se pueden escribir en menos de una semana; así, si te propones a escribir diario (de 30 minutos a 2 horas) la puedes escribir antes de que te fastidies y la dejes a la mitad.


  • Limita las descripciones
Algo que frecuentemente se busca es describir lo más posible un personaje, escena o escenario; sin embargo ésto es un arma de doble filo: si bien es cierto que una amplia descripción mejora el ambiente y entendimiento del tema, alargarse más de 4 o 6 líneas para describir un solo elemento resulta fastidioso. Hay varios recursos a los cuales pueden recurrir:
1.- Usen generalizaciones y ambigüedades para describir: no es necesario detallar centímetro por centímetro una escena, escenario o personaje. Hacer un par de comentarios generales bien pueden servir para describir algo, si no es implícitamente necesario detallarlo. Por ejemplo:

Citar
Una habitación polvorienta, descuidada y con varios muebles recostados sobre las paredes; la escasa luz le daba un ambiente lúgubre.
Aquí no detallé cómo era exactamente la habitación, si embargo el lector puede darse una buena idea de cómo es.

2.- Solo hacer énfasis en los detalles importantes. Complementando el punto anterior; sólo en aquellos casos que se requiere, hacer hincapié en los detalles que lo necesiten. Por ejemplo:

Citar
Una habitación polvorienta, descuidada y con varios muebles recostados sobre las paredes, una mesa redonda, algo carcomida por el tiempo, reposaba en el centro de la instancia y sobre ella se hallaban un sobre al lado de un tintero antiguo; la escasa luz le daba un ambiente lúgubre.
Aquí agregué el detalle de la mesa con sus objetos; ya de ésta manera el personaje podrá interactuar con ellos, tal vez por que necesite del sobre, o por que en un futuro haga uso del tintero para (tal vez) arrojarlo; en fin, solo describir específicamente los objetos que se requieran usar.

3.- Divide las descripciones largas. Hay ocasiones en las que los personajes (Y algunos escenarios) son muy complejos y se requiere dar a conocer todos esos detalles; sin embargo hay que evitar el describirlos en su totalidad en un solo texto.
-Puedes ir describiendo al personaje conforme se vaya necesitando; así como un escenario mediante se vaya avanzando en él y los personajes de fijen en aquello que los rodea.
-Una descripción no sólo se puede dar directamente de las palabras del escritor, también se puede hacer uso de diálogos y/o pensamientos de los personajes para complementar las descripciones. Una recomendación personal es hacer uso de los pensamientos, ya que éstos no necesariamente deben de tener concordancia con lo que está sucediendo. Sin embargo, cada diálogo debe de tener relación con el contexto actual


Emociónate por cada capítulo o escena que vas a describir, por cada acción que tus personajes ejecutarán y por cada emoción que desprenderás del lector.

sábado, 16 de agosto de 2014

Posicionar/Re-ordenar/Desplazar elementos de una página web [JQUERY,JavaScript,HTML]

Podría ser en ocasiones necesario que, dentro de una página web, el usuario pueda o tenga que ordenar una lista de elementos (enlaces, opciones, texto...) de manera vertical (u horizontal).
Teniendo una lista como:

1.- elemento a.
2.- elemento b.
3.- elemento c.
4.- elemento d.

Y que el usuario la pueda cambiar el orden:

2.- elemento b.
4.- elemento d.
1.- elemento a.
3.- elemento c.

Sea cual sea la razón, realizar este trabajo en web podría resultar confuso debido a la forma de posicionamiento en una página.
A mí me resultó bastante cómodo el no pensar acomodar directamente los elementos en la pantalla, sino más bien tener un arreglo en JavaScript que contenga en cada posición el "id" de cada elemento al cual el usuario podrá interactuar.
arreglo:

[0] = "elemento1";
[1] = "elemento2";
[2] = "elemento3";
[3] = "elemento4";

El usuario, mediante clics en imágenes, cambiará la posición de cada valor en el arreglo; me refiero a que si da clic en la imagen que "baja" de posición el valor "elemento2", el arreglo quedaría así:

[0] = "elemento1";
[1] = "elemento3";
[2] = "elemento2";
[3] = "elemento4";

Ya, teniendo el arreglo ordenado, es más sencillo posicionar los elementos (referidos con su id) dependiendo de la posición en el vector; algo como:

posición y = 100px + (posición en el vector * 20) px;

El método que diseñé funciona así:

http://unrinconenlaweb.webcindario.com/reordenar/desplazar_vertical.html

Por simple dejadez no me preocupé en diseñar el mismo funcionamiento con un botón para "subir" el elemento y otro para "bajar"; pero la mecánica es sencilla: Una función (evento clic) para desplazar el valor dentro del vector; y otra función para posicionar la coordenada 'Y' de los elementos según la posición de su 'id' (valor del vector) dentro del vector, la cual consiste en un simple bucle for.

Para descargar el ejemplo, está el enlace de abajo :P

desplazar verticalmente elementos HTML con JQuery