Aplicativo Desktop com Nwjs + AngularJS + Bootstrap + Sqlite

Olá pessoal, hoje faremos um aplicativo desktop simples para cadastro de pessoas, usando nwjs, AngularJS, Bootstrap e o banco de dados Sqlite. Veja aqui como fazer um aplicativo com nwjs, executar e empacotar.

Downloads

Para iniciar faça download das tecnologias necessárias:

As demais dependências serão instaladas com NPM.

Estrutura de pastas e arquivos

Agora faremos a estrutura de pastas e arquivos da nossa aplicação.

pastas2.fw

Banco de dados

Abra o SQLiteStudio, crie um banco de dados salvando o arquivo na pasta model da sua aplicação com o nome database.db.

Conectado ao banco de dados crie a seguinte tabela:

CREATE TABLE pessoas (
    id         INTEGER    PRIMARY KEY AUTOINCREMENT,
    nome       CHAR (100),
    email      CHAR (100),
    nascimento DATE,
    endereco   CHAR (200),
    ativo      INT        DEFAULT (1) 
);

Usaremos o campo ativo para informar se a pessoa está ativa ou não, se não está ativa está excluída.

Instalando pacotes

Para iniciar, deixaremos o arquivo package.json da seguinte maneira:

package.json


Feito isso, abra o terminal navegue usando cd até o diretório da aplicação e execute o seguinte comando: npm install

index.html

Este arquivo será o principal da nossa aplicação, e deve ter o seguinte conteúdo:

<html ng-app="cdg">
<head>
	<title>Clube dos Geeks</title>
	<link rel="stylesheet" type="text/css" href="bootstrap/css/bootstrap.css">

	<!-- jQuery -->
	<script src="http://code.jquery.com/jquery-1.12.0.min.js"></script>

	<!-- Bootstrap -->
	<script src="bootstrap/js/bootstrap.js"></script>

	<!-- Angular -->
	<script src="node_modules/angular/angular.js"></script>
	<!-- Angular - Pagination -->
	<script src="node_modules/angular-utils-pagination/dirPagination.js"></script>

	<!-- App -->
	<script src="app.js"></script>

	<!-- Controllers -->
	<script src="controllers/pessoaController.js"></script>

	<!-- Services -->
	<script src="services/dbService.js"></script>
</head>
<body>
	<!-- Menu -->
	<nav class="navbar navbar-default">
		<div class="container-fluid">
			<div class="navbar-header">
				<a class="navbar-brand" href="#/">
					Clube dos Geeks
				</a>
			</div>
			<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      			<ul class="nav navbar-nav">
      				<li>
      					<a href="#/pessoas">Pessoas</a>
      				</li>
      			</ul>
      		</div>
		</div>
	</nav>
	<!-- Onde será carregada a view -->
	<div ng-view="" class="container"></div>
	<!-- Rodapé -->
	<nav class="navbar navbar-default navbar-fixed-bottom">
	  	<div class="container">
	  		<ul class="nav navbar-nav">
	  			<li>
	  				<a href="//clubedosgeeks.com.br">Clube dos Geeks</a>
	  			</li>
	  			<li>
	  				<a href="//jayralencar.com.br">Jayr Alencar</a>
	  			</li>
	  		</ul>
	   	</div>
	</nav>
</body>
</html>

Observe que na linha 1, usamos o atributo ng-app, que serve para instanciar a aplicação, para que o angular possa trabalhar.

app.js

Criaremos agora o arquivo responsável por iniciar e direcionar as rotas do angular, veja:

var app = angular.module('cdg', [require('angular-route'),'angularUtils.directives.dirPagination']);

app.config(function($routeProvider){
	$routeProvider.when("/pessoas", {
		templateUrl : "views/pessoa.html",
		controller : "pessoaController",
        access: { requiredLogin: false }
	});
});

services/dbService.js

Este arquivo será responsável pela conexão com o banco de dados, busca e consolidação das informações.

Como a biblioteca para SQLite – desenvolvida por nós – já tem funções de inserção e edição que facilita as querys, este service irá retornar apenas a instância da biblioteca. Veja:

"USE STRICT";
app.factory("dbService", function($http){
	var sqlite = require('sqlite-sync');
	var db = sqlite.connect('model/database.db');
	return db;
});

controllers/pessoaControllers.js

Este arquivo, como o nome sugere, faz o controle da view, trata as informações, busca e salva no banco de dados.

Como você provavelmente vai querer criar outros CRUD’s, deve tomar esse controller como base para os outros, assim como a view, que falaremos mais abaixo.

Veja o arquivo:

