PageSourceSearch

https://railsblocks.com/assets/controllers/inline_edit_controller-…8515fd2affb99a7dcdc48047fd78e7d1e35d5820.js

js railsblocks.com collected 2026-09-25 20:23:34 UTC 2,807 bytes, 100 lines download raw bytes

1import { Controller } from "@hotwired/stimulus";
2import { Turbo } from "@hotwired/turbo-rails";
3
4export default class extends Controller {
5  static targets = ["display", "form", "input"]; // Targets for the display, form, and input fields
6  static values = {
7    showErrors: Boolean, // Whether to show errors
8    url: String, // URL for the form
9  };
10
11  connect() {
12    if (this.showErrorsValue) {
13      this.showEdit();
14    }
15    this.inputTarget.addEventListener("keydown", this.handleKeydown.bind(this));
16  }
17
18  disconnect() {
19    this.inputTarget.removeEventListener("keydown", this.handleKeydown.bind(this));
20  }
21
22  handleKeydown(event) {
23    if (event.key === "Escape") {
24      event.preventDefault();
25      this.hideEdit();
26    } else if (event.key === "Enter" && !event.shiftKey) {
27      event.preventDefault();
28      this.save(event);
29    }
30  }
31
32  showEdit() {
33    this.displayTarget.classList.add("hidden");
34    this.formTarget.classList.remove("hidden");
35    this.inputTarget.focus();
36    this.inputTarget.select();
37  }
38
39  hideEdit() {
40    this.displayTarget.classList.remove("hidden");
41    this.formTarget.classList.add("hidden");
42  }
43
44  save(event) {
45    event.preventDefault();
46
47    const value = this.inputTarget.value.trim();
48    if (!value) return;
49
50    if (this.hasUrlValue) {
51      // If URL value is provided, submit via AJAX
52      const formData = new FormData();
53      formData.append("title", value);
54
55      fetch(this.urlValue, {
56        method: "PATCH",
57        headers: {
58          "X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').content,
59          Accept: "text/vnd.turbo-stream.html",
60        },
61        body: formData,
62      })
63        .then((response) => {
64          if (response.ok) {
65            return response.text();
66          } else {
67            console.error("Failed to update");
68            throw new Error("Update failed");
69          }
70        })
71        .then((html) => {
72          // Let Turbo handle the stream response
73          const parser = new DOMParser();
74          const doc = parser.parseFromString(html, "text/html");
75          const streamElement = doc.querySelector("turbo-stream");
76          if (streamElement) {
77            Turbo.renderStreamMessage(html);
78          } else {
79            // Fallback to local update if no turbo stream response
80            this.updateDisplayText(value);
81            this.hideEdit();
82          }
83        })
84        .catch((error) => {
85          console.error("Error:", error);
86        });
87    } else {
88      // If no URL, just update the display text locally
89      this.updateDisplayText(value);
90      this.hideEdit();
91    }
92  }
93
94  updateDisplayText(value) {
95    const displayText = this.displayTarget.querySelector("span");
96    if (displayText) {
97      displayText.textContent = value;
98    }
99  }
100};

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.