visual_condition_builder 0.0.3 → 0.1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ccc5de806d1a4cf9ef077225054ebe26c6f80150
4
- data.tar.gz: 735e442bfbe57814e71e4fd4f218e99c0045e365
3
+ metadata.gz: 178da1aa116065c99dc12ee94a452dc9e458f198
4
+ data.tar.gz: 133d796fd6b683c0eef3c776afa246d7ec7dc9bc
5
5
  SHA512:
6
- metadata.gz: 52a80f4a49e6d7edce309174e05a3bdae69cbf247878ea652f3e2fbfc811a4055c63de213167dc57c26b42bc55900b25ee22903fb92a743cbe7ac140fe2c3d45
7
- data.tar.gz: 14337527f974dd0df23961a446b3648cd0eb49a826c615b93deaedc377f86e8d2159a2d764e743f14aed5746a15bc8caede33b4ecb7e652a36b6b963edadf4d6
6
+ metadata.gz: 85dec3cf9eb10c147f90d280ca0eb52f83adbdb108a91090836b6f7d181d1c031c76a2a9fc13976a819a8dc1ac4f59562bc167c70bd217f844a7327e75171036
7
+ data.tar.gz: 4a30c06b5e8564b4a7150d581d15b3c8e1593ccdabdb3a34072fa1b00d9de93e9aa89e344916ca3917601aac142fc505f73de01fa4b36cd067cf142ac33b9cd8
data/README.md CHANGED
@@ -1,155 +1,416 @@
1
- # Search Builder
1
+ # Search Builder
2
+ [![Code Climate](https://codeclimate.com/github/brunoporto/visual_condition_builder/badges/gpa.svg)](https://codeclimate.com/github/brunoporto/visual_condition_builder)
2
3
 
3
4
  A great and easy search builder to your rails project
4
5
 
5
- ### Instalação
6
+ ## How to install
6
7
 
7
8
  Add it to your **Gemfile**:
8
9
  ```ruby
9
10
  gem 'visual_condition_builder'
10
11
  ```
11
12
 
12
- Rubn the following command to install it:
13
+ Run the following command to install it:
13
14
  ```sh
14
15
  $ bundle install
16
+ $ rails generate visual_condition_builder:install
15
17
  ```
16
18
 
17
19
  Add it to your **app/assets/stylesheets/application.css**
18
20
  ```js
19
- *= require visual_condition_builder
21
+ *= require visual_condition_builder
20
22
  ```
21
23
 
22
24
  Add it to your **app/assets/javascripts/application.js**
23
25
  ```js
24
- //= require visual_condition_builder
26
+ //= require visual_condition_builder
25
27
  ```
26
- ### Dependencies
28
+
29
+ ## Dependency
27
30
 
28
31
  Antes de iniciar o plugin você precisa ter o jQuery adicionado no seu application.js
29
32
 
30
33
  Caso você tenha os seguintes plugins jQuery indicados no seu application.js, você deve remover:
31
34
 
32
- - select2
33
- - autoNumeric
34
-
35
+ - [select2](https://github.com/select2/select2)
36
+ - [autoNumeric](https://github.com/BobKnothe/autoNumeric#default-settings--supported-options)
35
37
 
36
38
  ### Select2 Languages
37
39
 
38
40
  Select2 supports multiple languages by simply including the right language JS file (visual_condition_builder/select2_i18n/it, visual_condition_builder/select2_i18n/pt-BR, etc.) after visual_condition_builder in your **application.js**
39
41
  ```js
40
- //= require visual_condition_builder
42
+ //= require visual_condition_builder/select2_i18n/en
41
43
  //= require visual_condition_builder/select2_i18n/pt-BR
42
44
  ```
43
45
 
44
- ## Como usar
46
+ ## Dictionaries
45
47
 
46
- Instancie em um elemento jQuery passando os parametros necessários:
48
+ As informações do gerador de condições são baseadas em um dicionário, portanto é necessário que você crie seus dicionários de acordo com o necessário.
47
49
 
48
- ```javascript
49
- var builder = $('#div-exemplo-regras').ruleBuilder({
50
- dicionario: [],
51
- regras: [],
52
- texto_instrucao: {
53
- campos: 'Selecione um campo',
54
- operadores: 'Selecione um operador',
55
- valores: 'Informe um valor'
56
- },
57
- permite_brancos: true,
58
- resultado: function(dados) {
59
- //RETORNO DO RESULTADO EM JSON
60
- }
61
- });
50
+ Para gerar um novo dicionário use o comando:
51
+
52
+ ```sh
53
+ $ rails g visual_condiction_builder:dictionary example
62
54
  ```
63
55
 
64
- Nos parâmetros dicionário e regras você pode informar diretamente um objeto com os dados ou informar uma url para carregar os dados. Atualmente o carregamento dessa fonte de dados é feita de forma síncrona);
65
- ```javascript
66
- var dicionario = [{
67
- "variavel": "nome_do_campo", //
68
- "tipo": "STRING", //
69
- "descricao": "descricao_do_campo", //
70
- "operadores": [
71
- {"operador": "simbolo_do_operador", "descricao": "texto_do_operador"},
72
- {"operador": "=", "descricao": "Igual"},
73
- {"operador": "EMPTY", "descricao": "Vazio", "sem_valor": "true"},
74
- {"operador": "IN", "descricao": "Presente em", "multiplo": "true"},
75
- {"operador": "BETWEEN", "descricao": "Entre", "multiplo": "2" }
76
- ],
77
- "valores": [
78
- {"id": "1", "label": "Um"},
79
- {"id": "65465", "label": "José da Silva"},
80
- {"id": "2016-06-15", "label": "Data de Hoje"},
81
- {"id": "50.8", "label": "Valor Total"}
82
- ]
83
- }];
84
- ```
85
- ### Parâmetros
86
-
87
- #### **dicionario**
88
-
89
- > Array de Hash: `[{},{},{}, ...]`
90
-
91
- - *variavel*: Indica qual será o VALUE utilizado no `<option>` do `<select>` na coluna CAMPO
92
- - *tipo*: Qual o tipo do valor do campo, esse tipo influência nos valores. Ex: Date mostra um datepicker no `<input>` do valor.
93
- - STRING, DECIMAL(n), INTEGER, DATE, TIME
94
- - *descricao*: Indica qual será o TEXT utilizado no `<option>` do `<select>` na coluna CAMPO
95
- - *operadores*: Array de Hash com os operadores que esse campo possibilita selecionar.
96
- - *operador*: Indica qual será o VALUE utilizado no `<option>` do `<select>` na coluna OPERADOR
97
- - *descricao*: Indica qual será o TEXT utilizado no `<option>` do `<select>` na coluna OPERADOR
98
- - *sem_valor*: Indica que esse operador não requer um valor, logo ele não será exibido.
99
- - *multiplo*: Indica que o campo possibilita informar multiplos valores. Caso você passe um número para esse campo, esse número indicará quantas caixas de valores serão exibidas para esse campo.
100
- - *valores*: É o Array dos valores que será exibidos para o usuário durante a seleção desse campo. Caso você não informe valores, será exibido um campo em aberto de acordo com o tipo selecionado. Também pode ser informado uma URL para carregar os dados diretamente dessa fonte.
101
- - *id*: Indica qual será o VALUE utilizado no `<option>` do `<select>` na coluna VALOR
102
- - *label*: Indica qual será o TEXT utilizado no `<option>` do `<select>` na coluna VALOR
103
- - *Exemplo*: `"valores": [{"id": "S", "label": "Sim" }, {"id": "N", "label": "Não" }]`
104
-
105
- #### **regras**
106
-
107
- > Array de Array: `[[],[], ...]`
108
-
109
- Esse parâmetro permite informar os dados que serão pré-selecionados ao carregar o plugin, é o estado inicial do plugin.
110
- O array interno das regras sempre deverá ser informado com 3 elementos: `["CAMPO], "OPERADOR", "VALOR"]`, onde o valor poderá ser uma outra array caso esse campo permita seleção de múltiplos valores.
111
-
112
- Exemplo:
56
+ Será criado um arquivo na pasta `app/condition_dictionaries/example_dictionary.rb` com a seguinte estrutura:
113
57
 
114
- ```javascript
115
- var regras = [
116
- ["nome_do_campo", "simbolo_do_operador", "id_do_valor"],
117
- ["campo_sim_ou_nao", "=", "S"],
118
- ["campo_decimal", "=", "88884.55"],
119
- ["campo_multiplo_2", "BETWEEN", ["2015-07-21","2015-07-30"]],
120
- ["campo_multiplo_true", "IN", ["A","B","C","D"]]
121
- ];
58
+ ```ruby
59
+ class ExampleDictionary < VisualConditionBuilder::Dictionary
60
+
61
+ dictionary do
62
+ param :name
63
+ end
64
+
65
+ end
122
66
  ```
123
67
 
124
- #### **permite_brancos**
68
+ Você pode criar multiplos contextos para esse dicionário:
69
+ ```ruby
70
+ dictionary :simple do
71
+ param :name
72
+ end
73
+
74
+ dictionary :complex do
75
+ param :first_name
76
+ param :last_name
77
+ end
78
+ ```
79
+
80
+ ### Params
81
+
82
+ Você não tem restrição ao uso dos parametros, pois eles não tem ligação com model ou qualquer outro elemento da aplicação.
83
+ Ao informar os parametros você pode passar argumentos para personalizar a forma como o gerador de condições será criado:
84
+
85
+ ```ruby
86
+ dictionary do
87
+ param :name, type: 'STRING', operators: [:eq]
88
+ param :created_at, type: 'DATE', operators: [{operator: 'eq', label: 'Equal', multiple: true, no_value: false}]
89
+ param :updated_at, type: 'DATE', operators: [{operator: 'between', label: 'Between ... and ...', multiple: 2, no_value: false}]
90
+ param :today, type: 'DATE', operators: [{operator: 'eq', label: 'Equal', multiple: false, no_value: true}]
91
+ end
92
+ ```
93
+
94
+ Veja abaixo todos os argumentos que você pode usar na construção dos operadores:
95
+
96
+ **TABELA DE PARAMETROS DE OPERADORES**
97
+
98
+ Por padrão, o gerador de condições implementa alguns operadores e argumentos, possibilitando que você informe apenas o nome do operador `operators: [:eq, :between]`
99
+
100
+ Lista de operadores padrões do gerador de condições
101
+
102
+ Operator | Description | Default Arguments
103
+ --- | --- | ---
104
+ between | Between .. e .. | multiple: 2
105
+ today | Today(date) | no_value: true
106
+ yesterday | Yesterday(date) | no_value: true
107
+ tomorrow | Tomorrow(date) | no_value: true
108
+ this_week | First day of Current Week .. Last day of Current Week | no_value: true
109
+ last_week | First day of Last Week .. Last day of Last Week | no_value: true
110
+ next_week | First day of Next Week .. Last day of Next Week | no_value: true
111
+ eq | Is exactly equal to a given value | multiple: false
112
+ not_eq | Opposite :eq | multiple: false
113
+ matches | Is like a given value | multiple: false
114
+ does_not_match |Opposite :matches | multiple: false
115
+ lt | is less than a given value | multiple: false
116
+ gt | is greater than a given value | multiple: false
117
+ lteq | is less than or equal to a given value | multiple: false
118
+ gteq | is greater than or equal to a given value | multiple: false
119
+ in | is within a specified list | multiple: true
120
+ not_in | Opposite :in | multiple: true
121
+ cont | contains a given value | multiple: false
122
+ not_cont | Opposite :not_cont | multiple: false
123
+ cont_any | contains any of the given values | multiple: true
124
+ not_cont_any | Opposite :cont_any | multiple: true
125
+ cont_all | contains all of the given values | multiple: true
126
+ not_cont_all | Opposite :cont_all | multiple: true
127
+ start | begins with a given value | multiple: false
128
+ not_start | Opposite :start | multiple: false
129
+ end | ends with a given value | multiple: false
130
+ not_end | Opposite :end | multiple: false
131
+ true | where a field is true | no_value: true, multiple: false
132
+ not_true | Opposite :true | no_value: true, multiple: false
133
+ false | where a field is false | no_value: true, multiple: false
134
+ not_false | Opposite :false | no_value: true, multiple: false
135
+ present | where a field is present (not null and not a blank string) | no_value: true, multiple: false
136
+ blank | Opposite :present | no_value: true, multiple: false
137
+ null | where a field is null | no_value: true, multiple: false
138
+ not_null | Opposite :null | no_value: true, multiple: false
139
+
140
+ Caso você não informe os operadores, o gerador de condições irá selecionar os operadores baseado no tipo informado:
141
+ *Se um tipo não for informado, será considerado STRING*
142
+
143
+ Type | Default Operators
144
+ --- | ---
145
+ DATE, DATETIME | eq, between, today, yesterday, tomorrow, this_week, last_week, next_week, present, blank
146
+ TIME | eq, between, present, blank
147
+ DECIMAL, INTEGER | eq, between
148
+ STRING | cont, eq, start, end, present, blank
149
+ ... | eq
150
+
151
+ Também é possível informar listas de valores ou valores pré-definidos para que o gerador de condições para carregar esses valores por padrão:
152
+
153
+ ```ruby
154
+ dictionary do
155
+ param :status, values: [{id: 1, label: 'Active', id: 2, label: 'Inactive'}]
156
+ param :status_list, values: MyStatus.all.dictionary_values(:code, :title)
157
+ param :status_proc, values: -> { MyService.get_status }
158
+ param :status_ajax, values: ajax_my_status_path
159
+ end
160
+ ```
161
+
162
+ Em todos os exemplos acima o resultado deve sempre seguir a estrutura :
163
+
164
+ ```ruby
165
+ [
166
+ {id: 1, label: 'Example'},
167
+ {id: 2, label: 'Example 2'},
168
+ {id: 'A', label: 'Example 3'},
169
+ {id: 'Text', label: 'My Text'}
170
+ ]
171
+ ```
172
+
173
+ Quando for utilizar uma chamada AJAX o gerador de condições fará requisições passando dois tipos de parametros: **init** ou **key**, onde:
174
+ * init - é o parametro com o valor inicial da lista. Quando o plugin tenta carregar a lista ele deverá mostrar um valor inicial antes da busca feita pelo usuário, portanto esse valor inicial deve ser retornado através do parametro init:
175
+ * key - é o parametro com o valor digitado pelo usuário para efetuar o retorno dos valores da lista.
176
+
177
+ O retorno deverá seguir a estrutua padrão de valores do dicionário e retornar em formato JSON. Exemplo de um controller que implementa essa função:
178
+ ```ruby
179
+ class CitiesController < ApplicationController
180
+ def ajax
181
+ if params[:init]
182
+ @cities = City.where(id: params[:init])
183
+ else
184
+ @cities = City.where('cities.name LIKE ?', "%#{params[:key]}%").order(:name).limit(100)
185
+ end
186
+ render json: @cities.select('cities.id, cities.name AS label').to_json
187
+ end
188
+ end
189
+ ```
190
+
191
+ ### Methods
192
+
193
+ Dictionary Class have public methods to get informations about self:
194
+ * fields(dictionary_context_name)
195
+ * dictionary(dictionary_context_name)
196
+ * dictionaries
197
+
198
+ ```ruby
199
+ #example_dictionary.rb
200
+ class ExampleDictionary < VisualConditionBuilder::Dictionary
201
+
202
+ dictionary do
203
+ param :name
204
+ end
205
+
206
+ dictionary :complex do
207
+ param :name
208
+ param :age
209
+ end
210
+
211
+ end
212
+
213
+ #rails console
214
+ ExampleDictionary.fields
215
+ # => {:name=>{:label=>"Name", :type=>"STRING"}}
216
+
217
+ ExampleDictionary.fields(:complex)
218
+ # => {:name=>{:label=>"Name", :type=>"STRING"}, :age=>{:label=>"Age", :type=>"STRING"}}
125
219
 
126
- > Boleano: true/false
220
+ ExampleDictionary.dictionary
221
+ # => [{:type=>"STRING", :operators=>[{:operator=>:cont, :multiple=>false, :no_value=>false, :label=>"Contém"}, {:operator=>:eq, :multiple=>false, :no_value=>false, :label=>"Igual"}, {:operator=>:start, :multiple=>false, :no_value=>false, :label=>"Começa com"}, {:operator=>:end, :multiple=>false, :no_value=>false, :label=>"Termina com"}, {:operator=>:present, :no_value=>true, :multiple=>false, :label=>"Presente"}, {:operator=>:blank, :no_value=>true, :multiple=>false, :label=>"Não Presente"}], :values=>[], :group=>"", :label=>"Name", :field=>:name}]
127
222
 
128
- Esse campo permite informar se as caixas de seleção irão ou não iniciar com valor "vazio" para que o usuário possa selecionar. Caso *false* seja informado o primeiro valor de cada coluna será pré-selecionado.
223
+ ExampleDictionary.dictionary(:complex)
224
+ # => [{:type=>"STRING", :operators=>[{:operator=>:cont, :multiple=>false, :no_value=>false, :label=>"Contém"}, {:operator=>:eq, :multiple=>false, :no_value=>false, :label=>"Igual"}, {:operator=>:start, :multiple=>false, :no_value=>false, :label=>"Começa com"}, {:operator=>:end, :multiple=>false, :no_value=>false, :label=>"Termina com"}, {:operator=>:present, :no_value=>true, :multiple=>false, :label=>"Presente"}, {:operator=>:blank, :no_value=>true, :multiple=>false, :label=>"Não Presente"}], :values=>[], :group=>"", :label=>"Name", :field=>:name}, {:type=>"STRING", :operators=>[{:operator=>:cont, :multiple=>false, :no_value=>false, :label=>"Contém"}, {:operator=>:eq, :multiple=>false, :no_value=>false, :label=>"Igual"}, {:operator=>:start, :multiple=>false, :no_value=>false, :label=>"Começa com"}, {:operator=>:end, :multiple=>false, :no_value=>false, :label=>"Termina com"}, {:operator=>:present, :no_value=>true, :multiple=>false, :label=>"Presente"}, {:operator=>:blank, :no_value=>true, :multiple=>false, :label=>"Não Presente"}], :values=>[], :group=>"", :label=>"Age", :field=>:age}]
129
225
 
130
- #### **resultado**
226
+ ExampleDictionary.dictionaries
227
+ # => {:default=>[{:type=>"STRING", :operators=>[{:operator=>:cont, :multiple=>false, :no_value=>false, :label=>"Contém"}, {:operator=>:eq, :multiple=>false, :no_value=>false, :label=>"Igual"}, {:operator=>:start, :multiple=>false, :no_value=>false, :label=>"Começa com"}, {:operator=>:end, :multiple=>false, :no_value=>false, :label=>"Termina com"}, {:operator=>:present, :no_value=>true, :multiple=>false, :label=>"Presente"}, {:operator=>:blank, :no_value=>true, :multiple=>false, :label=>"Não Presente"}], :values=>[], :group=>"", :label=>"Name", :field=>:name}], :padrao=>[{:type=>"STRING", :operators=>[{:operator=>:cont, :multiple=>false, :no_value=>false, :label=>"Contém"}, {:operator=>:eq, :multiple=>false, :no_value=>false, :label=>"Igual"}, {:operator=>:start, :multiple=>false, :no_value=>false, :label=>"Começa com"}, {:operator=>:end, :multiple=>false, :no_value=>false, :label=>"Termina com"}, {:operator=>:present, :no_value=>true, :multiple=>false, :label=>"Presente"}, {:operator=>:blank, :no_value=>true, :multiple=>false, :label=>"Não Presente"}], :values=>[], :group=>"", :label=>"Name", :field=>:name}, {:type=>"STRING", :operators=>[{:operator=>:cont, :multiple=>false, :no_value=>false, :label=>"Contém"}, {:operator=>:eq, :multiple=>false, :no_value=>false, :label=>"Igual"}, {:operator=>:start, :multiple=>false, :no_value=>false, :label=>"Começa com"}, {:operator=>:end, :multiple=>false, :no_value=>false, :label=>"Termina com"}, {:operator=>:present, :no_value=>true, :multiple=>false, :label=>"Presente"}, {:operator=>:blank, :no_value=>true, :multiple=>false, :label=>"Não Presente"}], :values=>[], :group=>"", :label=>"Age", :field=>:age}]}
228
+ ```
131
229
 
132
- > Função: `function(dados){}`
230
+ ## Helpers
133
231
 
134
- Callback de retorno dos dados em JSON (type object), o retorno segue o mesmo padrão do parâmetro regra, logo o mesmo formato que você informa para pré-popular o plugin será o formato que o plugin retornará apóas as modificações do usuário.
232
+ #### (class) dictionary_values(param_id, param_label)
233
+ Deve ser utilizado em objetos do tipo: Array ou ActiveRecord::Relation e usa o primeiro parametro como **id** e o segundo como **label** na construção da estrutura de valores para o dicionário
234
+ ```ruby
235
+ dictionary do
236
+ param :book_id, values: Book.all.dictionary_values(:code, :title)
237
+ #MyService.myarray = [['Active','1'], ['Inactive','2'], ['Blocked','3']]
238
+ param :status, values: MyService.myarray.dictionary_values(1, 0)
239
+ end
240
+ ```
241
+
242
+ #### (view) conditions_fields(name_of_dictionary)
243
+ Cria um seletor de campos em um elemento dropdown (bootstrap).
244
+ ```haml
245
+ = conditions_fields :example
246
+ -# with context:
247
+ = conditions_fields({:dictionary_name => :context_name})
248
+ ```
135
249
 
136
- Exemplo:
250
+ Mas você pode fazer a geração da lista de campos manualmente através do método `ExampleDictionary.fields(dictionary_name)` *(example_dictionary.rb)*, nesse caso você deve ter elementos "clicáveis" com a classe `add-condition-field` e atributo `data-field: field_name`
251
+ ```haml
252
+ %a.add-condition-field{href: '#', data: {field: 'name'}} Name
253
+ %a.add-condition-field{href: '#', data: {field: 'age'}} Age
254
+ %a.add-condition-field{href: '#', data: {field: 'example'}} Example Field
255
+ ```
256
+
257
+ #### (view) build_conditions(name_of_dictionary, *arguments)
258
+
259
+ Cria o gerador de condições na sua view:
260
+ ```haml
261
+ = form_tag obrigacoes_path, method: :get do
262
+ -# condition builder don't create input field with values, create it:
263
+ = hidden_field_tag('my_conditions', @example_conditions.to_json)
264
+ -# DropDown with fields
265
+ = conditions_fields :example
266
+ -# Conditions Element
267
+ = build_conditions :example, input: '#my_conditions', select2Config: {allowClear: true}
268
+ ```
269
+ Por padrão será gerado um elemento com o id no padrão dictionary_name + context_name + condition_container: `example_default_condition_container`
270
+
271
+ Para criar baseado em um dicionário de contexto específico use:
272
+ ```haml
273
+ = build_conditions({:dictionary_name => :context_name}, input: '#my_conditions', select2Config: {allowClear: true})
274
+ ```
275
+ Os argumentos possíveis para o build_conditions são:
276
+
277
+ Param | Description
278
+ --- | ---
279
+ placeholder | Placeholder for inputs {operators: 'Select a operator...', values: 'Enter a value...'},
280
+ values | initial values to fill conditions, format: [[field, operator, value], [field, operator, [value1, value2]]]
281
+ input | to get initial values and save values on change from a html element, like: #my_input_element
282
+ debug | to see debugs flags. default: false
283
+ numericConfig | When the field is decimal type then the generator will create an input with numeric mask. Default {aSep: '', aDec: '.', aSign: ''}. See [Auto Numeric Plugin](https://github.com/BobKnothe/autoNumeric#default-settings--supported-options)
284
+ select2Config: | Select2 Configuration. Default {theme: "bootstrap", width: 'auto', placeholder: '', allowClear: false, dropdownAutoWidth: 'true', tags: false, language: "en"}, but some parameters can be overwritten by condition builder. See [Select2 Plugin](https://github.com/select2/select2)
285
+
286
+ Também é possível criar o builder manualmente chamando o plugin jquery diretamente:
137
287
  ```javascript
138
- var resultado = function(objJSON) {
139
- //CONVERTO JSON EM STRING COMO EXEMPLO...
140
- var stringJSON = JSON.stringify(objJSON);
141
- }
288
+ //my_dictionary_json = ExampleDictionary.dictionary(:example).to_json
289
+ //my_initial_values = [['name','eq','My Name']]
290
+ var builder = $('#div-container').conditionBuilder({
291
+ placeholder: {values: 'Select a Value'},
292
+ dictionary: my_dictionary_json,
293
+ values: my_initial_values,
294
+ select2Config: {language: 'pt-BR'} //visual_condition_builder/select2_i18n/pt-BR
295
+ });
142
296
  ```
143
297
 
144
- Esse callback é chamado toda vez que o usuário faz uma modificação no plugin. Caso você queira forçar a recuperação desses dados através de um botão, você pode fazer:
298
+ ## Javascript Methods/Callback
299
+
300
+ The conditions builder plugin have two actions:
301
+ * **Clear** - clear the conditions rows
302
+ * **Result** - return the conditions values on change fields, operators or values.
303
+
304
+ Example:
305
+
145
306
  ```javascript
146
- var builder = $('#div-exemplo-regras').ruleBuilder({
147
- //...
148
- });
149
-
150
- $('#meu-botao').click(function(){
151
- var objJSON = builder.getResultado();
152
- //CONVERTO JSON EM STRING COMO EXEMPLO...
153
- var stringJSON = JSON.stringify(objJSON);
154
- });
155
- ```
307
+ $(document).ready(function () {
308
+ //get the builder instance
309
+ var $conditionBuilder = $('#example_default_condition_container').data('conditionBuilder');
310
+
311
+ //clear conditions rows
312
+ $('#button_to_clear_list').on('click',function(e){
313
+ e.preventDefault();
314
+ $conditionBuilder.clear_rows();
315
+ });
316
+
317
+ //Callback on change conditions
318
+ $conditionBuilder.result = function(data) {
319
+ //result data object: [[field, operator, value], [field, operator, [value1, value2]]]
320
+ console.log(data);
321
+ //convert to STRING before send FORM
322
+ var json_data = JSON.stringify(data);
323
+ }
324
+ });
325
+ ```
326
+
327
+ ## Converters
328
+
329
+ Condition Builder have converters of values to use in controller:
330
+ * **Ransack** - Convert conditions values `['name', 'eq', 'My Name']` in `{:name_eq => "My Name"}`
331
+
332
+ ```ruby
333
+ @example_conditions = JSON.parse(params[:my_conditions] ||= '[]')
334
+ ransack_params = VisualConditionBuilder::Converter.to_ransack(@example_conditions)
335
+ @q = source.ransack(ransack_params)
336
+ @records = @q.result.paginate(page: params[:page], per_page: 10)
337
+ ```
338
+
339
+ ## i18N
340
+
341
+ When you create the conditions with `build_conditions` and `conditions_fields` the builder automacaly translate attributes for you.
342
+ See locale file example `config/locales/visual_condition_builder.pt-BR.yml`:
343
+
344
+ ```yml
345
+ pt-BR:
346
+ condition_builder:
347
+ dropdown: 'Filtros'
348
+ operators:
349
+ between: 'Entre ... e ...'
350
+ today: 'Hoje'
351
+ yesterday: 'Ontem'
352
+ tomorrow: 'Amanhã'
353
+ this_week: 'Essa Semana'
354
+ last_week: 'Semana Passada'
355
+ next_week: 'Próxima Semana'
356
+ eq: 'Igual'
357
+ not_eq: 'Diferente'
358
+ matches: 'Parecido'
359
+ does_not_match: 'Não é Parecido'
360
+ lt: 'Menor'
361
+ gt: 'Maior'
362
+ lteq: 'Menor ou Igual'
363
+ gteq: 'Maior ou Igual'
364
+ in: 'Possui todos'
365
+ not_in: 'Não possui todos'
366
+ cont: 'Contém'
367
+ not_cont: 'Não Contém'
368
+ cont_any: 'Contém algum'
369
+ not_cont_any: 'Não Contém algum'
370
+ cont_all: 'Contém todos'
371
+ not_cont_all: 'Não contém todos'
372
+ start: 'Começa com'
373
+ not_start: 'Não começa com'
374
+ end: 'Termina com'
375
+ not_end: 'Não termina com'
376
+ true: 'Verdadeiro'
377
+ not_true: 'Não Verdadeiro'
378
+ false: 'Falso'
379
+ not_false: 'Não Falso'
380
+ present: 'Presente'
381
+ blank: 'Não Presente'
382
+ null: 'Nulo'
383
+ not_null: 'Não Nulo'
384
+ placeholder:
385
+ operators: 'Selecione um operador'
386
+ values: 'Selecione um valor'
387
+ dictionaries:
388
+ exemplo: 'Meu Dicionário de Exemplo'
389
+ condition_dictionaries:
390
+ exemplo:
391
+ nome: 'Nome'
392
+ idade: 'Idade'
393
+ ```
394
+
395
+ ## Bug reports
396
+
397
+ If you discover any bugs, feel free to create an issue on GitHub. Please add as much information as
398
+ possible to help us fixing the possible bug. We also encourage you to help even more by forking and
399
+ sending us a pull request.
400
+
401
+ https://github.com/brunoporto/visual_condition_builder/issues
402
+
403
+ ## Maintainers
404
+
405
+ * Bruno Porto (https://github.com/brunoporto)
406
+
407
+ ## License
408
+
409
+ The MIT License (MIT)
410
+ Copyright (c) 2016 Bruno Porto
411
+
412
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
413
+
414
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
415
+
416
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -21,7 +21,8 @@
21
21
  placeholder: '',
22
22
  allowClear: false,
23
23
  dropdownAutoWidth: 'true',
24
- tags: false
24
+ tags: false,
25
+ language: "en"
25
26
  }
26
27
  };
27
28
 
@@ -23,7 +23,7 @@ txtjs
23
23
  end
24
24
  end
25
25
 
26
- def conditions_fields(dictionary, *args)
26
+ def conditions_fields(dictionary)
27
27
  dictionary_name = get_dictionary_name(dictionary)
28
28
  container_name = "#{dictionary_name}_condition_container"
29
29
  capture do
@@ -0,0 +1,49 @@
1
+ en:
2
+ condition_builder:
3
+ dropdown: 'Fields'
4
+ operators:
5
+ between: 'between .. and ..'
6
+ today: 'today'
7
+ yesterday: 'yesterday'
8
+ this_week: 'this week'
9
+ last_week: 'last week'
10
+ eq: 'is exactly'
11
+ not_eq: 'not is exactly'
12
+ matches: 'match'
13
+ does_not_match: 'does not match'
14
+ lt: 'less than'
15
+ gt: 'greater than'
16
+ lteq: 'less than or equal to'
17
+ gteq: 'greater than or equal to'
18
+ in: 'in'
19
+ not_in: 'not in'
20
+ cont: 'contains'
21
+ not_cont: 'not contains'
22
+ cont_any: 'contains any'
23
+ not_cont_any: 'not contains any'
24
+ cont_all: 'contains all'
25
+ not_cont_all: 'not contains al'
26
+ start: 'starts with'
27
+ not_start: 'not starts with'
28
+ end: 'ends with'
29
+ not_end: 'not ends with'
30
+ true: 'is true'
31
+ not_true: 'not is true'
32
+ false: 'is false'
33
+ not_false: 'not is false'
34
+ present: 'is present '
35
+ blank: 'is blank'
36
+ null: 'is null'
37
+ not_null: 'not is null'
38
+ placeholder:
39
+ operators: 'select a operator'
40
+ values: 'select a value'
41
+ dictionaries:
42
+ example: 'Example'
43
+ another_example: 'Another Example'
44
+ condition_dictionaries:
45
+ example:
46
+ name: 'Name'
47
+ another_example:
48
+ name: 'Name'
49
+ age: 'Age'
@@ -0,0 +1,11 @@
1
+ class <%= @dictionary_name %>Dictionary < VisualConditionBuilder::Dictionary
2
+
3
+ dictionary do
4
+ param :name
5
+ end
6
+
7
+ # dictionary :context_name do
8
+ # param :name
9
+ # end
10
+
11
+ end
@@ -0,0 +1,12 @@
1
+ require 'rails/generators/base'
2
+
3
+ module VisualConditionBuilder
4
+ class DictionaryGenerator < Rails::Generators::NamedBase
5
+ source_root File.expand_path("../../templates", __FILE__)
6
+
7
+ def generate_dictionary
8
+ @dictionary_name = file_name.classify
9
+ template "generic_dictionary.erb", File.join('app/condition_dictionaries', "#{file_name.underscore}_dictionary.rb")
10
+ end
11
+ end
12
+ end
@@ -1,26 +1,16 @@
1
1
  require 'rails/generators/base'
2
- require 'rails/generators/migration'
3
2
 
4
3
  module VisualConditionBuilder
5
- class InstallGenerator < Rails::Generators::Base
6
- source_root File.expand_path("../../templates", __FILE__)
7
- include Rails::Generators::Migration
4
+ module Generators
8
5
 
9
- class_option :orm
10
- desc 'Instalando Taxweb Widgets'
6
+ class InstallGenerator < Rails::Generators::Base
7
+ source_root File.expand_path("../../../../config", __FILE__)
11
8
 
12
- desc 'Criando Migrations'
13
- def self.next_migration_number(path)
14
- unless @prev_migration_nr
15
- @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
16
- else
17
- @prev_migration_nr += 1
9
+ def copy_locales
10
+ directory 'locales', 'config/locales'
18
11
  end
19
- @prev_migration_nr.to_s
20
- end
21
12
 
22
- def create_migration_file
23
- migration_template 'create_visual_condition_builder_users.rb', 'db/migrate/create_visual_condition_builder_users.rb'
24
13
  end
14
+
25
15
  end
26
16
  end
@@ -1,6 +1,5 @@
1
1
  module VisualConditionBuilder
2
2
  class Engine < ::Rails::Engine
3
- # config.eager_load_paths << VisualConditionBuilder::Engine.root.join('app','widgets')
4
- config.autoload_paths << VisualConditionBuilder::Engine.root.join('app','widgets')
3
+
5
4
  end
6
5
  end
@@ -1,3 +1,3 @@
1
1
  module VisualConditionBuilder
2
- VERSION = "0.0.3"
2
+ VERSION = "0.1.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: visual_condition_builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bruno Porto
@@ -87,14 +87,11 @@ files:
87
87
  - app/views/visual_condition_builder/widgets/index.html.erb
88
88
  - config/initializers/assets.rb
89
89
  - config/initializers/visual_condition_builder.rb
90
- - config/locales/visual_condition_builder.yml
90
+ - config/locales/visual_condition_builder.en.yml
91
91
  - config/routes.rb
92
- - lib/generators/templates/create_taxweb_widgets_users.rb
93
- - lib/generators/templates/generic_widget.erb
94
- - lib/generators/templates/generic_widget.html.erb
92
+ - lib/generators/templates/generic_dictionary.erb
93
+ - lib/generators/visual_condition_builder/dictionary_generator.rb
95
94
  - lib/generators/visual_condition_builder/install_generator.rb
96
- - lib/generators/visual_condition_builder/view_generator.rb
97
- - lib/generators/visual_condition_builder/widget_generator.rb
98
95
  - lib/visual_condition_builder.rb
99
96
  - lib/visual_condition_builder/converter.rb
100
97
  - lib/visual_condition_builder/dictionary.rb
@@ -1,71 +0,0 @@
1
- pt-BR:
2
- condition_builder:
3
- dropdown: 'Filtros'
4
- operators:
5
- between: 'Entre ... e ...'
6
- today: 'Hoje'
7
- yesterday: 'Ontem'
8
- tomorrow: 'Amanhã'
9
- this_week: 'Essa Semana'
10
- last_week: 'Semana Passada'
11
- next_week: 'Próxima xxx Semana'
12
- eq: 'Igual'
13
- not_eq: 'Diferente'
14
- matches: 'Parecido'
15
- does_not_match: 'Não é Parecido'
16
- lt: 'Menor'
17
- gt: 'Maior'
18
- lteq: 'Menor ou Igual'
19
- gteq: 'Maior ou Igual'
20
- in: 'Possui todos'
21
- not_in: 'Não possui todos'
22
- cont: 'Contém'
23
- not_cont: 'Não Contém'
24
- cont_any: 'Contém algum'
25
- not_cont_any: 'Não Contém algum'
26
- cont_all: 'Contém todos'
27
- not_cont_all: 'Não contém todos'
28
- start: 'Começa com'
29
- not_start: 'Não começa com'
30
- end: 'Termina com'
31
- not_end: 'Não termina com'
32
- true: 'Verdadeiro'
33
- not_true: 'Não Verdadeiro'
34
- false: 'Falso'
35
- not_false: 'Não Falso'
36
- present: 'Presente'
37
- blank: 'Não Presente'
38
- null: 'Nulo'
39
- not_null: 'Não Nulo'
40
- placeholder:
41
- operators: 'Selecione um operador'
42
- values: 'Selecione um valor'
43
- dictionaries:
44
- fluxo_de_trabalho: 'Fluxo de Trabalho'
45
- obrigacao: 'Obrigação'
46
- condition_dictionaries:
47
- fluxo_de_trabalho:
48
- descricao: 'Descrição'
49
- obrigacao:
50
- nome: 'Nomezinho'
51
- obrigacao:
52
- nome: 'Nome'
53
- descricao: 'Descrição'
54
- periodicidade: 'Periodicidade'
55
- obrigatoriedade: 'Obrigatoriedade'
56
- ambito: 'Âmbito'
57
- legislacao: 'Legislação'
58
- centralizacao: 'Centralização'
59
- tipo: 'Tipo'
60
- apuracao_lucro: 'Apuração de Lucro'
61
- exigido_para_simples_nacional: 'Simples Nacional?'
62
- exigido_para_mei: 'MEI?'
63
- dt_inicio: 'Data início'
64
- dt_fim: 'Data fim'
65
- estado_id: 'Estado'
66
- municipio_id: 'Município'
67
- conta_id: 'Conta'
68
- fluxo_de_trablaho_id: 'Fluxo de Trabalho Padrão'
69
- meses_entrega: 'Mês(es) de Entrega'
70
- cnaes: 'CNAEs'
71
- meu_campo: 'Meu Campo'
@@ -1,18 +0,0 @@
1
- class CreateVisualConditionBuilderUsers < ActiveRecord::Migration
2
-
3
- def up
4
- unless table_exists?(:visual_condition_builder_users)
5
- create_table :visual_condition_builder_users do |t|
6
- t.references :user, index: true, foreign_key: false
7
- t.string :widget
8
- t.string :action
9
- t.index [:widget, :action]
10
- end
11
- end
12
- end
13
-
14
- def down
15
- drop_table :visual_condition_builder_users if table_exists? :visual_condition_builder_users
16
- end
17
-
18
- end
@@ -1,12 +0,0 @@
1
- class <%= @widget_name %>Widget < ApplicationWidget
2
-
3
- name! "<%= @widget_name %>"
4
- description! "O Widget <%= @widget_name %> tem como função..."
5
- #refresh_interval 60000 #60 segundos para refresh automático
6
-
7
- description! :exemplo, 'Essa ação é um exemplo'
8
- def exemplo
9
- @data = Date.today
10
- end
11
-
12
- end
@@ -1,2 +0,0 @@
1
- <h1>Exemplo de Widget<h1>
2
- Hoje é <%= data %>
@@ -1,11 +0,0 @@
1
- require 'rails/generators/base'
2
-
3
- module VisualConditionBuilder
4
- class ViewGenerator < Rails::Generators::Base
5
- source_root File.expand_path("../../../../app/views/visual_condition_builder", __FILE__)
6
-
7
- def copy_views
8
- directory 'widgets', 'app/views/visual_condition_builder/widgets'
9
- end
10
- end
11
- end
@@ -1,25 +0,0 @@
1
- require 'rails/generators/base'
2
-
3
- module VisualConditionBuilder
4
- class WidgetGenerator < Rails::Generators::NamedBase
5
- source_root File.expand_path("../../templates", __FILE__)
6
-
7
- def generate_widget
8
- @widget_name = file_name.classify
9
- view_dir = "app/views/widgets/#{widget_name_file}"
10
-
11
- template "generic_widget.erb", File.join('app/widgets', "#{widget_name_file}_widget.rb")
12
-
13
- if self.behavior == :revoke && Dir.exists?(view_dir)
14
- require 'fileutils'
15
- FileUtils.rm_rf(view_dir)
16
- elsif self.behavior == :invoke
17
- copy_file "generic_widget.html.erb", File.join(view_dir, 'exemplo.html.erb')
18
- end
19
- end
20
-
21
- def widget_name_file
22
- file_name.underscore
23
- end
24
- end
25
- end