Assign value to input without v-model and without databinding - data-binding

In my v-for i need to initialize some input field with some text WITHOUT binding it to the object. Currently i'm trying:
<div v-for="item in allItems">
<input type="text" class="header-title" value="item.name"></input>
</div>
but item.name is printed in the input instead of the item name. How to accomplish this?

v-model is just syntactic sugar for :value and an event, usually #input. See docs here.
You can pass a noop function () => {} to cancel the value update or do whatever you want with the new value, maybe assign it to another object.
Note: <input> elements are void, they do not require a closing tag.
new Vue({
el: '#app',
data() {
return {
allItems: [{ name: 'foo' },{ name: 'bar' }]
}
},
})
<script src="https://unpkg.com/vue#2.5.9/dist/vue.js"></script>
<div id="app">
<div v-for="item in allItems">
<input type="text" class="header-title" :value="item.name" #input="() => {}">
{{ item.name }}
</div>
</div>

You can have your input show value of item.value by only using the ref attribute.
Just add ref='' and map it's values to the inputs value, inside your mounted function.
new Vue({
el: '#app',
data () {
return {
allItems: [
{name: 'foo'},
{name: 'bar'}
]
}
},
mounted () {
let self = this;
this.$refs.inp.map( (m, k) => {
m.value = self.allItems[k].name
})
}
})
<script src="https://unpkg.com/vue#2.5.9/dist/vue.js"></script>
<div id="app">
<div v-for="item in allItems">
<input type="text" class="header-title" value="item.name" ref='inp'></input>
</div>
</div>

Related

VueJs calling :key in method

im new to Vue and trying myself in Vue3 and Vuetify.
Similar to this Post im trying to :key or ref a vue-signature-pad in a for loop.
I initialize an empty Array and push a new element, which adds a new signature.
<template>
<div>
<v-container>
<div class="row" v-for="(input, index) in inputs">
<v-container>
<VueSignaturePad
id="signature"
width="100%"
height="300px"
ref="signaturePad"
/>
</v-container>
<div class="buttons">
<button #click="undo">Undo</button>
<button #click="save">Save</button>
</div>
</div>
<v-row justify="center">
<v-btn #click="addRow"
class="ma-2"
color="blue-grey"
icon="mdi-plus-circle-outline"
></v-btn>
</v-row>
</v-container>
</div>
</template>
<script>
export default {
data: () => ({
inputs: [],
}),
methods: {
addRow() {
this.inputs.push({
name: ''
})
},
undo() {
this.$refs.signaturePad.undoSignature();
},
save() {
const { isEmpty, data } = this.$refs.signaturePad.saveSignature();
alert("Open DevTools see the save data.");
console.log(isEmpty);
console.log(data);
}
}
}
</script>
<style scope>
</style>
In the Post i already mentioned, i tried the Solution from Mathieu Janio.
So if i understand everything right, ref is not working and i have to use :key on the div itself.
So i tried his Solution
<template>
<div
class="row"
v-for="(applicants, index) in applicant_details"
:key="index"
>
<div class="col-sm-4">
<div class="form-group">
<p>Signature for {{ applicants.first_name }}</p>
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<VueSignaturePad ref="" />
<button type="button" #click="undo" class="btn btn-warning">
Undo
</button>
</div>
</div>
</div>
</template>
<script setup>
const applicant_details = [
{ first_name: 'john', signature: '' },
];
const undo = () => {
//will undo the signature
};
const save_signature = () => {
//Save the signature
};
</script>
But now im stuck at calling the right "undo"
The signatepad github example uses ref: at the single signaturepad, which is ok.
but not working at the forloop
How do i call now the right function in "undo" for the solution above?
I tried using "this.$.vnode.key" but this gives me an error.
"Uncaught TypeError: Cannot read properties of undefined (reading '$')".
I figured my first way out.
Heres what i have done.
The Signaturepad got an index on the ref.
<VueSignaturePad
:id="'signaturePad' + index"
width="100%"
height="300px"
:ref="'signaturePad' + index"
:options="options"
/>
The "undo" button is giving it "ref" with
<button #click="undo(`signaturePad${index}`)">Undo</button>
And the undo function itself has the first item in its ref array
undo(ref) {
this.$refs[ref][0].undoSignature();
}
Maybe someone has some more efficient way. Feel free :)

vue3 Cannot loop over an array of object passed as prop

In vue3 I am passing an array of options from parent component to child component in order to use it as options for a select.
At the moment, I am not able to use it to initialize my select.
Here is the child component SmartNumberInput
<template>
<div>
<div>Selected: {{ selected }} Initial:{{ initial }}</div>
{{ options }}
<div v-for="option in options" :key="option.value">
{{ option.text }}
</div>
<input type="number" v-model="input_value" />
<select v-model="selected">
<option
v-for="option in options"
:value="option.value"
:key="option.value"
>
{{ option.text }}
</option>
</select>
</div>
</template>
<script>
export default {
props: ["initial", "options"],
data() {
return {
selected: "",
input_value: "",
};
},
};
</script>
Here is the parent component
<template>
<div>
<h1>Hi! I am the root component</h1>
<div class="smart-number-input">
<smart-number-input
initial="B"
options="[{text:'Liters',value:'A'},{text:'Gallons',value:'B'},{text:'Pints',value:'C'}]"
/>
</div>
</div>
</template>
<script>
import SmartNumberInput from "./SmartNumberInput.vue";
export default {
data() {
return {
initial: "salut",
};
},
components: { SmartNumberInput },
};
</script>
<style>
.smart-number-input {
width: 100%;
background:#EEE;
}
</style>
In the result I get (see picture) there is no option visible in the select though when the small arrow is clicked it expands with a long empty list.
The {{options}} statement in the child displays what I pass as prop i.e. an array of objects but nothing is displayed in the div where I use a v-for loop.
When I declare the options as data in the child both loops (div and select) work fine.
Could somebody explain what is wrong in the way I pass or use the array of options ?
change options to :options (add colon symbol)
.
if you not put colon, it will treat the value as a String...

