1675052580
OpenAssistant is a chat-based assistant that understands tasks, can interact with third-party systems, and retrieve information dynamically to do so.
Open Assistant is a project meant to give everyone access to a great chat based large language model.
We believe that by doing this we will create a revolution in innovation in language. In the same way that stable-diffusion helped the world make art and images in new ways we hope Open Assistant can help improve the world by improving language itself.
If you are interested in taking a look at the current state of the project, you can set up an entire stack needed to run Open-Assistant, including the website, backend, and associated dependent services.
To start the demo, run this in the root directory of the repository:
docker compose up --build
Then, navigate to http://localhost:3000
(It may take some time to boot up) and interact with the website.
Note: When logging in via email, navigate to
http://localhost:1080
to get the magic email login link.
Note: If you would like to run this in a standardized development environment (a "devcontainer") using vscode locally or in a web browser using GitHub Codespaces, you can use the provided
.devcontainer
folder.
We want to get to an initial MVP as fast as possible, by following the 3-steps outlined in the InstructGPT paper.
We can then take the resulting model and continue with completion sampling step 2 for a next iteration.
We are not going to stop at replicating ChatGPT. We want to build the assistant of the future, able to not only write email and cover letters, but do meaningful work, use APIs, dynamically research information, and much more, with the ability to be personalized and extended by anyone. And we want to do this in a way that is open and accessible, which means we must not only build a great assistant, but also make it small and efficient enough to run on consumer hardware.
All open source projects begin with people like you. Open source is the belief that if we collaborate we can together gift our knowledge and technology to the world for the benefit of humanity.
Check out our contributing guide to get started.
Author: LAION-AI
Source Code: https://github.com/LAION-AI/Open-Assistant
License: Apache-2.0 license
#python #machinelearning #ai #nextjs
1555901576
In this article we are going to focus on building a basic sidebar, and the main chat window inside our chat shell. See below.
Chat shell with a fixed width sidebar and expanded chat window
This is the second article in this series. You can check out the previous article for setting up the shell OR you can just check out the chat-shell branch from the following repository.
https://github.com/lyraddigital/flexbox-chat-app.git
Open up the chat.html file. You should have the following HTML.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Chat App</title>
<link rel="stylesheet" type="text/css" media="screen" href="css/chat.css" />
</head>
<body>
<div id="chat-container">
</div>
</body>
</html>
Now inside of the chat-container div add the following HTML.
<div id="side-bar">
</div>
<div id="chat-window">
</div>
Now let’s also add the following CSS under the #chat-container selector in the chat.css file.
#side-bar {
background: #0048AA;
border-radius: 10px 0 0 10px;
}
#chat-window {
background: #999;
border-radius: 0 10px 10px 0;
}
Now reload the page. You should see the following:-
So what happened? Where is our sidebar and where is our chat window? I expected to see a blue side bar and a grey chat window, but it’s no where to be found. Well it’s all good. This is because we have no content inside of either element, so it can be 0 pixels wide.
Sizing Flex Items
So now that we know that our items are 0 pixels wide, let’s attempt to size them. We’ll attempt to try this first using explicit widths.
Add the following width property to the #side-bar rule, then reload the page.
width: 275px;
Hmm. Same result. It’s still a blank shell. Oh wait I have to make sure the height is 100% too. So we better do that too. Once again add the following property to the #side-bar rule, then reload the page.
height: 100%;
So now we have our sidebar that has grown to be exactly 275 pixels wide, and is 100% high. So that’s it. We’re done right? Wrong. Let me ask you a question. How big is the chat window? Let’s test that by adding some text to it. Try this yourself just add some text. You should see something similar to this.
So as you can see the chat window is only as big as the text that’s inside of it, and it is not next to the side bar. And this makes sense because up until now the chat shell is not a flex container, and just a regular block level element.
So let’s make our chat shell a flex container. Set the following display property for the #chat-window selector. Then reload the page.
display: flex;
So as you can see by the above illustration, we can see it’s now next to the side bar, and not below it. But as you can see currently it’s only as wide as the text that’s inside of it.
But we want it to take up the remaining space of the chat shell. Well we know how to do this, as we did it in the previous article. Set the flex-grow property to 1 on the #chat-window selector. Basically copy and paste the property below and reload the page.
flex-grow: 1;
So now we have the chat window taking up the remaining space of the chat shell. Next, let’s remove the background property, and also remove all text inside the chat-window div if any still exists. You should now see the result below.
But are we done? Technically yes, but before we move on, let’s improve things a little bit.
Understanding the default alignment
If you remember, before we had defined our chat shell to be a flex container, we had to make sure we set the height of the side bar to be 100%. Otherwise it was 0 pixels high, and as a result nothing was displayed. With that said, try removing the height property from the #side-bar selector and see what happens when you reload the page. Yes that’s right, it still works. The height of the sidebar is still 100% high.
So what happened here? Why do we no longer have to worry about setting the height to 100%? Well this is one of the cool things Flexbox gives you for free. By default every flex item will stretch vertically to fill in the entire height of the flex container. We can in fact change this behaviour, and we will see how this is done in a future article.
Setting the size of the side bar properly
So another feature of Flexbox is being able to set the size of a flex item by using the flex-basis property. The flex-basis property allows you to specify an initial size of a flex item, before any growing or shrinking takes place. We’ll understand more about this in an upcoming article.
For now I just want you to understand one important thing. And that is using width to specify the size of the sidebar is not a good idea. Let’s see why.
Say that potentially, if the screen is mobile we want the side bar to now appear across the top of the chat shell, acting like a top bar instead. We can do this by changing the direction flex items can flex inside a flex container. For example, add the following CSS to the #chat-container selector. Then reload the page.
flex-direction: column;
So as you can see we are back to a blank shell. So firstly let’s understand what we actually did here. By setting the flex-direction property to column, we changed the direction of how the flex items flex. By default flex items will flex from left to right. However when we set flex-direction to column, it changes this behaviour forcing flex items to flex from top to bottom instead. On top of this, when the direction of flex changes, the sizing and alignment of flex items changes as well.
When flexing from left to right, we get a height of 100% for free as already mentioned, and then we made sure the side bar was set to be 275 pixels wide, by setting the width property.
However now that we a flexing from top to bottom, the width of the flex item by default would be 100% wide, and you would need to specify the height instead. So try this. Add the following property to the #side-bar selector to set the height of the side bar. Then reload the page.
height: 275px;
Now we are seeing the side bar again, as we gave it a fixed height too. But we still have that fixed width. That’s not what we wanted. We want the side bar (ie our new top bar) here to now be 100% wide. Comment out the width for a moment and reload the page again.
So now we were able to move our side bar so it appears on top instead, acting like a top bar. Which as previously mentioned might be suited for mobile device widths. But to do this we had to swap the value of width to be the value of height. Wouldn’t it be great if this size was preserved regardless of which direction our items are flexing.
Try this, remove all widths and height properties from the #side-bar selector and write the following instead. Then reload the page.
flex-basis: 275px;
As you can see we get the same result. Now remove the flex-direction property from the #chat-container selector. Then once again reload the page.
Once again we are back to our final output. But now we also have the flexibility to easily change the side bar to be a top bar if we need to, by just changing the direction items can flow. Regardless of the direction of flex, the size of our side bar / top bar is preserved.
Conclusion
Ok so once again we didn’t build much, but we did cover a lot of concepts about Flexbox around sizing.
#css #programming #webdev
1650391200
The Ansible Jupyter Kernel adds a kernel backend for Jupyter to interface directly with Ansible and construct plays and tasks and execute them on the fly.
ansible-kernel
is available to be installed from pypi but you can also install it locally. The setup package itself will register the kernel with Jupyter
automatically.
pip install ansible-kernel
python -m ansible_kernel.install
pip install -e .
python -m ansible_kernel.install
pip install ansible-kernel
python -m ansible_kernel.install --sys-prefix
jupyter notebook
# In the notebook interface, select Ansible from the 'New' menu
docker run -p 8888:8888 benthomasson/ansible-jupyter-kernel
Then copy the URL from the output into your browser:
http://localhost:8888/?token=ABCD1234
Normally Ansible
brings together various components in different files and locations to launch a playbook and performs automation tasks. For this jupyter
interface you need to provide this information in cells by denoting what the cell contains and then finally writing your tasks that will make use of them. There are Examples available to help you, in this section we'll go over the currently supported cell types.
In order to denote what the cell contains you should prefix it with a pound/hash symbol (#) and the type as listed here as the first line as shown in the examples below.
The inventory that your tasks will use
#inventory
[all]
ahost ansible_connection=local
anotherhost examplevar=val
This represents the opening block of a typical Ansible
play
#play
name: Hello World
hosts: all
gather_facts: false
This is the default cell type if no type is given for the first line
#task
debug:
#task
shell: cat /tmp/afile
register: output
This takes an argument that represents the hostname. Variables defined in this file will be available in the tasks for that host.
#host_vars Host1
hostname: host1
This takes an argument that represents the group name. Variables defined in this file will be available in the tasks for hosts in that group.
#group_vars BranchOfficeX
gateway: 192.168.1.254
This takes an argument that represents the filename for use in later cells
#vars example_vars
message: hello vars
#play
name: hello world
hosts: localhost
gather_facts: false
vars_files:
- example_vars
This takes an argument in order to create a templated file that can be used in later cells
#template hello.j2
{{ message }}
#task
template:
src: hello.j2
dest: /tmp/hello
Provides overrides typically found in ansible.cfg
#ansible.cfg
[defaults]
host_key_checking=False
You can find various example notebooks in the repository
It's possible to use whatever python development process you feel comfortable with. The repository itself includes mechanisms for using pipenv
pipenv install
...
pipenv shell
Author: ansible
Source Code: https://github.com/ansible/ansible-jupyter-kernel
License: Apache-2.0 License
1612606870
Build a Real Time chat application that can integrated into your social handles. Add more life to your website or support portal with a real time chat solutions for mobile apps that shows online presence indicators, typing status, timestamp, multimedia sharing and much more. Users can also log into the live chat app using their social media logins sparing them from the need to remember usernames and passwords. For more information call us at +18444455767 or email us at hello@sisgain.com or Visit: https://sisgain.com/instant-real-time-chat-solutions-mobile-apps
#real time chat solutions for mobile apps #real time chat app development solutions #live chat software for mobile #live chat software solutions #real time chat app development #real time chat applications in java script
1649978400
Hoy vamos a aprender cómo hacer operaciones CRUD en JavaScript creando una aplicación Todo. Empecemos 🔥
Esta es la aplicación que estamos haciendo hoy:
CRUD significa -
CRUD es un tipo de mecanismo que le permite crear datos, leer datos, editarlos y eliminar esos datos. En nuestro caso, vamos a crear una aplicación Todo, por lo que tendremos 4 opciones para crear tareas, leer tareas, actualizar tareas o eliminar tareas.
Antes de comenzar el tutorial, primero, comprendamos los principios CRUD. Para eso, creemos una aplicación de redes sociales muy, muy simple.
Para este proyecto, seguiremos los siguientes pasos:
Dentro de la etiqueta del cuerpo, crea un div con un nombre de clase .container
. Ahí tendremos 2 secciones, .left
y .right
👇
<body>
<h1>Social Media App</h1>
<div class="container">
<div class="left"></div>
<div class="right"></div>
</div>
</body>
En el lado izquierdo, crearemos nuestras publicaciones. En el lado derecho, podemos ver, actualizar y eliminar nuestras publicaciones. Ahora, crea un formulario dentro de la etiqueta div .left 👇
<div class="left">
<form id="form">
<label for="post"> Write your post here</label>
<br><br>
<textarea name="post" id="input" cols="30" rows="10"></textarea>
<br> <br>
<div id="msg"></div>
<button type="submit">Post</button>
</form>
</div>
Escribe este código dentro del HTML para que podamos mostrar nuestra publicación en el lado derecho 👇
<div class="right">
<h3>Your posts here</h3>
<div id="posts"></div>
</div>
A continuación, insertaremos el CDN font-awesome dentro de la etiqueta de encabezado para usar sus fuentes en nuestro proyecto 👇
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />
Ahora, vamos a hacer algunas publicaciones de muestra con íconos de eliminar y editar. Escribe este código dentro del div con el id #posts: 👇
<div id="posts">
<div>
<p>Hello world post 1</p>
<span class="options">
<i class="fas fa-edit"></i>
<i class="fas fa-trash-alt"></i>
</span>
</div>
<div >
<p>Hello world post 2</p>
<span class="options">
<i class="fas fa-edit"></i>
<i class="fas fa-trash-alt"></i>
</span>
</div>
</div>
El resultado hasta ahora se ve así:
Mantengámoslo simple. Escribe estos estilos dentro de tu hoja de estilo: 👇
body {
font-family: sans-serif;
margin: 0 50px;
}
.container {
display: flex;
gap: 50px;
}
#posts {
width: 400px;
}
i {
cursor: pointer;
}
Ahora, escribe estos estilos para los íconos de opción y div posteriores: 👇
#posts div {
display: flex;
align-items: center;
justify-content: space-between;
}
.options {
display: flex;
gap: 25px;
}
#msg {
color: red;
}
Los resultados hasta ahora se ven así: 👇
De acuerdo con este diagrama de flujo, seguiremos adelante con el proyecto. No te preocupes, te explicaré todo en el camino. 👇
Primero, apuntemos a todos los selectores de ID del HTML en JavaScript. Así: 👇
let form = document.getElementById("form");
let input = document.getElementById("input");
let msg = document.getElementById("msg");
let posts = document.getElementById("posts");
Luego, cree un detector de eventos de envío para el formulario para que pueda evitar el comportamiento predeterminado de nuestra aplicación. Al mismo tiempo, crearemos una función llamada formValidation
. 👇
form.addEventListener("submit", (e) => {
e.preventDefault();
console.log("button clicked");
formValidation();
});
let formValidation = () => {};
Ahora, vamos a hacer una declaración if else dentro de nuestra formValidation
función. Esto nos ayudará a evitar que los usuarios envíen campos de entrada en blanco. 👇
let formValidation = () => {
if (input.value === "") {
msg.innerHTML = "Post cannot be blank";
console.log("failure");
} else {
console.log("successs");
msg.innerHTML = "";
}
};
Aquí está el resultado hasta ahora: 👇
Como puede ver, también aparecerá un mensaje si el usuario intenta enviar el formulario en blanco.
Cualesquiera que sean los datos que obtengamos de los campos de entrada, los almacenaremos en un objeto. Vamos a crear un objeto llamado data
. Y crea una función llamada acceptData
: 👇
let data = {};
let acceptData = () => {};
La idea principal es que, usando la función, recopilamos datos de las entradas y los almacenamos en nuestro objeto llamado data
. Ahora terminemos de construir nuestra acceptData
función.
let acceptData = () => {
data["text"] = input.value;
console.log(data);
};
Además, necesitamos que la acceptData
función funcione cuando el usuario haga clic en el botón Enviar. Para eso, activaremos esta función en la instrucción else de nuestra formValidation
función. 👇
let formValidation = () => {
if (input.value === "") {
// Other codes are here
} else {
// Other codes are here
acceptData();
}
};
Cuando ingresamos datos y enviamos el formulario, en la consola podemos ver un objeto que contiene los valores de entrada de nuestro usuario. Así: 👇
Para publicar nuestros datos de entrada en el lado derecho, necesitamos crear un elemento div y agregarlo al div de publicaciones. Primero, creemos una función y escribamos estas líneas: 👇
let createPost = () => {
posts.innerHTML += ``;
};
Los acentos graves son literales de plantilla. Funcionará como una plantilla para nosotros. Aquí, necesitamos 3 cosas: un div principal, la entrada en sí y el div de opciones que lleva los íconos de edición y eliminación. Terminemos nuestra función 👇
let createPost = () => {
posts.innerHTML += `
<div>
<p>${data.text}</p>
<span class="options">
<i onClick="editPost(this)" class="fas fa-edit"></i>
<i onClick="deletePost(this)" class="fas fa-trash-alt"></i>
</span>
</div>
`;
input.value = "";
};
En nuestra acceptdata
función, activaremos nuestra createPost
función. Así: 👇
let acceptData = () => {
// Other codes are here
createPost();
};
El resultado hasta ahora: 👇
Hasta ahora todo bien chicos, casi hemos terminado con el proyecto 1.
Para eliminar una publicación, en primer lugar, creemos una función dentro de nuestro archivo javascript:
let deletePost = (e) => {};
A continuación, activamos esta deletePost
función dentro de todos nuestros íconos de eliminación usando un atributo onClick. Escribirá estas líneas en HTML y en el literal de la plantilla. 👇
<i onClick="deletePost(this)" class="fas fa-trash-alt"></i>
La this
palabra clave se referirá al elemento que disparó el evento. en nuestro caso, el this
se refiere al botón eliminar.
Mire con cuidado, el padre del botón Eliminar es el tramo con opciones de nombre de clase. El padre del lapso es el div. Entonces, escribimos parentElement
dos veces para que podamos saltar del ícono de eliminar al div y apuntarlo directamente para eliminarlo.
Terminemos nuestra función. 👇
let deletePost = (e) => {
e.parentElement.parentElement.remove();
};
El resultado hasta ahora: 👇
Para editar una publicación, en primer lugar, creemos una función dentro de nuestro archivo JavaScript:
let editPost = (e) => {};
A continuación, activamos esta editPost
función dentro de todos nuestros íconos de edición usando un atributo onClick. Escribirá estas líneas en HTML y en el literal de la plantilla. 👇
<i onClick="editPost(this)" class="fas fa-edit"></i>
La this
palabra clave se referirá al elemento que disparó el evento. En nuestro caso, el this
se refiere al botón editar.
Mire con cuidado, el padre del botón de edición es el tramo con opciones de nombre de clase. El padre del lapso es el div. Entonces, escribimos parentElement
dos veces para que podamos saltar del ícono de edición al div y apuntarlo directamente para eliminarlo.
Luego, cualquier dato que esté dentro de la publicación, lo traemos de vuelta al campo de entrada para editarlo.
Terminemos nuestra función. 👇
let editPost = (e) => {
input.value = e.parentElement.previousElementSibling.innerHTML;
e.parentElement.parentElement.remove();
};
El resultado hasta ahora: 👇
Felicitaciones a todos por completar el proyecto 1. Ahora, ¡tómense un pequeño descanso!
Cómo hacer una aplicación de tareas pendientes usando operaciones CRUD
Comencemos a hacer el proyecto 2, que es una aplicación To-Do.
Para este proyecto, seguiremos los siguientes pasos:
Escribe este código de inicio dentro del archivo HTML: 👇
<div class="app">
<h4 class="mb-3">TODO App</h4>
<div id="addNew" data-bs-toggle="modal" data-bs-target="#form">
<span>Add New Task</span>
<i class="fas fa-plus"></i>
</div>
</div>
El div con una identificación addNew
es el botón que abrirá el modal. El intervalo se mostrará en el botón. El i
es el ícono de font-awesome.
Vamos a usar bootstrap para hacer nuestro modal. Usaremos el modal para agregar nuevas tareas. Para eso, agregue el enlace CDN de arranque dentro de la etiqueta principal. 👇
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
crossorigin="anonymous"
/>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
crossorigin="anonymous"
></script>
Para ver las tareas creadas, usaremos un div con una tarea de identificación, dentro del div con la aplicación de nombre de clase. 👇
<h5 class="text-center my-3">Tasks</h5>
<div id="tasks"></div>
Inserte el CDN font-awesome dentro de la etiqueta principal para usar fuentes en nuestro proyecto 👇
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />
Copie y pegue el código a continuación que proviene del modal de arranque. Lleva un formulario con 3 campos de entrada y un botón de envío. Si lo desea, puede buscar en el sitio web de Bootstrap escribiendo 'modal' en la barra de búsqueda.
<!-- Modal -->
<form
class="modal fade"
id="form"
tabindex="-1"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add New Task</h5>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">
<p>Task Title</p>
<input type="text" class="form-control" name="" id="textInput" />
<div id="msg"></div>
<br />
<p>Due Date</p>
<input type="date" class="form-control" name="" id="dateInput" />
<br />
<p>Description</p>
<textarea
name=""
class="form-control"
id="textarea"
cols="30"
rows="5"
></textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
Close
</button>
<button type="submit" id="add" class="btn btn-primary">Add</button>
</div>
</div>
</div>
</form>
El resultado hasta ahora: 👇
Hemos terminado con la configuración del archivo HTML. Comencemos el CSS.
Agregue estos estilos en el cuerpo para que podamos mantener nuestra aplicación en el centro exacto de la pantalla.
body {
font-family: sans-serif;
margin: 0 50px;
background-color: #e5e5e5;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
Apliquemos estilo al div con la aplicación classname. 👇
.app {
background-color: #fff;
width: 300px;
height: 500px;
border: 5px solid #abcea1;
border-radius: 8px;
padding: 15px;
}
El resultado hasta ahora: 👇
Ahora, diseñemos el botón con el id addNew
. 👇
#addNew {
display: flex;
justify-content: space-between;
align-items: center;
background-color: rgba(171, 206, 161, 0.35);
padding: 5px 10px;
border-radius: 5px;
cursor: pointer;
}
.fa-plus {
background-color: #abcea1;
padding: 3px;
border-radius: 3px;
}
El resultado hasta ahora: 👇
Si hace clic en el botón, el modal aparece así: 👇
En el archivo JavaScript, en primer lugar, seleccione todos los selectores del HTML que necesitamos usar. 👇
let form = document.getElementById("form");
let textInput = document.getElementById("textInput");
let dateInput = document.getElementById("dateInput");
let textarea = document.getElementById("textarea");
let msg = document.getElementById("msg");
let tasks = document.getElementById("tasks");
let add = document.getElementById("add");
No podemos permitir que un usuario envíe campos de entrada en blanco. Entonces, necesitamos validar los campos de entrada. 👇
form.addEventListener("submit", (e) => {
e.preventDefault();
formValidation();
});
let formValidation = () => {
if (textInput.value === "") {
console.log("failure");
msg.innerHTML = "Task cannot be blank";
} else {
console.log("success");
msg.innerHTML = "";
}
};
Además, agregue esta línea dentro del CSS:
#msg {
color: red;
}
El resultado hasta ahora: 👇
Como puede ver, la validación está funcionando. El código JavaScript no permite que el usuario envíe campos de entrada en blanco; de lo contrario, verá un mensaje de error.
Independientemente de las entradas que escriba el usuario, debemos recopilarlas y almacenarlas en el almacenamiento local.
Primero, recopilamos los datos de los campos de entrada, usando la función named acceptData
y una matriz llamada data
. Luego los empujamos dentro del almacenamiento local así: 👇
let data = [];
let acceptData = () => {
data.push({
text: textInput.value,
date: dateInput.value,
description: textarea.value,
});
localStorage.setItem("data", JSON.stringify(data));
console.log(data);
};
También tenga en cuenta que esto nunca funcionará a menos que invoque la función acceptData
dentro de la declaración else de la validación del formulario. Síguenos aquí: 👇
let formValidation = () => {
// Other codes are here
else {
// Other codes are here
acceptData();
}
};
Es posible que haya notado que el modal no se cierra automáticamente. Para resolver esto, escribe esta pequeña función dentro de la instrucción else de la validación del formulario: 👇
let formValidation = () => {
// Other codes are here
else {
// Other codes are here
acceptData();
add.setAttribute("data-bs-dismiss", "modal");
add.click();
(() => {
add.setAttribute("data-bs-dismiss", "");
})();
}
};
Si abre las herramientas de desarrollo de Chrome, vaya a la aplicación y abra el almacenamiento local. Puedes ver este resultado: 👇
Para crear una nueva tarea, necesitamos crear una función, usar literales de plantilla para crear los elementos HTML y usar un mapa para insertar los datos recopilados del usuario dentro de la plantilla. Síguenos aquí: 👇
let createTasks = () => {
tasks.innerHTML = "";
data.map((x, y) => {
return (tasks.innerHTML += `
<div id=${y}>
<span class="fw-bold">${x.text}</span>
<span class="small text-secondary">${x.date}</span>
<p>${x.description}</p>
<span class="options">
<i onClick= "editTask(this)" data-bs-toggle="modal" data-bs-target="#form" class="fas fa-edit"></i>
<i onClick ="deleteTask(this);createTasks()" class="fas fa-trash-alt"></i>
</span>
</div>
`);
});
resetForm();
};
También tenga en cuenta que la función nunca se ejecutará a menos que la invoque dentro de la acceptData
función, así: 👇
let acceptData = () => {
// Other codes are here
createTasks();
};
Una vez que hayamos terminado de recopilar y aceptar datos del usuario, debemos borrar los campos de entrada. Para eso creamos una función llamada resetForm
. Síguenos: 👇
let resetForm = () => {
textInput.value = "";
dateInput.value = "";
textarea.value = "";
};
El resultado hasta ahora: 👇
Como puede ver, no hay estilos con la tarjeta. Agreguemos algunos estilos: 👇
#tasks {
display: grid;
grid-template-columns: 1fr;
gap: 14px;
}
#tasks div {
border: 3px solid #abcea1;
background-color: #e2eede;
border-radius: 6px;
padding: 5px;
display: grid;
gap: 4px;
}
Dale estilo a los botones de editar y eliminar con este código: 👇
#tasks div .options {
justify-self: center;
display: flex;
gap: 20px;
}
#tasks div .options i {
cursor: pointer;
}
El resultado hasta ahora: 👇
Mire aquí cuidadosamente, agregué 3 líneas de código dentro de la función.
let deleteTask = (e) => {
e.parentElement.parentElement.remove();
data.splice(e.parentElement.parentElement.id, 1);
localStorage.setItem("data", JSON.stringify(data));
console.log(data);
};
Ahora cree una tarea ficticia e intente eliminarla. El resultado hasta ahora se ve así: 👇
Mire aquí cuidadosamente, agregué 5 líneas de código dentro de la función.
let editTask = (e) => {
let selectedTask = e.parentElement.parentElement;
textInput.value = selectedTask.children[0].innerHTML;
dateInput.value = selectedTask.children[1].innerHTML;
textarea.value = selectedTask.children[2].innerHTML;
deleteTask(e);
};
Ahora, intente crear una tarea ficticia y edítela. El resultado hasta ahora: 👇
Si actualiza la página, notará que todos sus datos han desaparecido. Para resolver ese problema, ejecutamos un IIFE (expresión de función invocada inmediatamente) para recuperar los datos del almacenamiento local. Síguenos: 👇
(() => {
data = JSON.parse(localStorage.getItem("data")) || [];
console.log(data);
createTasks();
})();
Ahora los datos aparecerán incluso si actualiza la página.
Felicitaciones por completar con éxito este tutorial. Ha aprendido a crear una aplicación de lista de tareas mediante operaciones CRUD. Ahora, puede crear su propia aplicación CRUD usando este tutorial.
Aquí está tu medalla por leer hasta el final. ❤️
Fuente: https://www.freecodecamp.org/news/learn-crud-operations-in-javascript-by-building-todo-app/
1650021960
今日は、Todoアプリを作成してJavaScriptでCRUD操作を行う方法を学びます。始めましょう🔥
これは私たちが今日作っているアプリです:
CRUDは-の略です
CRUDは、データの作成、データの読み取り、編集、およびそれらのデータの削除を可能にするメカニズムの一種です。この例では、Todoアプリを作成するので、タスクの作成、タスクの読み取り、タスクの更新、またはタスクの削除を行うための4つのオプションがあります。
チュートリアルを開始する前に、まず、CRUDの原則を理解しましょう。そのために、非常に単純なソーシャルメディアアプリケーションを作成しましょう。
このプロジェクトでは、以下の手順に従います。
bodyタグ内に、クラス名を使用してdivを作成します.container
。そこには2つのセクションがあり.left
、.right
👇
<body>
<h1>Social Media App</h1>
<div class="container">
<div class="left"></div>
<div class="right"></div>
</div>
</body>
左側に投稿を作成します。右側では、投稿を表示、更新、削除できます。次に、.leftdivタグ内にフォームを作成します👇
<div class="left">
<form id="form">
<label for="post"> Write your post here</label>
<br><br>
<textarea name="post" id="input" cols="30" rows="10"></textarea>
<br> <br>
<div id="msg"></div>
<button type="submit">Post</button>
</form>
</div>
このコードをHTML内に記述して、投稿を右側に表示できるようにします👇
<div class="right">
<h3>Your posts here</h3>
<div id="posts"></div>
</div>
次に、プロジェクトでそのフォントを使用するために、headタグ内にfont-awesomeCDNを挿入します👇
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />
次に、削除アイコンと編集アイコンを使用してサンプル投稿を作成します。このコードをdiv内にID#postsで記述します:👇
<div id="posts">
<div>
<p>Hello world post 1</p>
<span class="options">
<i class="fas fa-edit"></i>
<i class="fas fa-trash-alt"></i>
</span>
</div>
<div >
<p>Hello world post 2</p>
<span class="options">
<i class="fas fa-edit"></i>
<i class="fas fa-trash-alt"></i>
</span>
</div>
</div>
これまでの結果は次のようになります。
シンプルにしましょう。スタイルシート内にこれらのスタイルを記述します:👇
body {
font-family: sans-serif;
margin: 0 50px;
}
.container {
display: flex;
gap: 50px;
}
#posts {
width: 400px;
}
i {
cursor: pointer;
}
次に、投稿divとオプションアイコンに次のスタイルを記述します。👇
#posts div {
display: flex;
align-items: center;
justify-content: space-between;
}
.options {
display: flex;
gap: 25px;
}
#msg {
color: red;
}
これまでの結果は次のようになります:👇
このフローチャートに従って、プロジェクトを進めていきます。心配しないでください、私は途中ですべてを説明します。👇
まず、JavaScriptのHTMLからすべてのIDセレクターをターゲットにしましょう。このように:👇
let form = document.getElementById("form");
let input = document.getElementById("input");
let msg = document.getElementById("msg");
let posts = document.getElementById("posts");
次に、フォームの送信イベントリスナーを作成して、アプリのデフォルトの動作を防ぐことができるようにします。同時に、という名前の関数を作成しますformValidation
。👇
form.addEventListener("submit", (e) => {
e.preventDefault();
console.log("button clicked");
formValidation();
});
let formValidation = () => {};
次に、関数内でifelseステートメントを作成しformValidation
ます。これにより、ユーザーが空白の入力フィールドを送信するのを防ぐことができます。👇
let formValidation = () => {
if (input.value === "") {
msg.innerHTML = "Post cannot be blank";
console.log("failure");
} else {
console.log("successs");
msg.innerHTML = "";
}
};
これまでの結果は次のとおりです:👇
ご覧のとおり、ユーザーがフォームを空白で送信しようとすると、メッセージも表示されます。
入力フィールドから取得するデータが何であれ、それらをオブジェクトに格納します。。という名前のオブジェクトを作成しましょうdata
。そして、次の名前の関数を作成しますacceptData
:👇
let data = {};
let acceptData = () => {};
主なアイデアは、関数を使用して、入力からデータを収集し、という名前のオブジェクトに格納することdata
です。acceptData
それでは、関数の作成を完了しましょう。
let acceptData = () => {
data["text"] = input.value;
console.log(data);
};
また、acceptData
ユーザーが送信ボタンをクリックしたときに機能する機能が必要です。そのために、関数のelseステートメントでこの関数を起動しformValidation
ます。👇
let formValidation = () => {
if (input.value === "") {
// Other codes are here
} else {
// Other codes are here
acceptData();
}
};
データを入力してフォームを送信すると、コンソールにユーザーの入力値を保持しているオブジェクトが表示されます。このように:👇
入力データを右側に投稿するには、div要素を作成し、それを投稿divに追加する必要があります。まず、関数を作成して次の行を記述しましょう:👇
let createPost = () => {
posts.innerHTML += ``;
};
バックティックはテンプレートリテラルです。それは私たちのテンプレートとして機能します。ここでは、親div、入力自体、および編集アイコンと削除アイコンを保持するオプションdivの3つが必要です。機能を終了しましょう👇
let createPost = () => {
posts.innerHTML += `
<div>
<p>${data.text}</p>
<span class="options">
<i onClick="editPost(this)" class="fas fa-edit"></i>
<i onClick="deletePost(this)" class="fas fa-trash-alt"></i>
</span>
</div>
`;
input.value = "";
};
acceptdata
関数では、関数を起動しますcreatePost
。このように:👇
let acceptData = () => {
// Other codes are here
createPost();
};
これまでの結果:👇
これまでのところ、プロジェクト1はほぼ完了しています。
投稿を削除するために、まず、javascriptファイル内に関数を作成しましょう。
let deletePost = (e) => {};
deletePost
次に、onClick属性を使用して、すべての削除アイコン内でこの関数を起動します。これらの行は、HTMLとテンプレートリテラルで記述します。👇
<i onClick="deletePost(this)" class="fas fa-trash-alt"></i>
this
キーワードは、イベントを発生させた要素を参照します。この場合、this
は削除ボタンを指します。
注意深く見てください。削除ボタンの親は、クラス名オプションのあるスパンです。スパンの親はdivです。parentElement
したがって、削除アイコンからdivにジャンプし、直接ターゲットにして削除できるように、2回書き込みます。
関数を終了しましょう。👇
let deletePost = (e) => {
e.parentElement.parentElement.remove();
};
これまでの結果:👇
投稿を編集するために、まず、JavaScriptファイル内に関数を作成しましょう。
let editPost = (e) => {};
editPost
次に、onClick属性を使用して、すべての編集アイコン内でこの関数を起動します。これらの行は、HTMLとテンプレートリテラルで記述します。👇
<i onClick="editPost(this)" class="fas fa-edit"></i>
this
キーワードは、イベントを発生させた要素を参照します。この場合、this
は編集ボタンを指します。
注意深く見てください。編集ボタンの親は、クラス名オプションのあるスパンです。スパンの親はdivです。parentElement
したがって、編集アイコンからdivにジャンプし、直接ターゲットにして削除できるように、2回書き込みます。
次に、投稿内のデータが何であれ、入力フィールドに戻して編集します。
関数を終了しましょう。👇
let editPost = (e) => {
input.value = e.parentElement.previousElementSibling.innerHTML;
e.parentElement.parentElement.remove();
};
これまでの結果:👇
プロジェクト1を完了してくださった皆さん、おめでとうございます。さあ、ちょっと休憩してください。
CRUD操作を使用してToDoアプリを作成する方法
To-Doアプリであるプロジェクト2の作成を始めましょう。
このプロジェクトでは、以下の手順に従います。
このスターターコードをHTMLファイル内に記述します:👇
<div class="app">
<h4 class="mb-3">TODO App</h4>
<div id="addNew" data-bs-toggle="modal" data-bs-target="#form">
<span>Add New Task</span>
<i class="fas fa-plus"></i>
</div>
</div>
IDを持つdivaddNew
は、モーダルを開くボタンです。ボタンにスパンが表示されます。これi
はfont-awesomeのアイコンです。
ブートストラップを使用してモーダルを作成します。モーダルを使用して新しいタスクを追加します。そのために、headタグ内にブートストラップCDNリンクを追加します。👇
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
crossorigin="anonymous"
/>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
crossorigin="anonymous"
></script>
作成されたタスクを確認するには、クラス名アプリを使用したdiv内で、idタスクを使用したdivを使用します。👇
<h5 class="text-center my-3">Tasks</h5>
<div id="tasks"></div>
プロジェクトでフォントを使用するには、headタグ内にfont-awesomeCDNを挿入します👇
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />
ブートストラップモーダルからの以下のコードをコピーして貼り付けます。3つの入力フィールドと送信ボタンを備えたフォームがあります。必要に応じて、検索バーに「モーダル」と入力して、BootstrapのWebサイトを検索できます。
<!-- Modal -->
<form
class="modal fade"
id="form"
tabindex="-1"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add New Task</h5>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">
<p>Task Title</p>
<input type="text" class="form-control" name="" id="textInput" />
<div id="msg"></div>
<br />
<p>Due Date</p>
<input type="date" class="form-control" name="" id="dateInput" />
<br />
<p>Description</p>
<textarea
name=""
class="form-control"
id="textarea"
cols="30"
rows="5"
></textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
Close
</button>
<button type="submit" id="add" class="btn btn-primary">Add</button>
</div>
</div>
</div>
</form>
これまでの結果:👇
HTMLファイルの設定は完了です。CSSを始めましょう。
これらのスタイルを本文に追加して、アプリを画面の正確な中央に配置できるようにします。
body {
font-family: sans-serif;
margin: 0 50px;
background-color: #e5e5e5;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
classnameアプリでdivのスタイルを設定しましょう。👇
.app {
background-color: #fff;
width: 300px;
height: 500px;
border: 5px solid #abcea1;
border-radius: 8px;
padding: 15px;
}
これまでの結果:👇
それでは、idを使用してボタンのスタイルを設定しましょうaddNew
。👇
#addNew {
display: flex;
justify-content: space-between;
align-items: center;
background-color: rgba(171, 206, 161, 0.35);
padding: 5px 10px;
border-radius: 5px;
cursor: pointer;
}
.fa-plus {
background-color: #abcea1;
padding: 3px;
border-radius: 3px;
}
これまでの結果:👇
ボタンをクリックすると、モーダルが次のようにポップアップ表示されます:👇
JavaScriptファイルで、まず、使用する必要のあるHTMLからすべてのセレクターを選択します。👇
let form = document.getElementById("form");
let textInput = document.getElementById("textInput");
let dateInput = document.getElementById("dateInput");
let textarea = document.getElementById("textarea");
let msg = document.getElementById("msg");
let tasks = document.getElementById("tasks");
let add = document.getElementById("add");
ユーザーに空白の入力フィールドを送信させることはできません。したがって、入力フィールドを検証する必要があります。👇
form.addEventListener("submit", (e) => {
e.preventDefault();
formValidation();
});
let formValidation = () => {
if (textInput.value === "") {
console.log("failure");
msg.innerHTML = "Task cannot be blank";
} else {
console.log("success");
msg.innerHTML = "";
}
};
また、CSS内に次の行を追加します。
#msg {
color: red;
}
これまでの結果:👇
ご覧のとおり、検証は機能しています。JavaScriptコードでは、ユーザーが空白の入力フィールドを送信することはできません。そうしないと、エラーメッセージが表示されます。
ユーザーが書き込んだ入力が何であれ、それらを収集してローカルストレージに保存する必要があります。
まず、という名前の関数とという名前acceptData
の配列を使用して、入力フィールドからデータを収集しますdata
。次に、次のようにローカルストレージ内にプッシュします:👇
let data = [];
let acceptData = () => {
data.push({
text: textInput.value,
date: dateInput.value,
description: textarea.value,
});
localStorage.setItem("data", JSON.stringify(data));
console.log(data);
};
acceptData
また、フォーム検証のelseステートメント内で関数を呼び出さない限り、これは機能しないことに注意してください。ここに従ってください:👇
let formValidation = () => {
// Other codes are here
else {
// Other codes are here
acceptData();
}
};
モーダルが自動的に閉じないことに気付いたかもしれません。これを解決するには、フォーム検証のelseステートメント内にこの小さな関数を記述します。👇
let formValidation = () => {
// Other codes are here
else {
// Other codes are here
acceptData();
add.setAttribute("data-bs-dismiss", "modal");
add.click();
(() => {
add.setAttribute("data-bs-dismiss", "");
})();
}
};
Chrome開発ツールを開く場合は、アプリケーションに移動してローカルストレージを開きます。あなたはこの結果を見ることができます:👇
新しいタスクを作成するには、関数を作成し、テンプレートリテラルを使用してHTML要素を作成し、マップを使用してユーザーから収集したデータをテンプレート内にプッシュする必要があります。ここに従ってください:👇
let createTasks = () => {
tasks.innerHTML = "";
data.map((x, y) => {
return (tasks.innerHTML += `
<div id=${y}>
<span class="fw-bold">${x.text}</span>
<span class="small text-secondary">${x.date}</span>
<p>${x.description}</p>
<span class="options">
<i onClick= "editTask(this)" data-bs-toggle="modal" data-bs-target="#form" class="fas fa-edit"></i>
<i onClick ="deleteTask(this);createTasks()" class="fas fa-trash-alt"></i>
</span>
</div>
`);
});
resetForm();
};
また、次のacceptData
ように、関数内で呼び出さない限り、関数は実行されないことに注意してください。👇
let acceptData = () => {
// Other codes are here
createTasks();
};
ユーザーからのデータの収集と受け入れが完了したら、入力フィールドをクリアする必要があります。そのために、と呼ばれる関数を作成しますresetForm
。フォローする:👇
let resetForm = () => {
textInput.value = "";
dateInput.value = "";
textarea.value = "";
};
これまでの結果:👇
ご覧のとおり、このカードにはスタイルはありません。いくつかのスタイルを追加しましょう:👇
#tasks {
display: grid;
grid-template-columns: 1fr;
gap: 14px;
}
#tasks div {
border: 3px solid #abcea1;
background-color: #e2eede;
border-radius: 6px;
padding: 5px;
display: grid;
gap: 4px;
}
次のコードで編集ボタンと削除ボタンのスタイルを設定します:👇
#tasks div .options {
justify-self: center;
display: flex;
gap: 20px;
}
#tasks div .options i {
cursor: pointer;
}
これまでの結果:👇
ここを注意深く見てください。関数内に3行のコードを追加しました。
let deleteTask = (e) => {
e.parentElement.parentElement.remove();
data.splice(e.parentElement.parentElement.id, 1);
localStorage.setItem("data", JSON.stringify(data));
console.log(data);
};
次に、ダミータスクを作成し、それを削除してみます。これまでの結果は次のようになります:👇
ここを注意深く見てください。関数内に5行のコードを追加しました。
let editTask = (e) => {
let selectedTask = e.parentElement.parentElement;
textInput.value = selectedTask.children[0].innerHTML;
dateInput.value = selectedTask.children[1].innerHTML;
textarea.value = selectedTask.children[2].innerHTML;
deleteTask(e);
};
次に、ダミータスクを作成して編集してみます。これまでの結果:👇
ページを更新すると、すべてのデータが失われていることに気付くでしょう。この問題を解決するために、IIFE(即時呼び出し関数式)を実行して、ローカルストレージからデータを取得します。フォローする:👇
(() => {
data = JSON.parse(localStorage.getItem("data")) || [];
console.log(data);
createTasks();
})();
これで、ページを更新してもデータが表示されます。
このチュートリアルを正常に完了しました。おめでとうございます。CRUD操作を使用してToDoリストアプリケーションを作成する方法を学習しました。これで、このチュートリアルを使用して独自のCRUDアプリケーションを作成できます。
これが最後まで読むためのあなたのメダルです。❤️
ソース:https ://www.freecodecamp.org/news/learn-crud-operations-in-javascript-by-building-todo-app/