Thomas Sohet


1,680 Experience
9 Lessons Completed
1 Question Solved


Status update: [SOLVED]

Thanks to a live code of Adam Wathan himself, I found out that [v-cloak] was the solution I was looking for.

Here is the solution:

I have a classic RoR - Webpacker app.
On top of Webpacker, we have implemented Vue as our frontend framework and Tailwind as our css framework 👌

Everything is functioning fine. Yet I am not quite happy with the navbar behaviour at page load.

The implementation is the following:
The layout.html file:

doctype html lang=locale
    = stylesheet_pack_tag "application"
    = javascript_pack_tag "application"

    div data-behavior='vue'
      = sw-navigation
      == yield

The application.js file:

import { Navigation } from '../components/layout'
Vue.component('sw-navigation', Navigation)

document.addEventListener('DOMContentLoaded', () => {
  const app = new Vue({
    el: '[data-behavior="vue"]'

The sw-navigation is a straightforward vue component.

The issue is that at loading, my navbar has a weird behaviour that's making it look ugly:
The JS not being interpreted display yet, the element of the navbar appears on the right the screen without any style.

You can see the result in my screenshot here

How can I solve this ?

  • I know I can investigate in server-side rendering. But TBH I'd like to avoid that option just for a navbar component
  • I know I can use a plain old html navbar, no vue component. Yet this is exactly the perfect use case for a component in my opinion (needs JS for scrolling behaviour - content changes based on variables - ...)
  • What else ?

Please help, I am sure I am not the only one struggling with this 😉

Posted in Vue.js Trello Clone in Rails - Part 8 Discussion

+1 definitely

Posted in Rails & Vue.js Trello Clone - Part 4 Discussion

Hey Chris or anybody,

I am stuck here, the @change does not fire any event and the @end or others hooks does not provide the element in the event.

Without the element, it's pretty impossible to go further.

Thanks for you answer.

The @end event:

CustomEvent {isTrusted: false, to: div.dragArea, from: div.dragArea, item: div.card.card-body.card-padding, clone: div.card.card-body.card-padding, …}
isTrusted: false
detail: null
type: "end"
target: div.dragArea
currentTarget: null
eventPhase: 0
bubbles: true
cancelable: true
defaultPrevented: false
composed: false
timeStamp: 3530.1349999936065
srcElement: div.dragArea
returnValue: true
cancelBubble: false
path: (7) [div.dragArea, div.col-3, div#app.row.dragArea, body.lang-en, html, document, Window]
to: div.dragArea
from: div.dragArea
item: div.card.card-body.card-padding
clone: div.card.card-body.card-padding
oldIndex: 1
newIndex: 0
oldDraggableIndex: 1
newDraggableIndex: 0
originalEvent: DragEvent {isTrusted: true, dataTransfer: DataTransfer, screenX: 814, screenY: 471, clientX: 789, …}
pullMode: undefined
__proto__: CustomEvent
  <draggable v-model="lists" :options="{group: 'lists'}" class="row dragArea" id="app" @end="listMoved">
    <div class='col-3' v-for="(list, index) in lists">
      <h6>{{ }}</h6>
      <draggable v-model="lists.card" :options="{group: 'cards'}" class="dragArea" @end="cardMoved">
        <div class="card card-body card-padding" v-for="(card, index) in" :key="">
          {{ }}

      <div class="card card-body">
        <textarea v-model="messages[]" name="new_card" class="form-control"></textarea>
        <button @click="submitMesages(" class="btn btn-secondary">Add new card</button>

import draggable from 'vuedraggable'

export default {
  components: { draggable },
  props: ["original_lists"],
  data: function() {
    return {
      messages: {},
      lists: this.original_lists
  methods: {
    log: function(event) {
    listMoved: function(event) {
      let data = new FormData
      data.append("list[position]", event.newIndex + 1)

        url: `/lists/${this.lists[event.newIndex].id}/move`,
        type: "PATCH",
        data: data,
        dataType: 'json'
    cardMoved: function(id, event) {
      console.log(id, event)
      // const list_index = this.lists.findIndex((list) => {
      //   return => {
      //     console.log(event)
      //     // return ===
      //   })
      // })
    submitMesages: function(list_id) {
      let data = new FormData
      data.append("card[list_id]", list_id)
      data.append("card[name]", this.messages[list_id])

        url: "/cards",
        type: "POST",
        data: data,
        dataType: 'json',
        success: (data) => {
          const index = this.lists.findIndex(item => == list_id)
          this.messages[list_id] = undefined

<style scoped>
p {
  font-size: 2em;
  text-align: center;

.dragArea {
  padding: 5px;
  min-height: 20px;

.card-padding {
  margin-bottom: 10px

.ghost {
  opacity: 0.8;
  background: #f4f4f4;

'rails', ''
"vuedraggable": "2.23.2"
webpacker (4.2.2)

Posted in Rails & Vue.js Trello Clone - Part 4 Discussion

@Elijah, the @change is not working for me (the event is never fired), could you elaborate your solution please ?

logo Created with Sketch.

Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

© 2020 GoRails, LLC. All rights reserved.