Mostrando postagens com marcador AngularJS. Mostrar todas as postagens
Mostrando postagens com marcador AngularJS. Mostrar todas as postagens

sexta-feira, 22 de setembro de 2017

Focus and move cursor in Angular

HTML5 brings the autofocus attribute to the input tag.
This attribute works fine when the page is loaded the first time, but in some moments is necessary put the focus in runtime, e.g. after a validation.

In AngularJS I use the code below (unfortunately I did not save the link from where I copied it to thank):

function cursorToEnd(input) {
    input.focus();

    // If this function exists...
    if (input.setSelectionRange) {
        // ... then use it (Doesn't work in IE)
        // Double the length because Opera is inconsistent about whether a carriage return is one character or two. Sigh.
        var len = $(input).val().length * 2;

        input.setSelectionRange(len, len);
    } else {
        // ... otherwise replace the contents with itself
        // (Doesn't work in Google Chrome)
        $(input).val($(input).val());
    }

    // Scroll to the bottom, in case we're in a tall textarea
    // (Necessary for Firefox and Google Chrome)
    input.scrollTop = 999999;        
}

function focus(jQueryObject) {
    setTimeout(function() {
        cursorToEnd(jQueryObject);
    }, 500);
};

In my apps using Angular 4 I rewrite it to:

  cursorToEnd(input: ElementRef) {
    input.nativeElement.focus();

    if (input.nativeElement.setSelectionRange) {
      const len = input.nativeElement.value.length * 2;
      input.nativeElement.setSelectionRange(len, len);
    }

    input.nativeElement.scrollTop = 999999;
  }

  focus(input: ElementRef) {
      setTimeout(() => this.cursorToEnd(input), 300);
  }


quinta-feira, 17 de agosto de 2017

AngularJSExample

I created a project using AngularJS and Bootstrap to present to customers the productivity it.

No is necessary server side. 

The project is like public in my GitLab's account: https://gitlab.com/fabio_silva/AngularJSExample

The idea is build the same project using jQuery and other with Angular 4.

The project is in portuguese. Is noted the idea to prepared it to internationalisation.



terça-feira, 17 de janeiro de 2017

IE fazendo cache para $http do AngularJS

Estava tendo uma situação com um cliente onde ele salvava e recebia mensagem de confirmação de salvo com sucesso, mas ao editar novamente a informação não estava lá. Só no Internet Explorer acontecia isso.

Conversando vimos que ao dar logoff e entrar novamente a informação aparecia, desconfiei logo de cache e para centralizar pensei em colocar um no-cache no header via interceptor do AngularJS.

Procurando na internet achei este conteúdo muito bom:

Unindo minha idéia inicial e link acima e também com o objetivo de manter cache de outros recursos como html, imagens, css usei o seguinte:


