Commit fdd4dada172a399dc97d9152a61df5a3ce07402d

Authored by Nicolás Guarnieri
Exists in master

Merge branch 'master' into 'master'

Modal de búsqueda de producto con tabla, filtro, paginación y navegación por teclado

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