Meteor
Posted By Sebastian

Meteor & Svelte – Building Full-Stack Reactive Web Applications – 04: Writing Data


Subscribe On YouTube

Episodes

In the last part we’ve added a Meteor collection to the Issues sample application for managing our data. So far we’ve only used the Issues collection to retrieve data which is stored in the MongoDB database. In this episode we’re going to continue working with collections. This time we’ll enhance the client application so that the user can also create new issue data by using a form.

Adding A Form For Issue Input

Let’s start by adding the template code in App.svelte which is needed to display a form which can be used for entering values which are needed to create a new issue:

<header>
        <h1>Issues:</h1>
        <form on:submit|preventDefault={handleSubmit}>
            
            <label for="title">Title: </label>
            <input
                id="title"
                type="text"
                bind:value={newIssue.title}
                />

            <label for="description">Description:</label>
            <input
                id="description"
                type="text"
                bind:value={newIssue.description}
                />

            <label for="dueDate">Due Date:</label>
            <input
                id="dueDate"
                type="text"
                bind:value={newIssue.dueDate}
                />

            <label for="priority">Select Priority:</label>
            <select id="priority" bind:value={newIssue.priority}>
                <option value="Low">Low</option>
                <option value="Medium">Medium</option>
                <option value="High">High</option>
            </select>
            
            <input type="submit">
        </form>
    </header>

The form consists of five input elements:

  • Three text input elements for entering title, description, and due date.
  • A select input element for choosing the issue priority from a drop down list.
  • A submit input element

The values of the issue data input element are bound to properties of a newIssue object by using Svelte’s binding syntax:

bind:value={newIssue.title}

Furthermore we assigned an event handler function (handleSubmit, which is not yet implemented) to the submit event of the form:

on:submit|preventDefault={handleSubmit}

Now we’ve bound the form input field values to properties of the newIssue object. So we need to initialize this object in the script section of App component in the following way:

    let newIssue = {
        title: "",
        description: "",
        dueDate: "",
        priority: "Low"
    };

Handling The Form Submit Event

We’ve also assigned the handleSubmit function to the submit event of the form before. This function needs to be implemented in the script section of App.svelte as well. Insert the following code:

    function handleSubmit(event) {
        Issues.insert({
            title: newIssue.title,
            description: newIssue.description,
            dueDate: newIssue.dueDate,
            priority: newIssue.priority
        });

        newIssue = {
            title: "",
            description: "",
            dueDate: "",
            priority: ""
        };
    }

Here we’re using the Issues collection to call the insert method and handover a new issue object which is filled with the values coming from the newIssue object (which is containing the input values from the form). Executing the insert method is adding the new issue object to the Issues collection both on client and on server side.

Enhancing The Output

Finally we should enhance the output of our Svelte application. First of all, let’s bring in some styling by adding the Picnic CSS (https://picnicss.com/) framework to our app. The Picnic CSS framework makes it very easy because it applies some default styling without the need of explicitly assigning CSS classes to our HTML elements.

Adding the Picnic CSS framework in main.html is done by adding the a link element to the head section:

<head>
  <title>Issue List</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/picnic">
</head>

<body>
  <div id="app"></div>
</body>

In addition let’s change the output of issues from a list-based output to a table-based output which comprises all four issue properties.

Make the following changes in app.svelte:

    <div>
        <table>
            <tr>
                <th>Title</th>
                <th>Description</th>
                <th>Due Date</th>
                <th>Priority</th>
            </tr>
            {#each $issues as issue}
                <Issue issue={issue} />
            {/each}       
        </table>
    </div>

In issue.svelte we need to add the table structure as well. Each of the issues is outputted in a table row:

<script>
    export let issue;
</script>

<tr>
    <td>{issue.title}</td>
    <td>{issue.description}</td>
    <td>{issue.dueDate}</td>
    <td>{issue.priority}</td>
</tr>

With the changes being made we’re now ready to start the application again by typing in:

$ metoer

You should see a result similar to the following:

10.png

Now you can use the input form to create a new issue. If you click on the submit button the new issue is automatically added to the table output as you can see in the following screenshot:

20.png

Advertisement: Svelte.js - The Complete Guide

Build high-performance web applications with Svelte.js – a lightweight JavaScript compiler:

Svelte.js – The Complete Guide*

  • Svelte.js from scratch, with zero knowledge assumed
  • All the theory and practical applications of Svelte
  • Core concepts and advanced techniques to build Svelte applications

Go To Course*

* Affiliate Link / Advertisement: This blog post contains affiliate links, which means that if you click on one of the product links and buy a product, we’ll receive a small commission. There are no additional costs for you. This helps support the channel and allows us to continue to make videos like this. Thank you for the support!


Using and writing about best practices and latest technologies in web design & development is my passion.