Coding From Scratch – DebugEverything https://blog.debugeverything.com A new way to learn programming Sun, 22 May 2022 01:05:48 +0000 en-US hourly 1 https://wordpress.org/?v=7.1.4 https://blog.debugeverything.com/wp-content/uploads/2021/04/cropped-DE_white-32x32.png Coding From Scratch – DebugEverything https://blog.debugeverything.com 32 32 [From Scratch] Building an App with React Hooks – Extended and Detailed Version https://blog.debugeverything.com/from-scratch-building-app-with-react-hooks/ https://blog.debugeverything.com/from-scratch-building-app-with-react-hooks/#comments Tue, 02 Jun 2020 00:46:15 +0000 https://debugeverything.com/?p=1358 React is a front-end JavaScript library that can be used to create interactive user interfaces for your application. In this tutorial, we will create a “ToDo List” application that covers all four aspects of a CRUD: Create, Read, Update, and Delete.

This type of project is often done with Class components, but this application will integrate React Hooks. Hooks allow functional components to have a state and use life-cycle methods, allowing you to avoid using Class components and have more modular and readable code.

Without further ado, Let’s get started!

First Step 1 – Start a new React App

Installing npm

To install React, we need npm which is a package manager for JavaScript.

npm is installed together with Node.js. This means you have to install Node.js to get the npm installed on your computer.

Download Node.js from the official website: https://nodejs.org

Creating a new app

Let’s run the create-react-app command inside the terminal, in the folder where you want to create your project, followed by the name of our project, which will be for us, react-to-do, the command will look like this:

$ npx create-react-app react-to-do

npx is a tool to run npm packages that live inside the local node_modules folder or are not installed globally, this tool already comes in Node.js installation.

And the create-react-app command installs the necessary dependencies to build our React project and generates the initial structure that we will see next.

Once the installation is finished, we will test the application, just run these two commands on the same terminal:

$ cd react-to-do
$ npm run start

With the first command, you will enter the folder that the create-react-app command created, if you changed the name of the project, you need to change it here too.

The second command runs a Node.js service to host your application. It will host your application on a local service on route http://localhost:3000/.

The browser should open automatically and you will see something like this:

If your browser does not open directly, you can type localhost:3000 in your browser to open your application, this symbol will probably be spinning.

Step 2 – Creating a list of items

With your application running, let’s start on the reading part of the CRUD. We’ll make a list of things for you to read/view.

But before that, we will remove all unnecessary code from our src/App.js, your file should look like this:

import React from 'react';
import './App.css';

function App() {
  return (
    <div className="App">

    </div>
  );
}

export default App;

Creating a new component

Now let’s create a new folder called components and inside this folder create a file with the name TodoList.js.

This component will be responsible for displaying the list of items on our screen.

In our component declaration we will include two parameters: todos and updateTodos.

function TodoList({ todos, updateTodos }) {
...
}

At this point, we will pay attention only to the first parameter, todos. The second parameter we’ll treat further ahead.

This parameter is the list with all the items on our list. We will receive the list of the main component, always updated, to display for you.

So with a few lines, we’ve already managed to show our list, the main part of our component looks like this:

<div className="todo-list">
  {todos.map((todo, index) => (
    <div
      key={index}
      className="todo">
      Item {index + 1}: {todo.task}
    </div>
  ))}
</div>

Notice that all the code is inside a <div>, which contains a property, className="todo-list". This property inserts a new CSS class in this component, in the case of the CSS todo-list class, which I’ll show later.

Also, notice that, React uses className="" and not just class="" as we normally do with HTML, the reason behind this is that React uses JSX, I will create a dedicated post to explain more about JSX.

But for now, understand that it’s just a way of writing HTML into Javascript files.

So once the component receives the list, what we need to do is just iterate over the list and display it to the user. I am doing this using Javascript’s Array.map() method.

todos.map((todo, index) => (
  ...
))

To display the tasks, I used another <div>, inside Array.map(), with two very important properties.

One of them, className="all", I already commented before, will apply a CSS class to our element.

The second key={index} property helps React identify which items have been changed, added, or removed.

A key attribute must be included in your array, but in this case, as the items in our list have no ids, for example, we will use the index referring to their position in the array.

In the last line, as you can imagine, is where we display all the items on the list, along with a counter.

<div
  key={index}
  className="todo">
  Item {index + 1}: {todo.task}
</div>

The complete code of the TodoList component of our React App will look like this so far:

//TodoList
import React from 'react';

