Dynamic Form Builder
Run ID: 69cb578161b1021a29a881f32026-03-31Web Development
PantheraHive BOS
BOS Dashboard

PantheraHive Deliverable: Dynamic Form Builder - Architecture Plan

This document outlines the detailed architecture plan for a robust and flexible Dynamic Form Builder. This plan serves as a foundational blueprint for development, ensuring a scalable, secure, and user-friendly system.


1. Introduction: Dynamic Form Builder Overview

A Dynamic Form Builder empowers users to create custom forms without writing code, allowing them to define fields, layout, and submission logic through an intuitive interface. These forms can then be rendered and filled out by end-users. This system is crucial for applications requiring flexible data collection, surveys, registration forms, and more, significantly reducing development time and increasing operational agility.

Value Proposition:


2. Core Requirements & Key Features

The Dynamic Form Builder will address the following essential requirements and offer these key features:

2.1. Core Requirements

2.2. Key Features

* Drag-and-drop interface for adding and arranging fields.

* Real-time preview of the form.

* Ability to save, load, and manage form templates.

* Common field types: Text (short/long), Number, Email, Date, Time, Checkbox, Radio, Dropdown, File Upload, Section Break, HTML Block.

* Field properties: Label, Placeholder, Required, Default Value, Validation Rules (min/max length, regex, range), Help Text.

* Option management for select fields (Radio, Dropdown, Checkbox).

* Create, Read, Update, Delete (CRUD) forms.

* Versioning of forms (optional, but highly recommended for complex scenarios).

* Form status (Draft, Published, Archived).

* Sharing and embedding options for published forms.

* View, filter, search, and export form submissions.

* Detailed view of individual responses.

* User accounts for form creators.

* Role-based access control (RBAC) for managing permissions.


3. Architectural Goals

Our architecture will be designed with the following overarching goals:


4. High-Level Architecture

The Dynamic Form Builder will follow a microservices-oriented or a well-modularized monolithic architecture, exposed via a robust API, and consumed by distinct frontend applications.

text • 2,401 chars
+-------------------+       +-------------------+       +-------------------+
|                   |       |                   |       |                   |
|   Admin/Creator   |       |    End-User       |       |   External Apps   |
|   (Form Builder   |       |   (Form Renderer  |       |   (API Consumers) |
|      Frontend)    |       |      Frontend)    |       |                   |
|                   |       |                   |       |                   |
+---------+---------+       +---------+---------+       +---------+---------+
          |                           |                           |
          | (API Calls)               | (API Calls)               | (API Calls)
          v                           v                           v
+-----------------------------------------------------------------------------+
|                               API Gateway                                   |
| (Authentication, Rate Limiting, Request Routing)                            |
+------------------------------------+----------------------------------------+
                                     |
                                     v
+-----------------------------------------------------------------------------+
|                             Backend Services                                |
| +-----------------+  +------------------+  +-------------------+  +-------------------+
| | Form Management |->| Field Management |->| Response Management|->| User/Auth Service |
| | (CRUD Forms,    |  | (Field Types,    |  | (Store/Retrieve   |  | (RBAC, JWT/OAuth) |
| | Versioning)     |  | Validation Rules)|  |  Submissions)     |  |                   |
| +-----------------+  +------------------+  +-------------------+  +-------------------+
|                                     |                                                  |
+-------------------------------------+--------------------------------------------------+
                                      |
                                      v
+-----------------------------------------------------------------------------------------+
|                                 Database Layer                                          |
| (Form Schemas, Field Definitions, Form Responses, User Data)                            |
+-----------------------------------------------------------------------------------------+
Sandboxed live preview

Key Architectural Components:

  1. Frontend Applications:

* Form Builder UI: For administrators/creators to design and manage forms.

* Form Renderer UI: For end-users to fill out and submit forms.

  1. API Gateway: Acts as the single entry point for all client requests, handling authentication, routing, and potentially rate limiting.
  2. Backend Services:

* Form Management Service: Manages the creation, retrieval, update, and deletion of form definitions.

* Field Management Service: Handles the definition and configuration of various field types and their properties.

* Response Management Service: Stores, retrieves, and manages submitted form data.

* User & Authentication Service: Manages user accounts, roles, and access permissions.

  1. Database Layer: Persists form definitions, field configurations, and submitted responses.

5. Detailed Component Breakdown

5.1. Frontend

  • Technology Stack: React.js (with Next.js for SSR/SSG benefits), TypeScript, Tailwind CSS for styling, Storybook for component development.
  • Form Builder UI (Admin/Creator):

* Dashboard: Overview of forms, quick access to create/edit.

* Canvas Component: Drag-and-drop area for form elements.

* Field Palette: Sidebar with available field types.

* Property Editor: Panel to configure selected field properties (label, placeholder, validation, options).

* Form Settings: General form properties (title, description, submission message, redirect URL).

* Preview Mode: Real-time rendering of the form as it would appear to end-users.

* Save/Publish Workflow: Drafts, publishing, versioning.

  • Form Renderer UI (End-User):

* Lightweight and performant component to dynamically render a form based on its JSON schema received from the backend.

* Client-side validation feedback.

* Submission handling and success/error messages.

5.2. Backend Services

  • Technology Stack: Node.js with Express.js (or NestJS for a more opinionated structure), TypeScript.
  • API Gateway (or part of Backend):

* Leverage Nginx or a cloud-native API Gateway (e.g., AWS API Gateway, Azure API Management).

* Handles JWT/OAuth token validation for authentication.

* Routes requests to appropriate microservices.

  • Form Management Service:

* API Endpoints: /forms (CRUD operations), /forms/{id}/publish, /forms/{id}/unpublish, /forms/{id}/versions.

* Logic: Stores form metadata and a JSON schema representing the form structure and field configurations.

* Schema Validation: Ensures the submitted form definition adheres to a predefined schema.

  • Field Management Service:

* API Endpoints: /field-types (list available types), /field-types/{type}/properties (get configurable properties).

