Archivos de Categoría: Javascript - Paginas 2

Función como clase vs función factoría en Javascript

Normalmente suelo crear funciones que utilizo como clases en Javascript, por ejemplo una «clase» contador:

function Contador(init){
    this.num = (init!== undefined)?init:1;
    this.incrementa = function(){ this.num++; }
}

// y la usaríamos de la siguiente forma
var obj = new Contador(5);
obj.incrementa();
console.log(obj.num);

Como se ve, se puede acceder directamente a las propiedades del objeto y no siempre querremos esto. Para eso podemos usar una función factoría que básicamente funciona igual pero nos impide acceder a las propiedades (para acceder a estas tendremos que usar algún método).

function contador(init){
    var _num = (init!== undefined)?init:1;
    return {
        incrementa:function(){ _num++; },
        valor:function(){ return _num; }
    }
}

// y la usaríamos de la siguiente forma
var obj = contador(10);
obj.incrementa();
console.log(obj.valor());

Recargando combos dependientes

Es habitual que tengamos en un formulario el típico combo de provincias y localidades, para ello suelo usar la siguiente función:

function combosObj(padre, hijo, path){
        this.padre = padre;
        this.hijo = hijo;
        this.path = path;
        var _self = this;

        this.load = function(id){
            $.ajax({
                method: 'GET',
                url: this.path + '/' + id,
                dataType: 'json'
              })
              .done(function( resultado ) {
                  $('select[name="'+_self.hijo+'"] option').remove();
                  $.each(resultado, function(i, item) {
                      $('select[name="'+_self.hijo+'"]').append($('<option>').text(item.label).val(item.id));
                  });
                  if ($('select[name="'+_self.hijo+'"]').attr('data-default')) {
                      $('select[name="'+_self.hijo+'"] option[value="'+$('select[name="'+_self.hijo+'"]').data('default')+'"]').prop('selected', 'selected');
                  }
              });
        }

        this.load($('select[name="'+this.padre+'"]').val());
        $('select[name="'+this.padre+'"]').change(function(){
            _self.load($(this).val());
        });
    }

Y para usarla es tan sencillo como pasarle el nombre del select “padre”, el select “hijo” y la url que va a devolver un JSON con los valores a cargar (el JSON debe ser un array con valores id y label):

$(document).ready(function() {
        new combosObj('provincia_id', 'localidad_id', '/localidades');
        new combosObj('categoria_id', 'subcategoria_id', '/subcategorias');
});

En el caso de que tengamos un valor por defecto en el combo “hijo”, deberemos añadirle un atributo data-default con el id que queramos por defecto

<div class="form-group">
  <label for="">Provincia</label>
  <select name="provincia_id" class="form-control">
      @foreach($provincias as $item)
        <option value="{{$item->id}}">{{$item->provincia}}</option>
      @endforeach
  </select>
</div>
<div class="form-group">
  <label for="">Localidad clínica</label>
  <select name="localidad_id" class="form-control" data-default="{{$default_id}}">
  </select>
</div>

Maxlength en textareas

Es habitual querer limitar el número de caracteres de los textareas, además al diseñador con el que suelo trabajar le ha dado por poner un contador al lado indicando el número de caracteres restantes que le queda al usuario por escribir. El HTML básicamente sería así:

<div>
   <textarea name="pregunta" placeholder="Escribe tu pregunta aquí" maxlength="300"></textarea>
   <span class="contador">300</span>
</div>

Y el javascript que he montado sería el siguiente:

$("textarea[maxlength]").on("propertychange input", function() {
   if (this.value.length > this.maxlength) {
      this.value = this.value.substring(0, this.maxlength);
   }else if($(this).parent().find('span.contador').length){
      $(this).parent().find('span.contador').text($(this).attr('maxlength') - this.value.length);
   }
});