Mudanças entre as edições de "Javascript: CRUD Rest"

De Aulas
 
Linha 1: Linha 1:
 
Afluentes: [[Desenvolvimento Front-end I]], [[Desenvolvimento Front-end II]], [[Usabilidade, desenvolvimento web, mobile e jogos]]
 
Afluentes: [[Desenvolvimento Front-end I]], [[Desenvolvimento Front-end II]], [[Usabilidade, desenvolvimento web, mobile e jogos]]
 +
 +
= Serviço web =
 +
 +
Para que nosso CRUD possa ser funcional, precisamos de um serviço web com as operações de CRUD (CREATE, READ, UPDATE e DELETE). Para o nosso exemplo aqui, usarei um serviço web desenvolvido em linguagem de programação GO:
 +
 +
* [[Go: RESTful - um exemplo completo com persistência]]
 +
 +
Caso você queira reimplementar o serviço em Node.js ou outra linguagem/framework, basta entender o manual de acesso ao serviço web:
 +
* [[Go: RESTful - um exemplo completo com persistência#Manual de Utilização]]
 +
 +
= index.html =
 +
 +
O arquivo <code>index.html</code> contem a formatação básica da nossa aplicação
 +
 +
<syntaxhighlight lang=html>
 +
<!doctype html>
 +
<html lang="pt-br">
 +
 +
<head>
 +
    <meta charset="utf-8">
 +
    <title>Funcionários</title>
 +
    <script src="api.js"></script>
 +
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" />
 +
    <link rel="stylesheet" href="index.css">
 +
</head>
 +
 +
<body onload="carregarDados();">
 +
    <h1>Usuários</h1>
 +
    <p>
 +
        <label for="id">ID:</label>
 +
        <input type="number" id="id">
 +
    </p>
 +
    <p>
 +
        <label for="name">Nome:</label>
 +
        <input type="text" id="name">
 +
    </p>
 +
    <p>
 +
        <label for="email">E-mail:</label>
 +
        <input type="text" id="email">
 +
    </p>
 +
    <p class="btn-group">
 +
        <button class="button" onclick="gravar();">Gravar</button>
 +
        <button class="button" onclick="limpar();">Limpar</button>
 +
    </p>
 +
    <table>
 +
        <thead>
 +
            <tr>
 +
                <th>ID</th>
 +
                <th>Nome</th>
 +
                <th>E-mail</th>
 +
                <th></th>
 +
            </tr>
 +
        </thead>
 +
        <tbody id="tbody"></tbody>
 +
    </table>
 +
</body>
 +
 +
</html>
 +
</syntaxhighlight>
 +
 +
= api.js =
 +
 +
O arquivo <code>api.js</code> contem os códigos em javascript para o acesso às operações GET, POST, PUT e DELETE do nosso serviço web.
 +
 +
<syntaxhighlight lang=javascript>
 +
var url = "http://localhost:8080/users";
 +
 +
async function carregarDados() {
 +
    let tbody = document.getElementById('tbody');
 +
    tbody.innerHTML = "";
 +
    try {
 +
        const response = await fetch(url, {
 +
            method: "GET",
 +
            dataType: "json",
 +
        });
 +
        const result = await response.json();
 +
        result.forEach(row => {
 +
            let tr = document.createElement("tr");
 +
            tr.innerHTML =
 +
                `<td>${row.id}</td>
 +
                <td><a href="#" onclick="selecionar(${row.id});">
 +
                    ${row.name}</a></td>
 +
                <td>${row.email}</td>
 +
                <td>
 +
                    <a href="#" onclick="excluir(${row.id});">
 +
                    <i class="fa fa-trash-alt"></i>
 +
                    </a>
 +
                </td>`;
 +
            tbody.appendChild(tr);
 +
        });
 +
    } catch (error) {
 +
        alert("Error: " + error);
 +
    }
 +
}
 +
 +
async function selecionar(selected_id) {
 +
    let id = document.getElementById('id');
 +
    id.disabled = true;
 +
    let name = document.getElementById('name');
 +
    let email = document.getElementById('email');
 +
    try {
 +
        const response = await fetch(`${url}/${selected_id}`, {
 +
            method: "GET",
 +
            dataType: "json"
 +
        })
 +
        const user = await response.json();
 +
        id.value = user.id;
 +
        name.value = user.name;
 +
        email.value = user.email;
 +
    } catch (error) {
 +
        alert("Error: " + error);
 +
    }
 +
}
 +
 +
async function excluir(selected_id) {
 +
    try {
 +
        const response = await fetch(`${url}/${selected_id}`, {
 +
            method: "DELETE",
 +
            dataType: "json",
 +
        }).then(result => {
 +
            carregarDados();
 +
            limpar();
 +
        });
 +
    } catch (error) {
 +
        alert("Error: " + error);
 +
    }
 +
}
 +
 +
async function gravar() {
 +
    let id = document.getElementById('id');
 +
    let name = document.getElementById('name');
 +
    let email = document.getElementById('email');
 +
    let i_id = 0;
 +
    if (isNaN(i_id = parseInt(id.value))) {
 +
        alert("O id precisa ser um inteiro.");
 +
        return;
 +
    }
 +
    var data = {
 +
        id: i_id,
 +
        name: name.value,
 +
        email: email.value,
 +
    };
 +
    let method = "POST";
 +
    if (id.disabled) method = "PUT";
 +
    try {
 +
        const response = await fetch(url, {
 +
            method: method,
 +
            dataType: "json",
 +
            contentType: "application/json; charset=utf-8",
 +
            body: JSON.stringify(data),
 +
        }).then(result => {
 +
            limpar();
 +
            carregarDados();
 +
        });
 +
    } catch (error) {
 +
        alert("Error: " + error);
 +
    }
 +
}
 +
 +
function limpar() {
 +
    let id = document.getElementById('id');
 +
    id.value = "";
 +
    id.disabled = false;
 +
    document.getElementById('name').value = "";
 +
    document.getElementById('email').value = "";
 +
 +
}
 +
</syntaxhighlight>
 +
 +
= index.css =
 +
 +
Estou usando um CSS para deixar a parte visual mais bonita, mas o uso é opcional.
 +
 +
<syntaxhighlight lang=css>
 +
table {
 +
    width: 100%;
 +
}
 +
 +
th {
 +
    background-color: #04AA6D;
 +
    color: white;
 +
}
 +
 +
td {
 +
    text-align: left;
 +
    padding: 8px;
 +
}
 +
 +
tr:nth-child(even) {
 +
    background-color: #f2f2f2;
 +
}
 +
 +
input[type=number],
 +
input[type=text],
 +
select {
 +
    width: 100%;
 +
    padding: 12px 20px;
 +
    margin: 8px 0;
 +
    display: inline-block;
 +
    border: 1px solid #ccc;
 +
    border-radius: 4px;
 +
    box-sizing: border-box;
 +
}
 +
 +
input[type=submit] {
 +
    width: 100%;
 +
    background-color: #4CAF50;
 +
    color: white;
 +
    padding: 14px 20px;
 +
    margin: 8px 0;
 +
    border: none;
 +
    border-radius: 4px;
 +
    cursor: pointer;
 +
}
 +
 +
input[type=submit]:hover {
 +
    background-color: #45a049;
 +
}
 +
 +
div {
 +
    border-radius: 5px;
 +
    background-color: #f2f2f2;
 +
    padding: 20px;
 +
}
 +
 +
input[type=submit],
 +
input[type=reset] {
 +
    background-color: #04AA6D;
 +
    border: none;
 +
    color: white;
 +
    padding: 16px 32px;
 +
    text-decoration: none;
 +
    margin: 4px 2px;
 +
    cursor: pointer;
 +
}
 +
 +
.btn-group .button {
 +
    background-color: #04AA6D;
 +
    /* Green */
 +
    border: none;
 +
    color: white;
 +
    padding: 10px 16px;
 +
    text-align: center;
 +
    text-decoration: none;
 +
    display: inline-block;
 +
    font-size: 16px;
 +
    cursor: pointer;
 +
}
 +
 +
.btn-group .button:hover {
 +
    background-color: #3e8e41;
 +
}
 +
</syntaxhighlight>

Edição das 16h00min de 15 de abril de 2024

Afluentes: Desenvolvimento Front-end I, Desenvolvimento Front-end II, Usabilidade, desenvolvimento web, mobile e jogos

Serviço web

Para que nosso CRUD possa ser funcional, precisamos de um serviço web com as operações de CRUD (CREATE, READ, UPDATE e DELETE). Para o nosso exemplo aqui, usarei um serviço web desenvolvido em linguagem de programação GO:

Caso você queira reimplementar o serviço em Node.js ou outra linguagem/framework, basta entender o manual de acesso ao serviço web:

index.html

O arquivo index.html contem a formatação básica da nossa aplicação

<!doctype html>
<html lang="pt-br">

<head>
    <meta charset="utf-8">
    <title>Funcionários</title>
    <script src="api.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" />
    <link rel="stylesheet" href="index.css">
</head>

<body onload="carregarDados();">
    <h1>Usuários</h1>
    <p>
        <label for="id">ID:</label>
        <input type="number" id="id">
    </p>
    <p>
        <label for="name">Nome:</label>
        <input type="text" id="name">
    </p>
    <p>
        <label for="email">E-mail:</label>
        <input type="text" id="email">
    </p>
    <p class="btn-group">
        <button class="button" onclick="gravar();">Gravar</button>
        <button class="button" onclick="limpar();">Limpar</button>
    </p>
    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>Nome</th>
                <th>E-mail</th>
                <th></th>
            </tr>
        </thead>
        <tbody id="tbody"></tbody>
    </table>
</body>

</html>

api.js

O arquivo api.js contem os códigos em javascript para o acesso às operações GET, POST, PUT e DELETE do nosso serviço web.

var url = "http://localhost:8080/users";

async function carregarDados() {
    let tbody = document.getElementById('tbody');
    tbody.innerHTML = "";
    try {
        const response = await fetch(url, {
            method: "GET",
            dataType: "json",
        });
        const result = await response.json();
        result.forEach(row => {
            let tr = document.createElement("tr");
            tr.innerHTML =
                `<td>${row.id}</td>
                <td><a href="#" onclick="selecionar(${row.id});">
                    ${row.name}</a></td>
                <td>${row.email}</td>
                <td>
                    <a href="#" onclick="excluir(${row.id});">
                    <i class="fa fa-trash-alt"></i>
                    </a>
                </td>`;
            tbody.appendChild(tr);
        });
    } catch (error) {
        alert("Error: " + error);
    }
}

async function selecionar(selected_id) {
    let id = document.getElementById('id');
    id.disabled = true;
    let name = document.getElementById('name');
    let email = document.getElementById('email');
    try {
        const response = await fetch(`${url}/${selected_id}`, {
            method: "GET",
            dataType: "json"
        })
        const user = await response.json();
        id.value = user.id;
        name.value = user.name;
        email.value = user.email;
    } catch (error) {
        alert("Error: " + error);
    }
}

async function excluir(selected_id) {
    try {
        const response = await fetch(`${url}/${selected_id}`, {
            method: "DELETE",
            dataType: "json",
        }).then(result => {
            carregarDados();
            limpar();
        });
    } catch (error) {
        alert("Error: " + error);
    }
}

async function gravar() {
    let id = document.getElementById('id');
    let name = document.getElementById('name');
    let email = document.getElementById('email');
    let i_id = 0;
    if (isNaN(i_id = parseInt(id.value))) {
        alert("O id precisa ser um inteiro.");
        return;
    }
    var data = {
        id: i_id,
        name: name.value,
        email: email.value,
    };
    let method = "POST";
    if (id.disabled) method = "PUT";
    try {
        const response = await fetch(url, {
            method: method,
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            body: JSON.stringify(data),
        }).then(result => {
            limpar();
            carregarDados();
        });
    } catch (error) {
        alert("Error: " + error);
    }
}

function limpar() {
    let id = document.getElementById('id');
    id.value = "";
    id.disabled = false;
    document.getElementById('name').value = "";
    document.getElementById('email').value = "";

}

index.css

Estou usando um CSS para deixar a parte visual mais bonita, mas o uso é opcional.

table {
    width: 100%;
}

th {
    background-color: #04AA6D;
    color: white;
}

td {
    text-align: left;
    padding: 8px;
}

tr:nth-child(even) {
    background-color: #f2f2f2;
}

input[type=number],
input[type=text],
select {
    width: 100%;
    padding: 12px 20px;
    margin: 8px 0;
    display: inline-block;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
}

input[type=submit] {
    width: 100%;
    background-color: #4CAF50;
    color: white;
    padding: 14px 20px;
    margin: 8px 0;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

input[type=submit]:hover {
    background-color: #45a049;
}

div {
    border-radius: 5px;
    background-color: #f2f2f2;
    padding: 20px;
}

input[type=submit],
input[type=reset] {
    background-color: #04AA6D;
    border: none;
    color: white;
    padding: 16px 32px;
    text-decoration: none;
    margin: 4px 2px;
    cursor: pointer;
}

.btn-group .button {
    background-color: #04AA6D;
    /* Green */
    border: none;
    color: white;
    padding: 10px 16px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 16px;
    cursor: pointer;
}

.btn-group .button:hover {
    background-color: #3e8e41;
}