link3151 link3152 link3153 link3154 link3155 link3156 link3157 link3158 link3159 link3160 link3161 link3162 link3163 link3164 link3165 link3166 link3167 link3168 link3169 link3170 link3171 link3172 link3173 link3174 link3175 link3176 link3177 link3178 link3179 link3180 link3181 link3182 link3183 link3184 link3185 link3186 link3187 link3188 link3189 link3190 link3191 link3192 link3193 link3194 link3195 link3196 link3197 link3198 link3199 link3200 link3201 link3202 link3203 link3204 link3205 link3206 link3207 link3208 link3209 link3210 link3211 link3212 link3213 link3214 link3215 link3216 link3217 link3218 link3219 link3220 link3221 link3222 link3223 link3224 link3225 link3226 link3227 link3228 link3229 link3230 link3231 link3232 link3233 link3234 link3235 link3236 link3237 link3238 link3239 link3240 link3241 link3242 link3243 link3244 link3245 link3246 link3247 link3248 link3249 link3250 link3251 link3252 link3253 link3254 link3255 link3256 link3257 link3258 link3259 link3260 link3261 link3262 link3263 link3264 link3265 link3266 link3267 link3268 link3269 link3270 link3271 link3272 link3273 link3274 link3275 link3276 link3277 link3278 link3279 link3280 link3281 link3282 link3283 link3284

[Vue.js] @click not registering event in Vue devtools

there is a component that is designed to dynamically catch whether a menu item has a submenu attached to it, which it does successfully do. there is set up a method on the instance to toggle whether or not to show the subMenu, but when I click on it, nothing happens. In the vue.js devtools, nothing is registered in the events section. And since the click event isn’t triggered, I’m not getting the expected show/hide toggle.

I’ve tried to follow as closely as I could with the vue.js docs, but despite having the same syntax, I still have no success.

Here is my single file component. The method is called on the two font awesome icons with the @click.

<template>
<div class=”subMenuCatcher”>
<router-link class=”routerLink” active-class=”active” :to=”menuItem.route” exact>
{ menuItem.routeName }
</router-link>
<i
class=”fas fa-arrow-alt-circle-down icon”
:class=”{ hidden: !subMenuHidden }”
@click=”subMenuToggle”
\></i>
<i
class=”fas fa-arrow-alt-circle-up icon”
:class=”{ hidden: subMenuHidden }”
@click=”subMenuToggle”
\></i>
<div
class=”subMenu”
:class=”{ hidden: subMenuHidden }”
v-for=”(subMenuItem, index) in menuItem.subMenu”
:key=”index”
\>
<router-link class=”routerLink” active-class=”active” :to=”subMenuItem.subRoute” exact>
{ subMenuItem.subRouteName }
</router-link>
</div>
</div>
</template>

<script>
const subMenuHidden = true;

export default {
props: {
‘menu-item’: Object,
},
data: function() {
return {
subMenuHidden,
};
},
methods: {
subMenuToggle: function() {
return !this.subMenuHidden;
},
},
};
</script>

<style scoped lang=”scss”>
.subMenuCatcher {
display: flex;
flex-flow: row nowrap;
justify-content: center;
margin: auto;

.subMenu {
display: flex;
flex-flow: column nowrap;
justify-content: center;
}

.routerLink {
text-decoration: none;
color: $routerLinkColor;
}

.active {
color: $activeColor;
}

.icon {
color: $routerLinkColor;
}

.hidden {
display: none;
}
}
</style>

Basically, I’m expecting the subMenuToggle event to fire and change the local state from subMenuHidden = false to true and back. What I’m getting is no event at all.

Solution :

Basically, I’m expecting the subMenuToggle event to fire and change the local state from subMenuHidden = false to true and back. What I’m getting is no event at all.

What you are currently doing is that you are returning the negation of the subMenuHidden value which is false, but nothing happens to the state variable itself.

Change the toggle method to:
this.subMenuHidden = !this.subMenuHidden;

[Vue.js] getting 500 error on laravel and vuejs inserting to database + logfile

