How to use v-for in SweetAlert2 - vue.js

this.$swal
.fire({
title: '학교를 검색해주세요.',
input: 'text',
inputAttributes: {
autocapitalize: 'off'
},
showCancelButton: true,
confirmButtonText: '검색하기',
cancelButtonText: '취소',
icon: 'question',
preConfirm: (school) => {
return axios.get(`(serverIp)/school?query=${school}`)
.then(response => {
console.log(response.data.data.schools)
this.$swal.fire({
title:'학교를선택해주세요.',
html: `<div v-for="(item, index) in response.data.data.schools" :key="index">
{{ item.school_name }}
</div>`
})
})
},
allowOutsideClick: () => !this.$swal.isLoading()
})
I've tried this code, but this is what it looks like in html.
{{ item.school_name }}
How can i do?
I've not use "Sweetalert 2, I hope you'll understand if i can't.

vue-sweetalert2 doesn't support rendering HTML templates dynamically, so you can't pass Vue templates this way; but you don't really need to in this case. Instead, you could generate the HTML string in JavaScript like this:
axios
.get(apiUrl)
.then(response => {
this.$swal.fire({
html: response.data.data.schools
.map(item => `<div>${item.school_name}</div>`)
.join('')
})
})
The above code uses Array.prototype.map on the array in response.data.data.schools to map the array values into an array of divs. Then it uses Array.prototype.join to combine the resulting array values into one long HTML string.
demo

Related

Is there a way to neaten up deeply nested objects during a v-for loop?

