Description not saving when using summernote - laravel

I'm trying to create a page that when you click on the create product button
a modal pops up and then you enter whatever you like.
I'm using summernote as my WYSIWYG editor and I'm also using vue as my frontend.
The problem I'm having is that my description isn't being saved.
In my layouts.app I have summernote's cdn.
Here is my code
My Create.vue
<template>
<transition name="modal-fade">
<div>
<div class="modal-backdrop show"></div>
<div class="modal" style="display: inline;">
<div class="modal-dialog modal-dialog-scrollable" role="document" style="width: 680px; max-width: 680px;">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Create Product</h5>
<button type="button" class="close" #click="close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div>
<label>Name</label>
<input type="text" class="form-control" v-model="name">
</div>
<div class="mt-2">
<label>Description</label>
<textarea id="summernote" v-model="description"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" #click="close">Close</button>
<button type="button" class="btn btn-success" #click="save">Save</button>
</div>
</div>
</div>
</div>
</div>
</transition>
</template>
<script>
export default {
props: [],
data() {
return {
name: null,
description: null,
}
},
methods: {
close() {
this.$emit('close');
},
save() {
var description = document.getElementById("summernote").value;
axios.post('/admin/products', {
name: this.name,
description: description,
}).then((response) => {
});
}
},
mounted(){
$('#summernote').summernote();
}
}
</script>
<style>
.modal-fade-enter,
.modal-fade-leave-active {
opacity: 0;
}
.modal-fade-enter-active,
.modal-fade-leave-active {
transition: opacity .25s ease

Related

adding and editing events with fullcalendar 5, laravel 9, livewire, and a modal

I have a laravel 9 project with livewire, jetstream, fullcalendar 5, alpine, and tailwind (TALL stack) based off of this project:
https://github.com/LaravelDaily/Laravel-Jetstream-CRUD-Roles
and this tutorial: https://laravel.sillo.org/liveware-fullcalendar/
I have the drag and drop functionality as well as the select and eventClick actions working with livewire that submit event data to the database. I've also got the CRUD functions for events and timeline resources contributing data to the calendar view. I'm trying to employ a modal for both the select function and the eventClick function that adds an event and edits an event respectively.
My issues are currently threefold:
Curently, thanks to #ADyson, I managed to get the livewire calendar element to launch a livewire modal element and retrieve PART of the data. The event title, start, and end times. I'm trying to also include additional fields in the events CRUD for event acronym, city, venue, etc...I think the issue here is that I have not specifically declared these as EventObjects like ExtendedProps.
a)I'm interested specifically in where the livewire calendar class might be edited and imagine it's in this stanza of the view file where the events are constructed from JSON like this
events: JSON.parse(#this.events),
b) and I assume the select and eventClick statements in the same file would need to have the event info function altered to retrieve this information as well.
Below is the current fullcalendar 5 view file calendar.blade.php:
<style>
#calendar-container {
display: grid;
grid-template-columns: 200px 1fr;
padding: 20px;
}
#events {
grid-column: 1;
}
#calendar {
grid-column: 2;
height: 700px;
}
.dropEvent {
background-color: DodgerBlue;
color: white;
padding: 5px 16px;
margin-bottom: 10px;
text-align: center;
display: inline-block;
font-size: 16px;
border-radius: 4px;
cursor:pointer;
}
</style>
<div>
#include('livewire.eventmodal')
<div>
<!-- sidebar -->
<div id="calendar-container" wire:ignore>
<div id="events">
<div data-event='{"title":"Evénement A"}' class="dropEvent">Event One Drag</div>
<div data-event='{"title":"Evénement B"}' class="dropEvent">Event Two Draggable</div>
</div>
<div id="calendar"></div>
</div>
</div>
</div>
#push('scripts')
<script src='https://cdn.jsdelivr.net/npm/fullcalendar-scheduler#5.10.1/main.min.js'></script>
<script>
create_UUID = () => {
let dt = new Date().getTime();
const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
let r = (dt + Math.random() * 16) % 16 | 0;
dt = Math.floor(dt / 16);
return (c == 'x' ? r :(r&0x3|0x8)).toString(16);
});
return uuid;
}
document.addEventListener('livewire:load', function () {
const Calendar = FullCalendar.Calendar;
const calendarEl = document.getElementById('calendar');
const Draggable = FullCalendar.Draggable;
new Draggable(document.getElementById('events'), {
itemSelector: '.dropEvent'
});
const calendar = new Calendar(calendarEl, {
headerToolbar: {
left: 'promptResource prev,next today',
center: 'title',
right: 'resourceMonth,dayGridMonth,timeGridWeek,timeGridDay,listMonth'
},
views: {
resourceMonth: {
type: 'resourceTimelineMonth',
buttonText: 'personnel'
}
},
customButtons: {
promptResource: {
text: "+ personnel",
click: function() {
var title = prompt("Name");
if (title) {
calendar.addResource({
title: title
});
fetch("add_resources.php", {
method: "POST",
headers: {
Accept: "application/json"
},
body: encodeFormData({ title: title })
})
.then(response => console.log(response))
.catch(error => console.log(error));
}
}
}
},
initialView: 'resourceTimelineMonth',
locale: '{{ config('app.locale') }}',
events: JSON.parse(#this.events),
resourceAreaHeaderContent: 'Personnel',
resources: JSON.parse(#this.resources),
//'https://fullcalendar.io/api/demo-feeds/resources.json?with-nesting&with-colors',
editable: true,
eventResize: info => #this.eventChange(info.event),
eventDrop: info => #this.eventChange(info.event),
eventReceive: info => {
const id = create_UUID();
info.event.setProp('id', id);
#this.eventAdd(info.event);
},
selectable: true,
select: function(selectionInfo) {
$('#eventModal').modal('show');
},
eventClick: function(info) {
// Display the modal and set the values to the event values.
$('#updateEventModal').modal('show');
$('#updateEventModal').find('#title').val(info.event.title);
$('#updateEventModal').find('#acronym').val(info.event.acronym);
$('#updateEventModal').find('#city').val(info.event.city);
$('#updateEventModal').find('#start').val(info.event.start);
$('#updateEventModal').find('#end').val(info.event.end);
},
});
calendar.render();
});
</script>
<link href='https://cdn.jsdelivr.net/npm/fullcalendar-scheduler#5.11.3/main.min.css' rel='stylesheet' />
#endpush
I have further separated out the actual modal from being included in this file and it's a separate livewire element now called eventmodal.blade.php:
<!-- Insert Modal -->
<div wire:ignore.self class="modal fade" id="eventModal" tabindex="-1" aria-labelledby="eventModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="eventModalLabel">Create Event</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"
wire:click="closeModal"></button>
</div>
<form wire:submit.prevent="saveEvent">
<div class="modal-body">
<div class="mb-3">
<label>Event Name</label>
<input type="text" id="title" wire:model="title" class="form-control">
#error('title') <span class="text-danger">{{ $message }}</span> #enderror
</div>
<div class="mb-3">
<label>Event Acronym</label>
<input type="text" id="acronym" wire:model="acronym" class="form-control">
#error('acronym') <span class="text-danger">{{ $message }}</span> #enderror
</div>
<div class="mb-3">
<label>Event City</label>
<input type="text" id="city" wire:model="city" class="form-control">
#error('city') <span class="text-danger">{{ $message }}</span> #enderror
</div>
<div class="mb-3">
<label>Event Venue</label>
<input type="text" id="venue" wire:model="venue" class="form-control">
#error('venue') <span class="text-danger">{{ $message }}</span> #enderror
</div>
<div class="mb-3">
<label>Event Value</label>
<input type="text" id="value" wire:model="value" class="form-control">
#error('value') <span class="text-danger">{{ $message }}</span> #enderror
</div>
<div class="mb-3">
<label>Event Start</label>
<input type="text" id="start" wire:model="start" class="form-control">
#error('start') <span class="text-danger">{{ $message }}</span> #enderror
</div>
<div class="mb-3">
<label>Event End</label>
<input type="text" id="end" wire:model="end" class="form-control">
#error('end') <span class="text-danger">{{ $message }}</span> #enderror
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" wire:click="closeModal"
data-bs-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
<!-- Update Event Modal -->
<div wire:ignore.self class="modal fade" id="updateEventModal" tabindex="-1" aria-labelledby="updateEventModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="updateEventModalLabel">Edit Event</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" wire:click="closeModal"
aria-label="Close"></button>
</div>
<form wire:submit.prevent="updateEvent">
<div class="modal-body">
<div class="mb-3">
<label>Event Name</label>
<input type="text" id="title" wire:model="title" class="form-control">
#error('title') <span class="text-danger">{{ $message }}</span> #enderror
</div>
<div class="mb-3">
<label>Event Acronym</label>
<input type="text" id="acronym" wire:model="acronym" class="form-control">
#error('acronym') <span class="text-danger">{{ $message }}</span> #enderror
</div>
<div class="mb-3">
<label>Event City</label>
<input type="text" id="city" wire:model="city" class="form-control">
#error('city') <span class="text-danger">{{ $message }}</span> #enderror
</div>
<div class="mb-3">
<label>Event Venue</label>
<input type="text" id="venue" wire:model="venue" class="form-control">
#error('venue') <span class="text-danger">{{ $message }}</span> #enderror
</div>
<div class="mb-3">
<label>Event Value</label>
<input type="text" id="value" wire:model="value" class="form-control">
#error('value') <span class="text-danger">{{ $message }}</span> #enderror
</div>
<div class="mb-3">
<label>Event Start</label>
<input type="text" id="start" wire:model="start" class="form-control">
#error('start') <span class="text-danger">{{ $message }}</span> #enderror
</div>
<div class="mb-3">
<label>Event End</label>
<input type="text" id="end" wire:model="end" class="form-control">
#error('end') <span class="text-danger">{{ $message }}</span> #enderror
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" wire:click="closeModal"
data-bs-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Update</button>
</div>
</form>
</div>
</div>
</div>
<!-- Delete Event Modal -->
<div wire:ignore.self class="modal fade" id="deleteEventModal" tabindex="-1" aria-labelledby="deleteEventModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="deleteEventModalLabel">Delete Event</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" wire:click="closeModal"
aria-label="Close"></button>
</div>
<form wire:submit.prevent="destroyEvent">
<div class="modal-body">
<h4>Are you sure you want to delete this data ?</h4>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" wire:click="closeModal"
data-bs-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Yes! Delete</button>
</div>
</form>
</div>
</div>
</div>
Secondly, the current modals save functions are not working. I'm lost at where to start...do I need an additional route? Some additional code in the form of a controller?
Lastly, my select function...when you click on a date or a date range in the default fullcalendar view is not picking up the date ranges from fullcalendar as it does without the modal using the standard function like this:
select: arg => {
const title = prompt('Title :');
const id = create_UUID();
if (title) {
calendar.addEvent({
id: id,
title: title,
start: arg.start,
end: arg.end,
allDay: arg.allDay
});
#this.eventAdd(calendar.getEventById(id));
};
calendar.unselect();
Thanks to #ADyson, I've managed to retrieve the start and end date on the eventClick events within my livewire modal with the calendar.blade.php like so:
//...previously posted calendar view code above
select: function(selectionInfo) {
// Display the modal.
// You could fill in the start and end fields based on the parameters
$('#AddEventModal').modal('show');
},
eventClick: function(info) {
// Display the modal and set the values to the event values.
$('#AddEventModal').find('#title').val(info.event.title);
$('#AddEventModal').find('#acronym').val(info.event.acronym);
$('#AddEventModal').find('#start').val(info.event.start);
$('#AddEventModal').find('#end').val(info.event.end);
$('#AddEventModal').modal();
},
...
As you can see, I'm also trying to retrieve data from another field in the events table for 'acronym'. Perhaps the issue lies in either my livewire/calendar.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Event;
use App\Models\Resource;
use Illuminate\Support\Arr;
class Calendar extends Component
{
public $events, $resources, $title, $acronym, $city, $venue, $value ;
public function eventChange ( $event )
{
$e=Event::find($event['id']) ;
$e->start=$event['start'] ;
$e->acronym=$event['acronym'] ;
if(Arr::exists($event,'end')) {
$e->end=$event['end'];
}
$e->save();
}
public function render()
{
$this->events=json_encode(Event::all());
$this->resources=json_encode(Resource::all());
return view('livewire.calendar');
}
public function eventAdd ( $event )
{
Event::create ( $event );
}
public function eventRemove ( $id )
{
Event::destroy ( $id );
}
public function resourceAdd ( $resources )
{
Resource::create ( $resources );
}
public function resourceRemove ( $id )
{
Resource::destroy ( $id );
}
}
I managed to get the first part of my issue resolved. FullCalendar 5, when retrieving the events via JSON automatically detects extendedProps that can be retrieved with the eventClick method like so:
eventClick: function(info) {
// Display the modal and set the values to the event values.
$('#updateEventModal').modal('show');
$('#updateEventModal').find('#title').val(info.event.title);
$('#updateEventModal').find('#acronym').val(info.event.extendedProps.acronym);
$('#updateEventModal').find('#city').val(info.event.extendedProps.city);
$('#updateEventModal').find('#venue').val(info.event.extendedProps.venue);
$('#updateEventModal').find('#value').val(info.event.extendedProps.value);
$('#updateEventModal').find('#start').val(info.event.start);
$('#updateEventModal').find('#end').val(info.event.end);
},

bootstrap 4 modal not showing after button is clicked with VueJs

I just learned vuejs with bootstrap 4 and I tried to display modal provided that when the create button was not clicked then the HTML modal tag is not displayed in the inspect element, and after the create button click bootstrap modal displayed. When the button create first time click HTML modal tag display on inspect element but bootstrap modal cannot be displayed on the browser page and the second time the bootstrap modal can be displayed. Here is the source code that I made with Laravel, can you help me on this issue, thank you.
User.vue
HTML
<template>
<div class="container">
<div class="row">
<div class="col-sm">
<div class="card-deck mb-3">
<div class="card mb-4 box-shadow">
<div class="card-header bg-success text-white">
<h4 class="my-0 font-weight-bold">
<!-- Button create user -->
<button #click="initAddUser()" class="btn btn-danger btn-sm"><i class="fa fa-plus"></i> Create New User</button>
<span class="float-right">User</span>
</h4>
</div>
<div class="card-body">
<!-- Bootstrap modal -->
<div v-if="showModal" class="modal fade" id="add_user_model" tabindex="-1" role="dialog" aria-labelledby="add_user_model_label" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header bg-info text-white">
<h5 class="modal-title" id="add_user_model_label"><i class="fa fa-plus"></i> Add New User</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body">
<!-- Message errors create user -->
<div class="alert alert-danger" v-if="errors.length > 0">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
<h5>{{ messages }}</h5>
<ul>
<li v-for="error in errors">{{ error }}</li>
</ul>
</div>
<div class="form-group">
<label class="font-weight-bold" for="name">Name :</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Name" v-model="user.name">
</div>
<div class="form-group">
<label class="font-weight-bold" for="name">Email :</label>
<input type="email" class="form-control" id="email" name="email" placeholder="E-mail" v-model="user.email">
</div>
<div class="form-group">
<label class="font-weight-bold" for="password">Password:</label>
<input type="password" class="form-control" id="password" name="password" placeholder="Password" v-model="user.password">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-sm btn-primary" #click="createUser()">Submit</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
Js
<script>
export default {
data() {
return {
user: {
name: '',
email: '',
password: ''
},
errors: [],
users: [],
showModal: false,
}
},
mounted() {
this.readUsers();
},
methods: {
initAddUser() {
this.errors = [];
$("#add_user_model").modal("show");
this.showModal = true;
},
reset() {
this.user.name = '';
this.user.email = '';
this.user.password = '';
},
readUsers() {
axios.get('/user/show')
.then(response => {
this.users = response.data.users;
});
},
createUser() {
axios.post('/user', {
name: this.user.name,
email: this.user.email,
password: this.user.password,
})
.then(response => {
this.reset();
this.users.push(response.data.user);
this.readUsers();
$("#add_user_model").modal("hide");
})
.catch(error => {
this.errors = [];
this.messages = error.response.data.message;
if (error.response.data.errors.name) {
this.errors.push(error.response.data.errors.name[0]);
}
if (error.response.data.errors.email) {
this.errors.push(error.response.data.errors.email[0]);
}
if (error.response.data.errors.password) {
this.errors.push(error.response.data.errors.password[0]);
}
});
}
}
}
</script>
Result images inspect element
This image button first time click https://ibb.co/jKENbU
This image button second time click https://ibb.co/nRy4qp

cannot insert data into vue select sent from laravel

This is the vuejs component for editing song info. the problem here is with tags.I cannot show the tags of the song in vue select for editing.
<template>
<div>
<a data-toggle="modal" :data-target="'#EditModal'+ modalid" #click="select(song)"><span title="edit" class="glyphicon glyphicon-pencil" ></span></a>
<a class=""><span title="delete" class="glyphicon glyphicon-trash"></span></a>
<!-- Modal for editing song tracks-->
<div class="modal fade" :id="'EditModal'+ modalid" tabindex="-1" role="dialog" aria-labelledby="EditModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="EditModalLabel">Edit Song</h5>
<button type="button" class="close" ref="closemodal" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form ref="uploadform">
<div class="form-group">
<div class="row">
<div class="col-md-12">
<div class="col-md-5">
<button type="button" #click="browseImage" class="btn btn-md btn-default">Choose image:</button>
<div id="image_previews">
<img ref='image' class="" v-bind:src="image" width="200px" height="200px" >
<input class="form-control-file" ref="imageinput" type="file" name="feature_image" #change="showImage($event)">
</div>
</div>
<div class="col-md-7">
<div class="form-group">
<label for="title">Song Title:</label>
<input type="text" v-model="esong.title" class="form-control" required maxlength="255">
</div>
<div class="form-group">
<label for="genre"> Genre (tag atleast one) </label>
<v-select :placeholder="'choose tag'" v-model="tagids" label="name" multiple :options="tags"></v-select>
</div>
<div class="form-group">
<label for="upload_type">Song Upload Type</label>
<select name="upload_type" v-model="esong.upload_type" class="form-control">
<option value="public">public( free )</option>
<option value="private">private( for sale )</option>
</select>
</div>
<div class="form-group">
<label for="message-text" class="col-form-label">Description:</label>
<textarea class="form-control" id="message-text" v-model="esong.song_description"></textarea>
</div>
<div class="form-group" v-if="private">
<label for="upload_type">Song price</label>
<input type="text" v-model="esong.amount" class="form-control" required maxlength="255">
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" #click="edit">Save</button>
</div>
</div>
</div>
</div><!-- end of modal -->
</div>
</template>
<script>
import vSelect from 'vue-select'
export default {
props: ['song','modalid','index','tags'],
components: {vSelect},
mounted() {
},
watch: {
tagids() {
console.log('changed tagids value');
// this.value = this.tagsid;
}
},
computed: {
private() {
if(this.esong.upload_type == 'private') {
return true;
}
return false;
},
},
methods: {
select(song) {
console.log(song.title);
this.getTagIds(song);
},
edit() {
let formData = new FormData();
formData.append('title', this.esong.title);
formData.append('img', this.esong.img);
formData.append('description', this.esong.song_description);
formData.append('upload_type', this.esong.upload_type);
formData.append('amount', this.esong.amount);
formData.append('tags', JSON.stringify(this.tagids));
formData.append('_method', 'PUT');
axios.post('/artist/songs/' + this.esong.id, formData,{
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(response =>{
this.$refs.closemodal.click();
toastr.success('successfully edited song.');
this.$emit('update', {song:this.esong,index:this.index});
}).catch(error => {
console.log(error);
});
},
getTagIds(song) {
axios.post('/gettagids', song ).then(response =>{
this.tagids = response.data;
}).catch(error =>{
console.log(error);
});
},
browseImage() {
this.$refs.imageinput.click();
},
showImage(event) {
this.esong.img = event.target.files[0];
this.image = URL.createObjectURL(event.target.files[0]);
}
},
data() {
return {
esong: this.song,
tagids: {id:'', name:'', label:''},
name:'name',
image:this.song.image
}
}
}
</script>
<style scoped>
input[type="file"] {
display: none;
}
#image_previews {
border-radius: 5px;background-color: whitesmoke; width: 200px; height: 200px;
}
.btn{
border-radius: 0px;
}
</style>
here I cannot get the selected value that was inserted in my table. I wanted to show the tagged values for a song. I am able to get all object of tagged songs from axios post request but v-select doesn't shows the selected value retrieved from a table.
the object received from laravel is similar to the object provided in options which work well with v-select..but it doesn't show the same structure object provided to v-model..or should I provide other props. the document for vue select has not mentioned any of these things

Laravel 5, Vue 2 - send html form via controller and bind submit action to the component method

I am trying to bind action to component method, to the button which is sent via ajax response (json).
So far I have two Vue components - Service and Modal.
Service:
<template>
<div>
<h1>Services ({{ services.length }})</h1>
<div class="services-actions">
<button type="button" class="btn btn-primary" #click="openModal">Add Service</button>
</div>
<div class="services" v-for="(service, index) in services" :key="service.id">
<p>{{ service.name }}</p>
</div>
</div>
</template>
<script>
export default {
data(){
return {
services: []
}
},
methods: {
getAll(){
axios.get('/admin/services/all', {})
.then((response) => {
this.services = response.data
})
},
openModal(){
axios.get('/admin/services/create', {})
.then((response) => {
Event.$emit('modal:show', response.data)
})
},
save(){
console.log('test');
}
},
mounted(){
this.getAll()
}
}
</script>
Modal:
<template>
<div class="modal fade" tabindex="-1" role="dialog" id="main-modal">
<div class="modal-dialog" role="document">
<div class="modal-content">
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</template>
<script>
export default {
mounted(){
let mainModal = $('#main-modal')
Event.$on('modal:show', (html) => {
mainModal.find('.modal-content').html(html)
mainModal.modal('show')
})
Event.$on('modal:hide', () => {
mainModal.modal('hide')
})
}
}
</script>
View file:
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Modal title</h4>
</div>
<form id=service-store action='/admin/service/store'>
<label for="name">Name</label>
<input type="text" name=name id=name>
</form>
<div class="modal-body">
<p>One fine body…</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
Is it possible bind save changes to the Service component save method when I click the Save changes button?

Can't pass Vue variable to hidden input v-model in view(v-for)

I'm new to Vue JS and I'm building an application with Laravel Spark and trying to utilize Vue as much as possible.
I have a form to simply add an 'Asset Type' with a component. Once the Asset Type is successfully created, a list of properties is grabbed from the database and set to a 'data' attribute. In my view(I'm using an inline template), I have a 'v-for' that creates a form for each property that has two hidden inputs for the property id and the type id, and one "Add" button that assigns the property to the newly created type.
THE PROBLEM:
I can't seem to assign the value of the hidden inputs within the view while using v-models. When I submit one of the forms, the form request data always returns the initial data value from the new SparkForm object.
In other words, I need to assign the hidden input values within the v-for loop in the view.
Here's my component:
Vue.component('new-asset-type', {
props: [],
data() {
return {
// type_id: this.type_id,
properties: this.properties,
newAssetType: new SparkForm({
label: null,
enabled: false,
}),
assignPropForm: new SparkForm({
prop_id: "",
type_id: "",
}),
};
},
methods: {
createType: function () {
Spark.post('/asset-types', this.newAssetType)
.then(response => {
this.type_id = response.type_id;
axios.get('/getTypeNotProps/' + this.type_id).then((response) => {
this.properties = response.data;
console.log(this.properties);
});
})
.catch(response => {
console.log("fail");
});
},
assignProp: function () {
Spark.post('/asset-properties/add', this.assignPropForm)
.then(response => {
console.log(response);
})
.catch(response => {
console.log("fail");
});
}
}
});
And here's my view:
#extends('spark::layouts.app')
#section('content')
<new-asset-type inline-template>
<div class="container">
<!-- Application Dashboard -->
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Add a New Asset Type</div>
<div class="panel-body" id="addTypeForm">
<div class="form-horizontal">
<div class="form-group" :class="{'has-error': newAssetType.errors.has('label')}">
{{ Form::label('label', 'Label', ['class' => 'col-md-4 control-label']) }}
<div class="col-md-6" >
<input type="test" name="label" v-model="newAssetType.label">
<span class="help-block" v-show="newAssetType.errors.has('label')">
#{{ newAssetType.errors.get('label') }}
</span>
</div>
</div>
<div class="form-group">
{{ Form::label('enabled', 'Enabled?', ['class' => 'col-md-4 control-label']) }}
<div class="col-md-6">
<input type="checkbox" name="enabled" v-model="newAssetType.enabled" >
</div>
</div>
<!-- Submit -->
<div class="form-group">
<div class="col-md-8 col-md-offset-4">
<button class="btn btn-primary" #click="createType" :disabled="newAssetType.busy">
Create Asset Type
</button>
</div>
</div>
<div id="assignProps" v-if="newAssetType.successful">
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
Add Property
</button>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Add New Property to Asset Type</h4>
</div>
<div class="modal-body">
<assign-asset-prop v-for="property in properties" class="panel panel-info property-item">
<div class="panel-heading">#{{ property.label }}</div>
<div class="panel-body"><strong>Input Type: </strong>#{{ property.input_type }}
<div class="pull-right">
<input type="hidden" name="prop_id" v-bind:value="property.p_id" v-model="assignPropForm.prop_id">
<input type="hidden" name="type_id" v-bind:value="property.p_id" v-model="assignPropForm.type_id">
<button class="btn btn-primary" #click="assignProp" :disabled="assignPropForm.busy">
Add
</button>
</div>
</div>
</assign-asset-prop>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</new-asset-type>
#endsection
Thanks to the helpful comments, I learned that I shouldn't have been using hidden inputs at all. Instead, I simply passed the variables to the function on the click event.
<button class="btn btn-primary" #click="assignProp(type_id, property.p_id)" >
Add
</button>
Then in my component
methods: {
assignProp: function (type_id, property_id) {
var assignPropForm = new SparkForm({
propvalue: property_id,
typevalue: type_id,
});
Spark.post('/asset-properties/add', assignPropForm)
.then(response => {
console.log(response);
})
.catch(response => {
console.log("fail");
});
}
}
You need store variables at local data() dep., and geting it by getters function.

Resources