formstrap 0.3.1 → 0.3.2

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
  SHA256:
3
- metadata.gz: 2d52dd192e41d84f75bc6be46186bd8a5739ab34f72b8a03a7f57a2518024356
4
- data.tar.gz: 21985d08ac6f4837e06385a0de891e0785366322f8504a537f22a89d397903aa
3
+ metadata.gz: 98d133e0c15d72418662dbe8a98e296a3c701bc97aa9bec3620fa3f0a346ffec
4
+ data.tar.gz: f50c6dc41f0809c54e6522e14a718b0a6842a419fc3068928a64e156df771408
5
5
  SHA512:
6
- metadata.gz: d4e86b30d1f485050c98c72ef426d3590624544e86675b41efe409382595d8f121878b437cf5fdb7ff8dc7aef71dd11c5f689b3bae73d805d1011f6c68cd965b
7
- data.tar.gz: 1f04bdc357480984893120ef11166a2c62ade2e80ad793d49814a550f5e35099fd559ca05f57070ce51a166691a1c4c9a916fedd357b29f38c41b563e3c15601
6
+ metadata.gz: f540f4053664dc2095dd165f5e4d6c2c5a7257a7fe810bed486834b3477d5c0888ca4ee9bfc5f0e9ac8685d86e0f97039e5bde5795013a1e80350246580a35d3
7
+ data.tar.gz: 7318bdcee8bb2ac4a84a079374fb15b8385e1032186e8ce14cbe00b449b7d33e2f012b887ad5fa35773eebf9ad718a58c5cacb43188300dc59f27486804882b0
@@ -114,11 +114,11 @@ export default class extends Controller {
114
114
  }
115
115
 
116
116
  minActiveItems () {
117
- return parseInt(this.element.dataset.min, 10) || 0
117
+ return parseInt(this.validationInputTarget.dataset.min, 10) || 0
118
118
  }
119
119
 
120
120
  maxActiveItems () {
121
- return parseInt(this.element.dataset.max, 10) || Infinity
121
+ return parseInt(this.validationInputTarget.dataset.max, 10) || Infinity
122
122
  }
123
123
 