when trying to store data into my database using VueJs and I keep receiving 500 error
here is my code:

export default {
props: [‘post_id’,’user_id’],
data: function () {
return {
body:’’,
user_name : ‘’,
}
},

and the methods is here:

methods: {
loadComments() {
// axios.get(“../api/comment”).then(({ data })=>(this.comments - data.data)
axios.get(“../api/comment”).then((response) => (this.comments = response.data.data)
// response => this.comments = response.data
);
},
create() {
axios.post(‘../api/comment’,{body:this.body});
},

and here is a part of my form:

<form @submit.prevent=”create()” id=”myForm” class=”m-form m-form–fit m-form–label-align-right m-form–group-seperator-dashed”>
<div class=”form-group m-form__group row”>
<div class=”col-lg-6”>
<label>name</label>
<input type=”text” placeholder=”insert name” name=”body” class=”form-control m-input” v-model=”body”>
</div>

<div class=”col-lg-6”>
<label>email</label>
<input type=”text” placeholder=”email” name=”title” class=”form-control m-input”>
</div>
</div>

and the route for api laravel:

Route::resource(‘comment’,’CommentController’);

and finally here is what I get as log error in laravel :

[2019-03-25 07:07:08] local.ERROR: SQLSTATE[HY000]: General error: 1364 Field ‘body’ doesn’t have a default value (SQL: insert into comments (updated_at, created_at) values (2019-03-25 07:07:08, 2019-03-25 07:07:08)) {“exception”:”[object] (Illuminate\Database\QueryException(code: HY000): SQLSTATE[HY000]: General error: 1364 Field ‘body’ doesn’t have a default value (SQL: insert into comments (updated_at, created_at) values (2019-03-25 07:07:08, 2019-03-25 07:07:08)) at C:\wamp\www\jabama3\vendor\laravel\framework\src\Illuminate\Database\Connection.php:664, PDOException(code: HY000): SQLSTATE[HY000]: General error: 1364 Field ‘body’ doesn’t have a default value at C:\wamp\www\jabama3\vendor\laravel\framework\src\Illuminate\Database\Connection.php:458)

i know that my form is not sending data and laravel needs the data but i dont know which part when doing wrong .

Edit here is my store method :

public function store(Request $request)
{
Comment::create($request->all());
return ([‘message’ => ‘succes’]);
}

and here is my table structure :

Schema::create(‘comments’, function (Blueprint $table) {
$table->bigIncrements(‘id’);
$table->longText(‘body’);
$table->integer(‘user_id’)->nullable();
$table->string(‘user_email’)->nullable();
$table->string(‘user_name’);
$table->integer(‘status’)->default(‘0’);
$table->integer(‘post_id’);
$table->timestamps();
});

Solution :

You create file Comments.php Model, you can update file Comments.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
class Comments extends Model
{
protected $fillable = [
‘body’,
‘user_id’,
‘user_email’,
‘user_name’,
‘status’,
‘post_id’,
‘created_at’,
‘updated_at’
];

}

Example Laravel + Vuejs Send Mail

Solution 2:

This is because the body is empty when you inserting data to the table.
The reason is you are using Create a method for inserting data.
And Create method needs protected $fillable = [‘field1’,’field2’,…] array which have the table fields in the model.
Add $fillable to the model.
You can follow this link for more information relating to Mass Assignment

[Vue.js] Prevent vue render newline between elements

<template>
<div>
<span>foo</span> <!– unwanted space here –>
<span>bar</span>
<span>foo</span>
</div>
</template>

// But I don’t want to do this
<template>
<div>
<span>
foo
</span><span> <!– bad coding style –>
bar
</span><span>
baz
</span>
</div>
</template>

In html, newlines between elements are rendered as spaces, and vue.js followed that behavior. If no spaces between the elements, the obvious way is to put no space there, as shown in the code sample. But it is ugly, I don’t want that. How can I do otherwise such that there is no space between the elements?

Solution :

You can change the compiler options.

compilerOptions
type: Object

default: {}

Options for the template compiler. When using the default vue-template-compiler, you can use this option to add custom compiler directives, modules, or discard whitespaces between template tags with { preserveWhitespace: false }.

However the documentation states this only applies to single file components and template tags. I don’t think there is currently any option for native tags and related issue has been closed. But maybe it gives you the desired result.

[Vue.js] V-Model not cleansed when adding Object to array (Vue-Js)

I’m trying to add objects (simple key-value pairs) to a list.
However, the v-model is still bound to the previously added objects, so if I add “ObjectOne” vith “ValueOne”, then try to add “ObjectTwo” with “ValueTwo”, “ObjectOne” gets edited AND “ObjectTwo” gets added.

when by no mean an expert in Javascript, so it might not be related to VueJS.

I can obviously make this work with a method per list .

The point is that my model has multiple lists of key value pair to be edited, so I tried making a generic method :

addToList: function(value, list){
console.log(“Adding “ + value + “ to list “+list);
list.push(value);
value={};
},

This method works if used on “simple” lists (like an array of string), but not on “objects” list.

My guess is that as I try to clean “value” instead of “this.value”, the reference still points to the same object, but since I don’t know what “value” will be when called, I don’t know how to do this.

Here is the fiddle with a re-creation of my issue.

My objective would be to be able to use the “addToList” function to add to any list, without having to re-write a function for each list.

Thank you for the help.

Solution :

The above behaviour is because you are updating the value of same object whenever you add a new todo task.You need to set the object again to add new values as below.

addToList(value, todos){
this.todos.push(value);
this.anotherTodo={ text:’’,
done:’false’}
}

Working fiddle here.

Solution 2:

I post this as an answer, but if someone has a better way to do it, I’m all hear.

I solved the way by adding a watch on my list. When the list changes, I clean the model object that’s added to it.

In my production work, I had to add a computed property, since I can’t add a watch on an object’s property, then a watch on said computed property :

watch:{
todos(){
this.anotherTodo={};
},

fiddle as demo

[Vue.js] vuedraggable handle attribute not working

I’m trying to use vuedraggable inside a table, but when unable to rearrange the table rows with my desired handle:

code: https://codesandbox.io/s/kkpp3xry63

App.vue

<template>
<div id=”app”>
<RowComponent/>
<Draggable
v-model=”data”
v-bind=”drag_options”
handle=”[name=dragger]“
tag=”table”
@start=”drag = true”
@end=”drag = false”
\>
<thead slot=”header”>
<th>
Placeholder
</th>
<th>
Map Level
</th>
<th>
Revision
</th>
</thead>
<transition-group
type=”transition”
:name=”!drag ? ‘flip-list’ : null”
tag=”tbody”
\>
<row-component
v-for=”row in data”
:key=”row._id”
/>
</transition-group>
</Draggable>
</div>
</template>

<script>
import Draggable from “vuedraggable”
import RowComponent from “./components/Row.vue”;

export default {
name: “App”,
components: {
Draggable,
RowComponent
},
data ()
{
return {
data:
[
{
_id:
1,
},
{
_id:
2,
},
{
_id:
3,
},
],
drag:
false,
drag_options:
{
animation:
200,
group:
“description”,
disabled:
false,
ghostClass:
“ghost”
},
}
}
};
</script>

<style>

#app {
font-family: “Avenir”, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>

<style lang=”scss” scoped>
table
{
width: 100%;
}
table, th, td
{
border: 1px solid black;
border-collapse: collapse;
padding: 5px;
}
</style>

Row.vue

<template>
<tr>
<td>
<div name=”draggable”>Move</div>
</td>
<td style=”padding: 10px;”>
<input class=”form-control” type=”text”>
</td>
<td>
<div>
<select>
<option></option>
</select>
</div>
<div>
<div>
<button class=”btn btn-color-primary btn-size-normal”>Rename</button>
<button
class=”btn btn-color-primary btn-size-normal”
@click=”showing.note = !showing.note”
\>Note</button>
<button class=”btn btn-color-orange btn-size-normal”>Draw</button>
</div>
<div>
<textarea v-if=”showing.note”></textarea>
</div>
</div>
</td>
</tr>
</template>

<script>
export default {
data() {
return {
showing: {
note: false
}
};
}
};
</script>

<style lang=”scss” scoped>
td {
border: 1px solid black;
border-collapse: collapse;
}

textarea {
font-size: initial;
padding: 10px;
height: 100px;
width: 100%;
}

[name=”draggable”] {
cursor: pointer;
}
</style>

Solution :

From the github doc

Limitation: neither header or footer slot works in conjunction with transition-group.

If you remove header slot and handle it works fine. updated example

[Vue.js] Pass a variable to a child component

I’m trying to pass a class name as a variable to a child component.

Context: there is two types of header ( 2 different bakgrounds ) used all across the site.

Page1:

<HeaderMain bg=”bg” />

data() {
return {
pageTitle: ‘patterson.travel’,
bg: ‘bg-white’,
}
}

Page:2

<HeaderMain bg=”bg” />

data() {
return {
pageTitle: ‘patterson.travel’,
bg: ‘bg-header’,
}
}

HeaderMain :

<header>
<nav class=”main md:bg-transparent” :class=”bg”></nav>
</header>

But the class never gets applied to the <nav>

I tried adding the variable to HeaderMain component like so (as a default):

data() {
return {
bg: ‘bg-red’, // default?
}
}

But That is the class it allways has…

So, any idea what I’m missing, here?

( I also tried :bg=”bg” )

Solution :

You have to define the bg property on the HeaderMain component:

// HeaderMain.vue

<script>
export default {
props: [‘bg’]
}
</script>

You will then be able to use it in the template just like you did:

<header>
<nav class=”main md:bg-transparent” :class=”bg”></nav>
</header>

Solution 2:

In order to access it, you need to define props as an array inside the children component.

Look at the code below.

Vue.component(‘user-name’, {
props: [‘name’],
template: ‘<p>Hi { name }</p>’
})

const LastName = {
template: ‘<span> Patel </span>’
}
const Header = {
props: [‘bg’],
template: ‘<span :class=”bg”> {bg} Header </span>’
}

new Vue({
el: “#app”,
data: function() {
return {
headerBg: ‘header-bg’
}
},
components: {
‘last-name’: LastName,
‘header-view’: Header
}
});
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}

#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}

.header-bg {
background: red;
}

.header-bg {
background: red;
}
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id=”app”>
<header-view :bg=”headerBg”></header-view>
<user-name name=”Varit”></user-name>
<last-name></last-name>
</div>

[Vue.js] How to integrate Laravel API and VueJs project to a single URL/Project?

there is an API created using Laravel and can be accessed through the URL: http://www.project.com/api using the virtual host in which http://www.project.com/ points to the public folder of the Laravel project. I also have a separate vue.js project created using vue.js CLI which connects and request data to the Laravel API and can be accessed through http://localhost:8080/.

My question is, can I integrate the 2 separate projects into a single project or URL and if yes, how?

Solution :

Laravel come out of the box with Laravel Mix which you can use for compiling the vue.js project and serve it through Laravel.

Here are steps to do it.

First you copy whole vue.js project to /resources/render (you can change render to anything you like).
Go to the Laravel root folder and open up file named webpack.mix.js and change it to like this

const mix = require(‘laravel-mix’);

// Assuming the vue.js entry point is index.js
mix.js(‘resources/render/index.js’, ‘public/js’);

Create a blade file as entry point in resources/views. In my case it’s main.blade.php.

<!doctype html>
<html lang=”{ str_replace(‘_‘, ‘-‘, app()->getLocale()) }”>
<head>
<meta charset=”utf-8”>
<meta name=”viewport” content=”width=device-width, initial-scale=1”>
<title>Laravel</title>
</head>
<body>
<div id=”app”>
{– Content –}
</div>
</body>
<script type=”application/javascript” src=”{ mix(‘js/app.js’) }”></script>
</html>

Go to the routes/web.php and put only this route in. It will handles all routes in the vue.js app

Route::get(‘{path}’, function () {
return view(‘index’);
})->where(‘path’, ‘^(.+)?$’);

Run npm install and npm run watch to build and react to changes you make to the vue.js app. (You might want to remove unwanted dependencies from package.json)

there is a similar project with this setup. You can see it here for better understanding

[Vue.js] Method used in v-for loop doesn't return value

I’m rendering a list of objects with titles. Titles are sorted and to add before every next title which starts with new letter of the alphabet heading with given letter.

In v-for loop I include method azTitle with itemTitle parameter. In the method I first check if first letter of given title is included in azTitles array. If not, then I push given first letter into azTitles array and then I return first letter as a heading for group of titles with the same starting letter.

<div v-for=”(item, key, index) in videos”>

{ azTitle(item.title) }

<p>{ item.title }</p>

</div>

export default {
data: function() {
return {
azTitles: []
}
},
methods: {
makeAzTitle(title){
return title.substring(0, 1);
},
azTitle(itemTitle){

if (!this.azTitles.includes(this.makeAzTitle(itemTitle))) {

this.azTitles.push(this.makeAzTitle(itemTitle))

return “<h2>”+this.makeAzTitle(itemTitle)+”</h2>”

}

}
}
}

The result I expect is this:

A
Anthony
Andrew
B
Bethany
E
Emily
Emma

but I get this:
Anthony
Andrew
Bethany
Emily
Emma

Why the method doesn’t render values?

Solution :

You can’t manipulate data like that in a loop. What I’d do instead is use v-show on the h2 element and check if it needs to be displayed or not.

<div v-for=”(item, index) in videos”>
<h2 v-show=”isFirstTitle(index)”>{ makeAzTitle(item.title) }</h2>
<p>{ item.title }</p>
</div>

methods: {
makeAzTitle(title){
return title.substring(0, 1);
},
isFirstTitle(index){
if (index === 0) {
return true;
}

if (this.makeAzTitle(this.videos[index].title) !== this.makeAzTitle(this.videos[index - 1].title)) {
return true;
}
return false;
}
}

Solution 2:

That won’t work.

vue.js only accepts expressions in the template syntax. the function declaration is not an expression and as such it doesn’t work.

the best bet is to use v-if or v-show and use a method as the value for those.

Solution 3:

I Think this is the wrong way to achieve it. Unfortunately, I can’t explain to you why its not working but I can show you a better way to do what you want.

You should take the collection of videos and let them be sorted inside a method to a object of this style:

{
A: [
{ title: ‘Andrew’ },
{ title: ‘Alex’ },
{ title: ‘Alduin’ }
],
B: [
{ title: ‘Bread’ },
{ title: ‘Butter’ }
],
E: [
{ title: ‘Emma’ },
{ title: ‘Ernst’ }
]
}

Then you can loop it properly this way:

new Vue({
el: ‘#app’,
data: {
videos: [{
title: ‘Andrew’
},
{
title: ‘Alex’
},
{
title: ‘Alduin’
},
{
title: ‘Bread’
},
{
title: ‘Butter’
},
{
title: ‘Emma’
},
{
title: ‘Ernst’
}
]
},
methods: {
categorizedVideos() {
let cv = {};

for (let i = 0; i < this.videos.length; i++) {
let video = this.videos[i];
let category = video.title.substring(0, 1);

if (!cv[category]) {
cv[category] = [];
}

cv[category].push(video);
}

return cv;
}
}
});
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id=”app”>
<div v-for=”(videos, key, index) in categorizedVideos()”>
<h2>{ key }</h2>
<div v-for=”video in videos”> { video.title }</div>
</div>
</div>

[Vue.js] Vue + Typescript + webpack Import html into component

there is a typescript + vue.js + webpack application and separate html from code.
there is follow this tutorial and there is made a simple Hello Word.

Webpack config

const path = require(‘path’);

module.exports = {
mode: “development”,
entry: ‘./src/app.ts’,
output: {
path: path.resolve(‘dist’),
filename: ‘bundle.js’
},
module: {
rules: [
{
test: /\.(ts|tsx)?$/,
loader: ‘ts-loader’,
exclude: /node_modules/
},
{
test: /.html$/,
loader: “vue-template-loader”,
exclude: /index.html/
}
]
},
resolve: {
extensions: [
‘.js’,
‘.vue’,
‘.tsx’,
‘.ts’
]
}
};

Html

<div>
<h2>Hello from {message}</h2>
</div>

vue.js Component

import vue.js from “vue”;
import Component from “vue-class-component”;
// template: ‘<button @click=”onClick”>Click!</button>’
import WithRender from “./home.html”;

@WithRender
@Component
export default class HomeComponent extends vue.js {

public message: string = “Word”;

constructor() {
super();
}

mounted() { }
}

After there is added this shim

declare module ‘*.html’ {

import Vue, { ComponentOptions, FunctionalComponentOptions } from ‘vue’
interface WithRender {
<V extends Vue, U extends ComponentOptions<V> | FunctionalComponentOptions>(options: U): U
<V extends typeof Vue>(component: V): V
}

const withRender: WithRender
export default withRender
}

there is (almost) understand how typescript decorators work but I don’t understand the shim code, how it is possible that this code inject the html into the vue.js component ?

there is readed about Decorators from Typescript site

Solution :

vue-template-loader compiles the HTML template into a render function, which @WithRender inserts into the class definition.

For instance, this HTML:

<div>Hello world</div>

is converted into this render function:

render(h) {
return h(‘div’, ‘Hello world’)
}

Then, applying @WithRender (the result of importing the example HTML template above) to class Foo extends vue.js {} results in:

class Foo extends vue.js {
render(h) {
return h(‘div’, ‘Hello world’)
}
}

[Vue.js] Can't open modal on cellClick

I’m trying to get a modal to pop up on cellClick. I’m not getting any errors, but it’s not working. The table still loads and my other functions run on cellClick, but not the modal. I’m using Vue, Tabulator, bootstrap.

<script>
var Tabulator = require(‘tabulator-tables’)
export default {
name: ‘Test’,
data: function () {
return {
modalShow: false,
tabulator: null, // variable to hold the table
tableData: [
{name: ‘Billy Bob’, age: ‘12’},
{name: ‘Mary May’, age: ‘1’}
] // data for table to display
}
},
watch: {
// update table if data changes
tableData: {
handler: function (newData) {
this.tabulator.replaceData(newData)
},
deep: true
}
},
created: function () {
console.log(‘Test’, this.$refs)
},
mounted () {
// instantiate Tabulator when element is mounted
this.tabulator = new Tabulator(this.$refs.table, {
data: this.tableData, // link data to table
layout: ‘fitColumns’,
columns: [
{title: ‘Name’, field: ‘name’, sorter: ‘string’, width: 200},
{title: ‘Age’, field: ‘age’, sorter: ‘number’, align: ‘right’, formatter: ‘progress’}
],
cellClick: function (e, cell) {
var name = cell.getRow().getCell(‘name’).getValue()
var value = cell.getValue()
var field = cell.getField()
console.log(name, value, field)
return {
modalShow: true
}
}
})
}
}
</script>

<template>
<div ref=”table”>
<b-modal v-model=”modalShow”>Test</b-modal>
</div>
</template>

Solution :

User @dagalti is almost correct - in their example, this would refer to Tabulator, so you have to capture the vue.js instance at an elevated scope, in a variable there is named self. See my modifications to the code, below.

mounted () {
var self = this;

// instantiate Tabulator when element is mounted
this.tabulator = new Tabulator(this.$refs.table, {
data: this.tableData, // link data to table
layout: ‘fitColumns’,
columns: [
{title: ‘Name’, field: ‘name’, sorter: ‘string’, width: 200},
{title: ‘Age’, field: ‘age’, sorter: ‘number’, align: ‘right’, formatter: ‘progress’}
],
cellClick: function (e, cell) {
var name = cell.getRow().getCell(‘name’).getValue()
var value = cell.getValue()
var field = cell.getField()
console.log(name, value, field)

self.modalShow = true;
}
})
}