function TodoList({ todos, updateTodos }) {
  return (
    <div className="todo-list">
      {todos.map((todo, index) => (
        <div
          key={index}
          className="todo">
          Item {index + 1}: {todo.task}
        </div>
      ))}
    </div>
  );
};

export default TodoList;

Adding style to the App

Before displaying our list, I will create the CSS classes I have commented on, so our list will be more presentable. That’s why I didn’t remove the ./App.css call from our App.js, you will put the code there.

/* App.css */
.App {
  background: #27292d;
  padding: 30px;
  height: 100vh;
}

.todo-list {
  margin: auto;
  background: rgb(112, 111, 111);
  border-radius: 4px;
  padding: 5px;
  max-width: 400px;
}

.todo {
  background: #fff;
  box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.15);
  padding: 10px 10px;
  font-size: 20px;
  border-radius: 3px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  cursor: pointer;
}

The layout here is not the focus of our project, so I’ll skip the explanations.

Adding a new state

Back to our App.js, we’re going to use React Hooks, so the state will look a little different than if we used classes.

First of all, we need to import our Hook useState from the React library, like this:

import React, { useState } from 'react';

Now we can create our first state using Hooks, it’ll look like this:

const [todos, setTodos] = useState();

React Hooks are a new addition to React 16.8. They allow you to use state and other features without needing a class. Let’s break down our new state.

  • The first parameter, todos, is the name of our state.
  • The second parameter, setTodos, is what we’ll use to set the state.

The useState() hook is what React uses to connect to the component state or life cycle. We can also, initialize our state with an initial value.

Defining an initial state

Our initial state consists of an array of objects. Where we will define 3 tasks, following this format:

[
  { complete: false, task: "Read about MongoDb" },
  { complete: false, task: "Create a React ToDo App" },
  { complete: false, task: "Find my key" }
]

The first attribute completewill indicate whether the task has already been completed or not. The second attribute taskis the task description.

Therefore, every new task will be inserted in the existing list. In the “real world”, this list would probably come from a database.

Our state, will look like this at the end.

const [todos, setTodos] = useState([
  { complete: false, task: "Read about MongoDb" },
  { complete: false, task: "Create a React ToDo App" },
  { complete: false, task: "Find my key" }
]);

Finally, we need to import and declare our new component, TodoList, within our App.js.

import TodoList from './components/TodoForm';

And we also need to pass to it, the initial task list through the property todos, which we defined in our TodoList component.

<TodoList todos={todos}></TodoList>

O código completo do componente App do nosso React App, ficou assim até agora:

The complete code of our React App component will look like this:

import React from 'react';
import './App.css';
import TodoList from './components/TodoForm';

function App() {
    const [todos, setTodos] = useState([
        { complete: false, task: "Read about MongoDb" },
        { complete: false, task: "Create a React ToDo App" },
        { complete: false, task: "Find my key" }
      ]);
  return (
    <div className="App">
      <TodoList todos={todos}></TodoList>
    </div>
  );
}

export default App;

Your todo app must be looking like this right now:

Step 3 – Creating new items on the list

Now, let’s give our application the power to create a new item for our list.

Let’s create one more component.

In the same folder as the TodoList, create a component called TodoForm, this will be the component responsible for creating and submitting new items to the list.

In this component, we will define a second state, which will receive your input from the form. In this state, we’ll start by passing an empty string only, (this will make sense later).

const [userInput, setUserInput] = useState("");

Component parameters

As well as variables and constants, we can also send functions between components. And that’s exactly what we’re doing here.

...
function TodoForm({ addTodo }) {
...
}

The addTodo parameter is actually a function. The addTodo() function is not declared in the TodoForm component but received with one of the parameters during the component declaration.

With this method, we will send all the data we receive from the user to our main App.js component where our main state lives.

Creating the Form

We can now create our form to receive the data. The declaration of the form receives two properties, the first onSubmit={handleSubmit} is where we call the function that will manipulate the user’s data.

The second, className="todo-form" is the inclusion of a CSS class in that element.

<form onSubmit={handleSubmit} className="todo-form">

And within our form, only one input, responsible for receiving data from the user.

<input
    placeholder="New Task"
    type="text"
    value={userInput}
    onChange={e => setUserInput(e.target.value)}
/>

We set the property value={userInput} to delete from the form, after submission, what the user wrote. If the value property is not present and receiving the state value, every time the user enters and submits a new task, the text will not be deleted from the input.

