Rss

  • youtube
  • linkedin
  • google

Archives for : Javascript

Codigo de validação de CPF para Javascript

O código abaixo é de uma função em Javascript otimizada para ter o menor numero de complexidade ciclomática linhas que consegui baseado na explicação presente no artigo Algoritimo de validação de CPF brasileiro – Cadastro de Pessoa Física. Ele tem uma ligeira alteração no momento do cálculo do segundo digitido verificador. Ao invés de começar pelo segundo algarismo, o codigo começa pelo primeiro e usa o valor 11 como multiplicador. Outra alteração visivel é que para evitar a necessidade de comparação para saber se estamos no nono e decimo digitos, atribuo o valor zero ao ultimo elemento (indice 10) para reduzir mais uma comparação.

O algoritmo utilizado é o método 1 explicado no artigo e há um pequeno truque para evitar a comparação com o resto igual a 10 que é fazer o módulo de 10 do resto.

   // Codigo que valida um CPF informado quanto a validade de seus dígitos verificadores.

const validarCpf = (cpf) => {
  if (cpf.length !== 11) { // Supõe-se já vir filtrado o valor
    return false;
  }
  let elementos = cpf.split(''); // convertendo a string em array
  elementos[10] = 0; // Forçando ao valor da ultima multiplicacao ser zero
  let somaA = 0;
  let somaB = 0;

  elementos.reduce(function(i, valor, indice) {
    let multiplicador = 11 - indice;
    somaB += (valor * multiplicador);
    somaA += (valor * (multiplicador > 2 ? multiplicador - 1 : 0));
  }, somaA);
  let moduloA = ((somaA * 10) % 11) % 10;
  let moduloB = ((somaB * 10) % 11) % 10;
  return cpf.replace(/\d{9}(\d{2})$/g, '$1') == ("" + moduloA + moduloB);
}

Você pode testar esse código aqui.

Datatables + HTML 5 Export Buttons + Laravel-Mix (Webpack)

In the last days, I have experienced a problem trying to use Datatables and Bootstrap 4 with support for exporting results to Excel and PDF using Laravel-Mix. After hours and hours trying to put all scripts to work together, I finally win. So, I decide to write this little how to for those with same kind of troubles.



Continue Reading >>

Using jQueryMask Plugin to format dates in different patterns

jQuery Mask Plugin is a great Javascript library to format fields for presentation and/or to force a properly input by users.

Here, I show how to deal with input or another HTML element to display dates when the source date has a different format from target element.

Example:

  • We have a datetime with Year-Month-Day Hour:Minute:Seconds and need to show only the Year/Month/Day part.
  • We have da date in Year-Month-Day and need to format to Day/Month/Year.

jQueryMask is very simple to use. It do not need to much to mask whatever you need. Take a look at examples on his website.

If you need to format a simple date field (even in a non-input element), just use the code below.

jQuery('[data-role="date"]).mask("TC99/M9/D9", {
        placeholder: "____/__/__",
        translation: {
            "D": {pattern: /[0-3]/, optional: false, recursive: true},
            "M": {pattern: /[01]/, optional: false, recursive: true},
            "T": {pattern: /[12]/, optional: false, recursive: true},
            "C": {pattern: /[09]/, optional: false, recursive: true}
        }
    });

The code above can mask and pre-validate dates in YEAR/MONTH/DAY format.

With an input like

<input type="text" data-role="date" value="2018-06-11 15:47" />

would be changed his value to 2018/06/11.

If you try to type another date (after clear, of course) you cannot begin with a number different from 1 or 2. This reason is that our mask have a translation to be done when allowing chars. If the pattern does not match, the char is erased.

The meaning of “TC99/M9/D9” mask is:

  • Must begin with 1 or 2 (Translation T: /[12]/ – Custom format)
  • Must have number 0 or 9 (Translation C: /[09]/ – Custom format)
  • Must have a number (any) (Translation 9 – MaskPlugin Core format)
  • Must have a number (any) (Translation 9 – MaskPlugin Core format)
  • A slash will be added automatic ( / )
  • Must have number 0 or 1 (Translation M: /[01]/ – Custom format)
  • Must have a number (any) (Translation 9: MaskPlugin Core format)
  • A slash will be added automatic ( / )
  • Must have number 0, 1, 2 or 3 (Translation D: /[0-3]/ – Custom format)
  • Must have a number (any) (Translation 9: MaskPlugin Core format)

Of course, there is no real validation. You can type “2999/19/39” and this is not a valid date, but is almost done.

So, to format in another way, just change mask parameter order.

But, if the source date is in a different pattern, like MONTH/DAY/YEAR, the mask do not work. The date output for “06/11/2018 15:40” will be weird “1018/15/0“.

To handle different date formats will be needed more than simple mask. We will need a function.