How to bind variable window['array[element]'] in Ractive.js?

There is a need to have a two-way binding for a variable with such untypical name like "array[element]".
The syntax below works but when I change 0 to #index it gets broken. Adding back slashes before brackets [ ] does not work as well.
<input type="text" name="prices[{{#index}}]" value="{{someForm.inputs["prices[0]"].value}}" />
What is the proper syntax to get the variable binded?
You can use #context:
Ractive.DEBUG = false;
var ractive = Ractive({
target: output,
template: `
{{ #context.get('array[element]') }}
`,
data: { 'array[element]': "FOO" }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/ractive/1.0.0-build-99/ractive.min.js"></script>
<div id="output"></div>

binding attributes in vuejs component

I am trying to use the last version of vuejs with Laravel 5.3 ! The idea I am trying to fulfill is make a component foreach user. So that I have all users listed and foreach one there is a button "edit" , when I click this button I should see the form to update this user.
So this is how I defined the component :
<script>
new Vue({
el: '.view-wrap',
components: {
user-view: {
template: '#user-view',
props: ['user']
}
},
data: {
users: <?php echo json_encode($users); ?>,
},
methods: {
showForm: function(number){
$('div.update-user-'+number).css({'display':'block'});
},
getClassName: function (index) {
return "update-user-"+index;
},
getUpdateUrl: function(id){
return '/users/update/'+id;
},
}
});
This is the template for the "user-view" which take a class name "updateClass" which contains the id of every user (for show/hide purposes), an "updateUrl" which is the url to update the user to bind it with each form action and finally the object user :
<template id="user-view">
<div>
<div class="updateclass">
<form class="form-horizontal" method="PUT" action="updateUrl">
{{ csrf_field() }}
<ul>
<li>
<label for="name"> Name </label>
<input type="text" name="name" :value="user.name">
</li>
<li>
{!! Form::submit('Save', ['class' => 'button-green smaller right']) !!}
</li>
</ul>
{!! Form::close() !!}
</div>
and This is finally how I call the template :
<user-view v-for="user in users" :updateclass="getClassName(user.id)" :user="user" :updateUrl="getUpdateUrl(user.id)"></user-view>
The issue then : it seems that for example [class="updateclass"] doesn't change the value of updateclass with the result of getClassName(user.id) as defined in template call that is binded to. When I try it with [:class="updateclass"] in the template I get : Property or method "updateclass" is not defined on the instance ...
and the same thing applies to all other binded attributes.
The syntax you are using to assign a class dynamically is wrong. from the getClassName method you have to return a object having className like this : {"className: true} , like following
getClassName: function (index) {
var tmp = {}
var className = 'update-user-'+index
tmp[className] = true
return tmp
}
Than you can assign it like following as is in documentation:
<div :class="updateclass"></div>

Reactive-Tables Meteor

I am trying to get reactive-tables to work but I am having no luck following the instructions on GitHub.
This is what I have:
In my Main.html:
{{> courseTable }}
in my course_table.html:
<template name="courseTable">
<div id="table">
{{ > reactiveTable collection=Courses}}
</div>
</template>
in courses.js:(works with autoForm)
Courses = new Meteor.Collection("courses", {
schema: {....
Is there something I am missing? From my understanding once these commands are used, the rest is done from within the package. I can't find any more information on this package anywhere.
What I have now just shows a blank screen.
Thanks in advance!
This is what I have: (I'm using Meteor framework and bootstrap-3 package)
in index.html
<template name="clientes">
<div class="container">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Clientes</h3>
</div>
<div class="panel-body">
{{> reactiveTable collection=tables settings=tableSettings}}
</div>
</div>
</div>
</template>
in index.js
var Clientes = new Meteor.Collection('clientes')
Template.clientes.tables = function () {
return Clientes;
}
Template.clientes.tableSettings = function () {
return {
rowsPerPage: 10,
showFilter: false,
showNavigation: 'auto',
fields: [
{ key: 'nombre', label: 'Nombre' },
{ key: 'apellido', label: 'Apellido' },
{ key: 'correoe', label: 'E-mail' }
],
useFontAwesome: true,
group: 'client'
};
}
With this I can display all the records in the collection.
I hope this help you to go any further.
Courses is the collection object. To get some courses, you need to query the courses with find:
Courses.find()
However, to make this accessible in the template, you need a helper function.
//course_table.js
Template.courseTable.helpers({
courses: function () {
return Courses.find()
}
});
Then you can can set the table collection using the helper method (I used a lowercase "courses" for the helper method for clarity):
{{> reactiveTable collection=courses}}

Resources