PageSourceSearch

https://sifrcrm.up.railway.app/assets/controllers/form_builder_con…a1f9b8e3a350fe9525c1e4d2a834887e260e5077.js

js sifrcrm.up.railway.app collected 2026-10-03 12:15:38 UTC 4,879 bytes, 144 lines download raw bytes

1// app/javascript/controllers/form_builder_controller.js
2import { Controller } from "@hotwired/stimulus"
3
4export default class extends Controller {
5  static targets = ["fieldList", "previewContainer", "formTitle", "formDescription", "formType"]
6  static values = {
7    formId: String,
8    masjidSlug: String
9  }
10
11  connect() {
12    console.log("Form Builder controller connected")
13    this.setupSortable()
14    this.boundRefresh = this.refreshPreview.bind(this)
15    this.element.addEventListener("field-properties:fieldUpdated", this.boundRefresh)
16    this.element.addEventListener("info-block-options:fieldUpdated", this.boundRefresh)
17    this.element.addEventListener("waiver-field-options:fieldUpdated", this.boundRefresh)
18    this.element.addEventListener("tag-field-options:fieldUpdated", this.boundRefresh)
19    this.element.addEventListener("registrant-builder:fieldUpdated", this.boundRefresh)
20  }
21
22  disconnect() {
23    this.element.removeEventListener("field-properties:fieldUpdated", this.boundRefresh)
24    this.element.removeEventListener("info-block-options:fieldUpdated", this.boundRefresh)
25    this.element.removeEventListener("waiver-field-options:fieldUpdated", this.boundRefresh)
26    this.element.removeEventListener("tag-field-options:fieldUpdated", this.boundRefresh)
27    this.element.removeEventListener("registrant-builder:fieldUpdated", this.boundRefresh)
28  }
29  
30  setupSortable() {
31    if (typeof Sortable !== 'undefined') {
32      this.sortable = Sortable.create(this.fieldListTarget, {
33        animation: 150,
34        handle: '.drag-handle',
35        ghostClass: 'bg-gray-100',
36        // Add these options to fix the conflict
37        group: "form-fields",  // Give it a unique group name
38        draggable: "[data-field-id]", // Only make existing fields draggable
39        onEnd: this.updateFieldOrder.bind(this)
40      })
41    } else {
42      console.error('Sortable.js is not available. Please make sure it is properly imported.')
43    }
44  }
45
46  updateFieldOrder(event) {
47    // Get all field IDs in their new order
48    const fieldIds = Array.from(this.fieldListTarget.children).map(el => el.dataset.fieldId)
49    
50    // Send the new order to the server
51    fetch(`/forms/${this.formIdValue}/fields/reorder`, {
52      method: 'POST',
53      headers: {
54        'Content-Type': 'application/json',
55        'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
56      },
57      body: JSON.stringify({ field_ids: fieldIds })
58    })
59    .then(response => response.json())
60    .then(data => {
61      if (data.success) {
62        console.log('Field order updated successfully')
63        this.refreshPreview()
64      } else {
65        console.error('Failed to update field order:', data.errors || 'Unknown error')
66      }
67    })
68    .catch(error => {
69      console.error('Error updating field order:', error)
70    })
71  }
72  
73  updateFormTitle(event) {
74    this.updateFormAttribute('title', this.formTitleTarget.value)
75  }
76  
77  updateFormDescription(event) {
78    this.updateFormAttribute('formatted_description', this.formDescriptionTarget.value)
79  }
80  
81  updateFormAttribute(attribute, value) {
82    const formData = new FormData()
83    formData.append(`form[${attribute}]`, value)
84
85    fetch(`/forms/${this.formIdValue}`, {
86      method: 'PATCH',
87      headers: {
88        'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content,
89        'Accept': 'application/json'
90      },
91      body: formData
92    })
93    .then(response => response.json())
94    .then(data => {
95      if (!data.success) {
96        console.error(`Failed to update form ${attribute}`)
97      } else {
98        this.refreshPreview()
99      }
100    })
101  }
102
103  updateFormType(event) {
104    const formType = event.target.value
105    
106    fetch(`/forms/${this.formIdValue}`, {
107      method: 'PATCH',
108      headers: {
109        'Content-Type': 'application/json',
110        'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content,
111        'Accept': 'application/json'
112      },
113      body: JSON.stringify({
114        form: { form_type: formType }
115      })
116    })
117    .then(response => response.json())
118    .then(data => {
119      if (data.success) {
120        // Reload the page to update the contact fields section
121        window.location.reload()
122      } else {
123        console.error('Failed to update form type:', data.errors)
124      }
125    })
126    .catch(error => {
127      console.error('Error updating form type:', error)
128    })
129  }
130  
131  refreshPreview() {
132    const previewEl = document.getElementById('form_preview')
133    if (!previewEl) return
134
135    fetch(`/forms/${this.formIdValue}/preview_content`, {
136      headers: {
137        'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
138      }
139    })
140    .then(response => response.text())
141    .then(html => { previewEl.outerHTML = html })
142    .catch(error => console.error('Error refreshing preview:', error))
143  }
144};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.