Commit 9c15264e7f8bdef6b51369bfbc39cebd3b44ff60

Authored by Nicolás Guarnieri
1 parent 4eebd767d3
Exists in master

modal terminado con paginado, filtro y navegacion por teclas

1 # Busqueda de productos en modal para Debo Suite 1 # Busqueda de productos en modal para Debo Suite
2 2
3 Para ser utilizado en otro modulo debe iniciarse con este codigo ejemplo: 3 Para ser utilizado en otro modulo debe iniciarse con este codigo ejemplo:
4 <pre> 4 <pre>
5 var modalInstance = $uibModal.open( 5 var modalInstance = $uibModal.open(
6 { 6 {
7 ariaLabelledBy: 'Busqueda de Productos', 7 ariaLabelledBy: 'Busqueda de Productos',
8 templateUrl: 'src/views/modal-busqueda-productos.html', 8 templateUrl: 'src/views/modal-busqueda-productos.html',
9 controller: 'modalBusquedaProductosCtrl', 9 controller: 'modalBusquedaProductosCtrl',
10 size: 'md' 10 size: 'md'
11 } 11 }
12 ); 12 );
13 </pre> 13 </pre>
14 14
15 Y despues consiguiendo el resultado de esta forma: 15 Y despues consiguiendo el resultado de esta forma:
16 <pre> 16 <pre>
17 modalInstance.result.then( 17 modalInstance.result.then(
18 function (producto) { 18 function (producto) {
19 console.info(producto); 19 console.info(producto);
20 // variable producto tiene el producto seleccionado en el modal 20 // variable producto tiene el producto seleccionado en el modal
21 }, function () { 21 }, function () {
22 // funcion ejecutada cuando se cancela el modal 22 // funcion ejecutada cuando se cancela el modal
23 } 23 }
24 ); 24 );
25 </pre>
25 </pre>
1 <html ng-app="focaBusquedaProductos"> 1 <html ng-app="focaBusquedaProductos">
2 <head> 2 <head>
3 <meta charset="UTF-8"/> 3 <meta charset="UTF-8"/>
4 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> 4 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
5 5
6 <!--CSS--> 6 <!--CSS-->
7 <link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/> 7 <link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
8 <link href="node_modules/font-awesome/css/font-awesome.min.css" rel="stylesheet"/> 8 <link href="node_modules/font-awesome/css/font-awesome.min.css" rel="stylesheet"/>
9 9
10 <!--VENDOR JS--> 10 <!--VENDOR JS-->
11 <script src="node_modules/jquery/dist/jquery.min.js"></script> 11 <script src="node_modules/jquery/dist/jquery.min.js"></script>
12 <script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script> 12 <script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
13 <script src="node_modules/angular/angular.min.js"></script> 13 <script src="node_modules/angular/angular.min.js"></script>
14 <script src="node_modules/ui-bootstrap4/dist/ui-bootstrap-tpls.js"></script> 14 <script src="node_modules/ui-bootstrap4/dist/ui-bootstrap-tpls.js"></script>
15 <script src="node_modules/foca-directivas/dist/foca-directivas.min.js"></script>
15 16
16 <!-- BUILD --> 17 <!-- BUILD -->
17 <script src="src/js/app.js"></script> 18 <script src="src/js/app.js"></script>
18 <script src="src/js/controller.js"></script> 19 <script src="src/js/controller.js"></script>
19 <script src="src/js/service.js"></script> 20 <script src="src/js/service.js"></script>
20 21
21 <!-- /BUILD --> 22 <!-- /BUILD -->
22 23
23 <!-- CONFIG PARA DEVELOP --> 24 <!-- CONFIG PARA DEVELOP -->
24 <script src="src/etc/develop.js"></script> 25 <script src="src/etc/develop.js"></script>
25 <script type="text/javascript"> 26 <script type="text/javascript">
26 angular.module('focaBusquedaProductos') 27 angular.module('focaBusquedaProductos')
27 .controller('controller', [ 28 .controller('controller', [
28 '$scope', 29 '$scope',
29 '$uibModal', 30 '$uibModal',
30 '$timeout', 31 '$timeout',
31 function($scope, $uibModal, $timeout) { 32 function($scope, $uibModal, $timeout) {
32 openModal(); 33 openModal();
33 34
34 function openModal() { 35 function openModal() {
35 var modalInstance = $uibModal.open( 36 var modalInstance = $uibModal.open(
36 { 37 {
37 ariaLabelledBy: 'Busqueda de Productos', 38 ariaLabelledBy: 'Busqueda de Productos',
38 templateUrl: 'src/views/modal-busqueda-productos.html', 39 templateUrl: 'src/views/modal-busqueda-productos.html',
39 controller: 'modalBusquedaProductosCtrl', 40 controller: 'modalBusquedaProductosCtrl',
40 size: 'lg' 41 size: 'lg'
41 } 42 }
42 ); 43 );
43 44
44 modalInstance.result.then( 45 modalInstance.result.then(
45 function (selectedItem) { 46 function (selectedItem) {
46 console.info(selectedItem); 47 console.info(selectedItem);
47 $timeout(openModal,500); 48 $timeout(openModal,500);
48 }, function () { 49 }, function () {
49 console.info('modal-component dismissed at: ' + new Date()); 50 console.info('modal-component dismissed at: ' + new Date());
50 $timeout(openModal,500); 51 $timeout(openModal,500);
51 } 52 }
52 ); 53 );
53 } 54 }
54 } 55 }
55 ]); 56 ]);
56 </script> 57 </script>
57 </head> 58 </head>
58 <body ng-controller="controller"> 59 <body ng-controller="controller">
59 <style> 60 <style>
60 .p-5 { 61 .p-5 {
61 padding: 5px !important; 62 padding: 5px !important;
62 } 63 }
63 </style> 64 </style>
64 </body> 65 </body>
65 </html> 66 </html>
66 67
1 { 1 {
2 "name": "foca-navegacion-doble", 2 "name": "foca-modal-busqueda-productos",
3 "version": "0.0.1", 3 "version": "0.0.1",
4 "description": "Menu de navegacion de doble entrada", 4 "description": "Menu de navegacion de doble entrada",
5 "main": "index.js", 5 "main": "index.js",
6 "scripts": { 6 "scripts": {
7 "test": "echo \"Error: no test specified\" && exit 1", 7 "test": "echo \"Error: no test specified\" && exit 1",
8 "compile": "gulp templates && gulp uglify", 8 "compile": "gulp templates && gulp uglify",
9 "pre-commit": [ 9 "pre-commit": [
10 "gulp-pre-commit" 10 "gulp-pre-commit"
11 ], 11 ],
12 "postinstall": "npm run compile && rm -R src && rm index.html && rm .jshintrc && rm gulpfile.js", 12 "postinstall": "npm run compile && rm -R src && rm index.html && rm .jshintrc && rm gulpfile.js",
13 "install-dev": "npm install angular bootstrap jquery font-awesome gulp gulp-concat gulp-jshint gulp-rename gulp-replace gulp-uglify-es jshint pump gulp-connect jasmine-core pre-commit" 13 "install-dev": "npm install angular bootstrap jquery font-awesome gulp gulp-concat gulp-jshint gulp-rename gulp-replace gulp-uglify-es jshint pump gulp-connect jasmine-core pre-commit"
14 }, 14 },
15 "repository": { 15 "repository": {
16 "type": "git", 16 "type": "git",
17 "url": "https://192.168.0.11/modulos-npm/foca-navegacion-doble" 17 "url": "https://192.168.0.11/modulos-npm/foca-navegacion-doble"
18 }, 18 },
19 "author": "Nicolás Guarnieri", 19 "author": "Nicolás Guarnieri",
20 "license": "ISC", 20 "license": "ISC",
21 "peerDependencies": { 21 "peerDependencies": {
22 "angular": "^1.7.4", 22 "angular": "^1.7.4",
23 "bootstrap": "^4.1.3", 23 "bootstrap": "^4.1.3",
24 "font-awesome": "^4.7.0", 24 "font-awesome": "^4.7.0",
25 "ui-bootstrap4": "^3.0.4", 25 "ui-bootstrap4": "^3.0.4",
26 "gulp": "^3.9.1", 26 "gulp": "^3.9.1",
27 "gulp-angular-templatecache": "^2.2.1", 27 "gulp-angular-templatecache": "^2.2.1",
28 "gulp-concat": "^2.6.1", 28 "gulp-concat": "^2.6.1",
29 "gulp-connect": "^5.6.1", 29 "gulp-connect": "^5.6.1",
30 "gulp-htmlmin": "^5.0.1", 30 "gulp-htmlmin": "^5.0.1",
31 "gulp-rename": "^1.4.0", 31 "gulp-rename": "^1.4.0",
32 "gulp-replace": "^1.0.0", 32 "gulp-replace": "^1.0.0",
33 "gulp-uglify": "^3.0.1", 33 "gulp-uglify": "^3.0.1",
34 "jquery": "^3.3.1", 34 "jquery": "^3.3.1",
35 "pump": "^3.0.0" 35 "pump": "^3.0.0",
36 "foca-directivas": "git+https://192.168.0.11/modulos-npm/foca-directivas",
36 }, 37 },
37 "devDependencies": { 38 "devDependencies": {
38 "angular": "^1.7.4", 39 "angular": "^1.7.4",
39 "bootstrap": "^4.1.3", 40 "bootstrap": "^4.1.3",
41 "foca-directivas": "git+https://192.168.0.11/modulos-npm/foca-directivas",
40 "font-awesome": "^4.7.0", 42 "font-awesome": "^4.7.0",
41 "gulp": "^3.9.1", 43 "gulp": "^3.9.1",
42 "gulp-angular-templatecache": "^2.2.1", 44 "gulp-angular-templatecache": "^2.2.1",
43 "gulp-concat": "^2.6.1", 45 "gulp-concat": "^2.6.1",
44 "gulp-connect": "^5.6.1", 46 "gulp-connect": "^5.6.1",
45 "gulp-htmlmin": "^5.0.1", 47 "gulp-htmlmin": "^5.0.1",
46 "gulp-jshint": "^2.1.0", 48 "gulp-jshint": "^2.1.0",
47 "gulp-rename": "^1.4.0", 49 "gulp-rename": "^1.4.0",
48 "gulp-replace": "^1.0.0", 50 "gulp-replace": "^1.0.0",
49 "gulp-uglify": "^3.0.1", 51 "gulp-uglify": "^3.0.1",
50 "jasmine-core": "^3.2.1", 52 "jasmine-core": "^3.2.1",
51 "jquery": "^3.3.1", 53 "jquery": "^3.3.1",
52 "jshint": "^2.9.6", 54 "jshint": "^2.9.6",
53 "pre-commit": "^1.2.2", 55 "pre-commit": "^1.2.2",
54 "pump": "^3.0.0", 56 "pump": "^3.0.0",
55 "ui-bootstrap4": "^3.0.4" 57 "ui-bootstrap4": "^3.0.4"
56 } 58 }
57 } 59 }
58 60
1 angular.module('focaBusquedaProductos', ['ui.bootstrap']); 1 angular.module('focaBusquedaProductos', ['ui.bootstrap','focaDirectivas']);
2 2
src/js/controller.js
1 angular.module('focaBusquedaProductos') 1 angular.module('focaBusquedaProductos')
2 .controller('modalBusquedaProductosCtrl', 2 .controller('modalBusquedaProductosCtrl',
3 [ 3 [
4 '$filter', 4 '$filter',
5 '$scope', 5 '$scope',
6 '$uibModalInstance', 6 '$uibModalInstance',
7 'focaBusquedaProductosService', 7 'focaBusquedaProductosService',
8 function($filter, $scope, $uibModalInstance, focaBusquedaProductosService) { 8 function($filter, $scope, $uibModalInstance, focaBusquedaProductosService) {
9 focaBusquedaProductosService.getProductos().then( 9 focaBusquedaProductosService.getProductos().then(
10 function(res) { 10 function(res) {
11 $scope.productos = res; 11 $scope.productos = res.data;
12 $scope.search(); 12 $scope.search();
13 } 13 }
14 ); 14 );
15 15
16 // pagination 16 // pagination
17 $scope.numPerPage = 10; 17 $scope.numPerPage = 10;
18 $scope.currentPage = 1; 18 $scope.currentPage = 1;
19 $scope.filteredProductos = []; 19 $scope.filteredProductos = [];
20 $scope.currentPageProductos = []; 20 $scope.currentPageProductos = [];
21 $scope.selectProducto = 0; 21 $scope.selectedProducto = -1;
22 22
23
24 //METODOS 23 //METODOS
25 $scope.search = function() { 24 $scope.search = function() {
26 $scope.filteredProductos = $filter('filter')($scope.productos, {$: $scope.filters}); 25 $scope.filteredProductos = $filter('filter')($scope.productos, {$: $scope.filters});
26 $scope.lastPage = Math.ceil($scope.filteredProductos.length / $scope.numPerPage);
27 $scope.resetPage(); 27 $scope.resetPage();
28 } 28 }
29 29
30 $scope.resetPage = function() { 30 $scope.resetPage = function() {
31 $scope.currentPage = 1; 31 $scope.currentPage = 1;
32 $scope.selectPage(1); 32 $scope.selectPage(1);
33 } 33 }
34 34
35 $scope.selectPage = function(page) { 35 $scope.selectPage = function(page) {
36 var start = (page - 1) * $scope.numPerPage; 36 var start = (page - 1) * $scope.numPerPage;
37 var end = start + $scope.numPerPage; 37 var end = start + $scope.numPerPage;
38 $scope.paginas = [];
39 $scope.paginas = calcularPages(page);
38 $scope.currentPageProductos = $scope.filteredProductos.slice(start, end); 40 $scope.currentPageProductos = $scope.filteredProductos.slice(start, end);
41 $scope.currentPage = page;
39 } 42 }
40 43
41 $scope.select = function(producto) { 44 $scope.select = function(producto) {
42 $uibModalInstance.close(producto); 45 $uibModalInstance.close(producto);
43 } 46 }
44 47
45 $scope.cancel = function() { 48 $scope.cancel = function() {
46 $uibModalInstance.dismiss('cancel'); 49 $uibModalInstance.dismiss('cancel');
47 } 50 }
48 51
49 $scope.enter = function(key) { 52 $scope.busquedaDown = function(key) {
53 if (key === 40) {
54 primera(key);
55 }
56 }
57
58 $scope.busquedaPress = function(key) {
50 if (key === 13) { 59 if (key === 13) {
51 console.table($scope.currentPageProductos); 60 primera(key);
61 }
62 }
63
64 $scope.itemProducto = function(key) {
65 console.info(key);
66 if (key == 38) {
67 anterior(key);
68 }
69
70 if (key == 40) {
71 siguiente(key);
72 }
73
74 if (key == 37) {
75 retrocederPagina();
76 }
77
78 if (key == 39) {
79 avanzarPagina();
80 }
81 }
82
83 function calcularPages(paginaActual) {
84 var paginas = [];
85 paginas.push(paginaActual);
86
87 if (paginaActual - 1 > 1) {
88
89 paginas.unshift(paginaActual - 1);
90 if (paginaActual - 2 > 1) {
91 paginas.unshift(paginaActual - 2);
92 }
93 }
94
95 if (paginaActual + 1 < $scope.lastPage) {
96 paginas.push(paginaActual + 1);
97 if (paginaActual + 2 < $scope.lastPage) {
98 paginas.push(paginaActual + 2);
99 }
100 }
101
102 if (paginaActual !== 1) {
103 paginas.unshift(1);
104 }
105
106 if (paginaActual !== $scope.lastPage) {
107 paginas.push($scope.lastPage);
108 }
109
110 return paginas;
111 }
112
113 function primera(key) {
114 $scope.selectedProducto = 0;
115 }
116
117 function anterior(key) {
118 if ($scope.selectedProducto === 0) {
119 anteriorPagina();
120 } else {
121 $scope.selectedProducto--;
122 }
123 }
124
125 function siguiente(key) {
126 if ($scope.selectedProducto < $scope.currentPageProductos.length - 1 ) {
127 $scope.selectedProducto++;
128 } else {
129 avanzarPagina();
130 }
131 }
132
133 function retrocederPagina() {
134 if ($scope.currentPage > 1) {
135 $scope.selectPage($scope.currentPage - 1);
136 $scope.selectedProducto = $scope.numPerPage - 1;
137 }
138 }
139
140 function avanzarPagina() {
141 if ($scope.currentPage < $scope.lastPage) {
142 $scope.selectPage($scope.currentPage + 1);
143 $scope.selectedProducto = 0;
52 } 144 }
53 } 145 }
54 } 146 }
55 ] 147 ]
56 )
1 angular.module('focaBusquedaProductos') 1 angular.module('focaBusquedaProductos')
2 .service('focaBusquedaProductosService', ['$q', function($q) {
3 return {
4 getProductos: function(filtro) {
5 var deferred = $q.defer();
6
7 deferred.resolve([
8 {
9 idProducto: 1,
10 codigo: 1,
11 sector: 1,
12 descripcion: 'Nafta Comun',
13 codsecfilter: '1-1',
14 precio: 35
15 },
16 {
17 idProducto: 2,
18 codigo: 2,
19 sector: 1,
20 descripcion: 'Diesel',
21 codsecfilter: '1-2',
22 precio: 40
23 },
24 {
25 idProducto: 3,
26 codigo: 1,
27 sector: 2,
28 descripcion: 'Aceite',
29 codsecfilter: '2-1',
30 precio: 95
31 }
32 ]);
33
34 return deferred.promise;
35 }
36 }
37 }])
src/views/modal-busqueda-productos.html
1 <div class="modal-header"> 1 <div class="modal-header">
2 <h3 class="modal-title">Busqueda de Productos</h3> 2 <h3 class="modal-title">Busqueda de Productos</h3>
3 </div> 3 </div>
4 <div class="modal-body" id="modal-body"> 4 <div class="modal-body" id="modal-body">
5 <div class="input-group mb-3"> 5 <div class="input-group mb-3">
6 <input 6 <input
7 type="text" 7 type="text"
8 class="form-control" 8 class="form-control"
9 placeholder="Busqueda" 9 placeholder="Busqueda"
10 ng-model="filters" 10 ng-model="filters"
11 ng-change="search()" 11 ng-change="search()"
12 ng-keypress="enter($event.keyCode)" 12 ng-keydown="busquedaDown($event.keyCode)"
13 ng-keypress="busquedaPress($event.keyCode)"
14 foca-focus="selectedProducto == -1"
15 ng-focus="selectedProducto = -1"
13 > 16 >
14 <table class="table table-striped table-sm"> 17 <table class="table table-striped table-sm">
15 <thead> 18 <thead>
16 <tr> 19 <tr>
17 <th>Sec.</th> 20 <th>Sec.</th>
18 <th>Cod.</th> 21 <th>Cod.</th>
19 <th>Descripción</th> 22 <th>Descripción</th>
20 <th>P. Base</th> 23 <th>P. Base</th>
21 <th></th> 24 <th></th>
22 </tr> 25 </tr>
23 </thead> 26 </thead>
24 <tbody> 27 <tbody>
25 <tr ng-repeat="producto in filteredProductos"> 28 <tr ng-repeat="(key,producto) in currentPageProductos">
26 <td ng-bind="producto.sector"></td> 29 <td ng-bind="producto.sector"></td>
27 <td ng-bind="producto.codigo"></td> 30 <td ng-bind="producto.codigo"></td>
28 <td ng-bind="producto.descripcion"></td> 31 <td ng-bind="producto.descripcion"></td>
29 <td ng-bind="producto.precio | currency"></td> 32 <td ng-bind="producto.precio | currency"></td>
30 <td> 33 <td>
31 <button type="button" class="btn btn-secondary p-5 float-right mr-1" ng-click="select(producto)"> 34 <button
32 <i class="fa fa-check" aria-hidden="true"></i> 35 type="button"
36 class="btn p-5 float-right"
37 ng-class="{ 'btn-secondary': selectedProducto != key, 'btn-primary': selectedProducto == key}"
38 ng-click="select(producto)"
39 foca-focus="selectedProducto == {{key}}"
40 ng-keydown="itemProducto($event.keyCode)"
41 >
42 <i class="fa fa-arrow-right" aria-hidden="true"></i>
33 </button> 43 </button>
34 </td> 44 </td>
35 </tr> 45 </tr>
36 </tbody> 46 </tbody>
37 </table> 47 </table>
48 <nav>
49 <ul class="pagination justify-content-end">
50 <li class="page-item" ng-class="{'disabled': currentPage == 1}">
51 <a class="page-link" href="#" ng-click="selectPage(currentPage - 1)">
52 <span aria-hidden="true">&laquo;</span>
53 <span class="sr-only">Anterior</span>
54 </a>
55 </li>
56 <li class="page-item" ng-repeat="pagina in paginas" ng-class="{'active': pagina == currentPage}">
57 <a
58 class="page-link"
59 href="#"
60 ng-click="selectPage(pagina)"
61 ng-bind="pagina"
62 ></a>
63 </li>
64 <li class="page-item" ng-class="{'disabled': currentPage == lastPage}">
65 <a class="page-link" href="#" ng-click="selectPage(currentPage + 1)">
66 <span aria-hidden="true">&raquo;</span>
67 <span class="sr-only">Siguiente</span>
68 </a>
69 </li>
70 </ul>
71 </nav>
38 </div> 72 </div>
39 </div> 73 </div>
40 <div class="modal-footer"> 74 <div class="modal-footer">
41 <button class="btn btn-secondary" type="button" ng-click="cancel()">Cancelar</button> 75 <button class="btn btn-secondary" type="button" ng-click="cancel()">Cancelar</button>
42 </div> 76 </div>
43 77