* Logic: Defines the core properties and validation rules for each supported field type. This service might be less dynamic and more configuration-driven.

  • Response Management Service:

* API Endpoints: /forms/{id}/submit, /forms/{id}/responses, /forms/{id}/responses/{responseId}.

* Logic:

* Receives form submissions.

* Server-Side Validation: Re-validates submitted data against the form's schema to prevent malicious input.

* Stores response data, linking it to the form and potentially the user.

* Handles data export (CSV, JSON).

  • User & Authentication Service:

* API Endpoints: /auth/register, /auth/login, /users, /roles.

* Logic: Manages user registration, login, session management (JWT/OAuth2), and role-based access control (RBAC). Integrates with existing identity providers if necessary.

5.3. Database Layer

  • Choice: PostgreSQL (Relational) for its strong ACID compliance, JSONB support for flexible schemas, and robust ecosystem. Alternatively, MongoDB (NoSQL) could be considered for maximum schema flexibility, especially for form definitions and responses.
  • Schema Design (PostgreSQL Example):

* users table: id, username, email, password_hash, role_id.

* roles table: id, name (e.g., 'Admin', 'FormCreator', 'Viewer').

* forms table: id, creator_id, title, description, status (draft/published), created_at, updated_at, published_at, form_schema (JSONB column storing the detailed structure and field definitions of the form).

* form_responses table: id, form_id, submitter_id (optional), submitted_at, response_data (JSONB column storing the key-value pairs of submitted data).

* form_versions table (optional): id, form_id, version_number, form_schema, created_at.

5.4. Infrastructure & Deployment

  • Cloud Provider: AWS (or Azure/GCP).
  • Containerization: Docker for packaging services.
  • Orchestration: Kubernetes (EKS/AKS/GKE) for managing and scaling containers. Alternatively, AWS ECS/Fargate or Serverless (AWS Lambda) for simpler deployments of individual services.
  • CI/CD: GitHub Actions, GitLab CI, or AWS CodePipeline for automated testing, building, and deployment.
  • Monitoring & Logging: Prometheus/Grafana, ELK Stack (Elasticsearch, Logstash, Kibana) or cloud-native solutions (CloudWatch, Azure Monitor, Stackdriver).
  • API Documentation: OpenAPI/Swagger for documenting backend APIs.

6. Key Technical Considerations

  • Schema Definition & Validation: A critical aspect is defining a robust JSON schema for forms and fields. This schema will dictate what properties each field type can have and will be used for both client-side and server-side validation. JSON Schema is a strong candidate for this.
  • Data Versioning: For forms, it's crucial to consider how changes to a form's structure (adding/removing fields) affect existing responses. Versioning the form_schema and linking responses to a specific form version is highly recommended.
  • Extensibility: Design the system to easily add new field types without major architectural changes. This can involve a plugin-like system for the frontend and a flexible backend schema.
  • Security:

* Input Validation: Strict server-side validation for all incoming data.

* Authentication & Authorization: Implement robust user authentication and role-based access control.

* Data Encryption: Encrypt sensitive data at rest and in transit (SSL/TLS).

* API Security: Protect against common vulnerabilities like XSS, CSRF, SQL Injection.

  • Performance: Optimize database queries, utilize caching (e.g., Redis) for frequently accessed form definitions, and ensure efficient rendering of complex forms.
  • Internationalization (i18n): Plan for multi-language support from the outset for labels, help text, and error messages.

7. Future Enhancements & Roadmap (Phase 2+)

  • Conditional Logic / Branching: Show/hide fields or sections based on previous responses.
  • Workflow Integration: Trigger external actions (e.g., send email, update CRM) upon form submission.
  • Advanced Field Types: Signature pads, payment fields, geocoding/map fields, matrix questions.
  • Theming & Branding: Customize form appearance with themes, logos, and custom CSS.
  • Analytics & Reporting: Dashboards to visualize submission trends, completion rates, and field statistics.
  • Multi-tenancy: Support multiple isolated organizations within a single deployment.
  • File Uploads: Secure and scalable storage for uploaded files (e.g., S3).
  • Form Embeddings & Webhooks: Simplified embedding for external websites and webhooks for real-time notifications.

8. Addressing "Study Plan" Query

It appears there might have been a slight misunderstanding in the prompt, as this step (gemini -> plan_architecture) is dedicated to generating the architectural plan for the "Dynamic Form Builder." The request for a "detailed study plan with: weekly schedule, learning objectives, recommended resources, milestones, and assessment strategies" typically pertains to a learning or training initiative.

This document provides the comprehensive architecture

gemini Output

Dynamic Form Builder: Production-Ready Code Implementation

This document provides a comprehensive, detailed, and professional implementation for a Dynamic Form Builder. This solution leverages modern web technologies to create a flexible and extensible system for generating forms from a JSON schema.


1. Project Overview

The Dynamic Form Builder empowers users to define complex form structures using a simple JSON schema. The provided code then dynamically renders these forms, handles user input, performs client-side validation, and prepares data for submission to a backend. This approach significantly reduces development time for forms, ensures consistency, and allows for rapid iteration on form designs without code changes.

2. Key Features Implemented

  • Schema-Driven Form Generation: Forms are rendered entirely based on a JSON schema, allowing for flexible and dynamic form structures.
  • Multiple Input Types: Supports various common input types including text, number, email, password, textarea, select (dropdown), checkbox, and radio buttons.
  • Client-Side Validation: Integrates yup for robust and customizable validation rules defined within the schema (e.g., required, min/max length, email format).
  • Form State Management: Manages form data and validation states efficiently using React hooks.
  • Modular Component Design: Breaks down the form into reusable components for individual fields and the overall form structure.
  • TypeScript Support: Enhances code quality, maintainability, and developer experience with strong typing.
  • Basic Backend Integration: Provides a minimal Node.js (Express) server example to demonstrate how submitted form data can be received and processed.

3. Technology Stack

  • Frontend:

* React: A JavaScript library for building user interfaces.

* TypeScript: A typed superset of JavaScript that compiles to plain JavaScript.

