Why v-model is not working? - javascript

This is my very first code in Vue.js. I am following a simple online tutorial. After installing the application using the vue-cli, I created a simple component
Test.vue which contains a simple input control bound to the message property of my model:
Test.vue
<template>
<div
<input
type="text"
v-model="message"/>
<br/>
<p>The value of the input is: {{ message }}</p>
</div>
</template>
<script>
export default {
data:{
message: 'My name'
}
};
</script>
<style>
</style>
Then I load this component inside the <App />. But when I write a text inside the input box, the <p> element is not updated...
What am I doing wrong? This looks pretty straightforward. Thanks you for your suggestions and pointing me to the right direction.

In a component, data must be a function.
export default {
data(){
return {
message: 'My name'
}
}
};
Also, your template is missing a > in the first div, but I'm guessing that happened writing the question.
<template>
<div>
<input
type="text"
v-model="message"/>
<br/>
<p>The value of the input is: {{ message }}</p>
</div>
</template>

Related

VueJS two same components in a file, data change in one changes other's data?

I have created a VueJS component for dropdown.
<template>
<div>
<select v-bind:value="value" v-on:input="$emit('input', $event.target.value)">
<option v-for="(option, index) in dropdownOptions"
v-bind:key="index">
{{ option }}
</option>
</select>
</div>
</template>
<script>
export default {
props: {
dropdownOptions: Array,
value: String
},
mounted() {
this.value = this.dropdownOptions? this.dropdownOptions[0] : "";
}
}
</script>
And I have used it in parent as -
<div id="selectvideodropdown" class="col">
<Dropdown v-bind:dropdown-options="allVideos" v-model="selectedVideo">
</Dropdown>
</div>
<div id="selectvideodisplaymode" class="col">
<Dropdown v-bind:dropdown-options="allDisplayMode" v-model="selectedDisplayMode">
</Dropdown>
</div>
Parent's script -
<script>
import VideoPlayer from "./Videoplayer.vue"
import Dropdown from "../shared/Dropdown.vue"
export default {
components: {
VideoPlayer,
Dropdown
},
data() {
return {
allVideos: ["Video 1", "Video 2", "Video 3"],
allDisplayMode: ["With Bounding Box", "Without Bounding Box"],
selectedVideo: "",
selectedDisplayMode: "",
}
}
};
</script>
Weirdly, when I select the dropdown, it changes the current value of other dropdown to empty string. It only happens once after page load, and is not repeated again.
There are several issues here.
So, first, I’d recommend reading this which should help illuminate how v-model works.
Now, notice that v-model basically creates a two-way binding between data and a value attribute.
There’s a lot going on all at once, but the basic gist of it is that you’ve got data in your parent component that’s being bound to the value, but when you initialise each component you’re manually setting the value. When Vue updates everything, it ends up resetting the bound attribute in the other dropdown to the value being passed in from its v-model, which happens to be the empty string.
However, as a commenter mentioned, you’re also altering a property in the child component as if it were a data attribute, which is a very bad idea. Make that a separate data value.

Input field doesn't work inside vue-drag-resize

