Getting a slug to save in vue - laravel

I'm using both vue and laravel and I'm trying to create a product form that creates a slug as you type. I've managed to get
the slug to show up as you type but I'm not sure as to how I should save it to my database.
My vue
<template>
<div class="product-form">
<form v-on:submit="onSubmit(model)">
<div class="form-group">
<label for="title">Title</label>
<input type="text" id="title" class="form-control" name="title" v-model="model.title">
<input type="hidden" name="slug" title="slug" :value="slug(model.title)">
<p>{{ slug(model.title) }}</p>
</div>
<input type="submit" class="btn btn-default" value="Save"></input>
</form>
</div>
</template>
<script>
export default {
data() {
return {
model: {
title: '',
slug: '',
},
};
},
methods: {
slug() {
var title = this.model.title;
var slug_test = title.replace(/\s+/g, '-');
return slug_test;
},
onSubmit: function(model){
event.preventDefault();
this.$http.post('/database/articles', model)
}
},
}
</script>

It suffices to keep the slug property of your model up to date with the title property.
The cleanest approach here would be a watcher on your title that updates the slug, or by computing model.slug right before you POST it to the server.

You can append slug in Model Resource if you are using Laravel

Related

Nuxt with Axios POST to Laravel's API

guys, :)
I'm no expert (yet) with API call's, am successful with Laravel on its own. So, need your help.
I am able to use Laravel + Nuxt in general. All connected POST and GET working fine on all CRUDs.
I've created a new department to this existing APP.
I am able to call GET and receive in return Data from API, no problem.
I am able to POST with Postman to API to this table/CRUD.
I'm unable to figure out how to POST with my form to API.
I know it's dead simple for some of you, but google this time couldn't answer straight away. Using VUE as an answer didn't help either. So, you're my only hope to be true.
Here is my code in Page file:
<template>
<section class="max-content page">
<TitleBox :title="'Dodaj Towar'" />
<DodajTowar button-text="Submit" submit-form="products" />
</section>
</template>
<script>
import TitleBox from '~/components/global/TitleBox.vue'
import DodajTowar from '~/components/magazyn/towar/DodajTowar.vue'
export default {
components: {
TitleBox,
DodajTowar
}
}
</script>
Here is the components file. They are connected and I can insert the data to DB only what I'll hardcode in this file:
<template>
<section class="container">
<div>
<form #submit.prevent="products">
<p>
<label for="name" class="input-label">Nazwa</label>
<input id="name" type="text" name="name" class="input">
</p>
<p>
<label for="description" class="input-label">Opis</label>
<input id="description" type="text" name="description" class="input">
</p>
<p>
<label for="price" class="input-label">Cena</label>
<input id="price" type="text" name="price" class="input">
</p>
<p>
<button type="submit" value="Submit" class="button btn-primary">
Zapisz
</button>
</p>
</form>
</div>
</section>
</template>
<script>
export default {
products() {
return {
name: '',
description: '',
price: ''
}
},
methods: {
products() {
// this.$axios.$post('api/warehouse/products', console.log(this.products))
this.$axios({
method: 'post',
url: 'api/warehouse/products',
data: {
name: 'Fred',
description: 'Flintstone',
price: '111'
}
})
}
}
}
</script>
Can you please provide me with an example of how should I do it the right way? The form is working fine on its own as well, in the dev tools in VUE, I can see what I'm typing and submit as products.
Sorry if this question was before, but I was unable to find the solution for the last days and run out of options.
You need to make your 'products' elements 'data' elements and bind your data elements to your form.
//change from 'products'
data() {
return {
name: '',
description: '',
price: ''
}
},
Then your form should look like this:
<form #submit.prevent="products">
<p>
<label for="name" class="input-label">Nazwa</label>
<input id="name" v-model="name" type="text" name="name" class="input">
</p>
<p>
<label for="description" class="input-label">Opis</label>
<input id="description" v-model="description" type="text" name="description" class="input">
</p>
<p>
<label for="price" class="input-label">Cena</label>
<input id="price" v-model="price" type="text" name="price" class="input">
</p>
<p>
<button type="submit" value="Submit" class="button btn-primary">
Zapisz
</button>
</p>
</form>
The v-model attribute will bind the data elements to the inputs.
When you access the data elements in your method, you need to use 'this'.
products() {
this.$axios({
method: 'post',
url: 'api/warehouse/products',
data: {
name: this.name,
description: this.description,
price: this.price
}
})
//add a .then() and a .catch() here to deal with response.
}
And that should do it.

Laravel Vuejs form builder