124
124
  resetPositions () {
@@ -131,13 +131,7 @@ export default class extends Controller {
131
131
  }
132
132
 
133
133
  addNewItems (items) {
134
- const itemTargetIds = this.itemTargets.map((i) => { return parseInt(i.querySelectorAll('input')[1].value) })
135
134
  items.forEach((item) => {
136
- if (itemTargetIds.includes(item.blobId)) {
137
- // Do not add this item (as it is already present)
138
- return
139
- }
140
-
141
135
  this.addItem(item)
142
136
  })
143
137
  }
@@ -211,7 +205,7 @@ export default class extends Controller {
211
205
  const returnedBlobIds = elements.map((e) => { return e.blobId })
212
206
 
213
207
  items.forEach((item) => {
214
- const blobId = parseInt(item.querySelectorAll('input')[1].value)
208
+ const blobId = parseInt(item.querySelectorAll('input')[1].value, 10)
215
209
  if (returnedBlobIds.includes(blobId)) {
216
210
  // Do not delete this one
217
211
  return
@@ -237,7 +231,7 @@ export default class extends Controller {
237
231
 
238
232
  itemByBlobId (blobId) {
239
233
  return this.itemTargets.find((item) => {
240
- return item.querySelector('input[name*=\'blob_id\']').value === blobId
234
+ return parseInt(item.querySelector('input[name*=\'blob_id\']').value, 10) === blobId
241
235
  })
242
236
  }
243
237
 
@@ -249,7 +243,7 @@ export default class extends Controller {
249
243
 
250
244
  activeIds () {
251
245
  return this.activeItems().map((item) => {
252
- return item.querySelector('input[name$=\'[blob_id]\']').value
246
+ return parseInt(item.querySelector('input[name$=\'[blob_id]\']').value, 10)
253
247
  })
254
248
  }
255
249
  }
@@ -1,3 +1,4 @@
1
+ /* global XMLHttpRequest, MutationObserver */
1
2
  import { Controller } from '@hotwired/stimulus'
2
3
 
3
4
  export default class extends Controller {
@@ -30,7 +31,6 @@ export default class extends Controller {
30
31
  }
31
32
 
32
33
  autoResizeIframe () {
33
- // eslint-disable-next-line no-undef
34
34
  const observer = new MutationObserver((mutations) => {
35
35
  mutations.forEach((mutation) => {
36
36
  this.resizeIframe()
@@ -77,7 +77,6 @@ export default class extends Controller {
77
77
 
78
78
  requestPreview () {
79
79
  // Create an AJAX request
80
- // eslint-disable-next-line no-undef
81
80
  const xhr = new XMLHttpRequest()
82
81
  xhr.open('POST', this.urlValue, true)
83
82
 
@@ -109,7 +108,7 @@ export default class extends Controller {
109
108
  validateFields () {
110
109
  let allValid = true
111
110
  const fields = this.fieldsTarget
112
- const formElements = fields.querySelectorAll('input[name], select[name], textarea[name]')
111
+ const formElements = fields.querySelectorAll('input:not([type="hidden"]), select[name], textarea[name]')
113
112
  formElements.forEach(function (element) {
114
113
  const isValid = element.reportValidity()
115
114
  if (!isValid) {
@@ -110,6 +110,7 @@ export default class extends Controller {
110
110
  replaceIdsWithTimestamps (template) {
111
111
  const pattern = 'rrrrrrrrr'
112
112
  const replacement = new Date().getTime().toString()
113
+ const regex = new RegExp(pattern, 'g')
113
114
 
114
115
  // Replace ids
115
116
  template.querySelectorAll(`input[id*="${pattern}"], select[id*="${pattern}"], textarea[id*="${pattern}"], button[id*="${pattern}"]`).forEach((node) => {
@@ -117,6 +118,11 @@ export default class extends Controller {
117
118
  node.setAttribute('id', idValue.replace(pattern, replacement))
118
119
  })
119
120
 
121
+ // Search and replace pattern in templates
122
+ template.querySelectorAll('template').forEach((node) => {
123
+ node.innerHTML = node.innerHTML.replace(regex, replacement)
124
+ })
125
+
120
126
  // Replace labels
121
127
  template.querySelectorAll(`label[for*="${pattern}"]`).forEach((node) => {
122
128
  const forValue = node.getAttribute('for')
@@ -11035,10 +11035,10 @@ var media_controller_default = class extends Controller {
11035
11035
  }
11036
11036
  }
11037
11037
  minActiveItems() {
11038
- return parseInt(this.element.dataset.min, 10) || 0;
11038
+ return parseInt(this.validationInputTarget.dataset.min, 10) || 0;
11039
11039
  }
11040
11040
  maxActiveItems() {
11041
- return parseInt(this.element.dataset.max, 10) || Infinity;
11041
+ return parseInt(this.validationInputTarget.dataset.max, 10) || Infinity;
11042
11042
  }
11043
11043
  resetPositions() {
11044
11044
  this.activeItems().forEach((item, index2) => {
@@ -11049,13 +11049,7 @@ var media_controller_default = class extends Controller {
11049
11049
  });
11050
11050
  }
11051
11051
  addNewItems(items) {
11052
- const itemTargetIds = this.itemTargets.map((i) => {
11053
- return parseInt(i.querySelectorAll("input")[1].value);
11054
- });
11055
11052
  items.forEach((item) => {
11056
- if (itemTargetIds.includes(item.blobId)) {
11057
- return;
11058
- }
11059
11053
  this.addItem(item);
11060
11054
  });
11061
11055
  }
@@ -11112,7 +11106,7 @@ var media_controller_default = class extends Controller {
11112
11106
  return e.blobId;
11113
11107
  });
11114
11108
  items.forEach((item) => {
11115
- const blobId = parseInt(item.querySelectorAll("input")[1].value);
11109
+ const blobId = parseInt(item.querySelectorAll("input")[1].value, 10);
11116
11110
  if (returnedBlobIds.includes(blobId)) {
11117
11111
  return;
11118
11112
  }
@@ -11128,7 +11122,7 @@ var media_controller_default = class extends Controller {
11128
11122
  }
11129
11123
  itemByBlobId(blobId) {
11130
11124
  return this.itemTargets.find((item) => {
11131
- return item.querySelector("input[name*='blob_id']").value === blobId;
11125
+ return parseInt(item.querySelector("input[name*='blob_id']").value, 10) === blobId;
11132
11126
  });
11133
11127
  }
11134
11128
  activeItems() {
@@ -11138,7 +11132,7 @@ var media_controller_default = class extends Controller {
11138
11132
  }
11139
11133
  activeIds() {
11140
11134
  return this.activeItems().map((item) => {
11141
- return item.querySelector("input[name$='[blob_id]']").value;
11135
+ return parseInt(item.querySelector("input[name$='[blob_id]']").value, 10);
11142
11136
  });
11143
11137
  }
11144
11138
  };
@@ -11374,7 +11368,7 @@ var nested_preview_controller_default = class extends Controller {
11374
11368
  validateFields() {
11375
11369
  let allValid = true;
11376
11370
  const fields = this.fieldsTarget;
11377
- const formElements = fields.querySelectorAll("input[name], select[name], textarea[name]");
11371
+ const formElements = fields.querySelectorAll('input:not([type="hidden"]), select[name], textarea[name]');
11378
11372
  formElements.forEach(function(element) {
11379
11373
  const isValid = element.reportValidity();
11380
11374
  if (!isValid) {
@@ -13219,10 +13213,14 @@ var repeater_controller_default = class extends Controller {
13219
13213
  replaceIdsWithTimestamps(template) {
13220
13214
  const pattern = "rrrrrrrrr";
13221
13215
  const replacement = new Date().getTime().toString();
13216
+ const regex = new RegExp(pattern, "g");
13222
13217
  template.querySelectorAll(`input[id*="${pattern}"], select[id*="${pattern}"], textarea[id*="${pattern}"], button[id*="${pattern}"]`).forEach((node) => {
13223
13218
  const idValue = node.getAttribute("id");
13224
13219
  node.setAttribute("id", idValue.replace(pattern, replacement));
13225
13220
  });
13221
+ template.querySelectorAll("template").forEach((node) => {
13222
+ node.innerHTML = node.innerHTML.replace(regex, replacement);
13223
+ });
13226
13224
  template.querySelectorAll(`label[for*="${pattern}"]`).forEach((node) => {
13227
13225
  const forValue = node.getAttribute("for");
13228
13226
  node.setAttribute("for", forValue.replace(pattern, replacement));
@@ -1,14 +1,14 @@
1
1
  class ApplicationHelper
2
2
  def show_svg(attachment, options = {})
3
- return if !attachment.content_type.include?('svg')
3
+ return if !attachment.content_type.include?("svg")
4
4
 
5
5
  attachment.open do |file|
6
6
  content = file.read
7
7
  doc = Nokogiri::HTML::DocumentFragment.parse content
8
- svg = doc.at_css 'svg'
8
+ svg = doc.at_css "svg"
9
9
 
10
10
  # for security
11
- doc.search('script').each do |src|
11
+ doc.search("script").each do |src|
12
12
  src.remove
13
13
  end
14
14
 
@@ -17,4 +17,4 @@ class ApplicationHelper
17
17
  doc.to_html.html_safe
18
18
  end
19
19
  end
20
- end
20
+ end
@@ -19,8 +19,6 @@ module Formstrap
19
19
  data: {
20
20
  controller: "media",
21
21
  name: name,
22
- min: min,
23
- max: max,
24
22
  sort: sort,
25
23
  accept: accept,
26
24
  required: required.nil? ? 0 : required
@@ -31,7 +29,7 @@ module Formstrap
31
29
  def item_options
32
30
  options = {
33
31
  sort: sort,
34
- url: modal_url,
32
+ url: modal_url
35
33
  }
36
34
 
37
35
  # Don't pass width or height if it was not defined
@@ -108,10 +106,10 @@ module Formstrap
108
106
  end
109
107
 
110
108
  def min
111
- if @required
112
- (@min.to_i < 1) ? 1 : @min.to_i
109
+ if @min.to_i < 1
110
+ @required ? 1 : 0
113
111
  else
114
- (@min.to_i < 1) ? 0 : @min.to_i
112
+ @min.to_i
115
113
  end
116
114
  end
117
115
 
@@ -124,7 +122,14 @@ module Formstrap
124
122
  end
125
123
 
126
124
  def modal_url
127
- formstrap_media_path(name: name, ids: blob_ids, min: min, max: max, mimetype: accept, exclude_models: exclude_models)
125
+ formstrap_media_path(
126
+ name: name,
127
+ ids: blob_ids,
128
+ min: min,
129
+ max: max,
130
+ mimetype: accept,
131
+ exclude_models: exclude_models
132
+ )
128
133
  end
129
134
 
130
135
  def edit_modal_url(attachment)
@@ -92,10 +92,10 @@ module Formstrap
92
92
  blob.open do |file|
93
93
  content = file.read
94
94
  doc = Nokogiri::HTML::DocumentFragment.parse content
95
- svg = doc.at_css 'svg'
95
+ svg = doc.at_css "svg"
96
96
 
97
97
  # for security
98
- doc.search('script').each do |src|
98
+ doc.search("script").each do |src|
99
99
  src.remove
100
100
  end
101
101
 
@@ -5,6 +5,8 @@
5
5
  class: "formstrap-media-validation",
6
6
  data: {
7
7
  "media-target": "validationInput",
8
+ "min": min,
9
+ "max": max,
8
10
  "min-message": t(".min", count: min),
9
11
  "max-message": t(".max", count: max),
10
12
  } %>
@@ -15,7 +15,7 @@ module Formstrap
15
15
  default_options = {
16
16
  data: {
17
17
  controller: "preview",
18
- "preview-url-value": options[:url]
18
+ "preview-url-value": options[:url]
19
19
  },
20
20
  type: nil
21
21
  }
@@ -1,3 +1,3 @@
1
1
  module Formstrap
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.2"
3
3
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontierdotbe/formstrap",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Bootstrap-powered Form Helpers",
5
5
  "module": "app/assets/javascripts/formstrap.js",
6
6
  "main": "app/assets/javascripts/formstrap.js",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: formstrap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jef Vlamings
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-03-18 00:00:00.000000000 Z
11
+ date: 2024-03-20 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: An extensive Bootstrap form library to power your Ruby On Rails application.
14
14
  email: