Demo

Interactive Form Components

This demo showcases how to combine multiple LemonadeJS plugins to create rich, reactive user interfaces with real-time two-way data binding. Build beautiful forms with color pickers, star ratings, toggle switches, and modal dialogs.


<html>
<script src="https://cdn.jsdelivr.net/npm/lemonadejs/dist/lemonade.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@lemonadejs/rating/dist/index.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@lemonadejs/switch/dist/index.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@lemonadejs/modal/dist/index.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@jsuites/color-picker/dist/index.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lemonadejs/rating/dist/style.min.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lemonadejs/switch/dist/style.min.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lemonadejs/modal/dist/style.min.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@jsuites/color-picker/dist/style.min.css" />

<div id="root"></div>

<script>
function InteractiveFormDemo() {
    const self = this;

    // Form data as direct properties
    self.name = '';
    self.favoriteColor = '#3498db';
    self.rating = 0;
    self.notifications = true;
    self.darkMode = false;
    self.emailUpdates = true;

    // Handler functions for components
    self.updateRating = function(el, value) {
        self.rating = value;
        self.refresh();
    };

    self.updateNotifications = function(el, value) {
        self.notifications = value;
    };

    self.updateDarkMode = function(el, value) {
        self.darkMode = value;
    };

    self.updateEmailUpdates = function(el, value) {
        self.emailUpdates = value;
    };

    // Show modal with summary
    self.showSummary = function() {
        const summary = `
Name: ${self.name || 'Not provided'}
Favorite Color: ${self.favoriteColor}
Rating: ${self.rating} stars
Notifications: ${self.notifications ? 'Enabled' : 'Disabled'}
Dark Mode: ${self.darkMode ? 'On' : 'Off'}
Email Updates: ${self.emailUpdates ? 'Subscribed' : 'Unsubscribed'}
        `;
        alert(summary);
    }

    return `<div style="max-width: 900px; margin: 0 auto; padding: 20px;">
        <h3 style="text-align: center; margin-bottom: 30px;">User Preferences Form</h3>

        <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 30px;">
            <div style="background: white; padding: 20px; border-radius: 8px; border: 1px solid #e0e0e0;">
                <label style="display: block; margin-bottom: 8px; font-weight: 600;">Name:</label>
                <input type="text" :bind="self.name"
                       style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px;" />
            </div>

            <div style="background: white; padding: 20px; border-radius: 8px; border: 1px solid #e0e0e0;">
                <label style="display: block; margin-bottom: 8px; font-weight: 600;">Favorite Color:</label>
                <div style="display: flex; align-items: center; gap: 10px;">
                    <input type="color" :bind="self.favoriteColor"
                           style="width: 60px; height: 40px; border: none; cursor: pointer;" />
                    <span style="font-family: monospace;">{{self.favoriteColor}}</span>
                </div>
            </div>

            <div style="background: white; padding: 20px; border-radius: 8px; border: 1px solid #e0e0e0;">
                <label style="display: block; margin-bottom: 8px; font-weight: 600;">Rate Your Experience:</label>
                <Rating :value="self.rating" :onchange="self.updateRating" />
            </div>

            <div style="background: white; padding: 20px; border-radius: 8px; border: 1px solid #e0e0e0;">
                <label style="display: block; margin-bottom: 12px; font-weight: 600;">Preferences:</label>
                <div style="display: flex; flex-direction: column; gap: 12px;">
                    <label style="display: flex; align-items: center; cursor: pointer;">
                        <Switch :value="self.notifications" :onchange="self.updateNotifications" />
                        <span style="margin-left: 10px;">Enable Notifications</span>
                    </label>
                    <label style="display: flex; align-items: center; cursor: pointer;">
                        <Switch :value="self.darkMode" :onchange="self.updateDarkMode" />
                        <span style="margin-left: 10px;">Dark Mode</span>
                    </label>
                    <label style="display: flex; align-items: center; cursor: pointer;">
                        <Switch :value="self.emailUpdates" :onchange="self.updateEmailUpdates" />
                        <span style="margin-left: 10px;">Email Updates</span>
                    </label>
                </div>
            </div>
        </div>

        <button onclick="self.showSummary()"
                style="padding: 10px 20px; background: #3498db; color: white;
                       border: none; border-radius: 4px; cursor: pointer; font-size: 16px; display: block; margin: 0 auto;">
            Show Summary
        </button>

        <div style="margin-top: 30px; padding: 15px; background: #f8f9fa;
                    border-radius: 4px; border: 1px solid #e9ecef;">
            <h4>Live Data Preview:</h4>
            <pre style="background: white; padding: 10px; border-radius: 4px;
                        overflow-x: auto;">{{JSON.stringify({
                name: self.name,
                favoriteColor: self.favoriteColor,
                rating: self.rating,
                notifications: self.notifications,
                darkMode: self.darkMode,
                emailUpdates: self.emailUpdates
            }, null, 2)}}</pre>
        </div>
    </div>`;
}