"USE STRICT";
app.controller("pessoaController", function($scope, $location, dbService){
	//Listando
	$scope.listaPessoas = function(){
		dbService.runAsync("SELECT * FROM pessoas WHERE ativo = 1", function(data){
			$scope.pessoas = data;
		});
	}

	//Salvando
	$scope.salvar = function(){
		if($scope.pessoa.id){
			//Editar
			var id = $scope.pessoa.id;
			delete $scope.pessoa.id;
			delete $scope.pessoa.$$hashKey; //Apaga elemento $$hashKey do objeto
			dbService.update('pessoas', $scope.pessoa, {id: id}); //entidade, dados, where
		}else{
			//nova
			dbService.insert('pessoas', $scope.pessoa); // entidade, dados
		}
		$scope.pessoa = {};
		$scope.listaPessoas();
		$('#modalPessoa').modal('hide');
	}

	//Abrindo para editar
	$scope.editar = function(dados){
		$scope.pessoa = dados;
		$('#modalPessoa').modal('show');
	}

	//Excluindo
	$scope.excluir = function(dados){
		if(confirm("Deseja realmente apagar o cadastro de "+dados.nome+"?")){
			dbService.update('pessoas', {ativo:0}, {id: dados.id});
			$scope.listaPessoas();
		}
	}
});

views/pessoa.html

Agora, na pasta views criaremos nosso arquivo de visão, onde os dados serão mostrados.

Aqui nos usamos a diretiva dirPagination para fazer e a paginação dos dados na tabela. Veja:

<div class="row">
	<div class="col-md-8">
		<button class="btn btn-primary" data-toggle="modal" data-target="#modalPessoa"><span class="glyphicon glyphicon-plus"></span> Nova Pessoa</button>
	</div>
	<div class="col-md-4">
		<input class="form-control" placeholder="Pesquisar" ng-model="pesquisar">
	</div>
</div>
<hr>
<div class="row">
	<div class="col-md-12">
		<table class="table table-striped" ng-init="listaPessoas()">
			<thead>
				<th>#</th>
				<th>Nome</th>
				<th>E-mail</th>
				<th>Endereço</th>
				<th>Nascimento</th>
				<th></th>
			</thead>
			<tbody>
				<!-- Listagem -->
				<tr dir-paginate="pessoa in pessoas|filter:pesquisar|itemsPerPage:8">
					<td>{{pessoa.id}}</td>
					<td>{{pessoa.nome}}</td>
					<td>{{pessoa.email}}</td>
					<td>{{pessoa.endereco}}</td>
					<td>{{pessoa.nascimento}}</td>
					<td>
						<button class="btn btn-info btn-xs" ng-click="editar(pessoa)"><span class="glyphicon glyphicon-pencil"></span> Editar</button>
						<button class="btn btn-danger btn-xs" ng-click="excluir(pessoa)"><span class="glyphicon glyphicon-trash"></span> Excluir</button>
					</td>
				</tr>
			</tbody>
		</table>
	</div>
</div>
<!-- Paginação -->
<div class="row">
	<div class="col-md-12 text-center">
		<dir-pagination-controls>
	    </dir-pagination-controls>
	</div>
</div>

<!-- Modal Cadastro e Edição -->
<div class="modal fade" id="modalPessoa" tabindex="-1" role="dialog" >
	<div class="modal-dialog" role="document">
		<div class="modal-content">
			<div class="modal-header">
				<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
				<h4 class="modal-title" id="myModalLabel">Pessoa</h4>
			</div>
			<div class="modal-body">
				<div class="row">
					<div class="col-md-6">
						<label>Nome</label>
						<input class="form-control" type="text" ng-model="pessoa.nome">
					</div>
					<div class="col-md-6">
						<label>E-mail</label>
						<input class="form-control" type="text" ng-model="pessoa.email">
					</div>
				</div>
				<div class="row">
					<div class="col-md-6">
						<label>Data de Nascimento</label>
						<input class="form-control" type="text" ng-model="pessoa.nascimento">
					</div>
					<div class="col-md-6">
						<label>Endereço</label>
						<input class="form-control" type="text" ng-model="pessoa.endereco">
					</div>
				</div>
			</div>
			<div class="modal-footer">
				<button type="button" class="btn btn-default" ng-click="pessoa = {}" data-dismiss="modal">Cancelar</button>
				<button type="button" class="btn btn-primary" ng-click="salvar()">Salvar</button>
			</div>
		</div>
	</div>
</div>

Executando

Se você não sabe como executar ou gerar o .exe, Veja aqui

GitHub

Este exemplo está disponível do GitHub também, veja.

Prévia

 

Jayr Alencar

Doutorando em Ciências da Computação no Centro de Informática da Universidade Federal do Pernambuco (CIn - UFPE); Mestre pela mesma instituição; Formado em Análise e Desenvolvimento de Sistemas; Católico; Fã de O Senhor do Anéis.

Você pode gostar...

