I'm making a list with 'v-for' where each item has to have an if with a different value corresponding the array, but the Vue not allows to create a 'v-if' expression starting from {{ i.some_data_to_evaluate }} .
Have a way to solve this?
Here is my code:
HTML
<div id='test' v-for="i in items">
<p v-if={{i.value}}>{{i.some_text}}</p>
<p v-else>{{i.other_text}}</p>
</div>
JS
let test = new Vue({
el: '#test',
data: [
{some_text: 'jhon', other_text: 'jonas', value:false},
{some_text: 'joao', other_text: 'maria', value:true}
]
})
I'm just trying to change the version that is in the Vue guide.
Here's the link: http://vuejs.org/guide/list.html
You should replace the brackets with quotes on the v-if directive:
<div id="test" v-for="i in items">
<p v-if="i.value">{{i.some_text}}</p>
<p v-else>{{i.other_text}}</p>
</div>
Related
I'm trying to get just a simple hello world for v-for. I've googled this for an hour and found various other posts, such as this one to no use.
My HTML:
<ul>
<li v-for="item in history">
{{ item }}
</li>
</ul>
My JS:
new Vue({
el: '#app',
data: {
history: [
'red','green','blue'
],
},
});
My Output:
{{ item }}
Someone please tell me what I'm doing wrong and why I can't get this bare-bones example working. I've tried using arrays and objects, looping using the key attribute, and several other things.
Docs: https://v2.vuejs.org/v2/guide/list.html
EDIT: apologise for the awful title; I had to change it 13 times before SO stopped yelling at me...
EDIT 2: I have the app defined containing the entire body of HTML: <div id="app">, thank you for the answers though : )
EDIT 3: Resolved, I must've had a div tag closed prematurely; commenting it out fixed the code. Thanks for the answers.
Probably you don't define the id app in the HTML section. Here is the working code.
new Vue({
el: '#app',
data: {
history: [
'red', 'green', 'blue'
],
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<ul id='app'>
<li v-for="item in history">
{{ item }}
</li>
</ul>
You need to have "#app" id in your code like this
<ul id="app">
<li v-for="item in history">
{{ item }}
</li>
</ul>
I've been having some trouble recently with the order of Vue components in Bootstrap. I'm trying to generate some Bootstrap collapsible content in Vue here's the code so far:
HTML
<div class="col-sm main-content" id="main-content">
<p>
<main-section-button v-for="item in sections"
v-bind:section="item"
v-bind:data-target="'#section-' + item.text"
v-bind:aria-controls="'section-' + item.text">
</main-section-button>
</p>
<main-section v-for="item in sections"
v-bind:id="'section-' + item.text">
</main-section>
</div>
VueJS
Vue.component("main-section-button", {
props: ["section"],
template: String.raw`<button class="btn btn-block btn-dark" type="button" data-toggle="collapse" aria-expanded="false">{{ section.text }}</button>`
});
Vue.component("main-section", {
props: ["section"],
template: String.raw`<div class="collapse"><div class="card card-body"><p>Hello, World!</p></div></div></div>`
});
let app = new Vue({
el: '#main-content',
data: {
sections: [
{ id: 0, text: "example1"},
{ id: 0, text: "example2"}
]
}
});
I have tried to make just one component for main-section and main-section-button, but that did not work because of the requirement to pass an id to the card (collapsible content), and a data-target to the button that collapses and expands the content.
Current Result
Required Result
Is it possible to create a component so that the section content is always below the section button.
Thank you in advance.
I guess you have two options to achieve this:
Create a new component that takes the items and displays both components as you wish.
Do not iterate over the components, instead use a <div> around both components or a non-rendered <template> like this:
<div class="col-sm main-content" id="main-content">
<template v-for="item in sections">
<p>
<main-section-button
v-bind:section="item"
v-bind:data-target="'#section-' + item.text"
v-bind:aria-controls="'section-' + item.text">
</main-section-button>
</p>
<main-section
v-bind:id="'section-' + item.text">
</main-section>
</template>
</div>
I am trying to split the last end of the URL to get numeric value. It is throwing an error. I haven't used vue in a while but I know we can use methods/function to get desired results? Where am I doing it wrong?
<ul>
<li v-for="(character, index) in characters" :key="index">
<router-link :to="'/characters'+ character.url.split("/").pop()">
{{character.name}}
</router-link>
</li>
</ul>
Here is an example, hope this helps:
new Vue({
el: '#app',
data: {
character: {
url: 'https://jsonplaceholder.typicode.com/todos/101'
}
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-html="`/characters/${character.url.split('/').pop()}`"></div>
<div> {{ `/characters/${character.url.split('/').pop()}` }}</div>
</div>
I am using string literals (Template literals or Template strings) to keep the code clean by eliminating some double/single quotes and + used for concatenation.
I'm using a CMS to create a front-end form where customers (theatre directors) can define several showtimes. I have a button they click to "add another" input field as needed (sidenote: I don't know how to enable a 'remove last' button using Vue, but that's another topic for another day).
I've gotten that working. But now, once a director has created their showtimes and they come back to edit them, I need the starting index of the Vue counter to be the number of fields that already exist. So if they've defined 3 showtimes already (0,1,2), the first field dynamically placed with Vue should start with 3.
Alternatively, I wonder if it'd be easier to generate an array of the existing data in Vue when the page loads, but I don't know where I'd start with that method.
Here's my HTML and Vue JS:
new Vue({
el: '#app',
data: {
timeslots: [
{
count: 0
}
],
count: 0
},
methods: {
addAnother: function(){
this.timeslots.push({
count: ++this.count
});
}
}
});
<div id="app">
{{ performances }}
<input name="performances[{{ zero_index }}][showtime]" value="{{ showtime }}">
{{ /performances }}
<template v-for="slot in timeslots">
<input name="performances[#{{ slot.count }}][showtime]" value="{{ now }}">
</template>
<div>
<button #click.prevent="addAnother">Add another</button>
</div>
</div>
Any help to move forward is appreciated!
I solved it myself in shorter time than expected using the 2nd method I speculated about in my OP, and using $index instead of an arbitrary integer like count. This method requires the JS to be put directly in my template though, not in a separate file. But that's fine by me.
<div id="oven">
<template v-for="biscuit in oven">
<div>
<input type="text" name="performances[#{{ $index }}][showtime]" value="#{{ biscuit.showtime }}">
</div>
</template>
<span class="add small black btn" #click="addAnother"><i class="fa fa-plus-circle"></i> Add another</span>
</div>
<script>
new Vue({
el: '#oven',
data: {
oven: [
{{ performances }}
{
showtime: "{{ showtime }}"
},
{{ /performances }}
]
},
methods: {
addAnother: function(){
this.oven.push({
showtime: '{{ now modify_date="+2 months" format="Y-m-d" }} 7:30 PM'
});
}
}
});
</script>
So I have the next div in index.html:
...
<div ng-include src="'templates/blocks.html'" ng-controller='Foo'></div>
...
The Foo controller holds an array of html snippets under the "bars" property.
The blocks.html looks like:
<div class="block" ng-repeat="bar in bars">
<div ng-bind-html-unsafe="{{bar}}"></div>
</div>
and what I'm getting is the html as text in the div with class "block", meaning it is not evaluated as html.
thanks.
ng-bind-html-unsafe is removed in 1.2. Use ng-bing-html instead and remove the curly braces just like Sebastian said.
Include ngSanitize module as a dependancy to your app and dont forget to include its JS
//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular-sanitize.js.
Remove the curly braces in ng-bind-html-unsafe and it should work:
<div class="block" ng-repeat="bar in bars">
<div ng-bind-html-unsafe="bar"></div>
</div>
Just for completeness - here is a sample jsfiddle.
<div ng-repeat="item in tree" ng-include="'a.html'" class="node"></div>
a.html
<p> {{item.name}}</p>
controller.js
$scope.tree = [
{name: 'Узел', nodes: [] },
{name: 'Морской', nodes: []},
{name: 'Устричный', nodes: []}
];