I'm currently working on a project in Vue that uses the WP-Rest api. I'm bored of tediously nested objects when looping through objects. While I can destructure top-level objects, I'm not sure how make things like this: page.page.featuredImage.node.altText less ugly. Can anyone offer any good practices for handling nested objects within Vue loops?
<div v-for="(page, index) in pageGrid" :key="index"
class="flex flex-col overflow-hidden rounded-lg shadow-lg">
<div v-if="page.page.featuredImage" class="flex-shrink-0">
<img class="h-48 w-full object-cover" :alt="page.page.featuredImage.node.altText"
:sizes="page.page.featuredImage.node.sizes" :srcset="page.page.featuredImage.node.srcSet" />
Sometimes that is why to do it in the other hand you can map over your data when mounted for instant and return a new array that looks the way you want.
I am not sure how your data looks but I think you could also do something like this:
<div v-for="(page, index) in pageGrid.page" :key="index">
As per your template code, You are having below data structure contains by pageGrid.
[
{
page: {
featuredImage: {
node: {
altText: 'Text 1',
sizes: 'small',
srcSet: 'image src link'
}
}
}
},
{
page: {
featuredImage: {
node: {
altText: 'Text 1',
sizes: 'small',
srcSet: 'image src link'
}
}
}
},
...
...
]
To make this simple, You can move the whole node object into a separate array with the help of Array.map() method and then it will easy to iterate in the template.
pageGrid.map(({ page }) => page.featuredImage.node);
Live Demo :
new Vue({
el: '#app',
data: {
pageGrid: [
{
page: {
featuredImage: {
node: {
altText: 'Text 1',
sizes: 'small',
srcSet: 'image 1 src link'
}
}
}
},
{
page: {
featuredImage: {
node: {
altText: 'Text 2',
sizes: 'medium',
srcSet: 'image 2 src link'
}
}
}
}
],
updatedPageGrid: []
},
mounted() {
this.updatedPageGrid = this.pageGrid.map(({ page }) => page.featuredImage.node);
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="(page, index) in updatedPageGrid" :key="index">
{{ page.altText }}
{{ page.sizes }}
{{ page.srcSet }}
</div>
</div>

Vue.js component's methodreturns "undefined" to the HTML

I have tried to experience the Dropbox API, according to Packt's Book "Complete Vue.js 2 Web Development (Chapter 4)".
Since the include_media_info has been deprecated recently, I tried to adapt the example code to dropbox().filesGetMetadata() to query the metadata of images.
The javascript is like that:
Vue.component("dropbox-viewer", {
template: "#dropbox-viewer-template",
data() {
return {
accessToken:
"XXXXXX",
structure: [],
}
},
methods: {
dropbox() {
return new Dropbox.Dropbox({
accessToken: this.accessToken,
fetch: fetch,
})
},
getFolderStructure(path) {
this.dropbox()
.filesListFolder({ path: path })
.then((response) => {
console.log(response.entries)
this.structure = response.entries
})
.catch((error) => {
console.log(error)
})
},
getDimensions(path) {
let dimensions = ""
this.dropbox()
.filesGetMetadata({ path: path, include_media_info: true })
.then((response) => {
if ("media_info" in response) {
dimensions = response.media_info.metadata.dimensions
console.log(dimensions)
console.log(typeof dimensions)
return dimensions
}
})
.catch((error) => {
console.log(error)
})
},
},
created() {
this.getFolderStructure("")
},
})
And the relevant HTML is as below:
<div>
<h1>Dropbox Viewer</h1>
<li v-for="entry in structure">
<span>{{ entry[".tag"] }}</span>
<strong>{{ entry.name }}</strong>
<span v-if="entry.size"> - {{ entry.size }}</span>
<span v-if="entry['.tag'] === 'file'">
{{ entry.path_lower }}
{{ typeof getDimensions(entry.path_lower) }}
</span>
</li>
</div>
From the console.log(dimensions) in the js, I notice that dimensions is an object with height and width. Console output
However, it is undefined when it is rendered in the HTML.
Rendered HTML
I am not sure if I have any misconception about the returned value from Vue's method. So I would like to seek your advice. Thank you very much in advance.

How to Pass selected values of multiple select component into my API?

I am using vuesax multiple select component to select multiple options from the available options. But when I try to submit/Insert the selected value to my API, the values from the component are being passed as arrays. But my API accepts only string values. Can anyone help me with code to this problem?
Vuesax component code
<vs-select multiple autocomplete v-model="newRecord.required_sub" label="Subject" class="selectExample mt-5 w-full" name="item-category" v-validate="'required'">
<vs-select-item :key="item.value" :value="item.value" :text="item.text" v-for="item in teach_mode_drop" />
</vs-select>
my script for options
teach_mode_drop: [
{text:'Option1', value:'Option1'},
{text:'Option2', value:'Option2'},
{text:'Option3', value:'Option3'},
{text:'Option4', value:'Option4'},
],
main method
createRecord() {
this.$vs.loading();
jwt.createLeads(this.newRecord).then((response) => {
this.$vs.loading.close();
this.$vs.notify({
title: 'Success',
text: response.data.message,
iconPack: 'feather',
icon: 'icon-alert-circle',
color: 'success'
});
this.$store.dispatch("userManagement/upsertToState", { type: "Leads", data: response.data.leads });
this.newRecord.first_name = this.newRecord.last_name = this.newRecord.email_id = this.newRecord.phone_number = this.newRecord.location = this.newRecord.required_sub =''
}).catch((error) => {
console.log(error)
this.$vs.loading.close();
this.$vs.notify({
title: 'Error',
text: 'There was an error creating the Lead',
iconPack: 'feather',
icon: 'icon-alert-circle',
color: 'danger'
});
});
},

Filter data from database using v-for

Here I tried making a const data inside the script(vue js).
data() {
return {
event: [],
items: [
[id: '1', month:'January', date:'01'],
[id: '2', month:'February', date:'03'],
]}
}
filter(val) {
let items = this.items;
let filter = items.filter(el => el.month === val);
this.event = filter;
}
And had this in my v-for
<h1 v-for="(item, id) in event" v-bind:key="id"></h1>
<p>{{ items.month }}</p>
It loops the filtered items from the empty event array.
Since my const data is too many. I tried creating an API.
And this is how I get the data from database.
data() {
return {
Items: [],
}
}
getHoliday(){
getTest.getHoliday()
.then(response =>{
this.Items = response.data;
})
},
And loop through it using v-for
<h1 v-for="(Item, id) in Items" v-bind:key="id"></h1>
<p>{{ Item.month }}</p>
From here, I only know how to call the specific data through mustache. I can't do the filter that I use when using const data.
If I understand the question correctly, you can filter data from backend via computed properties.
computed: {
filteredItems() {
return this.Items.filter((item) => {...});
},
},
in your template you can iterate over this new property
<h1 v-for="(Item, id) in filteredItems" v-bind:key="id">{{ Item.month }}</h1>

Vue filter in v-for

Hi I am pretty new to VueJS and have started working on a very simple API request. I have an object that looks like this:
posts: [
text: "String",
choices: {"1":"Yes","2":"No"}
]
Coming from angular, this seems very straightforward. I would just use a filter to convert choices to an object and loop over it. However, I ran into a problem. When I attempt to use the filter 'log' or 'json' in the v-for, they don't work.
<template>
<div>
<li v-for="(post,index) in posts | log">
<ul>
{{ post.text | log }}
{{ post.choices | json }}
<li v-for="(value,key) in post.choices | json">
{{value}} {{key}}
</li>
</ul>
</li>
</div>
</template>
<script>
import {HTTP} from './main';
export default {
filters: {
json: function (value) {
return JSON.parse(value)
},
log: function (value) {
console.log(value)
}
},
props: [
'apiKey'
],
data: () => ({
posts: [],
post: [],
errors: []
}),
created() {
HTTP.get('questions', { headers: { 'Api-Key': this.apiKey} })
.then(response => {
this.posts = response.data
})
.catch(e => {
this.errors.push(e)
})
}
}
</script>
Then no data shows up, however they work fine in the mustache template. Any thoughts on how I can accomplish this?
tl;dr
works:
{{ post.choices | json }}
does not work:
<li v-for="(value,key) in post.choices | json">
Any work around? I can't use computed properties because this is a "sub-object" of an array and computed properties don't work that way, unless I am mistaken?
You cannot add a filter to a v-for directive.
Just parse the data before setting the posts data property:
HTTP.get('questions', { headers: { 'Api-Key': this.apiKey} })
.then(response => {
let posts = response.data;
post.forEach(p => p.choices = JSON.parse(p.choices));
this.posts = posts;
})
I don't see why you need to use JSON.parse, since the choices key refers to a valid JS object. Unless you have made a mistake, and that the choices key refers to a string.
Anyway, if you want to parse post.choice into a valid JS object, you can simply pass it into a custom function which returns the parsed JSON to v-for, for example:
<li v-for="(value,key) in postChoicesJson(post.choice)">
{{value}} {{key}}
</li>
And then declare a method for that:
postChoicesJson: function(obj) {
return JSON.parse(obj);
}
Note: Your DOM is invalid, because <li> elements must be a direct child of a <ul> or an <ol> element.