Our last property is the cherry of the cake. onChange is a default property of the tag <input />, what it does is quite simple, every time the input is modified (when the user types something, for example) the property triggers an event indicating that the component has been updated.

We will then use this event to update the current value of our state. Passing to our setUserInput() method the e.target.value which is the last value that the user typed.

Notice that I am using arrow function to receive the value of the event.

Manipulating the form values

To receive the values from the user, we will create a function called handleSubmit, it is triggered as soon as the user presses enter to write a new task.

Na primeira linha temos que fazer e.preventDefault(), e é o evento que o formulário emite após ser submetido. E o comportamento padrão de uma formulário é recarregar a página, o que não é interessante para nós.
E se caso o valor for uma string vazia "" o código não faz nada. Pois uma string vazia é falsy.

In the first line, we have to do e.preventDefault(), e it’s the event that the form issues after being submitted. And the default behavior of a form is to reload the page, which is not interesting for us.
And if the value is an empty string "" the code does nothing. Because an empty string is falsy.

Notice that we are passing an object with two properties (which follows the pattern defined in App.js), to the method, addTodo({ complete: false, task: userInput }).

And finally, on the last line of the method, I pass an empty string to the state, to clear the input value, as I explained above.

const handleSubmit = e => {
    e.preventDefault();
    if (!userInput) return;
    addTodo({ complete: false, task: userInput, });
    setUserInput("");
};

The complete code of the TodoForm component of our Todo App looks like this so far:

//TodoForm.js
import React, { useState } from 'react';

function TodoForm({ addTodo }) {
    const [userInput, setUserInput] = useState("");

    const handleSubmit = e => {
        e.preventDefault();
        if (!userInput) return;
        addTodo({ complete: false, task: userInput, });
        setUserInput("");
    };

    return (
        <form onSubmit={handleSubmit} className="todo-form">
            <input
                placeholder="New Task"
                type="text"
                className="input"
                value={userInput}
                onChange={e => setUserInput(e.target.value)}
            />
        </form>
    );
};
export default TodoForm;

And this is the CSS class code, todo-form that I commented before, notice that I am also applying CSS to our input through the CSS selectors.

/* 
App.css
*/
.todo-form{
  margin: auto;
  background: rgb(112, 111, 111);
  padding: 5px;
  max-width: 400px;
}

.todo-form input {
  width: 100%;
  padding: 5px;
  box-sizing: border-box;
  font-size: 18px;
}

Importing the form

Okay, now we need to import that component into App.js, just like we did with TodoList.

The idea is that the App.js serves as an intermediary between our form (TodoForm) and the display list (TodoList).

To make it clearer what we are going to do, I designed this outline of the project structure to facilitate understanding.

Receiving the form values in the main component

Using the addTodo parameter we create the connection between the two components TodoForm and App, as soon as the user presses Enter on the form, we receive the values in our App.js.

The addTodo parameter actually represents a function, which evaluates the data received from the TodoForm component and includes it in the existing task list.

The trim() method is just to remove possible whitespaces before and after a String.

(todo) => {
  if (todo.task.trim().length > 0) {
    setTodos([...todos, todo]);
  }
}

And for those who are not familiar with the spread operator… (the three dots). It is “expanding” the object we receive from TodoForm, within our task list. To make it clearer,look what’s happening with this example below:

const todo = [{complete: false, task: "New task"}]
const todos = [...todo,{complete: false, task: "Read about MongoDb"}]; 
console.log(todos);
/*[{complete: false, task: "New task"},{complete: false, task: "Read about MongoDb"}]*/

I’m just skipping these intermediate steps and entering all of them directly into the list todos using the setTodos from our state method.

This function we will pass to the TodoForm component through the addTodo parameter, this way:

<TodoForm addTodo={(todo) => {
  if (todo.task.trim().length > 0) {
    setTodos([...todos, todo]);
  }
}} />

The complete code of the App component of our Todo App looks like this at this point.

import React, { useState } from 'react';
import './App.css';
import TodoList from './components/TodoList';
import TodoForm from './components/TodoForm';

function App() {
  const [todos, setTodos] = useState([
    { complete: false, task: "Read about MongoDb" },
    { complete: false, task: "Create a React ToDo App" },
    { complete: false, task: "Find my key" }
  ]);
  return (
    <div className="App">
      <TodoForm addTodo={(todo) => {
        if (todo.task.trim().length > 0) {
          setTodos([...todos, todo]);
        }
      }} />
      <TodoList todos={todos} ></TodoList>
    </div>
  );
}

export default App;

And our React App should be working like this right now.