lemonade.render(InteractiveFormDemo, document.getElementById('root'));
</script>
</html>
import lemonade from 'lemonadejs';
import Rating from '@lemonadejs/rating';
import Switch from '@lemonadejs/switch';

export default function InteractiveFormDemo() {
    const self = this;

    // Form data as direct properties
    self.name = '';
    self.favoriteColor = '#3498db';
    self.rating = 0;
    self.notifications = true;
    self.darkMode = false;
    self.emailUpdates = true;

    // Handler functions for components
    self.updateRating = function(el, value) {
        self.rating = value;
        self.refresh();
    };

    self.updateNotifications = function(el, value) {
        self.notifications = value;
    };

    self.updateDarkMode = function(el, value) {
        self.darkMode = value;
    };

    self.updateEmailUpdates = function(el, value) {
        self.emailUpdates = value;
    };

    // Show modal with summary
    self.showSummary = function() {
        const summary = `
Name: ${self.name || 'Not provided'}
Favorite Color: ${self.favoriteColor}
Rating: ${self.rating} stars
Notifications: ${self.notifications ? 'Enabled' : 'Disabled'}
Dark Mode: ${self.darkMode ? 'On' : 'Off'}
Email Updates: ${self.emailUpdates ? 'Subscribed' : 'Unsubscribed'}
        `;
        alert(summary);
    }

    return `<div style="max-width: 900px; margin: 0 auto; padding: 20px;">
        <h3 style="text-align: center; margin-bottom: 30px;">User Preferences Form</h3>

        <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 30px;">
            <div style="background: white; padding: 20px; border-radius: 8px; border: 1px solid #e0e0e0;">
                <label style="display: block; margin-bottom: 8px; font-weight: 600;">Name:</label>
                <input type="text" :bind="self.name"
                       style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px;" />
            </div>

            <div style="background: white; padding: 20px; border-radius: 8px; border: 1px solid #e0e0e0;">
                <label style="display: block; margin-bottom: 8px; font-weight: 600;">Favorite Color:</label>
                <div style="display: flex; align-items: center; gap: 10px;">
                    <input type="color" :bind="self.favoriteColor"
                           style="width: 60px; height: 40px; border: none; cursor: pointer;" />
                    <span style="font-family: monospace;">{{self.favoriteColor}}</span>
                </div>
            </div>

            <div style="background: white; padding: 20px; border-radius: 8px; border: 1px solid #e0e0e0;">
                <label style="display: block; margin-bottom: 8px; font-weight: 600;">Rate Your Experience:</label>
                <Rating :value="self.rating" :onchange="self.updateRating" />
            </div>

            <div style="background: white; padding: 20px; border-radius: 8px; border: 1px solid #e0e0e0;">
                <label style="display: block; margin-bottom: 12px; font-weight: 600;">Preferences:</label>
                <div style="display: flex; flex-direction: column; gap: 12px;">
                    <label style="display: flex; align-items: center; cursor: pointer;">
                        <Switch :value="self.notifications" :onchange="self.updateNotifications" />
                        <span style="margin-left: 10px;">Enable Notifications</span>
                    </label>
                    <label style="display: flex; align-items: center; cursor: pointer;">
                        <Switch :value="self.darkMode" :onchange="self.updateDarkMode" />
                        <span style="margin-left: 10px;">Dark Mode</span>
                    </label>
                    <label style="display: flex; align-items: center; cursor: pointer;">
                        <Switch :value="self.emailUpdates" :onchange="self.updateEmailUpdates" />
                        <span style="margin-left: 10px;">Email Updates</span>
                    </label>
                </div>
            </div>
        </div>

        <button onclick="self.showSummary()"
                style="padding: 10px 20px; background: #3498db; color: white;
                       border: none; border-radius: 4px; cursor: pointer; font-size: 16px; display: block; margin: 0 auto;">
            Show Summary
        </button>

        <div style="margin-top: 30px; padding: 15px; background: #f8f9fa;
                    border-radius: 4px; border: 1px solid #e9ecef;">
            <h4>Live Data Preview:</h4>
            <pre style="background: white; padding: 10px; border-radius: 4px;
                        overflow-x: auto;">{{JSON.stringify({
                name: self.name,
                favoriteColor: self.favoriteColor,
                rating: self.rating,
                notifications: self.notifications,
                darkMode: self.darkMode,
                emailUpdates: self.emailUpdates
            }, null, 2)}}</pre>
        </div>
    </div>`;
}
import React, { useState } from 'react';
import { Rating } from '@lemonadejs/rating/react';
import { Switch } from '@lemonadejs/switch/react';
import '@lemonadejs/rating/dist/style.min.css';
import '@lemonadejs/switch/dist/style.min.css';