Look the code below

        var maskBehaviorDateTime = function (val, e, field) { // This function must return a MASK
                    var msk = "TC99/M9/D9"; // Our desired format
                    var v = field.is('input') ? field.val() : field.text(); // is a input or another html element??
                    v = v.replace(/\D/g, ''); // stripe non digits
                    if (v != '') { // has value?
                        if ((/^[01]\d[0-3]\d\d{4}$/).test(v)) { //test if pattern match Month/Day/Year only
                            v = v.replace(/^(\d{4})(\d{2})(\d{2})$/, '$3/$2/$1');
                        } else if ((/^[01]\d[0-3]\d\d{4}[012]\d[0-5]\d$/).test(v)) { //test if pattern match Month/Day/Year Hour:Minute
                            v = v.replace(/^(\d{2})(\d{2})(\d{4})(\d{2})(\d{2})$/, '$3/$2/$1');
                            // If we need to show hour and minute, returned mask must be changed too
                            // v = v.replace(/^(\d{2})(\d{2})(\d{4})(\d{2})(\d{2})$/, '$3/$2/$1 $4:$5');
                            // msk = 'TC99/M9/D9 h9:m9'; // h and m must be exists in Translation options
                        }
                        field.is('input') ? field.val(v) : field.text(v);
                    }
                    return msk;
                },
                optionsDateTime = {
                    placeholder: "____/__/__",
                    translation: {
                        "D": {pattern: /[0-3]/, optional: false, recursive: true},
                        "M": {pattern: /[01]/, optional: false, recursive: true},
                        "T": {pattern: /[12]/, optional: false, recursive: true},
                        "C": {pattern: /[09]/, optional: false, recursive: true},
                        "h": {pattern: /[0-2]/, optional: true, recursive: true},
                        "m": {pattern: /[0-5]/, optional: true, recursive: true}
                    }
                };
        jQuery('[data-role="date"]').mask(maskBehaviorDateTime,  optionsDateTime);

Now we have two more Translation Pattern (h and m). h means that the n-index position must have numbers 0, 1 or 2 and m numbers between 0 and 5. Keep in mind that CASE matters.

With the above code, we can format and show date in several ways. just change .test() and .replace() pattern to fill your desired pattern.

This is the code that I am using to format Database datetime fields with YEAR-MONTH-DAY HOUR:MINUTE:SECOND in html elements with DAY/YEAR/MONTH HOUR:MINUTE

    var maskBehaviorDateTime = function (val, e, field) {
            // Caso já exista um valor, o formata no padrão dd/mm/yyyy com o opcional hh:mm:ss
            var msk = "TC99/M9/D9 h9:m9:s9";
            if (field.attr("data-original-value") == undefined) {
                var o = field.is('input') ? field.val() : field.text();
            } else {
                var o = field.attr("data-original-value");
            }
            v = o.replace(/\D/g, '');
            if (v != '') {
                field.attr("data-original-value") == undefined && field.attr("data-original-value", o);
                if ((/^[12][09]\d{2}[01]\d[0123]\d$/).test(v)) { // year/month/day
                    v = v.replace(/^(\d{4})(\d{2})(\d{2})$/, '$3/$2/$1');
                    msk = "D9/M9/TC99";
                } else  if ((/^[12][09]\d{2}[01]\d[0123]\d[012]\d[0-5]\d$/).test(v)) { // year/month/day hour:minute
                    v = v.replace(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})$/, '$3/$2/$1 $4:$5');
                    msk = "D9/M9/TC99 h9:m9";
                } else if ((/^[12][09]\d{2}[01]\d[0123]\d[012]\d[0-5]\d[0-5]\d$/).test(v)) { // year/month/day hour:minute:second
                    v = v.replace(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/, '$3/$2/$1 $4:$5:$6');
                    msk = "D9/M9/TC99 h9:m9:s9";
                }
                field.is('input') ? field.val(v) : field.text(v);
            }

            return msk;
        },
        optionsDateTime = {
            placeholder: "__/__/____",
            translation: {
                "D": {pattern: /[0-3]/, optional: false, recursive: true},
                "M": {pattern: /[01]/, optional: false, recursive: true},
                "T": {pattern: /[12]/, optional: false, recursive: true},
                "C": {pattern: /[09]/, optional: false, recursive: true},
                "h": {pattern: /[0-2]/, optional: true, recursive: true},
                "m": {pattern: /[0-5]/, optional: true, recursive: true},
                "s": {pattern: /[0-5]/, optional: true, recursive: true}
            },
        };
    jQuery('[data-role="date"]').mask(maskBehaviorDateTime,  optionsDateTime);

With an input like

<input type="text" data-role="date" value="2018-06-11 15:40">

Output will be

11/06/2018 15:40

Hope this help you!