Step 4 – Updating the list

Okay, now let’s get back to work on our TodoList component. What we need now is a function that marks off the tasks already completed. The idea is to do something like this, when we click on the task, it is strikethrough, very simple.

What we need is a way to identify the item being clicked on and apply a CSS class that contains the effect we want.

To do that, we’ll create a function called markComplete.

const markComplete = (id) => {
    const updatedList = todos.map((item, index) => {
        if (id !== index) return item;
        return { ...item, complete: !(item.complete) };
    });
    uodateTodos(updatedList);
}

This function is very simple, it receives a parameter called id that will be the index referring to the position of that item in the array.

What the function will do is iterate over the list of items, using the Array.map() again, comparing the index and the id parameter that the function receives in order to update the complete property of the object that matches the two values.

As soon as the object is found, I just exchange the original value for the opposite of it. This is another great use of the Spread Operator, you can use it to update the values of an object, notice how it is being done in our function with this example:

const task = {complete: false, b: "Your task"};
const updatedTask = {...task, complete: true};
console.log(updatedTask);
// { complete: true, b: "Your task" }

One problem is that React does not recognise this “internal change” of attribute values, if you just change an attribute, of an object contained in the Array, this does not make React render the component.

Only when you remove, include, or change an element in the array, React will render the component again.

Tha’s why we are using Array.map(), because it creates a new array. And with that React is able to render our list.

E você se lembra do nosso segundo parâmetro updateTodos que passamos para o TodoList, logo no começo:

And you remember our second parameter updateTodos that we passed to the TodoList, right at the beginning:

function TodoList({ todos, updateTodos }) {
...
}

If you go back in the image where you have the schematic of the project, you will see that this method, updateTodos, is responsible for taking the data from the TodoList component to the App component.

So let’s go back to our App.js and change the line where the TodoList is called to include that parameter.

<TodoList todos={todos} updateTodos={(list) => { setTodos(list) }}></TodoList>

So as soon as the Array.map() method finishes creating the new array, already with the updated item values, I use the updateTodos method to send the updated list to our main component.

E com o método setTodos eu atualizo o nosso state com uma nova lista de items que formam marcados como concluídos/não concluídos.

And with the setTodos method I update our state with a new list, coming from the TodoList, with the items that are marked as completed/not completed.

Crossing out a task completed with CSS

Okay, what we need now is to use a method to recognise the click on one of the items on the list. The onClick method will serve us well. It will execute the markComplete() function.

<TodoList todos={todos} updateTodos={(list) => { setTodos(list) }}></TodoList>

This parameter index comes from the Array.map() that we are using to iterate and display the list items for the user.

And finally, we need to declare a condition on our className property, if the task is marked as done or complete:true we will apply the taskDone class, otherwise the class is removed.

className={`todo ${todo.complete ? "taskDone" : ""}`}

That’s the whole code of our componente:

//TodoList
import React from 'react';

function TodoList({ todos, updateTodos }) {

    const markComplete = (id) => {
        const updatedList = todos.map((item, index) => {
            if (id !== index) return item;
            return { ...item, complete: !(item.complete) };
        });
        updateTodos(updatedList);
    }
    return (
        <div className="todo-list">
            {todos.map((todo, index) => (
                <div
                    key={index}
                    className={`todo ${todo.complete ? "taskDone" : ""}`}
                    onClick={() => markComplete(index)}>
                    Item {index + 1}: {todo.task}
                </div>
            ))}
        </div>
    );
};

export default TodoList;

The CSS class we are applying is taskDone, so in our App.css file you must include it:

.taskDone{
  text-decoration: line-through;
}

Our Todo List will be working like this so far:

Step 5 – Removing items from the list

Thinking that we can accidentally add a wrong task or that we have a task in the list that we don’t need to do anymore, or because it has already been completed and doesn’t need to be there anymore, we will create a function to remove those unwanted items.

In our TodoList component, we will include a button in each item to perform the delete action and also create the function to remove the item.

I’m going to add a function called removeTask() that will receive the task’s index in the list, and using the filter method, I’ll create a new list without the element we just removed to update the state with the updateAll() method we’re receiving from App.js. A process similar to the one we did in the markComplete() function.

const removeTask = (index) => {
    const updatedList = todos.filter((task, taskIndex) => {
        return taskIndex !== index;
    });
    updateTodos(updatedList);
}

And below each item, we will include our button. Our button has only two properties, className to add a CSS class and the onClick function that will trigger our removeTask() method.

