My vue component like this :
<template>
<ul class="nav nav-tabs nav-tabs-bg">
<li role="presentation" v-for="item in tabs">
1. failed -> {{ item.name }} 2.success -> {{trans('purchase.payment.tab')}}
</li>
</ul>
</template>
<script>
export default {
data() {
return {
tabs: [
{name: "trans('purchase.payment.tab')"}
]
}
}
}
</script>
My lang in laravel(resources/lang/en/purchase.php) like this :
<?php
return [
'payment' => [
'tab' => 'Payment Status',
],
...
];
If the component vue executed, the result like this :
failed -> trans('purchase.payment.tab') 2.success -> Payment Status
So, if trans used in data, it does not work
How can I solve this problem?
Is not possible to use a PHP helper inside JavaScript. But, you can create an object of translations.
In your AppServiceProvider (you can create a new one if you want):
// Don't forget to import the facade
use Illuminate\Support\Facades\Lang;
public function boot() {
$translations = [
'auth' => Lang::get('auth'),
'pagination' => Lang::get('pagination'),
'passwords' => Lang::get('passwords'),
'validation' => Lang::get('validation'),
];
view()->share('translations', json_encode($translations));
}
In your HTML (I suggest header) you can just call:
window.app = {
translations: {!! $translations !!},
}
And to access using in JS, you can just do this, for example:
this.app.translations.auth.throttle // Too many login attempts. Please try again in :seconds seconds.
I use vue-i18n for that. That way you should make its own dictionary.
I made a i18n/en.js file;
module.exports = {
login: {
title: 'Login',
loginButton: 'Login',
emailInput: 'email',
passwordInput: 'password',
},
Form: {
title: 'Form',
}
}
and a i18n/hu.js with the same variables in Hungarian. Then I made a i18n/map.js file:
var en = require('./en.js');
var hu = require('./hu.js');
module.exports = {
en,
hu,
}
and finally, set it in vue.js, check my app.js file part:
require('./bootstrap'); // vue comes from here
import VueI18n from 'vue-i18n'
import dictionary from './i18n/map'
var localeTmp = document.documentElement.lang;
var locale = "hu";
if(localeTmp) {
locale = localeTmp
}
const i18n = new VueI18n({
locale: locale, // set locale
dictionary, // set map of dictionary
})
....
const app = new Vue({
el: 'app',
i18n,
});
Its a very elegant way.
and how I use in component? simple:
....
<md-input-container>
<md-icon>person</md-icon>
<label>{{ $t("loginForm.emailInput") }}</label>
<md-input email name="email" required v-model="email" />
</md-input-container>
....
Related
I have a project build in Laravel with Vue.js which work perfect statically, but I need convert it into dynamically to pull records from database table to v-data-table component.
I know Laravel and I know How these things works via Ajax/jQuery but I'm pretty new in Vue.js
Can someone explain to me how to display the results from the database in the v-data-table component.
Thanks.
Here is the Vue.js file:
<template>
<v-app>
<v-main>
<div>
<v-tab-item>
<v-card flat>
<v-card-text>
<v-card-title>
<v-spacer></v-spacer>
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Search"
single-line
hide-details
></v-text-field>
</v-card-title>
<v-data-table
:headers="headers"
:items="items"
:items-per-page="5"
class=""
:search="search">
</v-data-table>
</v-card-text>
</v-card>
</v-tab-item>
</div>
</v-main>
</v-app>
</template>
<script>
export default {
data: () => ({
search: '',
items: [],
headers: [
{
text: '#',
align: 'start',
sortable: false,
value: 'id',
},
{ text: 'Name', value: 'name' },
{ text: 'Slug', value: 'slug' },
],
/*THIS IS A STATIC DATA*/
// items: [
// {
// id: 1,
// name: 'Test Name 1',
// slug: 'test-name-1',
// },
// {
// id: 2,
// name: 'Test Name 2',
// slug: 'test-name-2',
// },
// ],
/*THIS IS A STATIC DATA*/
}),
created () {
this.getItems();
},
methods: {
getItems() {
axios
.get('/test/vue')
.then((response) => {
this.items = response.data,
console.log(response.data)
})
.catch(error => console.log(error))
},
}
}
</script>
And Here is Blade file:
#extends('it-pages.layout.vuetify')
#section('content')
<div id="appContainer">
<software-template></software-template>
</div>
Output in the console is :
console.log
Response from axios is also Ok
response
My Controller :
public function showData()
{
$items = Category::select('id', 'name', 'slug')->where('order', 1)->get();
// dd($items);
return response()->json(['items' => $items]);
}
My route:
Route::get('test/vue', 'PagesController#showData');
console.log after changes axios lines
console-log
So there were multiple issues here:
The backend did you return a correct array
The frontend performed a post request instead of a get
The this context is not correct since you are using a function instead of arrow syntax
Make sure to look at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions and read about how this changes how this is elevated.
In your case, you need to change the code on the then part of your axios call:
.then((response) => {
this.items = response.data
})
I must to say that I solve the problem.
Problem was been in axios response.
Instead this.items = response.data I change to this.items = response.data.items and it work perfectly.
methods: {
getItems() {
axios
.get('/test/vue')
.then((response) => {
this.items = response.data.items
console.log(response.data.items)
})
.catch(error => console.log(error))
},
}
I have used vue multiselect in my form and I have made the options dynamic as autocomplete by axios post . I am returning only id and name from the controller to js file but it is displaying all the properties of option
This is My form
<multiselect v-model="form.books" :options="options" :loading="isLoading" :internal-search="false" #search-change="getData" :multiple="true" :close-on-select="false" :hide-selected="true" :limit="5" :internal-search="false"></multiselect>
This is my vue js file
Vue.component('coupon-form', {
mixins: [AppForm],
data: function() {
return {
form: {
name: '' ,
description: '' ,
valid_from: '' ,
valid_till: '' ,
discount: '' ,
enabled: false,
books:[],
},
isLoading: false,
options: [],
}
},
methods: {
getData(query){
this.isLoading = true;
axios.post('/admin/books/find/'+query)
.then((response) => {
console.log(response);
this.options = response.data;
this.isLoading = false;
})
.catch((error) => {
this.isLoading = false;
});
}
}
});
This is my controller
public function find($books)
{
$search = $books;
$books = Book::select('id','name')
->where('id','like',"%$search%")
->orWhere('name','like',"%$search%")
->orWhere('sku','like',"%$search%")
->orWhere('sale_price','like',"%$search$")
->limit(5)->get();
return $books;
}
}
As we can see I am selecting the id and name of the Book Model but I am getting many properties of Book like this
And I want to show the name in the options and in the v-model I want to have id
How to do that
You need new field in your data and watcher for value so try something like this:
<multiselect v-model="selected"...></multiselect>
data () {
selected: []
...
},
watch: {
selected (newValues) {
this.form.books = newValues.map(obj => obj.id)
}
}
I think that is what you need.
I found a lot of issues about that and package doesn't have prop for that.
You can read more on there: link1, link2
Good luck!
DB::table('books')->select('id,name')->where('id','like',"%$search%")
->orWhere('name','like',"%$search%")
->orWhere('sku','like',"%$search%")
->orWhere('sale_price','like',"%$search$")
->limit(5)->get();
<template>
<div>
<multiselect v-model="yourForm.bindThis" :options="options" :custom-label="showItems" placeholder="Select one" :label="options.name_of_a_column_from_record" :track-by="options.id_of_record" :multiple="true"></multiselect>
</div>
</template>
<script>
import Multiselect from 'vue-multiselect';
data(){
return{
options: [],
yourForm: {
bindThis: '',
}
}
},
methods:{
showItems({data}){
return `${data.name_of_a_column_from_record}`;
}
}
</script>
Let me know if it did the magic
Add track-by and label props.
<multiselect
v-model="form.users"
:options="scholars"
:multiple="true"
:searchable="true"
label="name"
track-by="id"
>
</multiselect>
I have a project with Laravel + vue.js.
I made a vue component and it takes some data from a controller.
I wanted to display the data in the view using v-for, but nothing is displaying.
vue template code
<template>
<div v-for="val in expiredIos" class="card col-xs-12 col-md-5 col-lg-2 m-1 p-0 d-inline-block">
<div class="mx-0 p-2 text-truncate" style="width:10rem;vertical-align:middle;">
{{ val.app_name }}
</div>
</div>
...
</template>
vue script part
export default {
data: function() {
return {
expiredIos: []
}
},
mounted() {
console.log("expired here");
this.getExpiredIosData();
},
methods: {
getExpiredIosData: function() {
axios.post('/expired')
.then(response => {
for (var i = 0; i < response.data.length; i++) {
this.expiredIos[i] = response.data[i];
console.log(this.expiredIos[i]);
}
});
}
},
}
The result of console.log
{app_name: "app1", app_id: "migunstyle", ios_dev_exp: "2019-01-16"}
{app_name: "app2", app_id: "jcalling", ios_dev_exp: "2019-02-19"}
{app_name: "app3", app_id: "modoobebe", ios_dev_exp: "2019-03-08"}
{app_name: "app4", app_id: "babyfactory", ios_dev_exp: "2019-03-19"}
{app_name: "app5", app_id: "merrygirl", ios_dev_exp: "2019-03-21"}
...
What did I wrong here?
Try setting the entire array to the data property directly.
getExpiredIosData: function() {
axios.post('/expired')
.then(response => {
this.expiredIos = response.data; // <-- Set property directly
});
}
Vue tracks all data properties, but tracking array changes is something it cannot do. You need to either use the build in array manipulation functions or replace the array entirely for vue to pick up the change.
https://v2.vuejs.org/v2/guide/list.html#Array-Change-Detection
Axios loads data without any problem, doesn't show any data, Laravel Mix builds without error.
I have following code:
index.html (body)
<div id="app">
<posts></posts>
</div>
In app.js I use this:
import Vue from 'vue';
// global declare axios
window.axios = require('axios');
import Posts from './components/Posts';
Vue.component('posts', Posts);
new Vue({
el: '#app',
props: {
posts:[{
userId: [Number],
id: [Number],
title: [String, Number]
}]
}
});
In the Posts.vue component I create a template and a script loading the data when mounted:
<template>
<ul>
<li v-for="post in posts" v-text="post.title"></li>
</ul>
</template>
<script>
export default {
data: function() {
return {
posts: null,
}
},
// when stuff is loaded (document ready)
mounted: function() {
// use placeholder data for tests, capture asynchronous data from site using this.
axios.get('https://jsonplaceholder.typicode.com/posts')
.then(response => this.posts = response.posts)
.catch(error => this.posts = [{title: 'No posts found.'}])
.finally(console.log('Posts loading complete'));
},
}
</script>
So the data should be shown as a ul list:
<ul>
<li>
title
</li>
<li>
title
</li>
<li>
title
</li>
</ul>
Try the code below, I've made comments on the bits that need changing.
data() {
return {
posts: [] // this should be an array not null
};
},
// you can do this on created instead of mounted
created() {
axios.get('https://jsonplaceholder.typicode.com/posts')
.then(response => {
this.posts = response.data; // add data to the response
});
` Here "this.post" not take it has instance in axios call.So you have follow like this. `
var vm=this;
axios.get('https://jsonplaceholder.typicode.com/posts')
.then(response => vm.posts = response.posts)
.catch(error => vm.posts = [{title: 'No posts found.'}])
.finally(console.log('Posts loading complete'));
I need to implement a multiselect in the view in which I am working, the idea is to have several options selected in the same select. I have tried some components that I found on the web but without good results.
The route and the driver method in Laravel work well.
I have to feed the Multiselect from a method that brings the data
If you can give me a hand it would be great, I leave the code
<template>
<div>
<div class="col-sm-12">
<select class="form-control form-control-line">
<option v-for="coin in coins" :key="coin.id" value="coin.id">
{{ coin.name }}
</option>
</select>
</div>
</template>
<script>
export default {
data () {
coins: [],
},
created() {
this.getCoins();
},
methods: {
getCoins(){
let urlCoin = '/dashboard/coins';
axios.get(urlCoin)
.then((response) => {
this.coins = response.data;
})
.catch((err) => {
})
}
}
My Method in the CoinController
class CoinController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function coinList() {
$coins = Coin::orderBy('rank', 'asc')
->select('id', 'name', 'rank')
->get();
return response()->json($coins);
}
}
the idea is to do this
Multiselect
I used Laravel 5.6 and Vuejs
You can't use basic select tag to show multiple selected value that you get from server.. because it only support to select one option.. if you want to select multiple like your pict, you have to add more library like vue multiselect
<multiselect v-model="value",
:options="coins",
:multiple="true",
:close-on-select="false",
:clear-on-select="false",
:hide-selected="true",
:preserve-search="true",
placeholder="Pick some"
label="name",
track-by="name",
:preselect-first="true" >
<template slot="tag" slot-scope="props">
<span class="custom__tag">
<span>{{ props.option.language }}</span>
<span class="custom__remove"
#click="props.remove(props.option)">
x
</span>
</span>
</template>
</multiselect>
<script>
export default {
data () {
value: [],
coins: [],
},
created() {
this.getCoins();
},
methods: {
getCoins(){
let urlCoin = '/dashboard/coins';
axios.get(urlCoin)
.then((response) => {
this.coins = response.data;
})
.catch((err) => {
})
}
}