First time Vue js user, trying to learn by building a small blog/article system where a user can add a article and it'll show on the page (and store in the json)
my code so far:
I have a Json array I can display.
I have a form I can add name and surname to and have it display on the page.
Next:
I wish to click my button and have the new name and surname added to my json object in my file.
Question:
how can I click on my button and have this add to my users data array ?
My code:
Hello.vue
<template>
<div class="justify-content-center align-items-center container ">
<div class="row">
<div class="col-12 align-content-center">
<h2>Total articles: {{ users.length }}</h2>
<ul class="list-group">
<li class="list-group-item" v-for="user in users">
<div class="d-flex w-100 justify-content-between">
<h5>{{user.firstname}} {{user.lastname}}</h5>
<small>3 days ago (todo)</small>
</div>
<div class="text-justify">
<p>artical body test here (todo)</p>
<small>Author (todo)</small>
</div>
</li>
</ul>
</div>
</div>
<div class="row">
<div class="col-12 align-content-center">
<form v-on:submit="sub" action="#" method="post">
<div class="form-group">
<div class="col-6">
<label>Add first name:</label>
<b-form-input type="text" v-model="input_val_firstName" placeholder="Enter your first name"></b-form-input>
</div>
<div class="col-6">
<label>Add second name:</label>
<b-form-input type="text" v-model="input_val_secondName" placeholder="Enter your second name"></b-form-input>
</div>
<div class="col-6">
<button type="submit" class="btn btn-primary">Add article</button>
</div>
</div>
</form>
</div>
</div>
<div class="row">
<div class="col-12 align-content-center">
<h2>Preview article</h2>
<strong>Name:</strong>
<span v-text="input_val_firstName"></span>
<span v-text="input_val_secondName"></span>
<h3>log:{{log}}</h3>
</div>
</div>
</div>
</template>
<script>
export default {
methods: {
},
name: 'Hello',
data() {
return {
msg: 'Display articles',
secondmsg: 'This is a blog built in Vue.js.',
log: "",
users: [
{
firstname: 'Sebastian',
lastname: 'Eschweiler'
},
{
firstname: 'Bill',
lastname: 'Smith'
},
{
firstname: 'Tom',
lastname: 'bull'
},
{
firstname: 'John',
lastname: 'Porter'
}
],
input_val_firstName: '',
input_val_secondName: '',
counter: 0
}
}
}
</script>
Just add a method to add the user and this should work:
addUser: function() {
this.users.push({
firstname: this.input_val_firstName,
lastname: this.input_val_secondName
})
// assuming you'd like to clear the input-box fields after adding the user
this.input_val_firstName = ''
this.input_val_secondName = ''
}
Related
My Blade View 'chat.blade.php'
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading"</div>
<div class="panel-body">Chats
<chat-messages :messages="messages"></chat-messages>
</div>
<div class="panel-footer">
<chat-form
v-on:messagesent="addMessage"
:user="{{ Auth::user() }}"
></chat-form>
</div>
</div>
</div>
</div>
</div>
#endsection
This code is extend from app.blade.php, which probably its not really the main focus of the problem
and here is My 2 Component From My Vue JS
'ChatMessages.vue'
<template>
<ul class="chat">
<li class="left clearfix" v-for="message in messages">
<div class="chat-body clearfix">
<div class="header">
<strong class="primary-font">
{{ message.user.name }}
</strong>
</div>
<p>
{{ message.message }}
</p>
</div>
</li>
</ul>
</template>
<script>
export default {
props: ['messages']
};
</script>
and here is the 'ChatForm.vue'
<template>
<div class="input-group">
<input id="btn-input" type="text" name="message" class="form-control input-sm" placeholder="Type your message here..." v-model="newMessage" #keyup.enter="sendMessage">
<span class="input-group-btn">
<button class="btn btn-primary btn-sm" id="btn-chat" #click="sendMessage">
Send
</button>
</span>
</div>
</template>
<script>
export default {
props: ['user'],
data() {
return {
newMessage: ''
}
},
methods: {
sendMessage() {
this.$emit('messagesent', {
user: this.user,
message: this.newMessage
});
this.newMessage = ''
}
}
}
</script>
and here is the following screenshot of the problem
Click here for the Picture
as you can see in the screenshot, the chat component from vue.js listed below, wont show up, its just appear blank, only displaying scrollbar,navbar and 'Chats' text. which is came from app.blade.php]
Please help me :). Thanks
You do not commit any messages to your component. :messages="messages" is Vue syntax.
Assuming your controller assigns $messages to your view:
<chat-messages messages="{{ json_encode($messages) }}"></chat-messages>
should do it. You need to use blade variables to assign
My code is fetch data and put it in card ok, my event is when i add data in input move it to
a fetching data in card, this is run just one more, when i add more, data added in database but it does not move in data list?
code is:
Taskform.svelte
<script>
import { createEventDispatcher } from "svelte";
let title = '';
let dispatch = createEventDispatcher();
function addTask(){
axios.post('./api/tasks', {title: title});
dispatch('taskCreated', {
title: title,
});
title = '';
}
</script>
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card mt-2 bg-dark text-light">
<div class="card-header">Create Task</div>
<div class="card-body">
<form action="./api/tasks" method="POST" on:submit|preventDefault={addTask}>
<div class="form-group">
<input type="text" name="title" placeholder="Task Title" class="form-control" bind:value={title}>
</div>
<div class="form-group">
<input type="submit" value="Add Task" class="btn btn-primary">
</div>
</form>
</div>
</div>
</div>
</div>
Tasklist
<script>
import { onMount } from 'svelte';
import Task from './Task.svelte';
let tasks = [];
onMount(async (event) => {
axios.get('./api/tasks')
.then((response) => {
tasks = response.data;
});
});
function handler(event){
tasks = [...tasks, {
title: event.detail.title
}];
}
</script>
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card mt-2 bg-primary text-light">
<div class="card-header">List Of Tasks</div>
<div class="card-body">
<ul>
<div class="row">
{#each tasks as task (task.id)}
<div class="col-3">
<li>{task.title}</li>
</div>
{/each}
</div>
</ul>
</div>
</div>
</div>
</div>
<Task on:taskCreated={handler}/>
please help i tried so many ways, nothing worked .
thanks
Your dispatch is called as expected.
The issue is related to the lack of id in your tasks. If you'll add a unique id to each task it would all work (you can remove the (task.id) in your #each to verify).
I am working on vue.js rendering dynamic list, When user clicks on a button then the link in corresponding input field renders, then again I am pasting a link in input field and clicking add it adds the value to the second index which I don't want I know I have o use queue concept but here on ui I don't how to implement it
What I have done
new Vue({
el: '#app',
data() {
return {
anchorTags: [{
url: '',
value: ''
}]
}
},
methods: {
validateYouTubeUrl() {
var url = document.getElementById('youtubeUrl').value
this.anchorTags.push({
url: url,
value: url
});
}
}
})
.as-console-wrapper { max-height: 3em !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.9/vue.js"></script>
<div id=app>
<div class="container-fluid row">
<div class="form-group col-xs-12 col-sm-12 col-md-8 col-lg-8 col-xl-8" id="first">
<div class="input-group">
<input type="text" class="form-control" id="youtubeUrl" placeholder="Paste link here...">
<div class="input-group-append">
<button class="btn btn-primary" type="button" #click="validateYouTubeUrl">Add</button>
</div>
</div>
<hr>
</div>
<div class="form-group col-xs-12 col-sm-12 col-md-4 col-lg-4 col-xl-4" id="second">
<h3 class="form-control">Playlist</h3>
<hr>
<ul class="list-group">
<li v-for="(anchorTag, k) in anchorTags" :key="k" class="list-group-item">
<a :href="anchorTag.url" #click.prevent="playVideo($event)">{{anchorTag.value}}</a>
<span v-if="anchorTag.url!==''"><i class="fas fa-trash-alt"></i></span>
</li>
</ul>
</div>
</div>
</div>
So What I am trying to do is
To do it like quee like FIFO, when I enter some thing it is on top the again I enter something the latest one should be on top
I allowed myself to make some extra changes, moreover, to give you an answer (I used the v-model):
new Vue({
el: "#app",
data() {
return {
youtubeUrl: null,
anchorTags: []
};
},
methods: {
validateYouTubeUrl() {
this.anchorTags.push({
url: this.youtubeUrl,
value: this.youtubeUrl
});
}
},
computed: {
anchorList() {
return this.anchorTags.slice().reverse();
}
}
});
.as-console-wrapper {
max-height: 3em !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id=app>
<div class="container-fluid row">
<div class="form-group col-xs-12 col-sm-12 col-md-8 col-lg-8 col-xl-8" id="first">
<div class="input-group">
<input type="text" class="form-control" v-model="youtubeUrl" placeholder="Paste link here...">
<div class="input-group-append">
<button class="btn btn-primary" type="button" #click="validateYouTubeUrl">Add</button>
</div>
</div>
<hr>
</div>
<div class="form-group col-xs-12 col-sm-12 col-md-4 col-lg-4 col-xl-4" id="second">
<h3 class="form-control">Playlist</h3>
<hr>
<ul class="list-group">
<li v-for="(anchorTag, k) in anchorList" :key="k" class="list-group-item">
<a :href="anchorTag.url" #click.prevent="playVideo($event)">{{anchorTag.value}}</a>
<span v-if="anchorTag.url!==''"><i class="fas fa-trash-alt"></i></span>
</li>
</ul>
</div>
</div>
</div>
If that's not what you meant, edit your question and try to describe it in a more pathological way.
I am trying to figure out what I am missing here. I am trying to pre-fill some data for a user profile page. That pre-fill data is coming from a Firestore DB collection. I have been able to prefill existing fields when editing requests, however, I am stumped at the user profile portion. I've included a link to a video showing what I am seeing. Also here is an error I am getting:
vue-firestore.js?73c3:1 Uncaught (in promise) Error: This document (profile) is not exist or permission denied.
at Object.eval [as next] (vue-firestore.js?73c3:1)
at next (index.cjs.js?e89a:21048)
at eval (index.cjs.js?e89a:19341)
Video of my issue
I believe I am experiencing a problem with one of the following files. I can supply more info if needed.
Login.vue
<template>
<div class="login">
<!-- Modal -->
<div class="modal fade" id="login" tabindex="-1" role="dialog" aria-labelledby="loginTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-body">
<ul class="nav nav-fill nav-pills mb-3" id="pills-tab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="pills-home-tab" data-toggle="pill" href="#pills-login" role="tab" aria-controls="pills-login" aria-selected="true">Login</a>
</li>
<li class="nav-item">
<a class="nav-link" id="pills-register-tab" data-toggle="pill" href="#pills-register" role="tab" aria-controls="pills-register" aria-selected="false">Signup</a>
</li>
</ul>
<div class="tab-content" id="pills-tabContent">
<div class="tab-pane fade show active" id="pills-login" role="tabpanel" aria-labelledby="pills-login-tab">
<h5 class="text-center">Login Please</h5>
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" v-model="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email">
<small class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" #keyup.enter="login" v-model="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
<div class="form-group">
<button class="btn btn-primary" #click="login">Login</button>
</div>
</div>
<div class="tab-pane fade" id="pills-register" role="tabpanel" aria-labelledby="pills-register-tab">
<h5 class="text-center">Create New Account</h5>
<div class="form-group">
<label for="name">Your name</label>
<input type="text" v-model="name" class="form-control" id="name" placeholder="Your nice name">
</div>
<div class="form-group">
<label for="email">Email address</label>
<input type="email" v-model="email" class="form-control" id="email" aria-describedby="emailHelp" placeholder="Enter email">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" v-model="password" class="form-control" id="password" placeholder="Password">
</div>
<div class="form-group">
<button class="btn btn-primary" #click="register">Signup</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import {fb, db} from '../firebase'
export default {
name: "Login",
props: {
msg: String
},
data(){
return {
name: null,
email: null,
password: null
}
},
methods:{
login(){
fb.auth().signInWithEmailAndPassword(this.email, this.password)
.then(() => {
$('#login').modal('hide')
this.$router.replace('admin');
})
.catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
if (errorCode === 'auth/wrong-password') {
alert('Wrong password.');
} else {
alert(errorMessage);
}
console.log(error);
});
},
register(){
fb.auth().createUserWithEmailAndPassword(this.email, this.password)
.then((user) => {
$('#login').modal('hide')
// Add a new document in collection "profiles"
db.collection("profiles").doc("user.user.uid").set({
name: this.name,
})
.then(function() {
console.log("Document successfully written!");
})
.catch(function(error) {
console.error("Error writing document: ", error);
});
this.$router.replace('admin');
})
.catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
if (errorCode == 'auth/weak-password') {
alert('The password is too weak.');
} else {
alert(errorMessage);
}
console.log(error);
});
}
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
</style>
Here is the Profile.vue
<template>
<div class="profile">
<div class="container">
<div class="intro h-100">
<div class="row h-100 align-items-center">
<div class="col-md-6 ml-3">
<h3>Profile settings</h3>
<p>
Change your profile settings here
</p>
</div>
<div class="col-md-5">
<img src="/img/svg/profile.svg" width="300" alt="" class="img-fluid">
</div>
</div>
</div>
<div class="profile-content">
<ul class="nav nav-pills ml-3" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="true">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" id="account-tab" data-toggle="tab" href="#account" role="tab" aria-controls="account" aria-selected="false">Account settings</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active pt-3" id="profile" role="tabpanel" aria-labelledby="profile-tab">
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<input type="text" name="" v-model="profile.name" placeholder="Full name" class="form-control">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<input type="text" v-model="profile.phone" placeholder="Phone" class="form-control">
</div>
</div>
<div class="col-md-12">
<div class="form-group">
<input type="text" v-model="profile.address" placeholder="Address" class="form-control">
</div>
</div>
<div class="col-md-8">
<div class="form-group">
<input type="text" v-model="profile.postCode" placeholder="Postcode" class="form-control">
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<input type="submit" #click="updateProfile" value="Save Changes" class="btn btn-primary w-100">
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane fade pt-3" id="account" role="tabpanel" aria-labelledby="account-tab">
<div class="container">
<div class="row">
<div class="col-md-">
<div class="alert alert-info">
Please use the Reset password email button for reseting the password. The form doens't work currently
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<input type="text" v-model="account.name" placeholder="User name" class="form-control">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<input type="text" v-model="account.email" placeholder="Email address" class="form-control">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<input type="text" v-model="account.password" placeholder="New password" class="form-control">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<input type="text" v-model="account.confirmPassword" placeholder="Confirm password" class="form-control">
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<input type="file" #change="uploadImage" class="form-control">
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<input type="submit" value="Save Changes" class="btn btn-primary w-100">
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<input type="button" #click="resetPassword" value="Reset password email" class="btn btn-success w-100">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { fb, db } from '../firebase';
export default {
name: "Profile",
components: {
},
props: {
msg: String
},
data(){
return {
profile: {
name:null,
phone:null,
address:null,
postcode:null
},
account:{
name:null,
email:null,
photoUrl:null,
emailVerified:null,
password:null,
confirmPassword:null,
uid:null
}
}
},
firestore(){
const user = fb.auth().currentUser;
return {
profile: db.collection('profiles').doc(user.uid),
}
},
methods:{
resetPassword(){
const auth = fb.auth();
auth.sendPasswordResetEmail(auth.currentUser.email).then(() => {
Toast.fire({
type: 'success',
title: 'Email sent'
})
}).catch((error) => {
console.log(error);
});
},
updateProfile(){
this.$firestore.profile.update(this.profile);
},
uploadImage(){
}
},
created(){
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
</style>
Here is main.js
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import jQuery from "jquery";
import { fb } from "./firebase";
import VueFirestore from "vue-firestore";
import Swal from "sweetalert2";
Vue.use(VueFirestore, {
key: "id",
enumerable: true
});
window.Swal = Swal;
const Toast = Swal.mixin({
toast: true,
position: "top-end",
showConfirmButton: false,
timer: 3000
});
window.Toast = Toast;
window.$ = window.jQuery = jQuery;
Vue.use(VueFirestore);
import "popper.js";
import "bootstrap";
import "./assets/app.scss";
Vue.component("Navbar", require("./components/Navbar.vue").default);
Vue.component("NavAdmin", require("./views/NavAdmin.vue").default);
Vue.component("Requests", require("./views/Requests.vue").default);
Vue.component(
"ViewBulkRequest",
require("./views/ViewBulkRequest.vue").default
);
Vue.config.productionTip = false;
let app = "";
fb.auth().onAuthStateChanged(function(user) {
if (!app) {
new Vue({
router,
render: h => h(App)
}).$mount("#app");
}
});
This was not resolved, we simply switched over to some new code. Thank you.
I'm having a frustrating time trying to get this to work, Chrome keeps displaying an Uncaught Syntax error, but being a beginner to Vue, I have no idea where to look. Im at the part of the tutorial where it says Adding the listing area. Also here is a link to the tutorial as well. Any help or pointers would be appreciated. Thank you!
new Vue({
el: '#events',
data: {
event: {
name: "",
description: "",
date: ""
},
events: []
ready: function() {
// When the application loads, we want to call the method that initializes
// some data
this.fetchEvents();
},
fetchEvents: function() {
var events = [{
id: 1,
name: "TIFF",
description: "Toronto International Film Festival",
date: "2015-09-10"
},
{
id: 2,
name: "The Martian Premiere",
description: "The Martian Comes to Theatres.",
date: "2015-10-02"
},
{
id: 3
name: "SXSW",
description: "Music, film and interactive festival in Austin, TX.",
date: "2016-03-11"
}
];
this.$set("events", events);
},
addEvent: function() {
if (this.event.name) {
this.events.push(this.event);
this.event = {
name: "",
description: "",
date: ""
};
}
}
}
})
<!doctype html>
<head>
<meta charset="utf-8">
<title>Vue</title>
<!---CSS-->
<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
</head>
<body>
<!--Nav bar-->
<nav class="navbar navbar-default">
<div class="container fluid">
<a class="navbar-brand"><i class= "glyphicon glyphicon-bullhorn"></i> Vue Events Bulletin Board</a>
</div>
</nav>
<!--main body of our application-->
<div class="container" id="events">
<!--add an event form-->
<div class="col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">
<h3> Add An Event</h3>
</div>
<div class="panel-body">
<div class="form-group">
<input class="form-control" placeholoder="Event Name" v-model="event.name">
</div>
<div class="form-group">
<textarea class="form-control" placeholder="Event Description" v-model="event.description"></textarea>
</div>
<div class="form-group">
<input type="date" class="form-control" placeholoder="Date" v-model="event.date">
</div>
<button class="btn btn-primary" v-on="click: addEvent">Submit</button>
</div>
<div class="list-group" <a href="#" class="list-group-item" v-repeat="event in events">
<h4 class="list-group-item-heading">
<i class="glyphicon glyphicon-bullhorn"></i>
</h4>
<h5>
<i class="glyphicon glyphicon-calender" v-if="event.date"></i>
</h5>
<p class="list-group-item-text" v-if="event.description"> </p>
<button class="btn btn-xs btn-danger" v-on="click: deleteEvent($index)">Delete</button>
</div>
<!--show the events-->
<div class="col-sm-6">
<div class="list-group">
</div>
</div>
</div>
<!--JS-->
<script src="node_modules/vue/dist/vue.js"></script>
<script src="node_modules/vue-resource/dist/vue-resource.js"></script>
<script src="app1.js">
< /script < /
body > <
/html>
You're missing a comma in one of your object declarations
{
id: 3 // <- missing comma here
name: "SXSW",
description: "Music, film and interactive festival in Austin, TX.",
date: "2016-03-11"
}
It's plain Javascript, it has nothing to do with Vue