Note that we are already passing the index to the method.

<pre class="hljs" style="display: block; overflow-x: auto; padding: 0.5em; background: rgb(240, 240, 240); color: rgb(68, 68, 68);"><span class="hljs-keyword" style="font-weight: 700;">const</span> removeTask = (index) =&gt; {
    <span class="hljs-keyword" style="font-weight: 700;">const</span> updatedList = todos.filter((task, taskIndex) =&gt; {
        <span class="hljs-keyword" style="font-weight: 700;">return</span> taskIndex !== index;
    });
    updateTodos(updatedList);
}</pre>

The complete code of our TodoList component will look like this:

//TodoList
import React from 'react';

function TodoList({ todos, updateTodos }) {

    const removeTask = (index) => {
        const updatedList = todos.filter((task, taskIndex) => {
            return taskIndex !== index;
        });
        updateTodos(updatedList);
    }

    const markComplete = (id) => {
        return todos.map((item, index) => {
            if (id !== index) return item;
            return { ...item, complete: !(item.complete) };
        });
    }
    return (

        <div className="todo-list">
            {todos.map((todo, index) => (
                <div key={index}>
                    <div
                        className={`todo ${todo.complete ? "taskDone" : ""}`}
                        onClick={() => setTodos(markComplete(index))}>
                        Item {index + 1}: {todo.task}
                    </div>
                    <div><button className="button" onClick={() => removeTask(index)}>Delete</button>  </div>

                </div>

            ))}
        </div>
    );
};

export default TodoList;

Let’s add the style of our button to our CSS file:

.button{
  background-color: #f44336; /* red */
  border: none;
  color: white;
  padding: 10px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  width: 100%;
  margin-bottom: 10px;
}

E é isso, nosso app está pronto Todo app está pronto!

And that’s it, our app is Todo App is ready!

Let’s test it:

Bottom Line

This application uses React Hooks, which was introduced in version 16.8. It is a relatively new feature, but quite powerful and efficient. You can work the same way with Classes, but Hooks makes the code much cleaner and simpler to understand.

Creating an app that implements the basic CRUD functions is a great way to understand React life cycles.

I hope it was helpful.

See you next time.

]]>
https://blog.debugeverything.com/from-scratch-building-app-with-react-hooks/feed/ 2
[From Scratch] How to create a login page with Python – part 3 https://blog.debugeverything.com/from-scratch-how-to-create-a-login-page-with-python-part-3/ https://blog.debugeverything.com/from-scratch-how-to-create-a-login-page-with-python-part-3/#comments Thu, 09 Apr 2020 01:06:45 +0000 https://debugeverything.com/?p=731 But one step of our project, after creating the whole page structure with CSS and HTML in part 1 and adding Javascript to send the data to the server in part 2. The time has come to talk on the server side. And this time our login page with Python.

In part 2, I created an example of a PHP file to represent our server. But due to popular acclaim, we’re going to make the change now, and we’ll create our login page with python.

For those who have never had contact with language, it may not be the right way to start. In this article I won’t show you how to install Python or how to get started in the language, I’ll just quote some of the tools and procedures.

Python Virtual environments

Most projects, if not all, have dependencies, either in a library, framework or API. For this, each programming language has its own dependency management tools.

How does Python solve that problem? By creating virtual environments.

Virtual environments are independent groups of Python libraries. Packages installed for one project will not affect other projects or operating system packages.

Python 3 comes together with the venv module to create virtual environments. If you’re using Python 2, you might want to take a look on How to create Virtual Environments with Python virtualenv.

You can check the version using the python --version command in the terminal.

Login page with Python… and Flask

Flask is a micro web framework written in Python. It is classified as a microframework because it does not require specific tools or libraries.

And this miserable is very easy to use!

If everything is ok with Python on your computer, you just need to use the pip install flask command to install the latest version of Flask.

This code below you’ll find almost anywhere when you Google Flask. And it demonstrates how simple it is to create and run an application.

Open your text editor and put this code below and save the file as main.py.

from flask import Flask							
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"
if __name__ == "__main__":
    app.run()

Once you have done this, open a window in your terminal in the folder where you saved your file and type the python main.py command and press enter

Yes that’s all, and you already have an application running on the localhost:5000 port, which is the default port Flask uses.

If you open your browser on this route you will see a result possibly similar to this one:

Flask Debug Mode

To avoid that hassle of rebooting the server every time you make a change to the login page file using Python, you can do the following:

  • Change the line app.run() to app.run(debug=True)
  • Stop and restart the server