app.factory('commonHttpInterceptor', function ($q, $rootScope, commonConstants) {
    return {
        'request': function(config) {
            if (config.url.indexOf(commonConstants.URL_BASE) > -1) {
            if (!config.headers) config.headers = {};
            config.headers['Cache-Control'] = 'no-cache';
                config.headers['Pragma'] = 'no-cache';              
               
                $rootScope.openLoading();
            }
           
            return config;
        },

domingo, 4 de dezembro de 2016

Validação de campo em formulário

Em formulários para sinalizar para o usuário que o campo é inválido e o porque normalmente coloco uma borda vermelha no input e / ou um x vermelho ao lado, com tooltip com o motivo nos dois.

Um exemplo:

<div ng-class="{'has-error' : (formCrud.$submitted && formCrud.email.$error.required) || formCrud.email.$error.email}">
    <label>E-mail</label>
    <input type="email" id="email" name="email" class="campo-maior text-lowercase" ng-model="paciente.email" required
           uib-tooltip="{{(formCrud.$submitted && formCrud.email.$error.required ? MENSAGEM.OBRIGATORIO : MENSAGEM.FORMATO_INCORRETO)}}" 
           tooltip-enable="(formCrud.$submitted && formCrud.email.$error.required) || formCrud.email.$error.email" />
    <span ng-show="(formCrud.$submitted && formCrud.email.$error.required) || formCrud.email.$error.email
          class="glyphicon glyphicon-remove text-danger" 
          uib-tooltip="{{(formCrud.$submitted && formCrud.email.$error.required ? MENSAGEM.OBRIGATORIO : MENSAGEM.FORMATO_INCORRETO)}}"></span>
    <span ng-show="!formCrud.email.$error.required && !formCrud.email.$error.email" class="glyphicon glyphicon-ok text-success"></span>
</div>


Mas a repetição em destaque me incomodava (code smells), se precisar alterar a condição teria alguns pontos a fazer.
Pensava em criar uma diretiva e criar watchers quando necessário e variáveis para controle, mas não me parecia ainda opção adequada por ainda achar burocrática.

Então percebi que podia criar variáveis no html.

<div ng-class="{'has-error' : emailInvalid}">
    <label>E-mail</label>
    <input type="email" id="email" name="email" class="campo-maior text-lowercase" ng-model="paciente.email" required
           uib-tooltip="{{mensagemEmail}}" tooltip-enable="emailInvalid" />
    <span ng-show="emailInvalid = (formCrud.$submitted && formCrud.email.$error.required) || formCrud.email.$error.email
          class="glyphicon glyphicon-remove text-danger" 
          uib-tooltip="{{mensagemEmail = (formCrud.$submitted && formCrud.email.$error.required ? MENSAGEM.OBRIGATORIO : MENSAGEM.FORMATO_INCORRETO)}}"></span>
    <span ng-show="!formCrud.email.$error.required && !formCrud.email.$error.email" class="glyphicon glyphicon-ok text-success"></span>
</div>


quinta-feira, 10 de novembro de 2016

IE: SCRIPT7002: XMLHttpRequest: Erro de Rede 0x2f76, Não foi possível concluir a operação. Erro: 00002f76

Numa aplicação usando AngularJS me deparei com um erro muito estranho no Internet Explorer o  SCRIPT7002: XMLHttpRequest: Erro de Rede 0x2f76, Não foi possível concluir a operação. Erro: 00002f76, nos demais navegadores funcionava ok.

Analisando verifiquei que só acontecia quando retornar o HTTP Status Code 302 - Found, troquei para 200 - OK e funcionou corretamente.

Coisas do IE.




IE: SCRIPT7002: XMLHttpRequest: Erro de Rede 0x2f76, Não foi possível concluir a operação. Erro: 00002f76

Numa aplicação usando AngularJS me deparei com um erro muito estranho no Internet Explorer o SCRIPT7002: XMLHttpRequest: Erro de Rede 0x2f76, Não foi possível concluir a operação. Erro: 00002f76, nos demais navegadores funcionava ok.

Analisando verifiquei que só acontecia quando retornar o HTTP Status Code 302 - Found, troquei para para 200 - OK e funcionou corretamente.

Coisas do IE.




sábado, 9 de julho de 2016

Gateway de pagamento on-line

Fiz um gateway de pagamento on-line com cartão de crédito para meu cliente Lexsis, produto que está em produção desde 2014.

De fácil uso via requisições HTTPS / RESTful pode ser usado por qualquer aplicação em qualquer plataforma.

Caso precisem desse recurso em suas apps ou sites só entrar em contato com a Lexsis.

Alguns clientes que estão usando:
E também hotéis e pousadas que usam via portal de reservas on-line que fiz com AngularJS e Bootstrap:

terça-feira, 23 de fevereiro de 2016

Verificação de internet ativa para carregar libs JS remotas ou locais

Normalmente libs JS fornecem um caminho CDN e é uma boa prática usá-la porque como o browser faz cache do que baixa se outra aplicação usar a mesma lib o seu carregamento será mais rápido já que esta lib já está no cache do browser.

E hoje normalmente é mais difícil ficar sem internet, mas para evitar contratempos, ainda mais se você trabalha remoto com algum deslocamento é bom verificar se a internet está ativa e pegar as libs do CDN ou local.

Segue abaixo algumas sugestões variando conforme as linguagens de programação utilizadas:

PHP:
$internetON = @fsockopen("www.google.com", 80);

JS:
Algumas libs como jQuery e Angular criam um objeto que pode ser verificado. Esta metodologia não gosto muito porque se tiver que carregar um CSS do bootstrap por exemplo irei ter que tentar carregar a lib js na tab head e depois o css, sendo que, a boa prática recomenda carregar os CSS na tag head e os JS antes do fechamento da tag body.

<script src="http://code.jquery.com/jquery-1.11.3.min.js"/>
<script>
var internetON = (window.jQuery !== undefined);
if (internetON) {
      document.write('<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" >');
} else {
      document.write('<link rel="stylesheet" type="text/css" href="css/libs/bootstrap-3.3.6-dist/css/bootstrap.min.css">');
}
</script>

JSP / JAVA:
ApplicationUtil.java
    public static boolean internetON() {
        try {
            URL url = new URL("http://www.google.com");
            HttpURLConnection urlConnect = (HttpURLConnection)url.openConnection();
            Object objData = urlConnect.getContent();
        } catch (Exception e) { 
            return false;
        }
        
        return true;
    }

JSP
<%@ page import="br.com.lexsis.improvement.ApplicationUtil" %>
<%
    boolean internetON = false;
    if (request.getLocalName().equalsIgnoreCase("localhost")) {
        internetON = ApplicationUtil.internetON();
    } else {
        internetON = true;
    }
%>
...
<% if (internetON) { %>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<% } else { %>
<link rel="stylesheet" type="text/css" href="js/libs/bootstrap-3.3.6-dist/css/bootstrap.min.css">
<% } %>

JS / JAVA / RESTfull:
Aqui seria uma mescla do JS com JSP / JAVA. Fazer o load do AngularJS e fazer uma requisição RESTful para verificar se a internet está ON, se tiver faz a carga dos demais CSS e JS.


terça-feira, 2 de fevereiro de 2016

Route com templateUrl dinâmico

Normalmente os atributos templatetemplateUrl que vemos nos exemplos por aí retornam uma string, mas também pode ser uma function que retorna uma string e recebe um parâmetro com todos os atributos colocados no path. Então pode-se ter o seguinte:

when('/transpextraform/:idEmpresa/:id', {
    templateUrl: function(params) { 
        return 'ag0001.php?id_empresa=' + params.idEmpresa + "&id=" + params.id;
    },
    controller: 'TranspExtraCtrl'
})

Saiba mais:

sábado, 30 de janeiro de 2016

Route + reload e ng-click com bind

Estou usando route numa aplicação AngularJS de um cliente que estou dando manutenção. Usando PHP, AngularJS e Bootstrap.
Ao clicar num link imaginei que iria chamar novamente o controller mas isso não acontece pois utiliza o cache, devido isso tive que pensar de outra forma.
Então, removi o a href e usei o ng-click chamando uma função controlando se o item clicado foi o último clicado e se for o caso fazer o reload, pois limpar o cache também não resolveu.

Rotina pronta, outra situação para contornar o ng-click não aceita muito bem bind, no html até aparece certo mas ao passar para a function vai com os {{. Então tive que usar o parâmetro adicional no html com os parâmetros e a function ler este atributo do elemento target. E um outro detalhe como tenho um img dentro de uma tag a, na function ainda tive que verificar os parâmetros no parent do target porque dependendo de onde clicasse ia a img e não a tag a, ficando assim o código;

HTML
<a id='botao' ng-click="loadOption('transpextraform', $event);" 
                 data-parametros="{{::idEmpresa}}/{{item.id}}" title='Alterar'>
<img class='img_manutencao' src='../img/bt_019.gif' alt='Alterar'> ALTERAR
</a>

JS
function getTargetEvent(event) {
    return event.target || event.srcElement;
}

app.service("appService", function($rootScope, $route, $location, $http) {
    $rootScope.opcaoCorrente = {opcao: "", parametros: ""};
    
    $rootScope.loadOption = function(opcao, $event) {
        var target = $(getTargetEvent($event));
        var parametros = target.attr("data-parametros");
        
        if (!parametros) {
            parametros = target.parent().attr("data-parametros");
        }

        if (opcao === $rootScope.opcaoCorrente.opcao 
&& parametros === $rootScope.opcaoCorrente.parametros) {
            $route.reload();
        } else {
            $rootScope.opcaoCorrente.opcao = opcao;
            $rootScope.opcaoCorrente.parametros = parametros;
            
            if (parametros) {
                $location.path("/" + opcao + "/" + parametros);
            } else {
                $location.path("/" + opcao);
            }
        }
    };
});

sexta-feira, 28 de agosto de 2015

AngularJS Directives

Para quem está se aprofundando em AngularJS recomendo o canal no YouTube do Rodrigo Branas.

Boa didática e direto ao assunto. Muito bom todos vídeos mas destaco o Criando diretivas parte 2 e 3.


domingo, 5 de julho de 2015

Performance com AngularJS

Palestra da InfoQ que recomendo:

Alguns destaques:
* Use $emit em vez de $broadcast para troca de mensagens entre scopes
* Use two-way data binding somente quando realmente necessário, caso não seja, utilize one-way data binding. O one-way data-binding foi implementando na 1.3 e faz o valor ser renderizado uma só vez não sendo mais visitado pelo dirty checking. Para isso use ::, como em {{::valor}}. Tome cuidado somente ao usar one-way em valores dentro de um ng-repeat que possa vir a ser filtrado para não ter valores apresentados de forma incorreta.
* use ng-if em vez de ng-show. O ng-if inclui o elemento no DOM somente quando a condição for atendida enquanto que ng-show só oculta (display: none), com isso o dirty checking irá verificar o elemento com ng-show mais vezes do que com ng-if tendo um custo maior.
* use com moderação os filters, porque toda vez que um atributo two-way data binding é alterado o dirty checking repassa toda a árvore DOM revalidando todos os bindings. Sugestões aqui é já trazer o atributo já formatado ou manipular o array formatando-o usando o método map de Array (quando o filter foi utilizado para formatar) ou outra forma.
* nos ng-repeat utilize track by $index, isso irá otimizar o loop:
           ng-repeat="item in items track by $index"
* Uso de ng-model-options, também feature nova da 1.3, informa o tempo ou em que momento o model deve ser atualizado.

Veja também:
Exploring Angular 1.3: One-time bindings
Exploring Angular 1.3: ng-model-options

sábado, 25 de outubro de 2014

AngularJS: Javascript sem stress

Recomendo esse video do Renzo Nuccitelli, explica bem a criação de diretivas.

AngularJS: Javascript sem stress


sábado, 27 de setembro de 2014

Creating Web Apps with AngularJS

I recommend. Igor Costa's Hangout. Video in portuguese.