Editor JSON Github

Simple coding for json editor placed on github


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JSON Editor</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/9.5.6/jsoneditor.min.css">
    <style>
        #editor {
            width: 100%;
            height: 80vh;
        }
        #successMessage {
            display: none;
            color: green;
            margin-bottom: 10px;
        }
    </style>
</head>
<body>
    <h1>JSON Editor</h1>
    <label for="filePath">Choose JSON file:</label>
    <select id="filePath" onchange="loadSelectedFile()">
        <!-- File options will be populated dynamically -->
    </select>

    <label for="editorMode">Editor Mode:</label>
    <select id="editorMode" onchange="changeEditorMode()">
        <option value="tree">Tree</option>
        <option value="text">Text</option>
    </select>

    <div id="editor"></div>
    <div id="successMessage">Changes saved successfully!</div>
    <button onclick="saveChanges()">Save Changes</button>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/9.5.6/jsoneditor.min.js"></script>
    <script>
        const token = 'ghp_xxx'; // Ganti dengan token GitHub Anda
        const owner = 'konokae';
        const repo = 'sl';
        const branch = 'main';
        
        let editor = null;

        async function fetchRepoContents(path = '') {
            const response = await fetch(`https://api.github.com/repos/${owner}/${repo}/contents/${path}?ref=${branch}`, {
                headers: {
                    'Authorization': `token ${token}`
                }
            });
            return await response.json();
        }

        async function populateFileOptions() {
            const contents = await fetchRepoContents('datatheme');
            const select = document.getElementById('filePath');
            select.innerHTML = ''; // Clear previous options

            let fileCount = 1; // Initialize file counter starting from 1

            contents.forEach(item => {
                if (item.type === 'file' && item.name.endsWith('.json')) {
                    const option = document.createElement('option');
                    option.value = item.path;
                    option.textContent = `${fileCount}: ${item.name}`; // Display with the file count
                    select.appendChild(option);
                    fileCount++; // Increment file counter
                }
            });
        }

        async function fetchJson(path) {
            const response = await fetch(`https://api.github.com/repos/${owner}/${repo}/contents/${path}?ref=${branch}`, {
                headers: {
                    'Authorization': `token ${token}`
                }
            });
            const data = await response.json();
            const content = atob(data.content);
            editor.set(JSON.parse(content));
        }

        async function saveChanges() {
            const newContent = editor.get();
            const encodedContent = btoa(JSON.stringify(newContent, null, 2));
            const filePath = document.getElementById('filePath').value;

            // Get the current file SHA for updating
            const response = await fetch(`https://api.github.com/repos/${owner}/${repo}/contents/${filePath}?ref=${branch}`, {
                headers: {
                    'Authorization': `token ${token}`
                }
            });
            const data = await response.json();
            const sha = data.sha;

            // Update the file
            await fetch(`https://api.github.com/repos/${owner}/${repo}/contents/${filePath}`, {
                method: 'PUT',
                headers: {
                    'Authorization': `token ${token}`,
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    message: 'Updated JSON file via JSON editor',
                    content: encodedContent,
                    sha: sha,
                    branch: branch
                })
            });

            showSuccessMessage();
        }

        function showSuccessMessage() {
            const successMessage = document.getElementById('successMessage');
            successMessage.style.display = 'block';
            setTimeout(() => {
                successMessage.style.display = 'none';
            }, 3000);
        }

        function changeEditorMode() {
            const mode = document.getElementById('editorMode').value;
            const content = editor.get();
            editor.destroy();
            editor = new JSONEditor(document.getElementById('editor'), { mode: mode });
            editor.set(content);
        }

        async function loadSelectedFile() {
            const filePath = document.getElementById('filePath').value;
            if (filePath) {
                if (editor) {
                    editor.destroy();
                }
                const mode = document.getElementById('editorMode').value;
                editor = new JSONEditor(document.getElementById('editor'), { mode: mode });
                await fetchJson(filePath);
            }
        }

        document.addEventListener('DOMContentLoaded', async () => {
            document.getElementById('editorMode').value = 'tree'; // Set default mode to tree
            editor = new JSONEditor(document.getElementById('editor'), { mode: 'tree' });
            await populateFileOptions();
            loadSelectedFile();
        });
    </script>
</body>
</html>

Audio Title
0:00 / 0:00
Next Post Previous Post