Now every time you change and save the server is restarted automatically.

New structure of our login page with python

To use our Flask microframework on our login page with python we will need to make some small changes to our HTML and folder structure.

CSS and Javascript files

The CSS and Javascript files we created in the first part still remain the same ????. But the way to include them changes a bit.

Now, we will include the files using this template:

{{ url_for('static', filename='css/style.css') }}
{{ url_for('static', filename='js/script.js') }}

Now our code will stay that way:

<!-- Including CSS file-->
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">

<!-- Including Javascript file-->
<script src="{{ url_for('static', filename='js/script.js') }}"></script>

A little too much code, but it’s not the end of the world either. The url_for() function generates us a URL for the final route given a parameter.

Folder structure

Flask asks us (kindly) to create two folders a 'static‘ folder call where we will put our CSS and Javascript files. And a second folder called 'templates', where our HTML files goes.

By the way, static in that code up there, it references that folder we’re just creating.

To separate even better, inside the static folder I created a folder for each file type, the final structure of the folders looks like this:

/static
---css
---javascript
/templates
---login.html
main.py

Starting with Python

We’ve already made all the necessary adjustments to leave for Python. I’ll use that code we saw up there in the first example, and we’ll give it an increment.

from flask import Flask, render_template, request						
app = Flask(__name__)

@app.route("/login")
def screen():
    return render_template('login.html')

if __name__ == "__main__":
    app.run(debug=True)

What’s changed?

Well, in the first line, besides Flask, I’m also importing the request Object, which comes by default with Flask, and the render_template function.

request is the Object used to make and also receive HTTP requests. I look at this object and we’ll use it further on.

render_template to render our HTML, I had to import this function that comes with the Flask structure called render_template().

The render_template() function invokes the Jinja2 template engine that comes with the Flask framework (remember what I said about dependencies).

I also changed the main route name to "/login" and the function name to screen(). And instead of returning just a String I’m returning our HTML file, login.html.

Making Connection

If all went well so far, when you run your Python main.py file and access the localhost:5000/login route you should see your login page only using python this time.

Right, the time has come then to send the data we received on the form to our newly created server.

Remember our Javascript file, the same as part 2. We need to make a slight change. I know I said we wouldn’t touch that file. But in part 2 we used PHP, but now, we are creating our login page with python, so we need to remove that url and pass the new route.

We need to change a line.
Before:
xml.open("POST", "login.php");
After:
xml.open("POST", "/login");

Now our Javascript file is ready to send the data to our server. But remember I told you that that route does not accept POST. We need to figure this out.

To make the code more readable, I created a second route, with the same name, but which accepts the POST request.
Just put this second parameter methods = ['POST'] in the @app.route() function.

@app.route('/login',methods = ['POST'])
def login():
   if request.method == 'POST':
      email = request.form['email']
      password = request.form['password']
      return "Email: " + email + " <br> " + "Password: " + password

On this route I am using our Object request. With it I can access the data coming from the request on the customer side.
To access the data, just like in PHP we’ll use the field name we defined in our form in part 1.

Our final main.py file will look like this:

from flask import Flask, render_template, request						
app = Flask(__name__)

@app.route("/login")
def screen():
    return render_template('login.html')

@app.route('/login',methods = ['POST'])
def login():
   if request.method == 'POST':
      email = request.form['email']
      password = request.form['password']
      return "Email: " + email + " <br> " + "Password: " + password


if __name__ == "__main__":
    app.run(debug=True)

Testing the connection

The time has come to test. Our main.py file is just returning the data it receives, just like I did in the example in part 2.

The end result must also be very similar. Only now using Python.

So that’s it, the end of another part of the series of how to build a login page with python. And now it’s more than official. Python will also be used in our tutorials from now on.

If you like this news, and want to be notified when you have new content, just sign up to receive the notifications in the form below.

See you in next time!

]]>
https://blog.debugeverything.com/from-scratch-how-to-create-a-login-page-with-python-part-3/feed/ 1
[From scratch] How to create a login page – part 2 https://blog.debugeverything.com/from-scratch-how-to-create-a-login-page-part-2/ https://blog.debugeverything.com/from-scratch-how-to-create-a-login-page-part-2/#comments Thu, 02 Apr 2020 18:00:00 +0000 https://debugeverything.com/?p=697 In the first part of how to create a login page from scratch, we defined all the elements and create the whole page structure.

If you haven’t seen the first part, come back and check it out so you don’t get lost here.