26 Resultados

  1. Tiago Silva Pereira disse:

    Muito bom, parabéns!!! Simples e útil…

  2. Hille disse:

    Olá amigo tudo bem, muito bom este tutorial bem detalhado, eu queria só tirar uma duvida, se esta aplicação é necessário rodar online, eu sei que fica local, mas é necessario a pessoa ter conexão com Internet para funcionar o banco de dados e as demais requisições? Obrigado e sucesso!

    • Jayr Alencar disse:

      Opa Hille. Nessa aplicação não é necessário, a única coisa que precisa de conexão nela é o jQuery que é puxado da internet, o que vou mudar em breve.
      Mas você pode sim conectar ela com um banco na nuvem, ou com uma API RESTful de preferência.

  3. romulo disse:

    Depois que gero o executavel, no linux ou win, é possível pegar o fonte? Digo por questão de segurança na distribuição de um projeto pago.

  4. Wesley disse:

    Muito bom o artigo bem explicado, parabéns!

    Agora está dando erro no “require(‘angular-route’)”

    Uncaught ReferenceError: require is not defined(anonymous function) @ app.js:1
    pessoaController.js:2 Uncaught TypeError: Cannot read property ‘controller’ of undefined(anonymous function) @ pessoaController.js:2

    pode me ajudar?

    • Jayr Alencar disse:

      Oi Wesley, você executou o comando npm install?
      Se sim tente executar npm install angular-route para instalar o módulo em questão.
      Verifique se ocorre algum erro durante a instalação.

      • Wesley disse:

        executei sim!

        após executar o comando sugerido aparece a seguinte mensagem:

        C:\Users\wesley_oliveira\WebstormProjects\momadesAppDesktop>npm install angular-route
        nwjs-angular@1.0.0 C:\Users\wesley_oliveira\WebstormProjects\momadesAppDesktop
        └── angular-route@1.5.2

        npm WARN EPACKAGEJSON nwjs-angular@1.0.0 No repository field.

        e o erro persiste!

        Uncaught ReferenceError: require is not defined
        pessoaController.js:2 Uncaught TypeError: Cannot read property ‘controller’ of undefined
        dbService.js:2 Uncaught TypeError: Cannot read property ‘factory’ of undefined
        angular.js:4547 Uncaught Error: [$injector:modulerr] Failed to instantiate module cdg due to:
        Error: [$injector:nomod] Module ‘cdg’ is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

      • Wesley disse:

        ok, deu certo!

        Muito obrigado

      • Philipe disse:

        Bom dia!
        Estou com mesmo problema.

        \nwjs-angularjs-sqlite\app.js:1
        (function (exports, require, module, __filename, __dirname) { var app = angular.module(‘cdg’, [require(‘angular-route’),’angularUtils.directives.dirPagination’]);
        ^

        ReferenceError: angular is not defined
        at Object. (C:\Users\Philipe-TI\node-webk-32\projetos\p07\nwjs-angularjs-sqlite\app.js:1:81)
        at Module._compile (module.js:570:32)
        at Object.Module._extensions..js (module.js:579:10)
        at Module.load (module.js:487:32)
        at tryModuleLoad (module.js:446:12)
        at Function.Module._load (module.js:438:3)
        at Module.runMain (module.js:604:10)
        at run (bootstrap_node.js:394:7)
        at startup (bootstrap_node.js:149:9)
        at bootstrap_node.js:509:3

      • Eliézer disse:

        Bom dia.
        Parabéns pelo tutorial,

        Ao executar o comando npm install, estou tendo o segundo retorno:
        npm WARN nwjs-angular@1.0.0 No repository field.

        Tentei rondar no chrome e no console tenho o seguinte retorno:

        pessoaController.js:2 Uncaught TypeError: Cannot read property ‘controller’ of undefined
        at pessoaController.js:2
        (anonymous) @ pessoaController.js:2
        dbService.js:2 Uncaught TypeError: Cannot read property ‘factory’ of undefined
        at dbService.js:2

        O que está errado?

      • Eliézer disse:

        Troquei,
        mas continua retornando o mesmo erro:

        npm WARN nwjs-angular@1.5.1 No repository field.

  5. Angel disse:

    Excelente tutorial, gracias, necesitaba este ejemplo para realizar un proyecto

  6. Luciano disse:

    Jayr se eu quiser utilizar este mesmo projeto mas para web como seria, pq tentei usar num projeto q está hospedado e ele deu erro nesse require.

  7. Luciano disse:

    Dá pra instalar o sqlite na hospedagem, posso encarar como boa notícia?

  8. Marcao disse:

    Amigo, funcionou tudo, apareceu a página index, mas ao clicar em pessoa, parece que a rota não muda, nada acontece, a tela fica simplesmente branca, tentei inclusive com o do github e deu o mesmo erro. Pode me ajudar?

  9. Site e Sistema disse:

    Me ajuda, eu executo o nw.exe, mas a pagina de pessoas não abre, não da nenhum erro… uso o node.js 6.13.0, aparece só o header com os menus e o rodape.

  1. 22 de junho de 2016

    […] mostrando como desenvolver aplicativos desktop usando tecnologias WEB, com dois frameworks: NW.js e Electron. Hoje mostraremos um caminho mais rápido e mais simples para […]

Deixe um comentário para Jayr Alencar Cancelar resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *