Vue js Applications throws errors (Id not Found) - vue.js

I created loopback applications by using git bash . I am using vue js for front end development . When I run the applications in localhost and try to access the html page . I got following errors in google chrome console windows ..
server.js:1 Failed to load resource: the server responded with a status of 404 (Not Found)
vue.js:634 [Vue warn]: Cannot find element: #catApp
Here is code .
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<script src="./server.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.10/dist/vue.js"></script>
<script>
const API = 'http://localhost:3000/api/Cat/';
let catApp = new Vue({
el: '#catApp',
data: {
cats: [],
cat: {
id: '',
name: '',
age: '',
gender: '',
breed: ''
}
},
created: function () {
this.getCats();
},
methods: {
getCats: function () {
fetch(API)
.then(res => res.json())
.then(res => this.cats = res);
},
storeCat: function () {
let method;
console.log('storeCat', this.cat);
// Handle new vs old
if (this.cat.id === '') {
delete this.cat.id;
method = 'POST';
} else {
method = 'PUT';
}
fetch(API, {
headers: {
'Content-Type': 'application/json'
},
method: method,
body: JSON.stringify(this.cat)
})
.then(res => res.json())
.then(res => {
this.getCats();
this.reset();
});
},
deleteCat: function (c) {
fetch(API + c.id, {
headers: {
'Content-Type': 'application/json'
},
method: 'DELETE'
})
.then(res => res.json())
.then(res => {
this.getCats();
});
// call reset cuz the cat could be 'active'
this.reset();
},
editCat: function (c) {
/*
This line was bad as it made a reference, and as you typed, it updated
the list. A user may think they don't need to click save.
this.cat = c;
*/
this.cat.id = c.id;
this.cat.name = c.name;
this.cat.age = c.age;
this.cat.breed = c.breed;
this.cat.gender = c.gender;
},
reset: function () {
this.cat.id = '';
this.cat.name = '';
this.cat.age = '';
this.cat.breed = '';
this.cat.gender = '';
}
}
});
</script>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="catApp" v-cloak>
<h1>Cats</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Gender</th>
<th>Breed</th>
<td> </td>
</tr>
</thead>
<tbody>
<tr v-for="cat in cats">
<td #click="editCat(cat)" class="catItem" title="Click to Edit">{{cat.name}}</td>
<td>{{cat.age}}</td>
<td>{{cat.gender}}</td>
<td>{{cat.breed}}</td>
<td #click="deleteCat(cat)" class="deleteCat" title="Click to Delete">Delete</td>
</tr>
</tbody>
</table>
<form #submit.prevent="storeCat">
<p>
<label for="name">Name</label>
<input type="text" id="name" v-model="cat.name">
</p>
<p>
<label for="age">Age</label>
<input type="number" id="age" v-model="cat.age">
</p>
<p>
<label for="breed">Breed</label>
<input type="text" id="breed" v-model="cat.breed">
</p>
<p>
<label for="gender">Gender</label>
<input type="text" id="gender" v-model="cat.gender">
</p>
<input type="reset" value="Clear" #click="reset">
<input type="submit" value="Save Cat 🐱">
</form>
</div>
</body>
</html>
Here is the screen shot when I run the applications .

Put also all script tag before
Remove
<style>
[v-cloak] {
display: none;
}
</style>
and remove v-cloak
<div id="catApp" >

Related

Vue Js - focusing on element programatically

I am brand new to using VueJs (first day!)
I want to validate an email field, and return focus to the email inut if not valid. I am using the watch property (see below), and although I can successfully watch value changes, I am not able to set focus back to the email field.
What am I doing wrong?
Code snippet
<!DOCTYPE html>
<head>
<title>V3 Example</title>
<script src="https://unpkg.com/vue#3"></script>
</head>
<style type="text/css">
form input, form button {
display: block;
margin: 3px;
}
</style>
<body>
<div id="app">
<form #submit.prevent >
<h3></h3>
<input type="username" v-model="username" />
<input ref="email" type="email" v-model="email" />
<input type="password" v-model="passwd" autocomplete="off"/>
<button #click="logIt" >Login </button>
</form>
</div>
<script>
let app = Vue.createApp({
data() {
return {
username: '',
email: '',
passwd: '',
}
},
methods: {
logIt() {
console.log('here!');
}
},
watch: {
email(val1, val2){
if (!val2.includes('#')) {
this.$refs.email.focus(); // <- this is supposed to return focus to email input
console.log('Not valid email!');
}
else {
console.log(val1);
console.log(val2);
}
}
}
})
app.mount('#app');
</script>
</body>
</html>
Try this:
this.$refs.email.$el.focus();
Here is a solution that works, I've added a method onSubmit which is called when the form submits and inside it I validate email field, and focus it if is not valid. The key here is nextTick which makes sure to wait before Vue does any DOM update it needs before focusing the element.
<!DOCTYPE html>
<head>
<title>V3 Example</title>
<script src="https://unpkg.com/vue#3"></script>
</head>
<style type="text/css">
form input, form button {
display: block;
margin: 3px;
}
</style>
<body>
<div id="app">
<form #submit.prevent="onSubmit" >
<h3></h3>
<input type="username" v-model="username" />
<input ref="email" type="email" v-model="email" />
<input type="password" v-model="passwd" autocomplete="off"/>
<button #click="logIt" >Login </button>
</form>
</div>
<script>
let app = Vue.createApp({
data() {
return {
username: '',
email: '',
passwd: '',
}
},
methods: {
logIt() {
console.log('here!');
},
onSubmit() {
if (!this.email.includes('#')) {
this.$nextTick(() => { // must wait for next tick before interacting with DOM
this.$refs.email.focus();
console.log('Not valid email!');
})
}
}
},
watch: {
email(val1, val2){
if (!val2.includes('#')) {
this.$refs.email.focus(); // <- this is supposed to return focus to email input
console.log('Not valid email!');
}
else {
console.log(val1);
console.log(val2);
}
}
}
})
app.mount('#app');
</script>
</body>

Vue.js (v.2) Loading (fetch) data only after clicking on the button