If you want to follow up and be notified, click here and sign up to receive the notifications.

Next Steps

Cool, we already have our login page, very simple until then, only 5 elements. And this was the final result.

Well what’s missing from our page then? Action!

It has no function so far, it’s a static page. In this second part we will start working with Javascript.

The idea here is to create a function called:

  • userLogin() – This function will receive and send the form data to the server.

Before we do that, we need to make some minor changes to the code.

Adjusting the form

To receive the data from our page we need to include a few more things in our HTML form.

The first one is to define an id for our form, so javascript can easily find the form. We can do this quite simply, within our tag <form> we add id="login-form".

Second, we need to put a click action on the login button. Inside the tag <button> we’ll include a new attribute to specify that action.

The attribute with the name of the function (the action we want to perform) already assigned looks like this, onclick="userLogin()", very simple too. Our form code will look like this after these small inserts.

Capturing the form data

This is the function that will receive your data as soon as you click the login button.

There are several ways to do this, here I decided to use vanilla Javascript to simplify. What I’m doing is searching our form in our login page by the id we defined above, using the document.getElementById() function for that.

let userLogin = function () {
    let form = document.getElementById("login-form");
    let email = form.elements.namedItem("email").value;
    let password = form.elements.namedItem("password").value;
};

With our form in hands, we now need to search our email and password fields. Javascript also offers a quick way to do this, searching the field by the name="" atribute, which was also defined in the previous steps.

Sending the data to the server with XMLHttpRequest

We already have all the information we need, now we only need send to our server through an HTTP request.

For this we will use the Api XMLHttpRequest, which despite the name, we can use to get any kind of data, not only XML.

That’s the code I’ll use to send the data to the server. Don’t worry, I’ll clean it up, and explain what’s going on here.

let userLogin = function () {
    let form = document.getElementById("login-form");
    let email = form.elements.namedItem("email").value;
    let password = form.elements.namedItem("password").value;
    let credentials = "email=" + email + "&password=" + password;
    const xml = new XMLHttpRequest();

    xml.onreadystatechange = function () {
        if (xml.status == 200) {
            console.log(xml.response);
        }
    };

    xml.open("POST", "login.php");
    xml.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xml.send(credentials);
};

XMLHttpRequest() is the builder of the API. It must be called before any other API method.

xml.onreadystatechange this property contains the event manager to be called when the readystatechange event is triggered, i.e. whenever the XMLHttpRequest readyState property changes.

xml.status is the property that returns the HTTP code of the call response.

xml.response this property returns the body content of the response from the server in different formats, depending on the responseType.

xml.open() the method initialises a request, or resets an existing request.

xml.setRequestHeader() sets the header value of an HTTP request.

xml.send() this is the method that sends the request to the server.

Function Details

In the xml.open() function, I defined two parameters, the first one defines the type of request, in this case, as we want to send data to the server, I’m using the POST method. The second parameter represents the url to which we will send the request.

It also includes two parameters in the function, xml.setRequestHeader(). The first parameter creates a header for the request that defines the content type sent in the request, and the second identifies what type of content this is.

1, 2, 3… Testing

To test the function, I created a PHP file to receive this data inside localhost. As you can see in the code below, very simple, just for testing.

<?php
echo 'Server response:';
echo '<br>';
echo 'Email: ' . ($_POST["email"]);
echo '<br>';
echo 'Password: ' . ($_POST["password"]);

As soon as the user clicks the login button, the server responds with the data that was sent.

That’s all for now, I invite you to be part of the collaborative project, where you can put your ideas and practice what you have learned. Just click here to contribute to the project.

The project is not finished yet, the next step we’ll connect with the database. And we can also make a change to JAVA.

Leave in the comments what you want to see in the next content of the series.

And be sure to subscribe to the newsletter using the form below, and be notified as soon I release a new content.

]]>
https://blog.debugeverything.com/from-scratch-how-to-create-a-login-page-part-2/feed/ 6
[From Scratch] How to create a login page https://blog.debugeverything.com/from-scratch-how-to-create-a-login-page/ https://blog.debugeverything.com/from-scratch-how-to-create-a-login-page/#comments Thu, 26 Mar 2020 07:00:02 +0000 https://debugeverything.com/?p=643 In a new series of posts, “From Scratch”, I’ll show you how to build simple and complex applications showing all the code and tools used for development. In the first post of the series I will show how to create a login page, using only the basics of HTML and CSS and Javascript.

This will be the first part, where we will define the layout and structure of the page, we will leave Javascript for the second part.

