Vue: Setting initial data string with link - javascript

I have an array of objects as boxData in my initial data. How would I go about making the word "here" a hyperlink that I can use whenever referencing boxData?
data() {
return {
boxData: [
{
body: "This is the link here."
},
{
body: "Normal text."
}
]
}
}
Child component
<div v-for="(box, index) in boxData" class="box">
<div>
{{ box.body }}
</div>
</div>

Ideally, the objects with a link would have a property like url. Then, assuming all of the links should say "This is the link here", you could do:
<div v-for="(box, index) in boxData" class="box">
<div>
<template v-if="box.url">
This is the link <a :href="box.url">here</a>.
</template>
<template v-else>
{{ box.body }}
</template>
</div>
</div>
Then you don't need "This is the link here" in any of the objects.

You just have to put the data into the hyperlink like so:
<a :href="boxData.body">Here</a>
Much better
<router-link :to="boxData.body">Here</router-link>

Related

Opening url in json file with vue.js

I have a url key in my json file and there are values against it. When I create a button with vue.js and click this button, I want the url to be opened. How can I do it?
My code:
<template>
<div class="q-pa-md q-gutter-sm">
<q-btn #click="gotoUrl" color="white" text-color="black" label="Standard" />
</div>
</template>
<script>
import json from './assets/test.json'
export default defJson({
setup: () => ({jsonData}),
methods: {
gotoUrl(){
window.open()
}
}
})
</script>
Json file:
[
{
"id": "1",
"name": "stackoverflow",
"url": "https://stackoverflow.com/"
}
]
When I click this button, the link needs to be read and opened in the json file.
First you wan to loop over the objects in your JSON array like this:
<div v-for="site in jsonData" :key="site.id" class="q-pa-md q-gutter-sm">
...
</div>
Then you can simply create elements around your buttons with the url from the site in the href:
<div v-for="site in jsonData" :key="site.id" class="q-pa-md q-gutter-sm">
<a :href="site.url" target="_blank">
<q-btn color="white" text-color="black" :label="site.name" />
</a>
</div>
Its pretty basic vue stuff.. They have great documentation, check it out: https://vuejs.org/guide/introduction.html

Add #click event to text in vuejs

I am trying to add a click event to a text add states in description method stated below. Please help me resolve this issue.
<div>
class="alert-container"
v-for="alert in alerts"
>
<div class="alert-item">
<div class="alert-info">
{{alert.sender}}
</div>
<div v-if="alert.alert_type === 'urgent'">
<div class="alert-description">{{ addMethod(alert.description) }}</div>
</div>
<div v-else class="alert-description" v-html="alert.description"></div>
</div>
</div>
<script>
export default {
methods: {
addMethod(text) {
return text + '-' + add click event to here to the description text just so when the user clicks on the event below evacuation method runs.
},
evacuation() {
console.log("Leave the building now.")
}
}
}
</script>
Just render the description text then add the click avent to the wrapper element :
<div class="alert-description" #click="evacuation">{{ alert.description }} - </div>
adding the event inside a string and rendering it using v-html will not be interpreted.
<div class="alert-description">{{ alert.description }} - <div class="evacuation">Click here</div></div>
this is how I solved my problem

Accessing nested objects VueJS during for loop