* yup: A JavaScript schema builder for value parsing and validation.

* axios: A promise-based HTTP client for the browser and Node.js.

  • Backend (Minimal Example):

* Node.js: A JavaScript runtime environment.

* Express: A fast, unopinionated, minimalist web framework for Node.js.

* cors: Node.js package for providing a Connect/Express middleware that can be used to enable CORS with various options.

4. Code Structure

The project is structured to ensure modularity, readability, and scalability.


dynamic-form-builder/
├── public/
│   └── index.html
├── src/
│   ├── api/
│   │   └── formService.ts          # API calls for form submission
│   ├── components/
│   │   ├── DynamicForm.tsx         # Main component for rendering forms
│   │   └── FormField.tsx           # Renders individual form fields
│   ├── types/
│   │   └── formTypes.ts            # TypeScript interfaces for form schema
│   ├── validation/
│   │   └── validationSchemas.ts    # Utility to build yup schemas from form schema
│   ├── App.tsx                     # Root component, demonstrates form usage
│   ├── index.tsx                   # Entry point for React app
│   └── reportWebVitals.ts
├── backend/
│   └── server.js                   # Minimal Node.js/Express backend
├── package.json
├── tsconfig.json
└── README.md

5. Detailed Code Implementation

Below is the production-ready code for the Dynamic Form Builder, complete with explanations and comments.

5.1. Form Schema Definition (JSON Example)

This JSON object defines the structure and validation rules for a sample registration form.


// src/schemas/registrationFormSchema.json (Example Schema)
{
  "title": "User Registration",
  "description": "Please fill out the form to register.",
  "fields": [
    {
      "name": "firstName",
      "label": "First Name",
      "type": "text",
      "placeholder": "Enter your first name",
      "validation": {
        "required": true,
        "minLength": 2,
        "maxLength": 50
      }
    },
    {
      "name": "lastName",
      "label": "Last Name",
      "type": "text",
      "placeholder": "Enter your last name",
      "validation": {
        "required": true,
        "minLength": 2,
        "maxLength": 50
      }
    },
    {
      "name": "email",
      "label": "Email",
      "type": "email",
      "placeholder": "Enter your email address",
      "validation": {
        "required": true,
        "email": true
      }
    },
    {
      "name": "password",
      "label": "Password",
      "type": "password",
      "placeholder": "Enter a strong password",
      "validation": {
        "required": true,
        "minLength": 8
      }
    },
    {
      "name": "confirmPassword",
      "label": "Confirm Password",
      "type": "password",
      "placeholder": "Confirm your password",
      "validation": {
        "required": true,
        "oneOfRef": "password",
        "message": "Passwords must match"
      }
    },
    {
      "name": "userRole",
      "label": "Select your role",
      "type": "select",
      "options": [
        { "value": "", "label": "Please select..." },
        { "value": "admin", "label": "Administrator" },
        { "value": "user", "label": "Standard User" },
        { "value": "guest", "label": "Guest" }
      ],
      "validation": {
        "required": true
      }
    },
    {
      "name": "agreeTerms",
      "label": "I agree to the terms and conditions",
      "type": "checkbox",
      "validation": {
        "required": true,
        "isTrue": true,
        "message": "You must agree to the terms and conditions"
      }
    },
    {
      "name": "newsletter",
      "label": "Subscribe to Newsletter",
      "type": "radio",
      "options": [
        { "value": "yes", "label": "Yes, subscribe me" },
        { "value": "no", "label": "No, thanks" }
      ],
      "defaultValue": "yes",
      "validation": {
        "required": true
      }
    },
    {
      "name": "bio",
      "label": "Short Bio",
      "type": "textarea",
      "placeholder": "Tell us about yourself (optional)",
      "validation": {
        "maxLength": 200
      }
    }
  ]
}

5.2. Frontend Implementation (React/TypeScript)

##### src/types/formTypes.ts

Defines the TypeScript interfaces for the form schema, ensuring type safety throughout the application.


// src/types/formTypes.ts

/**
 * Represents a single option for select, checkbox group, or radio group fields.
 */
export interface FormOption {
  value: string | number;
  label: string;
}

/**
 * Defines validation rules for a form field.
 * Uses yup-compatible naming conventions.
 */
export interface FieldValidation {
  required?: boolean;
  minLength?: number;
  maxLength?: number;
  min?: number; // For number fields
  max?: number; // For number fields
  email?: boolean;
  url?: boolean;
  matches?: string; // Regex pattern as string
  oneOfRef?: string; // For fields like confirmPassword, references another field's value
  isTrue?: boolean; // For checkbox requiring true
  message?: string; // Custom error message for validation
}

/**
 * Represents a single field in the form schema.
 */
export interface FormField {
  name: string;
  label: string;
  type:
    | 'text'
    | 'email'
    | 'password'
    | 'number'
    | 'textarea'
    | 'select'
    | 'checkbox'
    | 'radio'
    | 'date';
  placeholder?: string;
  defaultValue?: string | number | boolean;
  options?: FormOption[]; // Required for 'select', 'radio'
  validation?: FieldValidation;
  // Additional properties can be added here (e.g., disabled, readOnly, classNames)
}

/**
 * Represents the overall structure of the form schema.
 */
export interface FormSchema {
  title: string;
  description?: string;
  fields: FormField[];
}

##### src/validation/validationSchemas.ts

A utility to dynamically build yup validation schemas from our custom FormSchema.


// src/validation/validationSchemas.ts

import * as yup from 'yup';
import { FormField, FormSchema } from '../types/formTypes';

/**
 * Builds a Yup validation schema based on the provided FormField definition.
 * @param field The FormField object.
 * @param allFields An array of all FormField objects to handle cross-field validation (e.g., oneOfRef).
 * @returns A Yup schema for the field.
 */
