Job Announcement Website: Building Post Page
Tags: javascript, webdev, react, opin
Published: 2022-08-14 05:02:00

{% embed https://dev.to/sokhavuth/table-of-contents-2o4e %}
GitHub: [https://github.com/Sokhavuth/opine-job](https://github.com/Sokhavuth/opine-job)
Deno Deploy: [https://khmerweb-job.deno.dev/users/post](https://khmerweb-job.deno.dev/users/post)
<br/>
<p>Post page is where we will write post about job offer to be published on the website. So, we need a rich text editor such as CKEditor 5 that can be built and downloaded from <a href="https://ckeditor.com/ckeditor-5/online-builder/">https://ckeditor.com/ckeditor-5/online-builder/</a>.</p>

<p>As we need some interactivity on client-side, we can hydrate this post page or include the form with CKEditor 5 as a string into the page. Doing so, the form will be rendered on client-side, and we can use vanilla JavaScript to select categories from the dropdown widget to include in the category input widget.</p>

```js
// controllers/users/post.js

import post from "../../views/users/post.jsx";


class Post{
    async getPage(req, res){
        const config = req.mysetting();
        config.page_title = "Post Page";
        config.route = "/users/post";
        config.username = (await req.mysession.get("user")).title;

        const html = await post(config);
        res.send(html);
    }
}


export default new Post();
```

```jsx
// views/users/post.jsx

/** @jsx h */
import { h, renderSSR } from "../../deps.ts";
import Index from "./index.jsx";


function PostJsx(props){
    const item = props.data.item;
    let editor = ``

    if(item){
        editor = `
            <form action="/admin/post/edit/${item.id}" name="form" method="post" 
                onSubmit="submitForm(event)">
                <input type="text" name="title" value="${item.title}" required 
                placeholder="Post title" />
                <textarea id="editor" name="content" >${item.content}</textarea>
                <input type="text" name="categories" value="${item.categories.toString()}" required 
                placeholder="Categories" />
                <div class="wrapper"> 
                    <select id="category" onChange="getCategory()">
                        <option>Select a category</option>
                        <option>News</option>
                        <option>Movie</option>
                        <option>Entertainment</option>
                        <option>Sport</option>
                    </select>
                    <input type="text" name="thumb" value="${item.thumb}" required 
                    placeholder="Thumbnail" />
                    <input type="datetime-local" value="${item.date}" name="datetime" required />
                    <input type="submit" value="Publish" />
                </div>
            </form>
        `
    }else{
        editor = `
            <form action="/admin/post" name="form" method="post" onSubmit="submitForm(event)">
                <input type="text" name="title" required placeholder="Post title" />
                <textarea id="editor" name="content"></textarea>
                <input type="text" name="categories" required placeholder="Categories" />
                <div class="wrapper"> 
                    <select id="category" onChange="getCategory()">
                        <option>Slect a category</option>
                        <option>ES6</option>
                        <option>Python</option>
                        <option>PHP</option>
                        <option>Video</option>
                    </select>
                    <input type="text" name="thumb" required placeholder="Thumbnail" />
                    <input type="datetime-local" name="datetime" required />
                    <input type="submit" value="Publish" />
                </div>
            </form>
        `
    }

    return(
        <section class="Post">
            <script src="/js/ckeditor/ckeditor.js"></script>
            <script src="/js/addCategory.js"></script>
            <link rel="stylesheet" href="/css/users/post.css" />

            <div dangerouslySetInnerHTML={{__html: `
                ${editor}
            `}}/>
          
            <script src="/js/ckeditor/config.js"></script>
        </section>
    )
}

export default function Post(props){
    props.pageInner = PostJsx;
    const html = renderSSR(<Index data={ props } />);

    return `<!DOCTYPE html>${ html }`;
}
```

```css
/* public/css/users/post.css */

.Index .main .content form .ck-editor__editable{
    min-height: 305px;
}

.Index .main .content form .wrapper,
.Index .main .content .wrapper{
    display: grid;
    grid-template-columns: 20% 32.5% 32.5% 15%;
}

.Index .main .content form input,
.Index .main .content form select,
.Index .main .content .wrapper input,
.Index .main .content .wrapper select{
    width: 100%;
    font: var(--body-font);
    padding: 2px 5px;
}

.Index .main .content .wrapper div input{
    height: 100%;
}

.Index .main .content form .submit{
    background: lavender;
    text-align: center;
    color: black;
    border: 1px solid grey;
    padding: 5px;
}
```

```js
// public/js/addCategory.js 

function getCategory(){
    const category = $('#category option:selected').text()
    $('select').prop('selectedIndex',0)
    let categories = $('[name=categories]').val()
    if(categories === ''){
        categories += category
    }else{
        categories += (`, ${category}`)
    }
    
    $('[name=categories]').val(categories)
}
```