HTML'de JavaScript ile dosyaya veri kaydetme ve oradan okuma

Ardaa_U

Yoctopat
Katılım
21 Mart 2024
Mesajlar
3
Daha fazla  
Cinsiyet
Erkek
Elimde böyle bir site var, sitenin amacı kullanıcının belirlediği tarihden geri sayım yapmak.
Ben bu kodda local storage kullandım ama bu verileri bir excel veya txt dosyasına yazdırıp siteye F5 attığım ve ya siteye yeni girdiğimde girdiğim tarih, proje isimleri ve listeyi bir dosyaya kaydedip site açılınca en son yaptığım işlerimleri görmek istiyorum.

Not: dönem proje ödevim.

HTML:
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Geri Sayım</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/FileSaver.min.js"></script>

    <style>
        body {
            background-color: rgb(92, 196, 196);
            font-family: Arial, sans-serif;
            margin: 20px;
        }

        .geri-sayim {
            display: grid;
            flex-direction: column;
            justify-content: left;
            align-items: left;
        }

        .proje {
            display: flex;
            align-items: center;
            margin: 10px;
            padding: 10px;
            border: 2px solid #ddd;
            border-radius: 5px;
        }

        .proje-adi {
            font-weight: bold;
            font-size: 30px;
            margin-right: 100px;
        }

        .sayac1 {
            font-size: 30px;
            margin: 5px;
        }

        .liste {
            display: grid;
            font-size: 20px;
        }

        .sayac1 span {
            font-weight: bold;
            color: #000000;
            transition: color 1s ease-in-out;
        }

        .sayac1 span.kirmizi {
            color: #FF0000;
        }

        .sayac1 span.turuncu {
            color: orange;
        }

        .sayac1 span.yesil {
            color: lawngreen;
        }

        .sayac1 span.sari {
            color: #FFFF00;
        }

        .sayac1 span.siyah {
            color: #000000;
        }

        #yeniTarihPenceresi button {
            border-radius: 5px;
            background-color: #0073b7;
            color: #ffffff;
            font-weight: bold;
            padding: 10px 20px;
            margin: 10px;
        }

        .degistir-button {
            border-radius: 5px;
            background-color: #0073b7;
            color: #ffffff;
            font-weight: bold;
            padding: 10px 20px;
            margin-left: 10px;

        }

        .tarih {
            border-radius: 5px;
            background-color: #0073b7;
            color: #ffffff;
            font-weight: bold;
            padding: 10px 20px;
            margin: 10px;
        }

        .geri-sayim .proje button {
            border-radius: 5px;
            background-color: #0073b7;
            color: #ffffff;
            font-weight: bold;
            padding: 5px 10px;
            margin: 5px;
        }
    </style>
</head>