In my project i have some events, each with a number of tags.
These tags are defined by the administrator user.
Some of these tags may have parameters.
For example, an email tag has two "Sender" and "Receiver" parameters.
Or the transfer tag has 2 parameters "From" and "To". and etc.
Do I have to use the form builder?
How do I implement this using Laravel and Vuejs?
Use Vue JS Component in Laravel like this.
Create Contact.vue component inside resources\assets\js\components then place your Vuejs there.
<template>
<div>
<h1>Contacts</h1>
<form action="#" #submit.prevent="createContact()">
<div class="form-group">
<label>Name</label>
<input v-model="contact.name" type="text" name="name" class="form-control">
</div>
<div class="form-group">
<label>Email</label>
<input v-model="contact.email" type="text" name="email" class="form-control">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">New Contact</button>
</div>
</form>
</div>
</template>
<script>
export default {
data: function(){
return {
contact:{
name:'',
email:'',
}
}
},
methods: {
createContact: function(){
//call axios to submit the form values in your Laravel controller method
let self = this
axios.post('/contact/store', params)
.then(function(){
self.contact.name = '';
self.contact.email = '';
})
.catch(function(error){
console.log(error);
});
console.log(this.contact);
return;
}
}
}
</script>
In app.js file inside \resources\assets\js add the component
Vue.component('contacts', require('./components/Contacts.vue'));
Finally, call the contacts component inside your blade file.
<div class="container">
<div id="app">
<contacts></contacts>
</div>
</div>

VueJs: How to create a select where options come from a query to other model

I'm new on VueJs and I don't know why I have the following problem:
I'm creating a view called Owners.vue where I show pub owners. In UpdateProfile.vue I show the owner data and here is where I have my problem: I'd like to build a select where the options are the possible pubs stored in my table "pubs":
My vue component is as follows:
UpdateProfile.vue
<template>
<confirm title="Edit User" ok="Save user" :show="show"
v-on:save="save"
v-on:close="close">
<div class="field">
<label class="label">Name</label>
<div class="control">
<input class="input" type="text" placeholder="User name" v-model="data.name">
</div>
</div>
<div class="field">
<label class="label">Lastname</label>
<div class="control">
<input class="input" type="text" placeholder="last name" v-model="data.lastname">
</div>
</div>
<div class="field">
<label class="label">Email</label>
<div class="control">
<input class="input" type="email" placeholder="email" v-model="data.email">
</div>
</div>
<!--Owner Pubs-->
<div class="field">
<label class="label">Pubs</label>
<div v-for="pub in data.userPubsOwned" class="control">
<input class="input" type="text" placeholder="Pub tapps" v-model="pub.name">
<div class="button is-danger" #click="deletePubFromOwner(pub.id)">
<span class="icon"><i class="far fa-trash-alt"></i></span>
<span>Delete</span>
</div>
</div>
<br>
</div>
<!--Owner Pubs-->
<!--Add Pubs to Owner-->
<div class="field">
<label class="label">Add new Pub</label>
<div class="select">
<select v-model="pubs">
<option v-for = "pub in pubs" :value="pub.id" >{{pub.name}}</option>
</select>
</div>
<br>
<br>
<div class="button is-info" #click="addPubToOwner()">
<span class="icon"><i class="fas fa-save fa-lg"></i></span>
<span>Add Tapp</span>
</div>
</div>
<!--Add Pubs to Owner-->
</confirm>
import User from "../../models/user";
export default {
props: {
show: Boolean,
data: Object,
},
data() {
return {
selected: null,
data: new User(),
pubs: [],
pub: new Pub(),
}
},
computed: {
},
methods: {
save() {
this.$emit('save', this.data);
},
close() {
this.$emit('close');
},
hasRootPermissionsAndIsNotRoot() {
return this.CONSTANTS.hasRootPermissions() && this.data.permissions !== this.CONSTANTS.ROOT_USER.permissions;
},
addPubToOwner(){
this.api.post('/owners/' + this.data.id + '/' + this.selected).then(response => {
this.data = response.data;
});
},
deletePubFromOwner(ownerpub) {
this.api.delete('/owners/' + this.data.id + '/' + ownerpub).then(response => {
this.data = response.data;
});
},
}
}
I just need to show all the pubs stored in my table pub...do I have to create a function? And how it would be?
Thanks a lot for your help!!
Yes, create a method in the mounted() section. I use a similar process to show all of the flavors/prices of a product in a shopping cart. Here is my code that you can use and hopefully extrapolate your answer from:
Mounted function to load upon vue mount
mounted: function() {
this.getPrice();
},
getPrice() function:
getPrice: function(){
axios.post('/getproductinfo', this.$data.model)
.then((response) => {
console.log(response);
this.display_name = response.data.display_name;
this.price = '$' + response.data.price;
})
.catch(error => {
this.errors.record(error.response.data.errors);
});
},
And finally the code in your view blade file
<select class="centerSelect" v-show="!loading && ordering" ref="quantitySelect" v-model="model.id" name="code_id" #change="getPrice">
#foreach ($code as $item)
<option value="{{$item->id}}">{{$item->display_name}}</option>
#endforeach
</select>