I am trying to dynamically create a form (why? It's 200+ fields long and I am not permitted to modify it). The entire app is in the VueJs environment.
The problem I'm having is that each field requires different things (obviously). I'm trying to add attributes dynamically to each field, which would allow me to render the entire form dynamically, rather than hard coding a 200+ field form. So in my stupidity I'm taking more time trying to solve this problem than it would take to just hard code the form. Oh well...
Here's a specific (simplified) example of what I want to do...
data() {
return {
form: {
input1: {value: "", classIWantToDynamicallyAdd: "FieldSizeSmallAF"},
input2: {value: "", classIWantToDynamicallyAdd: "FieldSizeBigAF"},
//Repeat 200 times
}
}
}
Now ultimately I want to get the value of "classIWantToDynamicallyAdd" and :class="put it here"
The HTML looks like this:
<template>
<div>
<div v-for="(field, index)" in form" :key="index">
<div class="labelAndInput" :class="**I don't know what to do here**">
<label>index</label> // Successfully outputs: "input1", "input2", etc...
<input>
</div>
</div>
</div>
</template>
Hopefully that's somewhat clear. I expected form.index.classIWantToDynamicallyAdd to work, but it did not, i got the following error:
TypeError: "_vm.form.index is undefined".
Thanks in advance!
You could do :class="[field.classIWantToDynamicallyAdd]" :
<div v-for="(field, index)" in form" :key="index">
<div class="labelAndInput" :class="[field.classIWantToDynamicallyAdd]">
....
<input>
</div>
</div>
You could define those class names on data() and just bind it to :class
Example:
https://jsfiddle.net/pguti19/hL2vamnw/
More help:
https://michaelnthiessen.com/dynamically-add-class-name/
<div id="app">
<h1>
Forms:
</h1>
<div v-for="(field, index) in form" :key="index">
<span :class="field.class">
Using {{field.class}} class
</span>
</div>
</div>
<script>
new Vue({
el: "#app",
data: {
form: {
input1: {value: "", class: "red-theme"},
input2: {value: "", class: "blue-theme"},
input3: {value: "", class: "green-theme"}
},
theme1: 'blue-theme',
theme2: 'red-theme',
theme3: 'green-theme'
},
methods: {
toggle: function(todo){
todo.done = !todo.done
}
}
})
</script>

Using summernote with meteor (Discover Meteor)

So, I've been working with Discover Meteor, and I'm having problems.
I'm trying to insert what content inputted in summernote into mongo but I'm having a few problems.
post_submit.html
<div class="form-group {{errorClass 'content'}}">
<textarea class="form-control" name="content" id="summernote"></textarea>
</div>
post_submit.js
var post = {
url: checkURLPrefix( $(e.target).find('[name=url]').val() ),
title: $(e.target).find('[name=title]').val(),
content: $(e.target).find('[name=content]').val()
};
lib/posts.js (will say Match Failed error when submitting)
meteor.methods({
postInsert: function(postAttributes) {
check(this.userId, String);
check(postAttributes, {
title: String,
url: String,
content: function(content){$('[name=content]').html($('#summernote').code());}
});
I've tried content: String to input the data into mongo. It would work but when I tried to load {{content}} in the post_page.html file, it would just show the unrendered HTML codes. {{{content}}} would show to content properly rendered but would mess up the functionality of the sorting system based on votes.
I'm really lost here and I wish I could find a solution soon.
Thank you in advance!
EDIT1: Here is my post_page.html and what I see when I insert content: String and load with {{content}}
<template name="postPage">
{{> postItem}}
<div class="col-md-12" style="background:blue;">
{{content}}
</div>
<ul class="comments">
{{#each comments}}
{{> commentItem}}
{{/each}}
</ul>
{{#if currentUser}}
{{> commentSubmit}}
{{else}}
<p>Please log in to leave a comment.</p>
{{/if}}
</template>
http://i.imgur.com/Fm0CXAN.png
First: you should use summernote in a div, not a textarea.
And in post_submit.js you have to leave it like this:
var post = {
...
content: $(e.target).find('#summernote').code()
};
In your post_page.html use triple brackets, because its HTML.
<div class="col-md-12" style="background:blue;">
{{{content}}}
</div>

JsRender if-else renders nothing

I have a simple model:
var model = [{
content: "",
type: "photo",
src: "xxx"
}, {
content: "",
type: "quote",
text: "blah"
}];
and a simple template:
{{if type eq='photo'}}
<img src="{{:src}}" />
<div class="photo-caption">
{{:caption}}
</div>
{{else type eq='quote'}}
<div class="quote-text">
{{:text}}
</div>
{{/if}}
The problem is that the template renders nothing at all when the type is "quote". If I change it slightly to two ifs instead of an if-else, it renders the quote, but also renders the div class="photo-caption">. I need it to only render one or the other. I have a feeling it's a simple matter of syntax, but can't seem to find sufficient docs on how this is done correctly on the JsRender site.
Here's a fiddle. The two templates should behave exactly alike. Instead one renders both, the other renders only the image.
I got it:
{{if type == 'quote' }}
<div>
{{: text }}
</div>
{{else type == 'photo'}}
<div>
{{: src }}
</div>
{{/if}}
http://jsfiddle.net/4QzZX/2/
When you tried the version with two if statements, did you remember to add a {{/if}} in addition to changing the {{else}} into an {{if}}?
{{if type eq='photo'}}
<img src="{{:src}}" />
<div class="photo-caption">
{{:caption}}
</div>
{{/if}}
{{if type eq='quote'}}
<div class="quote-text">
{{:text}}
</div>
{{/if}}

Categories