json-rules-filter 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/readme.md +47 -16
- package/src/jquery.jsonRulesFilter.js +57 -22
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -58,7 +58,7 @@ Instalar via **cdn**:
|
|
|
58
58
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
|
59
59
|
|
|
60
60
|
<!-- jsonRulesFilter -->
|
|
61
|
-
<script src="https://unpkg.com/json-rules-filter@1.0.
|
|
61
|
+
<script src="https://unpkg.com/json-rules-filter@1.0.9/src/jquery.jsonRulesFilter.js" class="script_" type="text/javascript"></script>
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
---
|
|
@@ -72,7 +72,19 @@ const data = [
|
|
|
72
72
|
{ name: "Luis", total: 150, cargo: "Admin" }
|
|
73
73
|
];
|
|
74
74
|
|
|
75
|
-
$("#miFiltro").jsonRulesFilter(data,
|
|
75
|
+
$("#miFiltro").jsonRulesFilter(data,
|
|
76
|
+
{
|
|
77
|
+
filters:[
|
|
78
|
+
{
|
|
79
|
+
name: "Total",
|
|
80
|
+
type: "number",
|
|
81
|
+
data: "total",
|
|
82
|
+
render: function(data) {
|
|
83
|
+
return data.text;
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
],
|
|
76
88
|
onApply: function (rules, filteredData) {
|
|
77
89
|
console.log("Reglas:", rules);
|
|
78
90
|
console.log("Resultados:", filteredData);
|
|
@@ -84,10 +96,20 @@ $("#miFiltro").jsonRulesFilter(data, {
|
|
|
84
96
|
|
|
85
97
|
## 🧠 Configuración
|
|
86
98
|
|
|
99
|
+
### bsVersion
|
|
100
|
+
|
|
101
|
+
Define la compatibilidad del plugin con la version de bootstrap , actualmente solo acepta dos valores , **4** para **bootstrap4** y **5** para **bootstrap5**
|
|
102
|
+
```javascript
|
|
103
|
+
bsVersion:5 //Bootstrap 5
|
|
104
|
+
```
|
|
105
|
+
---
|
|
106
|
+
|
|
87
107
|
### filters
|
|
88
108
|
|
|
89
109
|
Define las columnas disponibles para filtrar.
|
|
90
|
-
|
|
110
|
+
- name: (título del filtro)
|
|
111
|
+
- type: tipo de filtrado. Las opciones disponibles son **number**,**string** y **select**
|
|
112
|
+
- data: clave de referencia en el dataset de JSON, se usa tanto para filtrar como para generar las opciones únicas de los tipo **select**
|
|
91
113
|
```javascript
|
|
92
114
|
filters: [
|
|
93
115
|
{
|
|
@@ -109,15 +131,23 @@ Personaliza los operadores de filtrado.
|
|
|
109
131
|
|
|
110
132
|
```javascript
|
|
111
133
|
language: {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
134
|
+
string: {
|
|
135
|
+
sContain: "Contiene",
|
|
136
|
+
sNotContain: "No contiene",
|
|
137
|
+
sEquals: "Igual a",
|
|
138
|
+
sDifference: "Diferente de",
|
|
139
|
+
sStartWith: "Empieza con",
|
|
140
|
+
sEndWith: "Termina con"
|
|
141
|
+
},
|
|
142
|
+
number: {
|
|
143
|
+
nEquals: "Igual a",
|
|
144
|
+
nDifference: "Diferente de",
|
|
145
|
+
nGreatherThan: "Mayor que",
|
|
146
|
+
nGreatherThanOrEquals: "Mayor o igual que",
|
|
147
|
+
nLowerThan: "Menor que",
|
|
148
|
+
nLowerThanOrEquals: "Menor o igual que"
|
|
149
|
+
}
|
|
119
150
|
}
|
|
120
|
-
}
|
|
121
151
|
```
|
|
122
152
|
|
|
123
153
|
---
|
|
@@ -150,7 +180,7 @@ buttons: {
|
|
|
150
180
|
Título del componente.
|
|
151
181
|
|
|
152
182
|
```javascript
|
|
153
|
-
title: "Reglas de filtrado"
|
|
183
|
+
title: {text:"Reglas de filtrado",className:"fs-4"}
|
|
154
184
|
```
|
|
155
185
|
|
|
156
186
|
---
|
|
@@ -200,7 +230,7 @@ onApply: function (rules, filteredData) {
|
|
|
200
230
|
## 🛠️ Métodos públicos
|
|
201
231
|
|
|
202
232
|
### updateData
|
|
203
|
-
|
|
233
|
+
El datasets de JSON se mantiene en memoria tras la inicialización , si tu datasets cambió , debes pasarle en todo momento los datos actualizados.
|
|
204
234
|
```javascript
|
|
205
235
|
$("#miFiltro").jsonRulesFilter("updateData", nuevosDatos);
|
|
206
236
|
```
|
|
@@ -217,6 +247,7 @@ const empleados = [
|
|
|
217
247
|
];
|
|
218
248
|
|
|
219
249
|
$("#container-rules").jsonRulesFilter(empleados, {
|
|
250
|
+
bsVersion:5,
|
|
220
251
|
filters: [
|
|
221
252
|
{ name: "Nombre", type: "text", data: "name" },
|
|
222
253
|
{ name: "Total", type: "number", data: "total" },
|
|
@@ -226,10 +257,10 @@ $("#container-rules").jsonRulesFilter(empleados, {
|
|
|
226
257
|
],
|
|
227
258
|
onApply: function (rules, results) {
|
|
228
259
|
$("#container-rules-collapse").empty();
|
|
229
|
-
|
|
260
|
+
//aquí podemos actualizar la tabla de datos con los datos ya filtrados
|
|
230
261
|
//generamos indicador budge para contenedor de filtros
|
|
231
262
|
$.each(reglas, function (index, element) {
|
|
232
|
-
|
|
263
|
+
|
|
233
264
|
let text = `${element.dataName} ${element.optionFilterText.join("").toLowerCase()} ${element.searchValue}`;
|
|
234
265
|
|
|
235
266
|
if (element.typeFilter === 'select') {
|
|
@@ -270,7 +301,7 @@ $("#container-rules").jsonRulesFilter(empleados, {
|
|
|
270
301
|
---
|
|
271
302
|
|
|
272
303
|
## 📌 Notas
|
|
273
|
-
|
|
304
|
+
- Compatibilidad con bootstrap 4 y 5
|
|
274
305
|
- Soporta propiedades anidadas (ej: user.name)
|
|
275
306
|
- Usa lógica AND entre reglas
|
|
276
307
|
- Basado en Select2
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
// --- DEFAULT CONFIGURATION ---
|
|
22
22
|
const settings = $.extend(true, {
|
|
23
|
+
bsVersion:5,
|
|
23
24
|
filters: [
|
|
24
25
|
{ name: "Example", type: "number", data: "example", render: function(data){return data.text /*Callback to render html in options type select*/}}
|
|
25
26
|
],
|
|
@@ -33,10 +34,10 @@
|
|
|
33
34
|
nGreatherThanOrEquals: "Mayor o igual que", nLowerThan: "Menor que", nLowerThanOrEquals: "Menor o igual que"
|
|
34
35
|
}
|
|
35
36
|
},
|
|
36
|
-
title: "Reglas de filtrado",
|
|
37
|
+
title: {text:"Reglas de filtrado",className:"fs-4"},
|
|
37
38
|
buttons: {
|
|
38
39
|
reset: { text: "Resetear", className: "fw-semibold link-danger link-offset-2 link-underline link-underline-opacity-0" },
|
|
39
|
-
dropdown: { text: "Añadir regla", className: "btn btn-secondary"
|
|
40
|
+
dropdown: { text: "Añadir regla", className: "btn btn-secondary"},
|
|
40
41
|
apply: { text: "Aplicar regla", className: "btn btn-primary" },
|
|
41
42
|
},
|
|
42
43
|
onApply: function (filtros, datosFiltrados) { }
|
|
@@ -51,6 +52,31 @@
|
|
|
51
52
|
settings: settings,
|
|
52
53
|
$contenedor: $contenedor,
|
|
53
54
|
|
|
55
|
+
// ---- Compatibility helper bs5/bs4 ------
|
|
56
|
+
bs: function(classes) {
|
|
57
|
+
if (this.settings.bootstrapVersion === 5) return classes;
|
|
58
|
+
|
|
59
|
+
const map = {
|
|
60
|
+
'fw-semibold': 'font-weight-bold',
|
|
61
|
+
'fw-bold': 'font-weight-bold',
|
|
62
|
+
'link-danger': 'text-danger',
|
|
63
|
+
'ms-': 'ml-', // Margin start -> Margin left
|
|
64
|
+
'me-': 'mr-', // Margin end -> Margin right
|
|
65
|
+
'ps-': 'pl-', // Padding start -> Padding left
|
|
66
|
+
'pe-': 'pr-', // Padding end -> Padding right
|
|
67
|
+
'g-': 'row-grid-',
|
|
68
|
+
'link-offset-2': '',
|
|
69
|
+
'link-underline': '',
|
|
70
|
+
'link-underline-opacity-0': ''
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
let result = classes;
|
|
74
|
+
Object.keys(map).forEach(key => {
|
|
75
|
+
result = result.replace(new RegExp(key, 'g'), map[key]);
|
|
76
|
+
});
|
|
77
|
+
return result;
|
|
78
|
+
},
|
|
79
|
+
|
|
54
80
|
// Updates dataset from external source and refreshes the UI
|
|
55
81
|
updateData: function (newData) {
|
|
56
82
|
this.data = newData;
|
|
@@ -88,28 +114,36 @@
|
|
|
88
114
|
|
|
89
115
|
// Render main plugin skeleton
|
|
90
116
|
render: function () {
|
|
91
|
-
|
|
117
|
+
const self = this;
|
|
118
|
+
// Atributo de toggle dinámico
|
|
119
|
+
const toggleAttr = this.settings.bootstrapVersion === 4 ? 'data-toggle="dropdown"' : 'data-bs-toggle="dropdown"';
|
|
120
|
+
|
|
121
|
+
// Ajuste de Gutters para BS4 (usamos form-row en lugar de row g-2 si es BS4)
|
|
122
|
+
const rowClass = this.settings.bootstrapVersion === 4 ? 'form-row' : 'row g-2';
|
|
123
|
+
const colClass = this.settings.bootstrapVersion === 4 ? 'col-6' : 'col-6';
|
|
124
|
+
|
|
125
|
+
let columnasHtml = `<div class="${rowClass}">`;
|
|
92
126
|
this.settings.filters.forEach((col, index) => {
|
|
93
127
|
let icon = col.type === "number" ? "fa-solid fa-hashtag" : (col.type === "string" ? "fa-solid fa-language" : "fa-solid fa-circle-chevron-down");
|
|
94
128
|
columnasHtml += `
|
|
95
|
-
<li class="
|
|
129
|
+
<li class="${colClass} list-unstyled">
|
|
96
130
|
<a class="dropdown-item dropdown-rules-item" href="#" data-column-type="${col.type}" data-column-data="${col.data}" data-column-name="${col.name}">
|
|
97
131
|
<i class="${icon}"></i> ${col.name}
|
|
98
132
|
</a>
|
|
99
133
|
</li>`;
|
|
100
|
-
if (index % 2 !== 0 && index !== 0) columnasHtml +=
|
|
134
|
+
if (index % 2 !== 0 && index !== 0) columnasHtml += `</div><div class="${rowClass}">`;
|
|
101
135
|
});
|
|
102
136
|
columnasHtml += "</div>";
|
|
103
137
|
|
|
104
138
|
let template = `
|
|
105
139
|
<div class="d-flex justify-content-between">
|
|
106
|
-
<
|
|
107
|
-
<p><a class="${this.settings.buttons.reset.className} remove-rules-containers" href="#">${this.settings.buttons.reset.text}</a></p>
|
|
140
|
+
<p class="${this.bs(this.settings.title.className)}">${this.settings.title.text}</p>
|
|
141
|
+
<p><a class="${this.bs(this.settings.buttons.reset.className)} remove-rules-containers" href="#">${this.settings.buttons.reset.text}</a></p>
|
|
108
142
|
</div>
|
|
109
143
|
<div class="py-2" id="container-rules-filters"></div>
|
|
110
144
|
<div class="mt-2">
|
|
111
145
|
<div class="d-flex justify-content-start dropdown">
|
|
112
|
-
<button
|
|
146
|
+
<button class="${this.bs(this.settings.buttons.dropdown.className)} dropdown-toggle" type="button" ${toggleAttr}>
|
|
113
147
|
${this.settings.buttons.dropdown.text}
|
|
114
148
|
</button>
|
|
115
149
|
<div class="dropdown-menu p-2 dropdown-rules-columns" style="min-width: 300px;">
|
|
@@ -117,7 +151,7 @@
|
|
|
117
151
|
</div>
|
|
118
152
|
</div>
|
|
119
153
|
<div class="mt-2 d-flex justify-content-start">
|
|
120
|
-
<button type="button" id="apply-rules-btn" class="${this.settings.buttons.apply.className}">${this.settings.buttons.apply.text}</button>
|
|
154
|
+
<button type="button" id="apply-rules-btn" class="${this.bs(this.settings.buttons.apply.className)}">${this.settings.buttons.apply.text}</button>
|
|
121
155
|
</div>
|
|
122
156
|
</div>`;
|
|
123
157
|
this.$contenedor.append(template);
|
|
@@ -156,40 +190,41 @@
|
|
|
156
190
|
addRuleRow: function (type, dataField, name) {
|
|
157
191
|
const self = this;
|
|
158
192
|
const $container = this.$contenedor.find("#container-rules-filters");
|
|
159
|
-
let id_select = 0;
|
|
160
193
|
|
|
161
|
-
|
|
194
|
+
// Generate unique ID for the new row based on the last element
|
|
195
|
+
let id_select = 0;
|
|
162
196
|
const last_container = $contenedor.find("select[name=select-rule-option]").last();
|
|
163
|
-
if (last_container.length > 0) {
|
|
164
|
-
|
|
165
|
-
|
|
197
|
+
if (last_container.length > 0) { id_select = last_container.data("id") + 1; }
|
|
198
|
+
|
|
199
|
+
// Usar 'form-group' y 'font-weight-bold' si es BS4
|
|
200
|
+
const labelClass = this.settings.bootstrapVersion === 4 ? 'font-weight-bold' : 'form-label fw-bold';
|
|
201
|
+
const rowClass = this.settings.bootstrapVersion === 4 ? 'form-row' : 'row';
|
|
166
202
|
|
|
167
203
|
// Define search input template (hidden for 'select' type)
|
|
168
204
|
const searchInput = `
|
|
169
205
|
<div class="col-7">
|
|
170
|
-
<label class="
|
|
206
|
+
<label class="${labelClass}"><span class="text-danger">*</span>${type}</label>
|
|
171
207
|
<input type="text" class="form-control" name="input-rule-search" id="input-rule-search-${id_select}">
|
|
172
208
|
</div>`;
|
|
173
209
|
|
|
174
210
|
const row = `
|
|
175
211
|
<div id="select-rule-container-${id_select}" class="d-flex justify-content-between mt-2 pt-2 mb-4 ${$contenedor.find("[name=select-rule-option]").length > 0 ? ' border-top my-3' : ""}">
|
|
176
|
-
<div class="
|
|
212
|
+
<div class="${rowClass} flex-grow-1">
|
|
177
213
|
<div class="col-4">
|
|
178
|
-
<label class="
|
|
179
|
-
<select class="form-select" ${type === 'select' ? 'multiple' : ''} data-type="${type}" data-name="${name}" data-field="${dataField}" id="select-rule-option-${id_select}" data-id="${id_select}" name="select-rule-option"></select>
|
|
214
|
+
<label class="${labelClass}">${name}</label>
|
|
215
|
+
<select class="form-select form-control" ${type === 'select' ? 'multiple' : ''} data-type="${type}" data-name="${name}" data-field="${dataField}" id="select-rule-option-${id_select}" data-id="${id_select}" name="select-rule-option"></select>
|
|
180
216
|
</div>
|
|
181
217
|
${type === 'select' ? '' : searchInput}
|
|
182
218
|
</div>
|
|
183
|
-
<div class="">
|
|
184
|
-
<a href="#" class="link-danger btn-remove-rule" data-target="select-rule-container-${id_select}">
|
|
219
|
+
<div class="ml-2">
|
|
220
|
+
<a href="#" class="link-danger text-danger btn-remove-rule" data-target="select-rule-container-${id_select}">
|
|
185
221
|
<i class="fa-solid fa-trash-can"></i>
|
|
186
222
|
</a>
|
|
187
223
|
</div>
|
|
188
224
|
</div>`;
|
|
189
225
|
|
|
190
226
|
$container.append(row);
|
|
191
|
-
|
|
192
|
-
// Fetch custom render function from settings
|
|
227
|
+
// Fetch custom render function from settings
|
|
193
228
|
const render = self.settings.filters.find((e) => e.data === dataField).render;
|
|
194
229
|
this.initSelect2(id_select, type, dataField, render);
|
|
195
230
|
},
|