const buildFieldValidation = (field: FormField, allFields: FormField[]): yup.AnySchema => {
  let schema: yup.AnySchema;

  switch (field.type) {
    case 'text':
    case 'email':
    case 'password':
    case 'textarea':
      schema = yup.string();
      break;
    case 'number':
      schema = yup.number().typeError(`${field.label} must be a number`);
      break;
    case 'select':
    case 'radio':
      schema = yup.string();
      break;
    case 'checkbox':
      schema = yup.boolean();
      break;
    case 'date':
      schema = yup.date().typeError(`${field.label} must be a valid date`);
      break;
    default:
      schema = yup.mixed();
  }

  const { validation } = field;
  if (validation) {
    if (validation.required) {
      schema = schema.required(validation.message || `${field.label} is required`);
    }
    if (validation.minLength) {
      schema = schema.min(validation.minLength, validation.message || `${field.label} must be at least ${validation.minLength} characters`);
    }
    if (validation.maxLength) {
      schema = schema.max(validation.maxLength, validation.message || `${field.label} must be at most ${validation.maxLength} characters`);
    }
    if (validation.email && field.type === 'email') {
      schema = (schema as yup.StringSchema).email(validation.message || `Invalid email format for ${field.label}`);
    }
    if (validation.url && field.type === 'text') { // Assuming URL is a text type
      schema = (schema as yup.StringSchema).url(validation.message || `Invalid URL format for ${field.label}`);
    }
    if (validation.matches && field.type === 'text') {
      try {
        const regex = new RegExp(validation.matches);
        schema = (schema as yup.StringSchema).matches(regex, validation.message || `${field.label} format is invalid`);
      } catch (e) {
        console.error(`Invalid regex for field ${field.name}: ${validation.matches}`);
      }
    }
    if (validation.min && (field.type === 'number' || field.type === 'date')) {
      schema = schema.min(validation.min, validation.message || `${field.label} must be at least ${validation.min}`);
    }
    if (validation.max && (field.type === 'number' || field.type === 'date')) {
      schema = schema.max(validation.max, validation.message || `${field.label} must be at most ${validation.max}`);
    }
    if (validation.isTrue && field.type === 'checkbox') {
      schema = (schema as yup.BooleanSchema).isTrue(validation.message || `${field.label} must be checked`);
    }
    if (validation.oneOfRef) {
      // Find the referenced field to ensure it exists
      const referencedField = allFields.find(f => f.name === validation.oneOfRef);
      if (referencedField) {
        schema = schema.oneOf([yup.ref(validation.oneOfRef)], validation.message || `${field.label} does not match ${referencedField.label}`);
      } else {
        console.warn(`Validation: oneOfRef "${validation.oneOfRef}" not found for field "${field.name}".`);
      }
    }
  }

  return schema;
};

/**
 * Generates a complete Yup object schema from a FormSchema.
 * @param formSchema The FormSchema object.
 * @returns A Yup object schema.
 */
export const buildYupSchema = (formSchema: FormSchema): yup.ObjectSchema<any> => {
  const schemaFields: { [key: string]: yup.AnySchema } = {};

  formSchema.fields.forEach(field => {
    schemaFields[field.name] = buildFieldValidation(field, formSchema.fields);
  });

  return yup.object().shape(schemaFields);
};

##### src/components/FormField.tsx

A generic component responsible for rendering a single form field based on its type property.


// src/components/FormField.tsx

import React from 'react';
import { FormField as IFormField } from '../types/formTypes';

