custom_form_generator 1.0.4
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 +7 -0
- data/README.md +125 -0
- data/custom_form_generator.gemspec +42 -0
- data/lib/custom_form_generator/generator.rb +66 -0
- data/lib/custom_form_generator/helpers/field_renderers.rb +100 -0
- data/lib/custom_form_generator/helpers/filter_sort.rb +99 -0
- data/lib/custom_form_generator/helpers/form_element_renderer.rb +56 -0
- data/lib/custom_form_generator/helpers/json_loader.rb +18 -0
- data/lib/custom_form_generator/helpers/table_renderer.rb +38 -0
- data/lib/custom_form_generator/helpers/template_render.rb +52 -0
- data/lib/custom_form_generator/helpers/yaml_loader.rb +16 -0
- data/lib/custom_form_generator/version.rb +5 -0
- data/lib/custom_form_generator.rb +11 -0
- metadata +101 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3ba23a1a93a21d8bff1af16e497f7f7e9536abc168098f342a71d65211f8f6f3
|
4
|
+
data.tar.gz: a42375d97414ff4c920a110cfdefe6da8e814dd455a4e045aece47e6cd9b3ca9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 147be430a8c714f7a779c44c4b2a9b2deb8fb0d79cf11c0486e25d5310b35f02629f9a1d727006c1462e72c9e1c6bbc2adc78d3581dda08c163535c86edf349e
|
7
|
+
data.tar.gz: db3c5dbfd7aee5b3e02c6340256642674f8ffcb90a5a19d90b5d39a11628166158f832f2eac46a63269ec10bede32861026cdcc7fc8652a1592ab7c6faacccb1
|
data/README.md
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
# CustomFormGenerator
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
|
5
|
+
CustomFormGenerator is a Ruby gem designed to dynamically generate HTML forms and tables based on JSON configurations. It leverages the Slim templating engine to render forms, filter, sort options, and tabular views.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'custom_form_generator', path: '/path/to/custom_form_generator'
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
bundle install
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
### Preparation
|
19
|
+
|
20
|
+
To use CustomFormGenerator, you need to provide few JSON and YAML files that defines the structure of your form or table. Currently supporting use cases of 4 such files:
|
21
|
+
- form.yml
|
22
|
+
- data.json
|
23
|
+
- config.json
|
24
|
+
- table.yml
|
25
|
+
|
26
|
+
#### form.yml
|
27
|
+
```
|
28
|
+
- type: textfield
|
29
|
+
label: Name
|
30
|
+
key: properties.name
|
31
|
+
id: name_input
|
32
|
+
class: form-control
|
33
|
+
- type: dropdown
|
34
|
+
label: Language
|
35
|
+
key: language
|
36
|
+
id: language_select
|
37
|
+
class: form-select
|
38
|
+
disabled: true
|
39
|
+
```
|
40
|
+
|
41
|
+
#### data.json
|
42
|
+
```
|
43
|
+
[
|
44
|
+
{
|
45
|
+
"_id": { "$oid": "64df" },
|
46
|
+
"language": "jp",
|
47
|
+
"name": "Kishimoto S",
|
48
|
+
"properties": {
|
49
|
+
"name": "Kishimoto S",
|
50
|
+
"categories": ["/Yusuke/Urameshi"],
|
51
|
+
"sku": "B3743-B001"
|
52
|
+
}
|
53
|
+
}
|
54
|
+
]
|
55
|
+
|
56
|
+
```
|
57
|
+
|
58
|
+
#### config.json
|
59
|
+
```
|
60
|
+
{
|
61
|
+
"sort": [
|
62
|
+
{ "key": "name", "label": "Name" },
|
63
|
+
{ "key": "created_at", "label": "Created At" }
|
64
|
+
],
|
65
|
+
"filter": [
|
66
|
+
{ "key": "language", "label": "Language" },
|
67
|
+
{ "key": "published_at", "label": "Published At", "type": "radio", "options": ["all", "yes", "no"], "default": "all" }
|
68
|
+
],
|
69
|
+
"order_by": [
|
70
|
+
{ "key": "asc", "label": "Ascending" },
|
71
|
+
{ "key": "desc", "label": "Descending" }
|
72
|
+
]
|
73
|
+
}
|
74
|
+
|
75
|
+
```
|
76
|
+
|
77
|
+
#### table.yml
|
78
|
+
```
|
79
|
+
- key: images_url
|
80
|
+
label: Image
|
81
|
+
id: image_column
|
82
|
+
class: table-column
|
83
|
+
- key: properties.name
|
84
|
+
label: Name
|
85
|
+
id: name_column
|
86
|
+
class: table-column
|
87
|
+
```
|
88
|
+
|
89
|
+
### Usage Example
|
90
|
+
|
91
|
+
```
|
92
|
+
require 'custom_form_generator'
|
93
|
+
|
94
|
+
generator = CustomFormGenerator::Generator.new(
|
95
|
+
'path/to/form.yml',
|
96
|
+
'path/to/data.json',
|
97
|
+
'path/to/config.json',
|
98
|
+
'path/to/table.yml'
|
99
|
+
)
|
100
|
+
|
101
|
+
# Generate form
|
102
|
+
html_form = generator.generate_form
|
103
|
+
|
104
|
+
# Generate filter and sort
|
105
|
+
filter_html = generator.generate_filter_and_sort
|
106
|
+
|
107
|
+
# Generate table view
|
108
|
+
table_html = generator.generate_tabular_view(data)
|
109
|
+
```
|
110
|
+
|
111
|
+
## Development
|
112
|
+
|
113
|
+
After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests.
|
114
|
+
|
115
|
+
## Contributing
|
116
|
+
|
117
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/Manmohan-menon/SlimForms_gem. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/Manmohan-menon/SlimForms_gem/CODE_OF_CONDUCT.md).
|
118
|
+
|
119
|
+
## License
|
120
|
+
|
121
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
122
|
+
|
123
|
+
## Code of Conduct
|
124
|
+
|
125
|
+
Everyone interacting in the CustomFormGenerator project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/Manmohan-menon/SlimForms_gem/CODE_OF_CONDUCT.md).
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/custom_form_generator/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "custom_form_generator"
|
7
|
+
spec.version = CustomFormGenerator::VERSION
|
8
|
+
spec.authors = ["manmohan.menon"]
|
9
|
+
spec.email = ["manmohan.menon@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "A custom form generator using Slim and JSON data."
|
12
|
+
spec.description = "This gem generates forms based on JSON data, using Slim for templating."
|
13
|
+
spec.homepage = "https://github.com/Manmohan-menon/SlimForms_gem"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = ">= 2.6.0"
|
16
|
+
|
17
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
18
|
+
|
19
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
20
|
+
spec.metadata["source_code_uri"] = "https://github.com/Manmohan-menon/SlimForms_gem"
|
21
|
+
spec.metadata["changelog_uri"] = "https://github.com/Manmohan-menon/SlimForms_gem"
|
22
|
+
|
23
|
+
# Specify which files should be added to the gem when it is released.
|
24
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
25
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
26
|
+
Dir["lib/**/*.rb"] + %w[
|
27
|
+
README.md
|
28
|
+
custom_form_generator.gemspec
|
29
|
+
].reject { |file| file == "custom_form_generator-0.1.4.gem" }
|
30
|
+
end
|
31
|
+
spec.bindir = "exe"
|
32
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
33
|
+
spec.require_paths = ["lib"]
|
34
|
+
|
35
|
+
# Uncomment to register a new dependency of your gem
|
36
|
+
spec.add_dependency "json", "~> 2.6"
|
37
|
+
spec.add_dependency "slim", "~> 5.0.0"
|
38
|
+
spec.add_dependency "yaml", "~> 0.1.0"
|
39
|
+
|
40
|
+
# For more information and examples about making a new gem, check out our
|
41
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
42
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
require "slim"
|
5
|
+
require "yaml"
|
6
|
+
require_relative "helpers/yaml_loader"
|
7
|
+
require_relative "helpers/json_loader"
|
8
|
+
require_relative "helpers/template_render"
|
9
|
+
require_relative "helpers/form_element_renderer"
|
10
|
+
require_relative "helpers/field_renderers"
|
11
|
+
require_relative "helpers/filter_sort"
|
12
|
+
require_relative "helpers/table_renderer"
|
13
|
+
|
14
|
+
module CustomFormGenerator
|
15
|
+
# The Generator class is responsible for orchestrating the loading and rendering
|
16
|
+
# of form configurations, data, and templates. It integrates various helper modules
|
17
|
+
# to process YAML and JSON files, and to render forms and UI components using Slim templates.
|
18
|
+
class Generator
|
19
|
+
include Helpers::YamlLoader
|
20
|
+
include Helpers::JsonLoader
|
21
|
+
include Helpers::TemplateRender
|
22
|
+
include Helpers::FieldRenderers
|
23
|
+
include Helpers::FilterSort
|
24
|
+
include Helpers::TableRenderer
|
25
|
+
include Helpers::FormElementRenderer
|
26
|
+
|
27
|
+
def initialize(form_yaml, data_json, config_json, table_yaml, debug: false)
|
28
|
+
load_files(form_yaml, data_json, config_json, table_yaml)
|
29
|
+
@debug = { debug: debug }
|
30
|
+
rescue StandardError => e
|
31
|
+
raise CustomFormGenerator::Error, "Failed to load generator files: #{e.message}"
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def load_files(form_yaml, data_json, config_json, table_yaml)
|
37
|
+
@form_yaml = load_yaml(form_yaml)
|
38
|
+
@data_json = load_json(data_json)
|
39
|
+
@config_json = load_json(config_json)
|
40
|
+
@table_yaml = load_yaml(table_yaml)
|
41
|
+
rescue StandardError => e
|
42
|
+
raise CustomFormGenerator::Error, "Failed to load files: #{e.message}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def generate_form
|
46
|
+
debug_output("Generating form") if @debug
|
47
|
+
Slim::Template.new { form_template }.render(self)
|
48
|
+
end
|
49
|
+
|
50
|
+
def generate_filter_and_sort
|
51
|
+
debug_output("Generating filter and sort") if @debug
|
52
|
+
updated_config = generate_updated_config(@config_json, @data_json)
|
53
|
+
Slim::Template.new { filter_and_sort_template(updated_config) }.render(self, updated_config: updated_config)
|
54
|
+
end
|
55
|
+
|
56
|
+
def generate_form_with_data(item)
|
57
|
+
debug_output("Generating form with data") if @debug
|
58
|
+
@data_json = item
|
59
|
+
Slim::Template.new { form_template }.render(self)
|
60
|
+
end
|
61
|
+
|
62
|
+
def debug_output(message)
|
63
|
+
puts "[DEBUG] #{message}" if @debug[:debug]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cgi"
|
4
|
+
|
5
|
+
module CustomFormGenerator
|
6
|
+
# Helpers module provides form generation and rendering functionality
|
7
|
+
# Contains core modules for field rendering, validation, and HTML generation
|
8
|
+
module Helpers
|
9
|
+
include FormElementRenderer
|
10
|
+
|
11
|
+
# FieldRenderers module handles HTML form field generation with various input types
|
12
|
+
# and proper escaping for security
|
13
|
+
module FieldRenderers
|
14
|
+
def render_field(field)
|
15
|
+
validate_field(field)
|
16
|
+
field_attributes = extract_field_attributes(field)
|
17
|
+
render_field_by_type(field, field_attributes)
|
18
|
+
rescue StandardError => e
|
19
|
+
raise CustomFormGenerator::Error, "Failed to render field '#{field["key"]}': #{e.message}"
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def validate_field(field)
|
25
|
+
raise CustomFormGenerator::Error, "Invalid field structure" unless field.is_a?(Hash)
|
26
|
+
end
|
27
|
+
|
28
|
+
def extract_field_attributes(field)
|
29
|
+
{
|
30
|
+
label: CGI.escapeHTML(field["label"]),
|
31
|
+
id: CGI.escapeHTML(field["id"]),
|
32
|
+
key: CGI.escapeHTML(field["key"]),
|
33
|
+
css_class: CGI.escapeHTML(field["class"]),
|
34
|
+
value: fetch_nested_value(field["key"]).to_s,
|
35
|
+
type: field["type"]
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def render_field_by_type(field, attrs)
|
40
|
+
case attrs[:type]
|
41
|
+
when "textfield" then render_textfield(attrs)
|
42
|
+
when "dropdown" then render_dropdown(field, attrs)
|
43
|
+
when "datetime-local" then render_datetime(field, attrs)
|
44
|
+
when "radio" then render_radio(field, attrs)
|
45
|
+
when "textbox" then render_textbox(attrs)
|
46
|
+
else ""
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def fetch_dropdown_options(field, selected_value)
|
51
|
+
options = fetch_nested_value(field["key"])
|
52
|
+
return "" unless options.is_a?(Array)
|
53
|
+
|
54
|
+
options.map { |opt| generate_option(opt, opt == selected_value ? "selected" : "") }.join("\n")
|
55
|
+
rescue StandardError => e
|
56
|
+
raise CustomFormGenerator::Error, "Failed to generate dropdown options: #{e.message}"
|
57
|
+
end
|
58
|
+
|
59
|
+
def fetch_radio_options(field, selected_value)
|
60
|
+
return "" unless field.is_a?(Hash) && field.key?("options")
|
61
|
+
|
62
|
+
generate_radio_options(field, selected_value)
|
63
|
+
rescue StandardError => e
|
64
|
+
raise CustomFormGenerator::Error, "Failed to generate radio options: #{e.message}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def generate_radio_options(field, selected_value)
|
68
|
+
field["options"].map do |opt|
|
69
|
+
generate_radio_option(opt, selected_value)
|
70
|
+
end.join("<br>")
|
71
|
+
end
|
72
|
+
|
73
|
+
def generate_radio_option(opt, selected_value)
|
74
|
+
opt_value = CGI.escapeHTML(opt["value"])
|
75
|
+
opt_label = CGI.escapeHTML(opt["label"])
|
76
|
+
checked = opt["value"] == selected_value ? "checked" : ""
|
77
|
+
<<~HTML
|
78
|
+
<input type='radio' id='#{id}_#{opt_value}' class='#{css_class}'#{" "}
|
79
|
+
name='#{key}' value='#{opt_value}' #{checked}>
|
80
|
+
<label for='#{id}_#{opt_value}'>#{opt_label}</label>
|
81
|
+
HTML
|
82
|
+
end
|
83
|
+
|
84
|
+
def fetch_nested_value(key)
|
85
|
+
keys = key.split(".")
|
86
|
+
value = keys.reduce(@data_json) do |data, k|
|
87
|
+
return "" unless data.is_a?(Hash) && data.key?(k)
|
88
|
+
|
89
|
+
data[k]
|
90
|
+
end
|
91
|
+
puts "DEBUG: key = #{key}, value = #{value.inspect}" if @debug
|
92
|
+
value.is_a?(Array) ? value : value || ""
|
93
|
+
end
|
94
|
+
|
95
|
+
def generate_option(option, selected)
|
96
|
+
"<option value='#{CGI.escapeHTML(option)}' #{selected}>#{CGI.escapeHTML(option)}</option>"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cgi"
|
4
|
+
require "slim"
|
5
|
+
|
6
|
+
module CustomFormGenerator
|
7
|
+
module Helpers
|
8
|
+
# FilterSort module handles configuration updates and template generation for filtering and sorting
|
9
|
+
module FilterSort
|
10
|
+
def generate_updated_config(config, data)
|
11
|
+
validate_inputs(config, data)
|
12
|
+
parsed_data = parse_input_data(config, data)
|
13
|
+
update_filter_options(parsed_data)
|
14
|
+
end
|
15
|
+
|
16
|
+
def filter_and_sort_template(_updated_config)
|
17
|
+
<<-SLIM
|
18
|
+
div
|
19
|
+
button onclick='showFilterPanel()' Filter
|
20
|
+
select name='sort'
|
21
|
+
- updated_config['sort'].each do |sort_option|
|
22
|
+
option value=sort_option['key'] = sort_option['label']
|
23
|
+
select name='order_by'
|
24
|
+
- updated_config['order_by'].each do |order_option|
|
25
|
+
option value=order_option['key'] = order_option['label']
|
26
|
+
div id='filterPanel' style='display:none;'
|
27
|
+
- updated_config['filter'].each do |filter_option|
|
28
|
+
label = filter_option['label']
|
29
|
+
- if filter_option['type'] == 'radio'
|
30
|
+
fieldset
|
31
|
+
legend= filter_option['label']
|
32
|
+
- filter_option['options'].each do |option|
|
33
|
+
input type='radio' name=filter_option['key'] value=option['value']
|
34
|
+
label= option['label']
|
35
|
+
- if filter_option['default']
|
36
|
+
input type='radio' name=filter_option['key'] value=filter_option['default'] checked
|
37
|
+
- else
|
38
|
+
- filter_option['options'].each do |option|
|
39
|
+
input type='checkbox' name=filter_option['key'] value=option['value']
|
40
|
+
label= option['label']
|
41
|
+
button type='submit' Apply
|
42
|
+
SLIM
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def validate_inputs(config, data)
|
48
|
+
raise CustomFormGenerator::Error, "Config is not a hash: #{config.class}" unless config.is_a?(Hash)
|
49
|
+
raise CustomFormGenerator::Error, "Data is not an array: #{data.class}" unless data.is_a?(Array)
|
50
|
+
end
|
51
|
+
|
52
|
+
def parse_input_data(config, data)
|
53
|
+
{
|
54
|
+
config: config.is_a?(String) ? load_json(config) : config,
|
55
|
+
data: data.is_a?(String) ? load_json(data) : data
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def update_filter_options(parsed_data)
|
60
|
+
config = parsed_data[:config]
|
61
|
+
config["filter"].each do |filter|
|
62
|
+
next if filter["options"]&.any?
|
63
|
+
|
64
|
+
unique_values = extract_unique_values(parsed_data[:data], filter["key"])
|
65
|
+
update_filter_settings(filter, unique_values)
|
66
|
+
end
|
67
|
+
config
|
68
|
+
end
|
69
|
+
|
70
|
+
def extract_unique_values(data, key)
|
71
|
+
data.map { |entry| extract_value(entry, key) }
|
72
|
+
.flatten
|
73
|
+
.uniq
|
74
|
+
.compact
|
75
|
+
end
|
76
|
+
|
77
|
+
def extract_value(entry, key)
|
78
|
+
value = entry[key] || entry.dig(*key.split("."))
|
79
|
+
value.is_a?(Array) ? value : [value]
|
80
|
+
end
|
81
|
+
|
82
|
+
def update_filter_settings(filter, unique_values)
|
83
|
+
filter["default"] ||= unique_values.first if filter["type"] == "radio"
|
84
|
+
filter["options"] ||= generate_options(unique_values)
|
85
|
+
end
|
86
|
+
|
87
|
+
def generate_options(values)
|
88
|
+
values.map do |value|
|
89
|
+
formatted_value = format_name(value)
|
90
|
+
{ "value" => formatted_value, "label" => formatted_value }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def format_name(name)
|
95
|
+
name.gsub("/", " ").strip.split.map(&:capitalize).join(" ")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cgi"
|
4
|
+
|
5
|
+
module CustomFormGenerator
|
6
|
+
module Helpers
|
7
|
+
# FormElementRenderer module handles HTML form element generation
|
8
|
+
module FormElementRenderer
|
9
|
+
def render_textfield(attrs)
|
10
|
+
<<~HTML
|
11
|
+
<label for='#{attrs[:id]}'>#{attrs[:label]}</label>
|
12
|
+
<input type='text' id='#{attrs[:id]}' class='#{attrs[:css_class]}'#{" "}
|
13
|
+
name='#{attrs[:key]}' value='#{CGI.escapeHTML(attrs[:value])}'#{" "}
|
14
|
+
placeholder='Enter your #{attrs[:label]}'/>
|
15
|
+
HTML
|
16
|
+
end
|
17
|
+
|
18
|
+
def render_dropdown(field, attrs)
|
19
|
+
options = fetch_dropdown_options(field, attrs[:value])
|
20
|
+
<<~HTML
|
21
|
+
<label for='#{attrs[:id]}'>#{attrs[:label]}</label>
|
22
|
+
<select id='#{attrs[:id]}' class='#{attrs[:css_class]}' name='#{attrs[:key]}'>
|
23
|
+
#{options}
|
24
|
+
</select>
|
25
|
+
HTML
|
26
|
+
end
|
27
|
+
|
28
|
+
def render_datetime(field, attrs)
|
29
|
+
disabled_attr = field["disabled"] ? "disabled" : ""
|
30
|
+
<<~HTML
|
31
|
+
<label for='#{attrs[:id]}'>#{attrs[:label]}</label>
|
32
|
+
<input type='datetime-local' id='#{attrs[:id]}' class='#{attrs[:css_class]}'#{" "}
|
33
|
+
name='#{attrs[:key]}' value='#{CGI.escapeHTML(attrs[:value])}' #{disabled_attr} />
|
34
|
+
HTML
|
35
|
+
end
|
36
|
+
|
37
|
+
def render_radio(field, attrs)
|
38
|
+
options = fetch_radio_options(field, attrs[:value])
|
39
|
+
<<~HTML
|
40
|
+
<fieldset>
|
41
|
+
<legend>#{attrs[:label]}</legend>
|
42
|
+
#{options}
|
43
|
+
</fieldset>
|
44
|
+
HTML
|
45
|
+
end
|
46
|
+
|
47
|
+
def render_textbox(attrs)
|
48
|
+
<<~HTML
|
49
|
+
<label for='#{attrs[:id]}'>#{attrs[:label]}</label>
|
50
|
+
<textarea id='#{attrs[:id]}' class='#{attrs[:css_class]}' name='#{attrs[:key]}'#{" "}
|
51
|
+
placeholder='Enter your #{attrs[:label]}'>#{CGI.escapeHTML(attrs[:value])}</textarea>
|
52
|
+
HTML
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
puts "JSON Version: #{JSON::VERSION}"
|
5
|
+
|
6
|
+
module CustomFormGenerator
|
7
|
+
module Helpers
|
8
|
+
# JsonLoader module provides JSON file loading functionality with safety checks
|
9
|
+
# along with error handling for the CustomFormGenerator gem
|
10
|
+
module JsonLoader
|
11
|
+
def load_json(file_path)
|
12
|
+
raise CustomFormGenerator::Error, "JSON file not found: #{file_path}" unless File.exist?(file_path)
|
13
|
+
|
14
|
+
JSON.parse(File.read(file_path))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "slim"
|
4
|
+
module CustomFormGenerator
|
5
|
+
module Helpers
|
6
|
+
# Module CustomFormGenerator::Helpers::TableRenderer helps in gnerating table from yaml using slim template
|
7
|
+
module TableRenderer
|
8
|
+
def table_template
|
9
|
+
<<-SLIM
|
10
|
+
table
|
11
|
+
tr
|
12
|
+
- @table_yaml.each do |field|
|
13
|
+
th id=CGI.escapeHTML(field["id"]) class=CGI.escapeHTML(field["class"]) = field['label']
|
14
|
+
th Activities
|
15
|
+
- data.each do |entry|
|
16
|
+
tr
|
17
|
+
- @table_yaml.each do |field|
|
18
|
+
td id=CGI.escapeHTML(field["id"]) class=CGI.escapeHTML(field["class"])
|
19
|
+
- value = entry.dig(*field['key'].split('.'))
|
20
|
+
- if field['key'] == 'properties.published_at' && value.nil?
|
21
|
+
| false
|
22
|
+
- elsif field['key'] == 'properties.image_url' && value.nil?
|
23
|
+
img src='/path/to/default_image.jpg' alt='Default Thumbnail'
|
24
|
+
- else
|
25
|
+
= value
|
26
|
+
td
|
27
|
+
button class='edit-button' data-id=entry['_id']['$oid'] Edit
|
28
|
+
button class='delete-button' data-id=entry['_id']['$oid'] Delete
|
29
|
+
SLIM
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate_tabular_view(data:, table_template:)
|
33
|
+
template = Slim::Template.new { table_template }
|
34
|
+
template.render(self, data: data)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "slim"
|
4
|
+
require "cgi"
|
5
|
+
|
6
|
+
module CustomFormGenerator
|
7
|
+
module Helpers
|
8
|
+
# TemplateRender module handles rendering of Slim templates.
|
9
|
+
# Provides methods to generate dynamic HTML content for form
|
10
|
+
# based on the provided configuration and data.
|
11
|
+
module TemplateRender
|
12
|
+
def form_template
|
13
|
+
<<-SLIM
|
14
|
+
form
|
15
|
+
- @form_yaml.each do |field|
|
16
|
+
- next if field['key'] == '_id'
|
17
|
+
== render_field(field)
|
18
|
+
br
|
19
|
+
SLIM
|
20
|
+
end
|
21
|
+
|
22
|
+
def filter_and_sort_template(_config)
|
23
|
+
<<-SLIM
|
24
|
+
div
|
25
|
+
button onclick='showFilterPanel()' Filter
|
26
|
+
select name='sort'
|
27
|
+
- config['sort'].each do |sort_option|
|
28
|
+
option value=sort_option['key'] = sort_option['label']
|
29
|
+
select name='order_by'
|
30
|
+
- config['order_by'].each do |order_option|
|
31
|
+
option value=order_option['key'] = order_option['label']
|
32
|
+
div id='filterPanel' style='display:none;'
|
33
|
+
- config['filter'].each do |filter_option|
|
34
|
+
label = filter_option['label']
|
35
|
+
- if filter_option['type'] == 'radio'
|
36
|
+
fieldset
|
37
|
+
legend= filter_option['label']
|
38
|
+
- filter_option['options'].each do |option|
|
39
|
+
input type='radio' name=filter_option['key'] value=option['value']
|
40
|
+
label= option['label']
|
41
|
+
- if filter_option['default']
|
42
|
+
input type='radio' name=filter_option['key'] value=filter_option['default'] checked
|
43
|
+
- else
|
44
|
+
- filter_option['options'].each do |option|
|
45
|
+
input type='checkbox' name=filter_option['key'] value=option['value']
|
46
|
+
label= option['label']
|
47
|
+
button type='submit' Apply
|
48
|
+
SLIM
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
module CustomFormGenerator
|
5
|
+
module Helpers
|
6
|
+
# YamlLoader module provides YAML file loading functionality with safety checks
|
7
|
+
# along with error handling for the CustomFormGenerator gem
|
8
|
+
module YamlLoader
|
9
|
+
def load_yaml(file_path)
|
10
|
+
raise CustomFormGenerator::Error, "YAML file not found: #{file_path}" unless File.exist?(file_path)
|
11
|
+
|
12
|
+
YAML.safe_load(File.read(file_path), permitted_classes: [Symbol])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "custom_form_generator/version"
|
4
|
+
require "json"
|
5
|
+
require "slim"
|
6
|
+
require "yaml"
|
7
|
+
require_relative "custom_form_generator/generator"
|
8
|
+
|
9
|
+
module CustomFormGenerator
|
10
|
+
class Error < StandardError; end
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: custom_form_generator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- manmohan.menon
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-10-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: json
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: slim
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 5.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 5.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: yaml
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.1.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.1.0
|
55
|
+
description: This gem generates forms based on JSON data, using Slim for templating.
|
56
|
+
email:
|
57
|
+
- manmohan.menon@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- README.md
|
63
|
+
- custom_form_generator.gemspec
|
64
|
+
- lib/custom_form_generator.rb
|
65
|
+
- lib/custom_form_generator/generator.rb
|
66
|
+
- lib/custom_form_generator/helpers/field_renderers.rb
|
67
|
+
- lib/custom_form_generator/helpers/filter_sort.rb
|
68
|
+
- lib/custom_form_generator/helpers/form_element_renderer.rb
|
69
|
+
- lib/custom_form_generator/helpers/json_loader.rb
|
70
|
+
- lib/custom_form_generator/helpers/table_renderer.rb
|
71
|
+
- lib/custom_form_generator/helpers/template_render.rb
|
72
|
+
- lib/custom_form_generator/helpers/yaml_loader.rb
|
73
|
+
- lib/custom_form_generator/version.rb
|
74
|
+
homepage: https://github.com/Manmohan-menon/SlimForms_gem
|
75
|
+
licenses:
|
76
|
+
- MIT
|
77
|
+
metadata:
|
78
|
+
allowed_push_host: https://rubygems.org
|
79
|
+
homepage_uri: https://github.com/Manmohan-menon/SlimForms_gem
|
80
|
+
source_code_uri: https://github.com/Manmohan-menon/SlimForms_gem
|
81
|
+
changelog_uri: https://github.com/Manmohan-menon/SlimForms_gem
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 2.6.0
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubygems_version: 3.4.1
|
98
|
+
signing_key:
|
99
|
+
specification_version: 4
|
100
|
+
summary: A custom form generator using Slim and JSON data.
|
101
|
+
test_files: []
|