Im using vue-drag-resize from https://github.com/kirillmurashov/vue-drag-resize.
I can't focus and type anything inside input text field if it is placed inside vue-drag resize component. Does anybody know solution how to fix this problem?
I've faced this issue when I'm using vue-drag-resize npm on my vue project.
In the vue-drag-resize container, input field didn't work.
So I fixed it with input focus function
This is Code Example
<template>
<VueDragResize>
<input v-model="name" ref="input" #click="inputClicked" />
</VueDragResize>
</template>
<script>
...
...
methods: {
inputClicked() {
this.$refs.input.focus()
}
}
</script>
Sometimes, we will have "... .focus is not a function" error.
If you faced this error, please try like this
this.$refs.input[0].focus()
this.$refs.input.$el.focus()
Either one will work.
#activated="onActivated"
methods: {
onActivated() {
this.$refs['yourinput'].focus();
}

Vue.js component method "not defined on the instance"

I'm learning vue.js and used vue-cli to setup a new project. Now I tried adding a method to a component but something is wrong:
<template>
<div>
<div v-for="task in $state.settings.subtasks">
<input type="text" v-model="task.text">
<input type="text" v-model="task.assignedTo">
<input type="button" v-on:click="removeTask(task)">
</div>
</div>
</template>
<script>
export default {
name: 'settings',
methods:{
removeTask:function(task){
console.log("remove task");
}
}
}
Clicking the button should call the removeTask function but it just outputs an error in the console:
[Vue warn]: Property or method "removeTask" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
found in
---> <Settings> at src/views/Settings.vue
<App> at src/App.vue
<Root>
What is wrong here?
When I went back to my question I noticed I was missing the </script> end tag. Adding that solved my problem.

Meteor Color Picker

Im trying to get jscolor (http://jscolor.com/) to work on my meteor app.
The jscolor.js javascript file is located at:
client/lib/jscolor.js
Now when I put an input element with class jscolor in my main.html like:
<head>
<title>Meteor Site</title>
</head>
<body>
<input class="jscolor" value="ab2567">
</body>
it works! But as soon as I put it inside a template which is controlled by the iron router, settings for instance:
<template name="settings">
Settings
<input class="jscolor" value="ab2567">
</template>
It does nothing and it stay a regular input field. Do I need to pass the javascript file to a template somehow or do I need to make it global? Hope someone can help me out?
meteor add risul:bootstrap-colorpicker
html file
<template name="hello">
<input type="text" class="demo1" value="#5367ce" />
</template>
js file
Template.hello.rendered = function() {
$('.demo1').colorpicker();
}

Polymer v1.0 input validation on button click

Noob at polymer here, so please bear with me.
I'm trying to learn how to create a form, one that requires the user to input text into a textbox, before hitting "Submit". Should the user hit "Submit" without anything in the textbox, the textbox is highlighted red, and displays an error message, etc.
Here's my code (no validation yet) so far:
<dom-module id="accountability-ticket">
<template>
<paper-dialog with-backdrop entry-animation="scale-up-animation" exit-animation="fade-out-animation" id="diagTicket">
<h2>I Own It Ticket</h2>
<div>
<paper-input-container id="gcashDeco" required error="GCash Ref. Required">
<input id="gcashText" is="iron-input">
</paper-input-container>
<div class="ctrlButtons flex">
<paper-button dialog-dismiss>Cancel</paper-button>
<paper-button on-click="confirmClick">Submit</paper-button>
</div>
</div>
</paper-dialog>
</template>
</dom-module>
<script>
Polymer({
is: "accountability-ticket",
confirmClick: function(event){
console.log(event);
var gCashDeco = document.getElementById('gcashDeco');
var gCashText = document.getElementById('gcashText');
}
});
</script>
I've been reading the Polymer documentation, and so far came up with two things:
<paper-input> doesn't validate, per se, according to v0.5 - It must be wrapped in <paper-input-decorator> first.
Version 1.0 is even less clear than that, with <paper-input-container> instead of <paper-input-decorator>, and mixed tags in the demo pages.
Given that I want to stick with the latest version (v1.0), what do I need to add to my code to get it to check if the textbox is empty, and display an error message if it is?
Thanks.
Yep, the Polymer docu is somewhat confusing, but as a general rule of thumb: always have a look at the behaviours the element is equiped with.
So, paper-input (in 1.0) comes with PaperInputBehavior and this implies that you can simply write the following:
<paper-input label="Input label" required error-message="Field required!"></paper-input>
<paper-input label="Input label" minlength="4" maxlength="10" auto-validate></paper-input>
<paper-input label="Input label" pattern="MY_REGEX" auto-validate></paper-input>
<paper-input label="Input label" validator="myvalidator"></paper-input>
auto-validate makes the input – of course – validate as it is being typed into. myvalidator must be an element implementing the IronValidatorBehavior and inserted somewhere on the page. If you don't want the fields to be auto-validating or wanna do it yourself, call validate() on that field or set the invalid-flag and the error message will be shown. You can even adjust the message programmatically.
While the validator seems to be useful, I've found it to be simple enough to test the inputs directly. This will do what you need:
...
<div>
<paper-input-container id="gcashDeco">
<paper-input-error>Field is empty</paper-input-error>
<input id="gcashText" is="iron-input" value="{{gcashInput::input}}">
</paper-input-container>
<div class="ctrlButtons flex">
<paper-button dialog-dismiss>Cancel</paper-button>
<paper-button on-tap="confirmClick">Submit</paper-button>
</div>
</div>
...
...
Polymer({
is: "accountability-ticket",
confirmClick: function() {
if (this.gcashInput == null)
{
//show error
this.$.gcashDeco.invalid = true;
}
}
This paper-input-error element is referenced by the id of whatever paper-input-container it is inside of. Setting it's invalid property to true shows the error, and false hides it.
<paper-input-error>Field is empty</paper-input-error>
This next snippet binds the field's input value to a variable this.gcashInput which you can access inside confirmClick or any other method.
{{gcashInput::input}}
As a final note, getting id's of elements inside of your Polymer element is done like this:
this.$.gcashDeco
Not the way you would with vanilla Javascript:
document.getElementById('gcashDeco');
The latter, vanilla JS way, would search the main DOM, not the Shadow DOM where your element resides. So, use document.getElementById() if you need to search the DOM, and use this.$.elemendId if you need to search your element for an id.

Categories

Resources