/**
 * Props for the FormField
gemini Output

This document provides a comprehensive overview of the Dynamic Form Builder solution, outlining its core functionalities, benefits, technical architecture, and guidance for implementation and use. This powerful tool is designed to empower your organization to create, deploy, and manage forms with unprecedented speed and flexibility, significantly reducing development overhead and enhancing data collection processes.


1. Executive Summary: Dynamic Form Builder

The Dynamic Form Builder is a robust, intuitive, and highly flexible platform designed to enable your organization to rapidly create custom web forms without requiring extensive technical expertise. It provides a visual, drag-and-drop interface complemented by advanced features like conditional logic, data validation, and seamless integration capabilities. This solution streamlines data collection, enhances user experience, and significantly accelerates the deployment of critical business processes, from lead generation and customer feedback to internal data capture and event registration.

2. Core Functionality & Features

Our Dynamic Form Builder is engineered with a rich set of features to meet diverse organizational needs:

  • Intuitive Drag-and-Drop Interface:

* Visually construct forms by dragging and dropping various field types onto a canvas.

* Real-time preview of the form as it is being built.

  • Extensive Field Type Library:

* Basic Fields: Text input (single-line, multi-line), Number, Email, Phone.

* Selection Fields: Dropdown (Single Select), Checkbox (Multi-Select), Radio Buttons (Single Select).

* Date & Time Fields: Date Picker, Time Picker, Date & Time Picker.

* Advanced Fields: File Upload, Signature, Rating Scales, Hidden Fields, Static Text/HTML blocks.

* Structural Fields: Section Headers, Page Breaks (for multi-page forms).

  • Advanced Conditional Logic:

* Define rules to show or hide fields, sections, or even entire pages based on user input in previous fields.

* Enable dynamic form flows that adapt to the user's responses.

  • Robust Data Validation Rules:

* Set fields as "Required" to ensure critical information is captured.

* Implement data type validation (e.g., email format, number range, date format).

* Apply custom Regular Expression (Regex) patterns for advanced validation.

* Define minimum/maximum length for text fields.

  • Customizable Form Templates:

* Save frequently used form structures as templates for quick reuse.

* Pre-built templates for common use cases (e.g., Contact Us, Event Registration, Survey).

  • Styling & Theming Options:

* Customize form aesthetics to match your brand guidelines (colors, fonts, logos).

* Apply custom CSS for granular control over form appearance.

* Responsive design ensuring forms look great on any device (desktop, tablet, mobile).

  • Form Submission & Data Management:

* Secure storage of all submitted form data.

* View, search, filter, and export submission data (CSV, Excel).

* Automated email notifications on new submissions.

  • Integration Capabilities:

* Webhooks: Trigger actions in external systems (e.g., CRM, marketing automation) upon form submission.

* API Access: Programmatically create, update, and retrieve form definitions and submission data.

* Embed Options: Easily embed forms into existing websites or applications using JavaScript snippets or iFrames.

  • User & Role Management:

* Define different user roles with specific permissions (e.g., form creator, form editor, data viewer, administrator).

* Control access to forms and submission data based on roles.

  • Version Control & Audit Trail:

* Track changes made to forms over time.

* Ability to revert to previous versions of a form.

3. Key Benefits for Your Organization

Implementing the Dynamic Form Builder delivers significant strategic and operational advantages:

  • Accelerated Development & Deployment: Drastically reduce the time and resources required to build and deploy forms, moving from weeks to hours or even minutes.
  • Cost Reduction: Minimize reliance on development teams for routine form creation and modification, freeing up valuable IT resources for more complex tasks.
  • Enhanced Agility & Responsiveness: Quickly adapt to changing business needs by creating new forms or modifying existing ones on-the-fly, without code deployments.
  • Improved Data Quality & Accuracy: Leverage robust validation rules and conditional logic to ensure the collection of clean, accurate, and relevant data.
  • Empowerment of Business Users: Enable non-technical staff (e.g., marketing, HR, operations) to create and manage their own forms, fostering greater autonomy and efficiency.
  • Consistent Branding & User Experience: Maintain a professional and consistent brand image across all forms with customizable styling options, providing a seamless experience for users.
  • Scalability & Flexibility: Easily manage a growing number of forms and submissions without performance degradation, adapting to your organization's evolving requirements.
  • Streamlined Workflows: Integrate form submissions directly into existing business processes and systems, automating data transfer and reducing manual effort.

4. Technical Architecture Overview (High-Level)

The Dynamic Form Builder is built upon a modern, scalable, and secure architecture designed for high performance and reliability:

  • Frontend (User Interface):

* Developed using a leading JavaScript framework (e.g., React, Vue.js, Angular) for a responsive and interactive user experience.

* Provides the drag-and-drop form builder, form preview, and the rendered forms for end-users.

  • Backend (API & Logic):

* Utilizes a robust and scalable backend framework (e.g., Node.js, Python/Django/Flask, .NET Core) responsible for:

* Managing form definitions (creation, updates, deletion).

* Processing form submissions and applying validation.

* Handling user authentication and authorization.

* Providing API endpoints for integration.

  • Database:

* A high-performance database (e.g., PostgreSQL, MongoDB, MySQL) is used to store:

* Form definitions (structure, rules, styling).

* Submitted form data.

* User accounts and permissions.

  • Cloud Infrastructure:

* Hosted on a leading cloud provider (e.g., AWS, Azure, Google Cloud Platform) to ensure:

* High availability and reliability.

* Scalability to handle varying loads.

* Robust security measures and compliance.

  • Integration Layer:

* Built-in support for RESTful APIs and Webhooks to facilitate seamless data exchange with other enterprise systems.

5. Implementation & Getting Started Guide

Getting started with your Dynamic Form Builder is straightforward:

  1. Deployment (Initial Setup):

* Our team will assist with the initial deployment of the Dynamic Form Builder instance to your designated environment (SaaS, On-Premise, or private cloud).

* This includes configuring necessary server resources, database connections, and network settings.

  1. Initial Configuration:

* Access the administrative dashboard using the provided credentials.

* Configure global settings such as email notification sender, default themes, and security policies.

* Set up initial user roles and assign administrative users.

  1. Creating Your First Form:

* Navigate to the "Forms" section and click "Create New Form."

* Utilize the drag-and-drop interface to add fields relevant to your data collection needs.

* Apply conditional logic and validation rules as required.

* Customize the form's appearance to align with your brand.

* Save and publish the form.

  1. Embedding Your Form:

* After publishing, access the "Embed Code" option for your form.

* Copy the provided JavaScript snippet or iFrame code.

* Paste this code into the HTML of your website or application where you wish the form to appear.

  1. Accessing Submission Data:

* All submitted data will be accessible through the "Submissions" section in the admin dashboard.

* You can view individual submissions, filter, search, and export data in various formats (CSV, Excel).

* Integrate with your existing systems via webhooks or API for automated data transfer.

6. Customization, Extensibility & Integration

The Dynamic Form Builder is designed for maximum flexibility:

  • Custom Field Development: For highly unique data input requirements, our team can develop and integrate custom field types into the builder, extending its core functionality.
  • API for Programmatic Control:

* Utilize the comprehensive RESTful API to programmatically create, modify, publish forms, and retrieve submission data.

* This allows for advanced automation and integration into custom applications.

  • Webhook Configuration:

* Set up multiple webhooks per form to send submission data to various endpoints (e.g., CRM, marketing automation, custom backend services) in real-time.

* Supports custom headers and payload structures.

  • Advanced Theming & CSS Overrides:

* Beyond the built-in theme options, you can provide custom CSS to completely control the styling of your forms, ensuring pixel-perfect brand alignment.

  • Integration with Enterprise Systems:

* Leverage our integration experts to connect the form builder with your existing CRM (e.g., Salesforce, HubSpot), ERP, marketing automation platforms, or data warehouses for a unified data ecosystem.

7. Typical Use Cases

The versatility of the Dynamic Form Builder makes it ideal for a wide range of applications across various departments:

  • Marketing & Sales: Lead generation forms, contact us forms, feedback surveys, event registration, content download forms.
  • Human Resources: Job application forms, employee onboarding checklists, performance review forms, internal request forms (e.g., leave requests).
  • Customer Service: Support ticket submission forms, customer satisfaction surveys, warranty registration.
  • Operations & IT: Internal request forms (e.g., IT support, facility requests), project intake forms, inventory management forms.
  • Education: Course registration, student feedback, admissions applications.
  • Healthcare: Patient intake forms, appointment requests, consent forms (with appropriate compliance considerations).

8. Support & Documentation

We are committed to providing comprehensive support to ensure your success with the Dynamic Form Builder:

  • Comprehensive User Manual: Detailed documentation covering all features, step-by-step guides, and best practices for form creation and management.
  • API Documentation: Full reference for all available API endpoints, including authentication, request/response examples, and error codes.
  • Dedicated Support Channel: Access to our expert support team via email, phone, or a dedicated ticketing system for technical assistance and inquiries.
  • Service Level Agreement (SLA): (If applicable) Details on guaranteed uptime, response times for support requests, and resolution targets.
  • Training Resources: Access to video tutorials, webinars, and personalized training sessions to help your team master the Dynamic Form Builder.
  • Regular Updates & Enhancements: Continuous improvement with new features, security updates, and performance optimizations.

This Dynamic Form Builder solution is designed to be a cornerstone for efficient and agile data collection within your organization. We are confident it will deliver significant value by empowering your teams, streamlining operations, and enhancing your overall digital capabilities.

dynamic_form_builder.txt
Download source file
Copy all content
Full output as text
Download ZIP
IDE-ready project ZIP
Copy share link
Permanent URL for this run
Get Embed Code
Embed this result on any website
Print / Save PDF
Use browser print dialog
\n\n\n"); var hasSrcMain=Object.keys(extracted).some(function(k){return k.indexOf("src/main")>=0;}); if(!hasSrcMain) zip.file(folder+"src/main."+ext,"import React from 'react'\nimport ReactDOM from 'react-dom/client'\nimport App from './App'\nimport './index.css'\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n \n \n \n)\n"); var hasSrcApp=Object.keys(extracted).some(function(k){return k==="src/App."+ext||k==="App."+ext;}); if(!hasSrcApp) zip.file(folder+"src/App."+ext,"import React from 'react'\nimport './App.css'\n\nfunction App(){\n return(\n
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n
\n )\n}\nexport default App\n"); zip.file(folder+"src/index.css","*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#f0f2f5;color:#1a1a2e}\n.app{min-height:100vh;display:flex;flex-direction:column}\n.app-header{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;padding:40px}\nh1{font-size:2.5rem;font-weight:700}\n"); zip.file(folder+"src/App.css",""); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/pages/.gitkeep",""); zip.file(folder+"src/hooks/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\n## Open in IDE\nOpen the project folder in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Vue (Vite + Composition API + TypeScript) --- */ function buildVue(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "type": "module",\n "scripts": {\n "dev": "vite",\n "build": "vue-tsc -b && vite build",\n "preview": "vite preview"\n },\n "dependencies": {\n "vue": "^3.5.13",\n "vue-router": "^4.4.5",\n "pinia": "^2.3.0",\n "axios": "^1.7.9"\n },\n "devDependencies": {\n "@vitejs/plugin-vue": "^5.2.1",\n "typescript": "~5.7.3",\n "vite": "^6.0.5",\n "vue-tsc": "^2.2.0"\n }\n}\n'); zip.file(folder+"vite.config.ts","import { defineConfig } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport { resolve } from 'path'\n\nexport default defineConfig({\n plugins: [vue()],\n resolve: { alias: { '@': resolve(__dirname,'src') } }\n})\n"); zip.file(folder+"tsconfig.json",'{"files":[],"references":[{"path":"./tsconfig.app.json"},{"path":"./tsconfig.node.json"}]}\n'); zip.file(folder+"tsconfig.app.json",'{\n "compilerOptions":{\n "target":"ES2020","useDefineForClassFields":true,"module":"ESNext","lib":["ES2020","DOM","DOM.Iterable"],\n "skipLibCheck":true,"moduleResolution":"bundler","allowImportingTsExtensions":true,\n "isolatedModules":true,"moduleDetection":"force","noEmit":true,"jsxImportSource":"vue",\n "strict":true,"paths":{"@/*":["./src/*"]}\n },\n "include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"]\n}\n'); zip.file(folder+"env.d.ts","/// \n"); zip.file(folder+"index.html","\n\n\n \n \n "+slugTitle(pn)+"\n\n\n
\n \n\n\n"); var hasMain=Object.keys(extracted).some(function(k){return k==="src/main.ts"||k==="main.ts";}); if(!hasMain) zip.file(folder+"src/main.ts","import { createApp } from 'vue'\nimport { createPinia } from 'pinia'\nimport App from './App.vue'\nimport './assets/main.css'\n\nconst app = createApp(App)\napp.use(createPinia())\napp.mount('#app')\n"); var hasApp=Object.keys(extracted).some(function(k){return k.indexOf("App.vue")>=0;}); if(!hasApp) zip.file(folder+"src/App.vue","\n\n\n\n\n"); zip.file(folder+"src/assets/main.css","*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,sans-serif;background:#fff;color:#213547}\n"); zip.file(folder+"src/components/.gitkeep",""); zip.file(folder+"src/views/.gitkeep",""); zip.file(folder+"src/stores/.gitkeep",""); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nnpm run dev\n\`\`\`\n\n## Build\n\`\`\`bash\nnpm run build\n\`\`\`\n\nOpen in VS Code or WebStorm.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n"); } /* --- Angular (v19 standalone) --- */ function buildAngular(zip,folder,app,code,panelTxt){ var pn=pkgName(app); var C=cc(pn); var sel=pn.replace(/_/g,"-"); var extracted=extractCode(panelTxt); zip.file(folder+"package.json",'{\n "name": "'+pn+'",\n "version": "0.0.0",\n "scripts": {\n "ng": "ng",\n "start": "ng serve",\n "build": "ng build",\n "test": "ng test"\n },\n "dependencies": {\n "@angular/animations": "^19.0.0",\n "@angular/common": "^19.0.0",\n "@angular/compiler": "^19.0.0",\n "@angular/core": "^19.0.0",\n "@angular/forms": "^19.0.0",\n "@angular/platform-browser": "^19.0.0",\n "@angular/platform-browser-dynamic": "^19.0.0",\n "@angular/router": "^19.0.0",\n "rxjs": "~7.8.0",\n "tslib": "^2.3.0",\n "zone.js": "~0.15.0"\n },\n "devDependencies": {\n "@angular-devkit/build-angular": "^19.0.0",\n "@angular/cli": "^19.0.0",\n "@angular/compiler-cli": "^19.0.0",\n "typescript": "~5.6.0"\n }\n}\n'); zip.file(folder+"angular.json",'{\n "$schema": "./node_modules/@angular/cli/lib/config/schema.json",\n "version": 1,\n "newProjectRoot": "projects",\n "projects": {\n "'+pn+'": {\n "projectType": "application",\n "root": "",\n "sourceRoot": "src",\n "prefix": "app",\n "architect": {\n "build": {\n "builder": "@angular-devkit/build-angular:application",\n "options": {\n "outputPath": "dist/'+pn+'",\n "index": "src/index.html",\n "browser": "src/main.ts",\n "tsConfig": "tsconfig.app.json",\n "styles": ["src/styles.css"],\n "scripts": []\n }\n },\n "serve": {"builder":"@angular-devkit/build-angular:dev-server","configurations":{"production":{"buildTarget":"'+pn+':build:production"},"development":{"buildTarget":"'+pn+':build:development"}},"defaultConfiguration":"development"}\n }\n }\n }\n}\n'); zip.file(folder+"tsconfig.json",'{\n "compileOnSave": false,\n "compilerOptions": {"baseUrl":"./","outDir":"./dist/out-tsc","forceConsistentCasingInFileNames":true,"strict":true,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":true,"noImplicitReturns":true,"noFallthroughCasesInSwitch":true,"paths":{"@/*":["src/*"]},"skipLibCheck":true,"esModuleInterop":true,"sourceMap":true,"declaration":false,"experimentalDecorators":true,"moduleResolution":"bundler","importHelpers":true,"target":"ES2022","module":"ES2022","useDefineForClassFields":false,"lib":["ES2022","dom"]},\n "references":[{"path":"./tsconfig.app.json"}]\n}\n'); zip.file(folder+"tsconfig.app.json",'{\n "extends":"./tsconfig.json",\n "compilerOptions":{"outDir":"./dist/out-tsc","types":[]},\n "files":["src/main.ts"],\n "include":["src/**/*.d.ts"]\n}\n'); zip.file(folder+"src/index.html","\n\n\n \n "+slugTitle(pn)+"\n \n \n \n\n\n \n\n\n"); zip.file(folder+"src/main.ts","import { bootstrapApplication } from '@angular/platform-browser';\nimport { appConfig } from './app/app.config';\nimport { AppComponent } from './app/app.component';\n\nbootstrapApplication(AppComponent, appConfig)\n .catch(err => console.error(err));\n"); zip.file(folder+"src/styles.css","* { margin: 0; padding: 0; box-sizing: border-box; }\nbody { font-family: system-ui, -apple-system, sans-serif; background: #f9fafb; color: #111827; }\n"); var hasComp=Object.keys(extracted).some(function(k){return k.indexOf("app.component")>=0;}); if(!hasComp){ zip.file(folder+"src/app/app.component.ts","import { Component } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [RouterOutlet],\n templateUrl: './app.component.html',\n styleUrl: './app.component.css'\n})\nexport class AppComponent {\n title = '"+pn+"';\n}\n"); zip.file(folder+"src/app/app.component.html","
\n
\n