Have a form to edit user account, make default values current values but still use v-model?

I'm trying to make a form to edit your user account in Vue/Laravel.
Ideally I'd like to make the name and email boxes pre-filled with the users current values. I could do that easily using
<input type="text" class="form-control" name="user" autocomplete="false" :value="$parent.user.name">
The issue is that I'd also like to use v-model="form.name" like so:
<template>
<form class="row" #submit.prevent="onSubmit">
<div class="form-group col-md-6 col-lg-3">
<label>Name</label>
<input type="text" class="form-control" name="user" autocomplete="false" :value="$parent.user.name" v-model="form.name">
</div>
<div class="form-group col-md-6 col-lg-3">
<label>Email address</label>
<input type="email" class="form-control" placeholder="Enter email" autocomplete="false" name="email" :value="$parent.user.email" v-model="form.email">
</div>
<div class="form-group col-lg-3">
<label>Password</label>
<input type="password" class="form-control" placeholder="Password" autocomplete="new-password" name="password" v-model="form.password">
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</template>
<script>
export default {
data() {
return {
form: new Form({
name: '',
email: '',
password: '',
})
}
},
methods: {
onSubmit() {
// ajax stuff here
}
}
}
</script>
But this throws an error :value="$parent.user.name" conflicts with v-model on the same element because the latter already expands to a value binding internally which I think I understand as it can't be two models.
Is there a better way to go about getting a form filled with values already, but bind it to some sort of model so I can easily submit the form with axios? (I'm trying to use the Form class from the Vue Laracast tutorial but not sure if there's a better method of doing all of this.) https://github.com/laracasts/Vue-Forms/blob/master/public/js/app.js
It appears I can access $parent.user.name in the template part, but can't use this.$parent.user.name in the script part of the file.
This is all in a route Vue file if that makes any difference. Here is my main vue app.
import Nav from './components/Nav';
import AuthUser from './models/AuthUser';
new Vue({
el: '#app',
components: {
Nav
},
data() {
return {
user: []
}
},
created() {
AuthUser.load(user => this.user = user);
},
router
});
v-model already binds the value, so you can't bind the value to one thing and v-model to something else.
To start with the desired values, you can do this:
data() {
return {
form: new Form({
name: this.$parent.user.name,
email: this.$parent.user.email,
password: this.$parent.user.password, //please don't, it's just an example :)
})
}
},
And remove :value from the elements:
<input type="text" class="form-control" name="user" autocomplete="false" v-model="form.name">

How to add and item to an Array using Vue JS?

I'm using VUE JS and for some reason I don't get the new item displayed on the view. if I use the push method, nothing happens. If I use this.$set('productos',producto) the item is displayed, but when I tried to push another item to the array, the previous item is deleted.
new Vue({
el: '#ticket',
data:{
newCodigo:{
codigo: '',
},
productos:[],
},
computed:{
errors: function(){
for(var key in this.newCodigo){
if(! this.newCodigo[key])
return true;
}
return false;
}
},
methods:{
addProducto: function(){
var codigo = this.newCodigo;
this.$http.post('/api/addProducto', codigo).success(function(producto){
this.productos.push(producto);
//this.$set('productos',producto);
});
}
}
});
I'm able to retrieve the data from the DB, but it's not displayed on the view.
<div class="container">
<div class="row">
<div id="ticket">
<form action="POST" v-on:submit.prevent="addProducto">
<input type="hidden" name="_token" id="token" value="{{ csrf_token() }}" >
<div class="form-group">
<label for="Codigo">
Escanea:
<span class="error" v-if="! newCodigo.codigo">*</span>
</label>
<input type="text" name="codigo" id="codigo" class="form-control" v-model="newCodigo.codigo">
</div>
</form>
<article v-for="producto in productos" :data="productos">
<h3>#{{producto.descripcion}}</h3>
<h3>#{{producto.precio}}</h3>
</article>
</div>
</div>
In the callback function of your ajax call, this does not point to the vm instance. Just change it to:
this.$http.post('/api/addProducto', codigo).success(function (producto) {
this.productos.push(producto);
}.bind(this));

Resources