export default function InteractiveFormDemo() {
    const [userData, setUserData] = useState({
        name: '',
        favoriteColor: '#3498db',
        rating: 0,
        notifications: true,
        darkMode: false,
        emailUpdates: true
    });

    const updateField = (field, value) => {
        setUserData(prev => ({ ...prev, [field]: value }));
    };

    const showSummary = () => {
        const summary = `
Name: ${userData.name || 'Not provided'}
Favorite Color: ${userData.favoriteColor}
Rating: ${userData.rating} stars
Notifications: ${userData.notifications ? 'Enabled' : 'Disabled'}
Dark Mode: ${userData.darkMode ? 'On' : 'Off'}
Email Updates: ${userData.emailUpdates ? 'Subscribed' : 'Unsubscribed'}
        `;
        alert(summary);
    };

    return (
        <div style={{ maxWidth: '900px', margin: '0 auto', padding: '20px' }}>
            <h3 style={{ textAlign: 'center', marginBottom: '30px' }}>User Preferences Form</h3>

            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '20px', marginBottom: '30px' }}>
                <div style={{ background: 'white', padding: '20px', borderRadius: '8px', border: '1px solid #e0e0e0' }}>
                    <label style={{ display: 'block', marginBottom: '8px', fontWeight: '600' }}>Name:</label>
                    <input
                        type="text"
                        value={userData.name}
                        onChange={(e) => updateField('name', e.target.value)}
                        style={{ width: '100%', padding: '8px', border: '1px solid #ddd', borderRadius: '4px' }}
                    />
                </div>

                <div style={{ background: 'white', padding: '20px', borderRadius: '8px', border: '1px solid #e0e0e0' }}>
                    <label style={{ display: 'block', marginBottom: '8px', fontWeight: '600' }}>Favorite Color:</label>
                    <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
                        <input
                            type="color"
                            value={userData.favoriteColor}
                            onChange={(e) => updateField('favoriteColor', e.target.value)}
                            style={{ width: '60px', height: '40px', border: 'none', cursor: 'pointer' }}
                        />
                        <span style={{ fontFamily: 'monospace' }}>{userData.favoriteColor}</span>
                    </div>
                </div>

                <div style={{ background: 'white', padding: '20px', borderRadius: '8px', border: '1px solid #e0e0e0' }}>
                    <label style={{ display: 'block', marginBottom: '8px', fontWeight: '600' }}>Rate Your Experience:</label>
                    <Rating
                        value={userData.rating}
                        onchange={(value) => updateField('rating', value)}
                    />
                    <span style={{ marginLeft: '10px' }}>{userData.rating} / 5 stars</span>
                </div>

                <div style={{ background: 'white', padding: '20px', borderRadius: '8px', border: '1px solid #e0e0e0' }}>
                    <label style={{ display: 'block', marginBottom: '12px', fontWeight: '600' }}>Preferences:</label>
                    <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
                        <label style={{ display: 'flex', alignItems: 'center', cursor: 'pointer' }}>
                            <Switch
                                value={userData.notifications}
                                onchange={(value) => updateField('notifications', value)}
                            />
                            <span style={{ marginLeft: '10px' }}>Enable Notifications</span>
                        </label>
                        <label style={{ display: 'flex', alignItems: 'center', cursor: 'pointer' }}>
                            <Switch
                                value={userData.darkMode}
                                onchange={(value) => updateField('darkMode', value)}
                            />
                            <span style={{ marginLeft: '10px' }}>Dark Mode</span>
                        </label>
                        <label style={{ display: 'flex', alignItems: 'center', cursor: 'pointer' }}>
                            <Switch
                                value={userData.emailUpdates}
                                onchange={(value) => updateField('emailUpdates', value)}
                            />
                            <span style={{ marginLeft: '10px' }}>Email Updates</span>
                        </label>
                    </div>
                </div>
            </div>

            <button
                onClick={showSummary}
                style={{
                    padding: '10px 20px',
                    background: '#3498db',
                    color: 'white',
                    border: 'none',
                    borderRadius: '4px',
                    cursor: 'pointer',
                    fontSize: '16px',
                    display: 'block',
                    margin: '0 auto'
                }}
            >
                Show Summary
            </button>

            <div style={{
                marginTop: '30px',
                padding: '15px',
                background: '#f8f9fa',
                borderRadius: '4px',
                border: '1px solid #e9ecef'
            }}>
                <h4>Live Data Preview:</h4>
                <pre style={{
                    background: 'white',
                    padding: '10px',
                    borderRadius: '4px',
                    overflowX: 'auto'
                }}>
                    {JSON.stringify(userData, null, 2)}
                </pre>
            </div>
        </div>
    );
}
<template>
    <div style="max-width: 900px; margin: 0 auto; padding: 20px;">
        <h3 style="text-align: center; margin-bottom: 30px;">User Preferences Form</h3>

        <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 30px;">
            <div style="background: white; padding: 20px; border-radius: 8px; border: 1px solid #e0e0e0;">
                <label style="display: block; margin-bottom: 8px; font-weight: 600;">Name:</label>
                <input
                    type="text"
                    v-model="userData.name"
                    style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px;"
                />
            </div>

            <div style="background: white; padding: 20px; border-radius: 8px; border: 1px solid #e0e0e0;">
                <label style="display: block; margin-bottom: 8px; font-weight: 600;">Favorite Color:</label>
                <div style="display: flex; align-items: center; gap: 10px;">
                    <input
                        type="color"
                        v-model="userData.favoriteColor"
                        style="width: 60px; height: 40px; border: none; cursor: pointer;"
                    />
                    <span style="font-family: monospace;">{{ userData.favoriteColor }}</span>
                </div>
            </div>

            <div style="background: white; padding: 20px; border-radius: 8px; border: 1px solid #e0e0e0;">
                <label style="display: block; margin-bottom: 8px; font-weight: 600;">Rate Your Experience:</label>
                <Rating v-model="userData.rating" />
                <span style="margin-left: 10px;">{{ userData.rating }} / 5 stars</span>
            </div>

            <div style="background: white; padding: 20px; border-radius: 8px; border: 1px solid #e0e0e0;">
                <label style="display: block; margin-bottom: 12px; font-weight: 600;">Preferences:</label>
                <div style="display: flex; flex-direction: column; gap: 12px;">
                    <label style="display: flex; align-items: center; cursor: pointer;">
                        <Switch v-model="userData.notifications" />
                        <span style="margin-left: 10px;">Enable Notifications</span>
                    </label>
                    <label style="display: flex; align-items: center; cursor: pointer;">
                        <Switch v-model="userData.darkMode" />
                        <span style="margin-left: 10px;">Dark Mode</span>
                    </label>
                    <label style="display: flex; align-items: center; cursor: pointer;">
                        <Switch v-model="userData.emailUpdates" />
                        <span style="margin-left: 10px;">Email Updates</span>
                    </label>
                </div>
            </div>
        </div>

        <button
            @click="showSummary"
            style="padding: 10px 20px; background: #3498db; color: white;
                   border: none; border-radius: 4px; cursor: pointer; font-size: 16px; display: block; margin: 0 auto;"
        >
            Show Summary
        </button>

        <div style="margin-top: 30px; padding: 15px; background: #f8f9fa;
                    border-radius: 4px; border: 1px solid #e9ecef;">
            <h4>Live Data Preview:</h4>
            <pre style="background: white; padding: 10px; border-radius: 4px; overflow-x: auto;">{{ JSON.stringify(userData, null, 2) }}</pre>
        </div>
    </div>
</template>

<script>
import { Rating } from '@lemonadejs/rating/vue';
import { Switch } from '@lemonadejs/switch/vue';
import '@lemonadejs/rating/dist/style.min.css';
import '@lemonadejs/switch/dist/style.min.css';

export default {
    name: 'InteractiveFormDemo',
    components: {
        Rating,
        Switch
    },
    data() {
        return {
            userData: {
                name: '',
                favoriteColor: '#3498db',
                rating: 0,
                notifications: true,
                darkMode: false,
                emailUpdates: true
            }
        }
    },
    methods: {
        showSummary() {
            const summary = `
Name: ${this.userData.name || 'Not provided'}
Favorite Color: ${this.userData.favoriteColor}
Rating: ${this.userData.rating} stars
Notifications: ${this.userData.notifications ? 'Enabled' : 'Disabled'}
Dark Mode: ${this.userData.darkMode ? 'On' : 'Off'}
Email Updates: ${this.userData.emailUpdates ? 'Subscribed' : 'Unsubscribed'}
            `;
            alert(summary);
        }
    }
}
</script>