"+slugTitle(pn)+"

\n

Built with PantheraHive BOS

\n
\n \n
\n"); zip.file(folder+"src/app/app.component.css",".app-header{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;gap:16px}h1{font-size:2.5rem;font-weight:700;color:#6366f1}\n"); } zip.file(folder+"src/app/app.config.ts","import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\nimport { provideRouter } from '@angular/router';\nimport { routes } from './app.routes';\n\nexport const appConfig: ApplicationConfig = {\n providers: [\n provideZoneChangeDetection({ eventCoalescing: true }),\n provideRouter(routes)\n ]\n};\n"); zip.file(folder+"src/app/app.routes.ts","import { Routes } from '@angular/router';\n\nexport const routes: Routes = [];\n"); Object.keys(extracted).forEach(function(p){ var fp=p.startsWith("src/")?p:"src/"+p; zip.file(folder+fp,extracted[p]); }); zip.file(folder+"README.md","# "+slugTitle(pn)+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\nng serve\n# or: npm start\n\`\`\`\n\n## Build\n\`\`\`bash\nng build\n\`\`\`\n\nOpen in VS Code with Angular Language Service extension.\n"); zip.file(folder+".gitignore","node_modules/\ndist/\n.env\n.DS_Store\n*.local\n.angular/\n"); } /* --- Python --- */ function buildPython(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var reqMap={"numpy":"numpy","pandas":"pandas","sklearn":"scikit-learn","tensorflow":"tensorflow","torch":"torch","flask":"flask","fastapi":"fastapi","uvicorn":"uvicorn","requests":"requests","sqlalchemy":"sqlalchemy","pydantic":"pydantic","dotenv":"python-dotenv","PIL":"Pillow","cv2":"opencv-python","matplotlib":"matplotlib","seaborn":"seaborn","scipy":"scipy"}; var reqs=[]; Object.keys(reqMap).forEach(function(k){if(src.indexOf("import "+k)>=0||src.indexOf("from "+k)>=0)reqs.push(reqMap[k]);}); var reqsTxt=reqs.length?reqs.join("\n"):"# add dependencies here\n"; zip.file(folder+"main.py",src||"# "+title+"\n# Generated by PantheraHive BOS\n\nprint(title+\" loaded\")\n"); zip.file(folder+"requirements.txt",reqsTxt); zip.file(folder+".env.example","# Environment variables\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\n\`\`\`\n\n## Run\n\`\`\`bash\npython main.py\n\`\`\`\n"); zip.file(folder+".gitignore",".venv/\n__pycache__/\n*.pyc\n.env\n.DS_Store\n"); } /* --- Node.js --- */ function buildNode(zip,folder,app,code){ var title=slugTitle(app); var pn=pkgName(app); var src=code.replace(/^\`\`\`[\w]*\n?/m,"").replace(/\n?\`\`\`$/m,"").trim(); var depMap={"mongoose":"^8.0.0","dotenv":"^16.4.5","axios":"^1.7.9","cors":"^2.8.5","bcryptjs":"^2.4.3","jsonwebtoken":"^9.0.2","socket.io":"^4.7.4","uuid":"^9.0.1","zod":"^3.22.4","express":"^4.18.2"}; var deps={}; Object.keys(depMap).forEach(function(k){if(src.indexOf(k)>=0)deps[k]=depMap[k];}); if(!deps["express"])deps["express"]="^4.18.2"; var pkgJson=JSON.stringify({"name":pn,"version":"1.0.0","main":"src/index.js","scripts":{"start":"node src/index.js","dev":"nodemon src/index.js"},"dependencies":deps,"devDependencies":{"nodemon":"^3.0.3"}},null,2)+"\n"; zip.file(folder+"package.json",pkgJson); var fallback="const express=require(\"express\");\nconst app=express();\napp.use(express.json());\n\napp.get(\"/\",(req,res)=>{\n res.json({message:\""+title+" API\"});\n});\n\nconst PORT=process.env.PORT||3000;\napp.listen(PORT,()=>console.log(\"Server on port \"+PORT));\n"; zip.file(folder+"src/index.js",src||fallback); zip.file(folder+".env.example","PORT=3000\n"); zip.file(folder+".gitignore","node_modules/\n.env\n.DS_Store\n"); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Setup\n\`\`\`bash\nnpm install\n\`\`\`\n\n## Run\n\`\`\`bash\nnpm run dev\n\`\`\`\n"); } /* --- Vanilla HTML --- */ function buildVanillaHtml(zip,folder,app,code){ var title=slugTitle(app); var isFullDoc=code.trim().toLowerCase().indexOf("=0||code.trim().toLowerCase().indexOf("=0; var indexHtml=isFullDoc?code:"\n\n\n\n\n"+title+"\n\n\n\n"+code+"\n\n\n\n"; zip.file(folder+"index.html",indexHtml); zip.file(folder+"style.css","/* "+title+" — styles */\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:system-ui,-apple-system,sans-serif;background:#fff;color:#1a1a2e}\n"); zip.file(folder+"script.js","/* "+title+" — scripts */\n"); zip.file(folder+"assets/.gitkeep",""); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\n## Open\nDouble-click \`index.html\` in your browser.\n\nOr serve locally:\n\`\`\`bash\nnpx serve .\n# or\npython3 -m http.server 3000\n\`\`\`\n"); zip.file(folder+".gitignore",".DS_Store\nnode_modules/\n.env\n"); } /* ===== MAIN ===== */ var sc=document.createElement("script"); sc.src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"; sc.onerror=function(){ if(lbl)lbl.textContent="Download ZIP"; alert("JSZip load failed — check connection."); }; sc.onload=function(){ var zip=new JSZip(); var base=(_phFname||"output").replace(/\.[^.]+$/,""); var app=base.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_+|_+$/g,"")||"my_app"; var folder=app+"/"; var vc=document.getElementById("panel-content"); var panelTxt=vc?(vc.innerText||vc.textContent||""):""; var lang=detectLang(_phCode,panelTxt); if(_phIsHtml){ buildVanillaHtml(zip,folder,app,_phCode); } else if(lang==="flutter"){ buildFlutter(zip,folder,app,_phCode,panelTxt); } else if(lang==="react-native"){ buildReactNative(zip,folder,app,_phCode,panelTxt); } else if(lang==="swift"){ buildSwift(zip,folder,app,_phCode,panelTxt); } else if(lang==="kotlin"){ buildKotlin(zip,folder,app,_phCode,panelTxt); } else if(lang==="react"){ buildReact(zip,folder,app,_phCode,panelTxt); } else if(lang==="vue"){ buildVue(zip,folder,app,_phCode,panelTxt); } else if(lang==="angular"){ buildAngular(zip,folder,app,_phCode,panelTxt); } else if(lang==="python"){ buildPython(zip,folder,app,_phCode); } else if(lang==="node"){ buildNode(zip,folder,app,_phCode); } else { /* Document/content workflow */ var title=app.replace(/_/g," "); var md=_phAll||_phCode||panelTxt||"No content"; zip.file(folder+app+".md",md); var h=""+title+""; h+="

"+title+"

"; var hc=md.replace(/&/g,"&").replace(//g,">"); hc=hc.replace(/^### (.+)$/gm,"

$1

"); hc=hc.replace(/^## (.+)$/gm,"

$1

"); hc=hc.replace(/^# (.+)$/gm,"

$1

"); hc=hc.replace(/\*\*(.+?)\*\*/g,"$1"); hc=hc.replace(/\n{2,}/g,"

"); h+="

"+hc+"

Generated by PantheraHive BOS
"; zip.file(folder+app+".html",h); zip.file(folder+"README.md","# "+title+"\n\nGenerated by PantheraHive BOS.\n\nFiles:\n- "+app+".md (Markdown)\n- "+app+".html (styled HTML)\n"); } zip.generateAsync({type:"blob"}).then(function(blob){ var a=document.createElement("a"); a.href=URL.createObjectURL(blob); a.download=app+".zip"; a.click(); URL.revokeObjectURL(a.href); if(lbl)lbl.textContent="Download ZIP"; }); }; document.head.appendChild(sc); } function phShare(){navigator.clipboard.writeText(window.location.href).then(function(){var el=document.getElementById("ph-share-lbl");if(el){el.textContent="Link copied!";setTimeout(function(){el.textContent="Copy share link";},2500);}});}function phEmbed(){var runId=window.location.pathname.split("/").pop().replace(".html","");var embedUrl="https://pantherahive.com/embed/"+runId;var code='';navigator.clipboard.writeText(code).then(function(){var el=document.getElementById("ph-embed-lbl");if(el){el.textContent="Embed code copied!";setTimeout(function(){el.textContent="Get Embed Code";},2500);}});}