<body>

    <button class="tarih" onclick="yeniTarihPenceresiAc()">Yeni Tarih Ver</button>



    <div id="yeniTarihPenceresi" style="display: none;">

        <select id="projeSecimi">
            <option value="">Proje Seçin</option>
            <option value="1">Proje 1</option>
            <option value="2">Proje 2</option>
            <option value="3">Proje 3</option>
            <option value="4">Proje 4</option>
            <option value="5">Proje 5</option>
        </select>
        <input type="datetime-local" id="yeniTarih">

        <button onclick="yeniTarihiKaydet()">Kaydet</button>
    </div>

    <script>

        function yeniTarihPenceresiAc() {
            document.getElementById("yeniTarihPenceresi").style.display = "block";
        }

        function yeniTarihiKaydet() {
            const projeId = document.getElementById("projeSecimi").value;
            const yeniTarih = document.getElementById("yeniTarih").value;

            const suankiTarih = new Date();
            const index = parseInt(projeId) - 1;

            if (projeler[index]) {
                projeler[index].bitisTarihi = yeniTarih;
                projeler[index].baslangicTarihi = suankiTarih.toISOString().slice(0, 16);
            } else {
                const yeniProje = {
                    isim: "Proje " + projeId,
                    baslangicTarihi: suankiTarih.toISOString().slice(0, 16),
                    bitisTarihi: yeniTarih
                };
                projeler.push(yeniProje);
            }

            localStorage.setItem('projeler', JSON.stringify(projeler));
            document.getElementById("yeniTarihPenceresi").style.display = "none";

            geriSayim();
        }
    </script>

    <button class="degistir-button" onclick="isimDegistir()">Projeyi Değiştir</button>

    <script>

        function isimDegistir() {
            const projeIndex = document.getElementById("projeSecimi2").value;
            const yeniIsim = prompt("Yeni ismi girin:");
            if (yeniIsim !== null && yeniIsim !== "" && projeIndex !== "") {
                const proje = projeler[parseInt(projeIndex) - 1];
                if (proje) {
                    proje.isim = yeniIsim;
                    document.getElementById("projeAdi" + projeIndex).textContent = yeniIsim;
                    localStorage.setItem('proje' + projeIndex + 'Isim', yeniIsim);
                    geriSayim();
                } else {
                    alert("Belirtilen proje bulunamadı.");
                }
            } else {
                alert(" geçerli bir proje seçin ve yeni bir isim girin.");
            }
        }

    </script>
    <select id="projeSecimi2">
        <option value="">Proje Seçin</option>
        <option value="1">Proje 1</option>
        <option value="2">Proje 2</option>
        <option value="3">Proje 3</option>
        <option value="4">Proje 4</option>
        <option value="5">Proje 5</option>
    </select>
 

    <script>
    </script>

    <div class="geri-sayim">

        <div class="proje">
            <h2 class="proje-adi" id="projeAdi1">Proje 1</h2>
            <div class="sayac sayac1">
                <span id="gun1">0</span> Gün <span id="saat1">0</span> Saat <span id="dakika1">0</span> Dakika <span
                    id="saniye1">0</span> Saniye
                <input type="checkbox" class="form-check-input" id="check1" name="option1" value="something">
                <label class="form-check-label" for="check1"></label>
            </div>
        </div>
        <div class="proje">
            <h2 class="proje-adi" id="projeAdi2">Proje 2</h2>
            <div class="sayac sayac1">
                <span id="gun2">0</span> Gün <span id="saat2">0</span> Saat <span id="dakika2">0</span> Dakika <span
                    id="saniye2">0</span> Saniye
                <input type="checkbox" class="form-check-input" id="check2" name="option2" value="something">
                <label class="form-check-label" for="check2"></label>
            </div>
        </div>
        <div class="proje">
            <h2 class="proje-adi" id="projeAdi3">Proje 3</h2>
            <div class="sayac sayac1">
                <span id="gun3">0</span> Gün <span id="saat3">0</span> Saat <span id="dakika3">0</span> Dakika <span
                    id="saniye3">0</span> Saniye
                <input type="checkbox" class="form-check-input" id="check3" name="option3" value="something">
                <label class="form-check-label" for="check3"></label>
            </div>
        </div>
        <div class="proje">
            <h2 class="proje-adi" id="projeAdi4">Proje 4</h2>
            <div class="sayac sayac1">
                <span id="gun4">0</span> Gün <span id="saat4">0</span> Saat <span id="dakika4">0</span> Dakika <span
                    id="saniye4">0</span> Saniye
                <input type="checkbox" class="form-check-input" id="check4" name="option4" value="something">
                <label class="form-check-label" for="check4"></label>
            </div>
        </div>
        <div class="proje">
            <h2 class="proje-adi" id="projeAdi5">Proje 5</h2>
            <div class="sayac sayac1">
                <span id="gun5">0</span> Gün <span id="saat5">0</span> Saat <span id="dakika5">0</span> Dakika <span
                    id="saniye5">0</span> Saniye
                <input type="checkbox" class="form-check-input" id="check5" name="option5" value="something">
                <label class="form-check-label" for="check5"></label>
            </div>
        </div>
        <div class="liste">
            <ul class="list-group">

            </ul>
        </div>
    </div>


    <script>

        const projeler = JSON.parse(localStorage.getItem('projeler')) || [

            {
                isim: "Proje 1",
                baslangicTarihi: new Date().toISOString().slice(0, 16),
                bitisTarihi: "2024-03-13T19:23"
            },
            {
                isim: "Proje 2",
                baslangicTarihi: new Date().toISOString().slice(0, 16),
                bitisTarihi: "2024-03-13T17:45"
            },
            {
                isim: "Proje 3",
                baslangicTarihi: new Date().toISOString().slice(0, 16),
                bitisTarihi: "2024-03-11T10:00"
            },
            {
                isim: "Proje 4",
                baslangicTarihi: new Date().toISOString().slice(0, 16),
                bitisTarihi: "2024-03-11T10:00"
            },
            {
                isim: "Proje 5",
                baslangicTarihi: new Date().toISOString().slice(0, 16),
                bitisTarihi: "2024-03-11T10:00"
            },
        ];

        function calculateRemainingPercentage(kalanSure, totalSure) {
            if (totalSure > 0 && !isNaN(totalSure) && !isNaN(kalanSure)) {
                const percentageRemaining = (kalanSure / totalSure) * 100;
                console.log("Yüzde:", percentageRemaining);

                if (percentageRemaining <= 30) {
                    return "kirmizi";
                } else if (percentageRemaining <= 50) {
                    return "turuncu";
                } else if (percentageRemaining <= 70) {
                    return "sari";
                } else {
                    return "yesil";
                }
            } else {
                console.error("Invalid total or remaining duration. Check the start and end dates.");
            }
        }

        function kontrolEtVeEkle() {
            const tamamlananProjeler = JSON.parse(localStorage.getItem('tamamlananProjeler')) || [];
            const listGroup = document.querySelector(".list-group");

            for (let i = 1; i <= projeler.length; i++) {
                const checkbox = document.getElementById("check" + i);
                const projeAdi = document.getElementById("projeAdi" + i).textContent;

                if (checkbox.checked) {
                    const listItem = document.createElement("li");
                    listItem.className = "list-group-item";
                    listItem.textContent = projeAdi + " - Tamamlandı";
                    listGroup.appendChild(listItem);

                    checkbox.checked = false;

                    tamamlananProjeler.push(projeAdi);
                    localStorage.setItem('tamamlananProjeler', JSON.stringify(tamamlananProjeler));
                }
            }
        }

       window.onload = function () {
            for (let i = 0; i < projeler.length; i++) {
                const isim = localStorage.getItem('proje' + (i + 1) + 'Isim');
                if (isim) {
                    document.getElementById("projeAdi" + (i + 1)).textContent = isim;

                }
            }
            const tamamlananProjeler = JSON.parse(localStorage.getItem('tamamlananProjeler')) || [];
            const listGroup = document.querySelector(".list-group");

            tamamlananProjeler.forEach(proje => {
                const listItem = document.createElement("li");
                listItem.className = "list-group-item";
                listItem.textContent = proje + " - Tamamlandı";
                listGroup.appendChild(listItem);
            });
        };

        function updateCountdownElement(id, value) {
            document.getElementById(id).innerHTML = value;
        }

        function updateColorClass(id, colorClass) {
            const element = document.getElementById(id);
            element.classList.remove("kirmizi", "sari", "yesil", "turuncu");
            element.classList.add(colorClass);
        }


        function geriSayim() {
            const suankiZaman = new Date().getTime() + (1000 * 60 * 60 * 0);

            for (let i = 0; i < projeler.length; i++) {
                const proje = projeler;
                const bitisZamani = new Date(proje.bitisTarihi).getTime();
                const totalSure = bitisZamani - new Date(proje.baslangicTarihi).getTime();
                const kalanSure = bitisZamani - suankiZaman;

                if (kalanSure <= 0) {
                    updateCountdownElement("gun" + (i + 1), "0");
                    updateCountdownElement("saat" + (i + 1), "0");
                    updateCountdownElement("dakika" + (i + 1), "0");
                    updateCountdownElement("saniye" + (i + 1), "0");


                    updateColorClass("gun" + (i + 1), "yesil");
                    updateColorClass("saat" + (i + 1), "yesil");
                    updateColorClass("dakika" + (i + 1), "yesil");
                    updateColorClass("saniye" + (i + 1), "yesil");
                } else {
                    const gun = Math.floor(kalanSure / (1000 * 60 * 60 * 24));
                    const saat = Math.floor((kalanSure % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
                    const dakika = Math.floor((kalanSure % (1000 * 60 * 60)) / (1000 * 60));
                    const saniye = Math.floor((kalanSure % (1000 * 60)) / 1000);

                    updateCountdownElement("gun" + (i + 1), gun);
                    updateCountdownElement("saat" + (i + 1), saat);
                    updateCountdownElement("dakika" + (i + 1), dakika);
                    updateCountdownElement("saniye" + (i + 1), saniye);

                    const colorClass = calculateRemainingPercentage(kalanSure, totalSure);
                    updateColorClass("gun" + (i + 1), colorClass);
                    updateColorClass("saat" + (i + 1), colorClass);
                    updateColorClass("dakika" + (i + 1), colorClass);
                    updateColorClass("saniye" + (i + 1), colorClass);
                }

            }

            setTimeout(geriSayim, 1000);
            kontrolEtVeEkle();

        }

        geriSayim();
    </script>
</body>

</html>
 
Localstorage iş görmesi lazım. Görmüyor mu? Veya tam isteğin nedir?
Localstorage da tuttuğun veri f5 ile kaybolmaz. Amacı bu zaten. Veriyi tutmak. Tarayıcı geçmişini silmediğini sürece orada kalır.

Diyelim ki iş görmüyor. O zaman Server taraflı bir işlem yapmak istiyorsun. Bunun içinde server taraflı bir dil kullanman lazım. Php, C#, Nodejs vs olabilir.
Veya serverless bir uygulama kullan. Firebase, supabase vs.
Veya Google sheets veya benzer sistemleri de kullanabilirsin.

Google sheets ile veri kaydetmek;
 
Localstorage iş görmesi lazım. Görmüyor mu? Veya tam isteğin nedir?
Localstorage da tuttuğun veri F5 ile kaybolmaz. Amacı bu zaten. Veriyi tutmak. Tarayıcı geçmişini silmediğini sürece orada kalır.

Diyelim ki iş görmüyor. O zaman server taraflı bir işlem yapmak istiyorsun. Bunun içinde server taraflı bir dil kullanman lazım. PHP, C#, Node.js vs olabilir.
Veya serverless bir uygulama kullan. Firebase, supabase vs.
veya Google sheets veya benzer sistemleri de kullanabilirsin.

Google sheets ile veri kaydetmek;

Local host iş görüyor evet ama benden local host kullanmamı istemiyorlar. Özellikle bir dosyaya kaydet sayfa oradan yüklensin istiyorlar büyük ihtimalle server kısmınıda kabul etmezler.

@RaSGooL internetten baktığıma göre file API diye bir yöntem varmış ama nasıl kullanırım hiçbir fikrim yok eğer biliyorsanız bana anlatabilir misiniz?
 
Son düzenleme:
Local host iş görüyor evet ama benden local host kullanmamı istemiyorlar. Özellikle bir dosyaya kaydet sayfa oradan yüklensin istiyorlar büyük ihtimalle server kısmınıda kabul etmezler.

@RaSGooL internetten baktığıma göre file API diye bir yöntem varmış ama nasıl kullanırım hiçbir fikrim yok eğer biliyorsanız bana anlatabilir misiniz?

Anladığım kadarıyla sürekli kullanıcının girdiği zamana göre geri sayım yapan bir sayaç yapmak istiyorsunuz. Bence bu gibi bir durumda backend tarafında işlemi gerçekleştirmek daha mantıklı olabilir. Eğer bir dosyaya kayıt edecekseniz hem çok güvenli olmaz, hem de çok fazla yer kaplamaz mı? Ayrıca adam kendi bilgisayarında çalıştırmak istese sizin ona dosyayı göndermeniz gerekmez mi, ben böyle düşünüyorum. Sizin dediğiniz gibi bir olay buldum internette belki yardımcı olur.
 
Anladığım kadarıyla sürekli kullanıcının girdiği zamana göre geri sayım yapan bir sayaç yapmak istiyorsunuz. Bence bu gibi bir durumda backend tarafında işlemi gerçekleştirmek daha mantıklı olabilir. Eğer bir dosyaya kayıt edecekseniz hem çok güvenli olmaz, hem de çok fazla yer kaplamaz mı? Ayrıca adam kendi bilgisayarında çalıştırmak istese sizin ona dosyayı göndermeniz gerekmez mi, ben böyle düşünüyorum. Sizin dediğiniz gibi bir olay buldum internette belki yardımcı olur.

Evet dediğiniz gibi bir dosyaya yazmak pek mantıklı değil ama bunu gelin bir de öğretmenime anlatın kendisi bu şekilde yapmamı istiyor.

Attığınız linkteki yöntemi de denedim ama bu yöntemde de istediğimiz gibi olmuyor tam olarak istenilene göre hep aynı dosya olacak ve örneğin bir butona basarak o dosyaya yazacak verileri ve her seferinde yeni veri yazmak yerine eski veriyi güncelleyecek bu da bir Excel tablosu ile olabiliyormuş sanırım denilene göre.
 
Evet dediğiniz gibi bir dosyaya yazmak pek mantıklı değil ama bunu gelin bir de öğretmenime anlatın kendisi bu şekilde yapmamı istiyor.

Attığınız linkteki yöntemi de denedim ama bu yöntemde de istediğimiz gibi olmuyor tam olarak istenilene göre hep aynı dosya olacak ve örneğin bir butona basarak o dosyaya yazacak verileri ve her seferinde yeni veri yazmak yerine eski veriyi güncelleyecek bu da bir Excel tablosu ile olabiliyormuş sanırım denilene göre.

Bu işlemi Node.js ile de yapabilirsiniz ama saf JS ile nasıl yapılır bilemiyorum?
 
@RaSGooL internetten baktığıma göre file API diye bir yöntem varmış ama nasıl kullanırım hiçbir fikrim yok eğer biliyorsanız bana anlatabilir misiniz?

File API dedğin şey nedir bilmiyorum. Yukarıdaki mesajımda nasıl yapacağın ile ilgili yöntemler söyledim. Basit bir PHP kodu ile yapılır bu dediğin. TXT ye yaz oradan geri oku.
PHP kaynak;

Bu işlemi Node.js ile de yapabilirsiniz ama saf JS ile nasıl yapılır bilemiyorum?
Saf JS sadece Client (tarayıcı) tarafında çalışır. Server tarafına müdahale edemez. Node.js iş görür. Attığın kaynakta bir dosya indirmeyi gösterir. Server tarafına değil, Client tarafında indirilir. Bu da bizim işimize yaramaz.

İlk mesajımda birçok yöntem söyledim. Hocanız illa bir txt dosyasına yazmanızı istiyor anlaşılan.
Önce bu kodları biraz düzenle. Her yere localStorage.setItem getItem yazma. Bunlar data işleri. Bu işleri DOM dan ayırmakta fayda var. Şöyle yapabilirsin;

JavaScript:
class DataService { // Genelde bu tarz genel bir service yazmayız. Servislerin genel içeriğine göre servisler olur mesela ProjectService gibi. Genel kültür olsun diye yazayım dedim.
    async getProjects() {
        return JSON.parse(localStorage.getItem('projeler'))
    }
    async setProject({id, name}) {
        localStorage.setItem('proje' + id + 'Isim', name)
    }
    // blabla
}

İşte şimdi istediğin server kullanabilirsin. Artık business kodun datayı nereden aldığın ile ilgilenmez. İşte Node.js ile nasıl yapabilirsin kodu (Technopat üzerinden yazıyorum syntax hatası verebilir düzeltirsin.);

JavaScript:
class DataService {
    async getProjects() {
        const fetchPromise = await fetch("/api/projects")
        return await fetchPromise.json()
    }
    async setProject({id, name}) {
        await fetch(`/api/projects/${id}`, {
            method: "POST",
            data: name
        })
    }
    // blabla
}

Nodejs tarafı da böyle bir şey olur. Dediğim gibi PHP ile daha basit yapılabilir. index.html yerine index.php yaparsın form kullanırsın. Action da yakalarsın. Biraz kafan karışmış olabilir. ChatGPT ye bu anahtar kelimeler ile sorsan sana bir şeyler sunabilir.
JavaScript:
const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs');

const app = express();
const port = 3000;

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

let projeler = JSON.parse(fs.readFileSync("projects.json"));

app.get('/projects', (req, res) => {
    return res.json(projeler)
})

app.post('/projects/:id', (req, res) => {
    var project = projects.find(x => x.id == req.params.id);
    if(!project) {
        return res.status(404).json({message: "Proje bulunamadı!"})
    }
    project.name = req.body;
    fs.writeFileSync('projects.json', JSON.stringify(projeler));

    res.send('Proje başarıyla eklendi.');
});

app.listen(port, () => {
    console.log("running");
});
 

Yeni konular

Geri
Yukarı