If you want to follow up and be notified, click here and sign up to receive the notifications.

Without further ado, let’s get our hands on it.

Basic HTML structure

Starting from the basics, the structure of any HTML page will be quite similar to this one.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login Page</title>
</head>

  <body>

  </body>

</html>

Some information about this structure.

A tag of type <meta> provides metadata about the HTML document.

<meta charset="UTF-8"> specifies the character encoding for the HTML document.

width=device-width defines that the page width should follow the screen width of the device (which will vary depending on the device).

initial-scale=1.0 sets the initial zoom level when the page is loaded for the first time by the browser.

Login Page Structure

Right, set the basic structure, let’s start how to start create our login page, now it’s time to start putting the elements on the screen.

It’s only five elements, nothing too complex.

  • Page logo
  • Form field for email
  • Form field for password
  • Login button
  • Image for the background

Let’s work with our form first. To help with the structure and appearance of the page, I’ll use Bootstrap 4.4, which is very simple to use and has excellent documentation. To include the bootstrap CSS file in the page, there’s no mystery, just copy and paste the code with the link just below the <meta> tag.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
    <title>Login Page</title>
</head>

  <body>

  </body>

</html>

Login Form

I want to build the form centralised on the page, and regardless of the size of the screen, I want it to follow the same proportions.

Bootstrap has a lot of useful tools and classes to adjust the responsiveness. Good without wasting time, this is the form code.

<div class="row align-items-center h-100 ">
    <div class="col-8 col-md-3 col-xs-8 mx-auto l-form">
        <form class="form" method="post">
            <img class="row mx-auto" src="https://i.imgur.com/RhJpe7c.png" width="150">
            <div class="form-group ">
                <input type="text" placeholder="Email" class="form-control i-form">
            </div>
            <div class="form-group">
                <input type="password" placeholder="Password" class="form-control i-form">
            </div>
            <div class="form-group">
                <button type="submit" class="btn btn-dark btn-md btn-block">Login</button>
            </div>
        </form>
    </div>
</div>

In that code I’ve already put 4 of the elements that we had previously defined. The logo of the page is there, believe me, only it’s white, so it won’t appear until we change the background.

What I’m creating with this code is a structure, using the Bootstrap Grid System, to align our form horizontally and vertically in the center of the screen.

I also used the classes: col-8 col-md-3 col-xs-8 to keep the proportions on different types of canvas.

There are probably several other ways and classes I could use to create the same form with the same characteristics. But this code is meant to be quite simple, we don’t need extremely elaborate solutions yet.

Suggestions are always welcome, leave your comment.

Your page should look like this at the moment.

Improving the appearance

To improve the overall appearance of the page, I created a very simple CSS file. That specifies the l-form and i-form classes, and some other attributes for the <body> and <html> tags.

body,html{
  height: 100%; 
  overflow: hidden;
  background-image: url(https://i.imgur.com/X97iVv1.jpg);
  background-size: cover;
}

.l-form{
  background-color:rgba(39, 41, 45, 0.5);
  border-radius:12px;
  padding: 12px;
}

.i-form{
  border-radius:12px;
  padding: 12px;
}

For the <body> and <html> 5 attributes:

height:100% so we can enjoy the entire usable area of the screen.

overflow: hidden removes the scroll bars from the page.

background-image and background-size defines an image for the background of your page and the behaviour of that image, respectively.

This is our final HTML file, after we put all the pieces together:

<!doctype html>
<html lang="en">

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="../css/login-style.css">
    <title>Login Page</title>
</head>

<body>
  <div class="row align-items-center h-100 ">
      <div class="col-8 col-md-3 col-xs-8 mx-auto l-form">
          <form>
              <img class="row mx-auto" src="https://i.imgur.com/RhJpe7c.png" width="150">
              <div class="form-group">
                  <input type="text" name="email" placeholder="Email" class="form-control i-form">
              </div>
              <div class="form-group">
                  <input type="password" name="password" placeholder="Password" class="form-control i-form">
              </div>
              <div class="form-group">
                  <button type="button" class="btn btn-dark btn-md btn-block">Login</button>
              </div>
          </form>
      </div>
  </div>
</body>

</html>

If you’ve followed everything so far as your login page was taught, it should look like this:

This was a very easy tutorial, but a login page is like the front door, a business card and I believe the first impression is very important.

I hope you enjoyed it. Until part 2.

]]>
https://blog.debugeverything.com/from-scratch-how-to-create-a-login-page/feed/ 4