I'm a beginner in VUE, I have programmed code that, after loading the web pages, downloads the data from json and renders it to wonder with the id "app".
However, I need the data to be loaded not at the beginning, but only after clicking the button.
Thank you very much for the tips and advice.
const app = new Vue ({
el: '#app',
data: {
urlPrefix: '',
newName: '',
newDescription: '',
newExperts_advice: '',
newProduct_benefit_2: '',
newImage: '',
characters: [{
}
],
},
methods: {
add() {
this.characters.push ({
name: this.newName,
description: this.newDescription,
experts_advice: this.newExperts_advice,
product_benefit_2: this.newProduct_benefit_2,
image: this.newImage,
})
}
},
created: function(){
fetch('./data.json')
.then(res => res.json())
.then(json => this.characters = json)
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TEST</title>
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.12/dist/vue.js"></script>
<link rel="icon" href="favicon.ico" type="image/x-icon"/>
</head>
<body>
<div id="app">
<button>Fetch data</button>
<div class="info-v1" v-for="item in characters">
<section class="head">
<h2>{{ item.name }}</h2>
<p> {{ item.description }}</p>
</section>
<section class="body">
<img v-bind:src="urlPrefix + item.image " />
<h3>{{ item.product_benefit_2 }}</h3>
<p>{{ item.experts_advice }}</p>
</section>
</div>
</div>
</body>
</html>
First you should create method in methods to fetch your data.
methods: {
yourNewMethodToFetchData() {
fetch('./data.json')
.then(res => res.json())
.then(json => this.characters = json)
}
}
Second add click event to your fetch data button like this:
<button #click="yourNewMethodToFetchData">Fetch data</button>
Lastly remove fetch code from created hook:
created: function(){
}

Vuelidate reset specific field so that $error flag is false

Using Vuelidate you can reset the validation errors by using this.$v.$reset(). In this Codepen example resetting the lastName field that uses a Vuetify component works - $invalid is true while $error is set to false.
When resetting the regular text input for firstName it doesn't work as the $error flag is still true. How can I modify the text input so that $error is false when calling reset?
I've also tried this.$nextTick(() => {...}) but that doesn't work either.
Vue.use(window.vuelidate.default)
var validationMixin = window.vuelidate.validationMixin
const {
maxLength,
required
} = window.validators
new Vue({
el: '#app',
mixins: [validationMixin],
data: () => ({
form: {
firstName: '',
lastName: ''
}
}),
validations: {
form: {
firstName: {
required, maxLength: maxLength(2)
},
lastName: {
required, maxLength: maxLength(2)
},
}
}
})
input.raw {
border: solid;
}
.is-invalid {
border-color: #FF5252 !important;
}
<html>
<head>
<script src="https://unpkg.com/vuelidate#0.6.1/dist/validators.min.js"></script>
<script src="https://unpkg.com/vuelidate#0.6.1/dist/vuelidate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
</head>
<body>
<div id="app">
<label for="firstName">First Name</label>
<input
v-model="form.firstName"
id="firstName"
class="raw"
:class="{ 'is-invalid': $v.form.firstName.$error }"
type="text"
width="100%"
:oninput="$v.form.firstName.$touch()"
:onblur="$v.form.firstName.$touch()"
/>
<button #click="$v.form.firstName.$touch()">
$touch
</button>
<button #click="$v.form.firstName.$reset()">
$reset
</button>
<pre>{{ $v.form.firstName }}</pre>
</div>
</body>
</html>
In your example, you are using oninput and onblur HTML attributes, but in Vue, you should use #input(v-on:input) and #blur(v-on:blur) bindings instead. See docs for details.
Replacing HTML attributes with Vue bindings made your example work correctly:
Vue.use(window.vuelidate.default)
var validationMixin = window.vuelidate.validationMixin
const {
maxLength,
required
} = window.validators
new Vue({
el: '#app',
mixins: [validationMixin],
data: () => ({
form: {
firstName: '',
lastName: ''
}
}),
validations: {
form: {
firstName: {
required, maxLength: maxLength(2)
},
lastName: {
required, maxLength: maxLength(2)
},
}
}
})
input.raw {
border: solid;
}
.is-invalid {
border-color: #FF5252 !important;
}
<html>
<head>
<script src="https://unpkg.com/vuelidate#0.6.1/dist/validators.min.js"></script>
<script src="https://unpkg.com/vuelidate#0.6.1/dist/vuelidate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
</head>
<body>
<div id="app">
<label for="firstName">First Name</label>
<input
v-model="form.firstName"
id="firstName"
class="raw"
:class="{ 'is-invalid': $v.form.firstName.$error }"
type="text"
width="100%"
#input="$v.form.firstName.$touch()"
#blur="$v.form.firstName.$touch()"
/>
<button #click="$v.form.firstName.$touch()">
$touch
</button>
<button #click="$v.form.firstName.$reset()">
$reset
</button>
<pre>{{ $v.form.firstName }}</pre>
</div>
</body>
</html>
This is Issue From Vuelidate and they must be fixed, in this position you can not reset form and give same (badly) behavior you can re-render by the router
// re render component for reset all fileds
this.$router.go(0)

Vue instance in double quotes

I use vue instance but it is not parsing , i think problem is relevant with using double quotes in Metro.dialog.Create.content.
Here is the main page include table and it works correctly.I added when dblclick table on main page open dialog and another table showing in this dialog.
var app2= new Vue({
el: '#appTable',
data: {
squads: [
]
},
mounted: function () {
Metro.init();
var self = this;
$.ajax({
url: '#Url.Action("Find", "Squad")',
method: 'GET',
success: function (data) {
self.squads = data;
},
});
},
methods:{
clickList: function (squad) {
bindSquadToEditTable(squad.ID);
Metro.dialog.create({
title: "Team",
content:
'<div class ="row-4-3 rowspan" >'+
'<div id="appTableMembers">'+
'<table class="table cell-border ">'+
'<thead>'+
'<tr>'+
'<th>Personal Code</th>'+
'<th>Name</th>'+
'<th>Email</th>'+
'</tr>'+
'</thead>'+
'<tbody>'+
"<tr v-for=squad in members :key=squad.PersonalCode > <td>{{squad.PersonalCode}}</td> <td>{{squad.FullName}}</td> <td>{{squad.Email}}</td>"+
'</tr>'+
'</tbody>'+
'</table>'+
'</div>',
});
}
}
});
That is my Main page;
<div id="appTable">
<table class="table striped">
<thead>
<tr>
<th>Code</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr v-for="squad in squads" :key="squad.Code" v-on:dblclick="clickList(squad)">
<td>{{squad.Code}}</td> <td>{{squad.Description}}</td>
</tr>
</tbody>
</table>
</div>
Here is the binding data to dialog ;
<script>
function bindSquadToEditTable(ID){
app3 = new Vue({
el: 'appTableMembers',
data: {
members:[]
},
mounted:function(){
Metro.init();
var self = this;
$.ajax({
type: "GET",
"url": '#Url.Action("FindByID", "Squad")',
"data": { id: ID },
"dataSrc": "",
success: function(data){
self.members = data;
},
});
}
})
}
</script>
I was curious how this would work so I threw together a quick test. Worked fine using the hidden <div> for the modal content.
HTML
<html>
<head>
<link rel="stylesheet" href="https://cdn.metroui.org.ua/v4/css/metro-all.min.css">
</head>
<body>
<div id="app">
<input type="button" value="modal" #click="showModal" />
<div style="display: none" ref="modalContent">
<div>My name is {{name}}</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.metroui.org.ua/v4/js/metro.min.js"></script>
</body>
</html>
Javascript
new Vue({
el: "#app",
data: {
name: 'Sample User'
},
methods: {
showModal: function() {
Metro.dialog.create({
title: "Modal Title",
content: this.getModalContent
});
},
getModalContent: function() {
return this.$refs.modalContent.innerHTML;
}
}
});
I change the my opinion and i will implement modal in the script;
<script type="text/template" id="data-input-form-template" >
<label>Code</label>
<input type="text" v-model="squad[0].Code"/>
<label>Name</label>
<input type="text" v-model="squad[0].Name" />
<label>Description</label>
<textarea style="height:175px" v-model="squad[0].Description"></textarea>
<div id="appTableMembers">
<table class="cell-border" >
<thead>
<tr>
<th>Personal Code</th>
<th>Adı</th>
</tr>
</thead>
<tbody>
<tr v-for="m in squad[0].members">
<td>{{m.PersonalCode}}</td>
<td>{{m.FullName}}</td>
</tr>
</tbody>
</table>
</div>
</script>
And this my openDialog function;
function openDialog(ID) {
var html = $('#data-input-form-template').html();
$('#data-input-form').html(html);
app4 = new Vue({
el:'#data-input-form',
data: function(){
return {
squad: [{
members: []
}]
}
},
mounted:function(){
Metro.init();
var self = this;
$.ajax({
type: "GET",
"url": '#Url.Action("FindByID", "Squad")',
"data": { id: ID },
"dataSrc": "",
success: function (data) {
self.squad = data;
},
error: function (error) {
alert(error);
}
});
}
});
Metro.dialog.open('#demoDialog1');
}
Main Page html;
<div class="dialog" data-role="dialog" id="demoDialog1"> src="#" />
<div class="dialog-content" style="height:400px">
<form id="data-input-form">
</form>
</div>
</div>

angularjs routing not work for me

Please help me.
Here is my code.
Javascript:
var myMailMod = angular.module('myMail', []);
function configView($routeProvider)
{
$routeProvider.
when('/', {
templateUrl: 'list.html',
controller: 'ListController'
}).
when('/view/:id', {
templateUrl: 'details.html',
controller: 'DetailsController'
}).
otherwise({ redirectTo: '/' });
}
myMailMod.config(configView);
var messages = [
{
id:0, sender: 'mahshad', date:'14/8/2014',
recipients: ['missprogrammer#yahoo.com', 'test#gmail.com'],
subject: 'salam', text: 'salam shaghaliiiiii khobi? :x'
},
{
id:1, sender: 'enayat', date:'16/8/2014',
recipients: ['aryanpour1990#gmail.com'],
subject: 'salam', text: 'khobam to khobi? che khabar?!'
},
{
id:2, sender: 'nooshin', date:'18/8/2014',
recipients: ['nooshin#yahoo.com'],
subject: 'salam', text: 'salam chetoriah? hahaha :)'
}
];
myMailMod.controller('ListController', function($scope)
{
$scope.messages = messages;
});
myMailMod.controller('DetailsController', function($scope, $routeParams)
{
$scope.message = messages[$routeParams.id];
});
HTML(1):
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.2.x" src="https://code.angularjs.org/1.2.21/angular.js" data-semver="1.2.21"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<h1>myMail app</h1>
<div ng-view></div>
</body>
</html>
HTML(2):
<div>sender: {{messages.sender}}</div>
<div>date: {{messages.date}}</div>
<div>from: <span ng-repeat="recipient in messages.recipients">{{recipient}}</span></div>
<div>subject: {{messages.subject}}</div>
<div>{{messages.text}}</div>
HTML(3):
<table>
<tr>
<th>Sender</th>
<th>Subject</th>
<th>Date</th>
</tr>
<tr ng-repeat="message in messages">
<td>{{message.sender}}</td>
<td><a ng-href="#/view/{{messages.id}}">{{message.subject}}</a></td>
<td>{{message.date}}</td>
</tr>
</table>
What should i do?