Vue 3 Accessing Array Object - vue.js

I'm trying to generate passwords by reactively. I have an array object inside my instance and I can list this object with v-for. Also and I can generate random passwords with characters in a passArry. But I need to send chars in data to the passArray when the checkbox is checked. But I can't reach options.status What should I do?
<div class="form-check" v-for="options in options" :key="options.optionName">
<input type="checkbox" class="form-check-input" v-model="options.status">
export default {
data() {
return {
generate: 5,
result: '',
passArry : [],
options :[
{
optionName : 'Lowercase',
status : true,
chars : 'abcdefghijklmnopqrstuvwxyz',
},
{
optionName: 'Uppercase',
status: false,
chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
},
{
optionName: 'Numbers',
status: true,
chars: '1234567890',
},
{
optionName: 'Symbols',
status: false,
chars: '~!##$%^&*()_-+={[}]|:;<,>.?/'
},
]
}
},
watch:{
generate(){
this.result.length > 0 ? this.result = '' : this.result
let charLength = this.passArry.length;
for(let i = 0; i < this.generate; i++){
this.result += this.passArry[Math.floor(Math.random() * charLength )]
}
},

In you case you would reach it not with option.status but options[0].status. Note that it is options[Array{Object, Object, Object, Object }], so you need to point at the first element of your array.

You have an 's' too many:
options in options should be option in options and then using this singular option:
<div class="form-check" v-for="option in options" :key="option.optionName">
<input type="checkbox" class="form-check-input" v-model="option.status">
</div>

Related

Passing selected option to the button to perform an action using vuejs

I have a select element that contains some options elements built from an array.
Right now, when I select an option it immediately calls the function and produces the output but what I want is that once I select any option, and if that option's value is "students" then only it should run the function instantly.
When I click on the add button it does not work at all.
<form name="Form1" >
<b>Field Name</b> : <p>Student Council</p>
<b>Field Type:</b> <p>List of Links</p>
<b>Range:</b><br>
<select name="selectOption" id="listSelect" v-model="selected">
<option hidden value="">Select a list</option>
<option v-for="List in fieldlist" v-if="List.ListName != 'student_council'"> {{ List.ListName}}</option>
</select>
<button #click="add"> Save </button>
<br><br>
<b> Student_Council list:</b>
{{fieldlist[5].student_council}}</v-list-item>
</form>
<script>
var vm = new Vue({
el : '#new_list' , // id of the elemnt we ware working on to call it
data: {
selected : null,
fieldlist: [
{
ListName: 'students',
Students: [
{
StudentName: 'Yousef',
StudentAge: '24',
isStudent: true,
},
{
StudentName: 'Baqir',
StudentAge: '23',
isStudent: true,
},
]
},
{
ListName: 'departments',
departments: [],
},
{
ListName: 'department_with_most_students',
Department_With_Most_Students: [],
},
{
ListName: 'active_students',
active_students: [],
},
{
ListName: 'dean',
dean: [],
},
{
ListName: 'student_council',
student_council: [],
},
],
},
methods: { // functions
add: function(option){
if(this.selectOption.option.target.value=== "students"){
if(!this.fieldlist[5].student_council.includes(this.fieldlist[0].Students)){
this.fieldlist[5].student_council.push(this.fieldlist[0].Students);
}else{
this.fieldlist[5].student_council.length = 0;
return false;
}
}
},
}
I tried to call the select element to check its option, but this is also not working so far.
I'm expecting if I select the option "students" and click on the add button, it should pass the data inside the students array to the student_council array
I have read your question I think you have to deal with
this.selected
instead of
this.selectOption.option.target.value
in vuejs we don't need to deal with name of tag element we deal with v-model
please update me if i miss something

Can't reset checked radio value to defaut value ( Vue js)

By default, I use local pickup option, with value 1. When user changes to free delivery, there will be some condition: if zip codes are valid, then it will changed to free delivery, if not, alert message will be displayed and local pickup will be checked again. The problem is that, I can set a default delivery value to 1 if zipcode is not suitable. But radio displays checked option as 2.
<label v-for="(del, index) in delivery" :key="index">
<input type="radio" name="del" :value="del.value" v-model="defaultDelivery" #change="changeDelivery(del.value)">{{ del.label }}
</label>
export default {
data () {
return {
delivery: [
{value: 1, label: 'Local pickup'},
{value: 2, label: 'Free Delivery'}
],
accepted_zips: [
12345,
12346
],
defaultDelivery: 1,
zip_code: 78745
}
},
changeDelivery: function(val) {
if(val == 2 && !this.accepted_zips.includes(this.zip_code))
{
this.defaultDelivery = 1 //it should set 1 as checked again! But it is not aplied
alert('Sorry but currently we don't cover your area.')
}
},
Note that the apostrophe in "don't" is closing your string, and you didn't put your method in a methods section. Correcting for that, your code works fine for me.
new Vue({
el: '#app',
data() {
return {
delivery: [{
value: 1,
label: 'Local pickup'
},
{
value: 2,
label: 'Free Delivery'
}
],
accepted_zips: [
12345,
12346
],
defaultDelivery: 1,
zip_code: 78745
};
},
methods: {
changeDelivery(val) {
if (val == 2 && !this.accepted_zips.includes(+this.zip_code)) {
this.defaultDelivery = 1 //it should set 1 as checked again! But it is not aplied
alert('Sorry but currently we don\'t cover your area.')
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div>ZIP code <input v-model="zip_code"></div>
<label v-for="(del, index) in delivery" :key="index">
<input type="radio" name="del" :value="del.value" v-model="defaultDelivery" #change="changeDelivery(del.value)">{{ del.label }}
</label>
</div>

Checked item form Array 1, and pass checked item to Array 2, then hide checked item from Array 2 rendered list

First, please check this pen I found, the concept is similar to my question, ReactJS - Baby Name Inspiration. I hope to make it via Vue.js but sorry I don't know React.
The question I want to ask if the user click the list item from Array 1, I named Array 1 as animals, the structure will show below. Then, it will pass the clicked item to Array 2, Array 2 as wished_pets_list. If for example {displayName: "Kitty", value: "cat"} clicked from animals list, animals & wished_pets_list also stored this object. When the same object in two arrays, the render of animals element will hide the object's output in HTML; it also renders to wished_pets_list as button. If click wished_pets_list's item button, it will remove the object data from wished_pets_list, and can access back on animals HTML list. And it can loop again.
The setting of data, default:
data: () => ({
animals: [
{displayName: "Kitty", value: "cat"},
{displayName: "Puppy", value: "dog"},
{displayName: "Chick", value: "bird"},
{displayName: "Fawn", value: "Deer"},
{displayName: "Joey", value: "Kangaroo"},
{displayName: "Piglet", value: "pig"},
{displayName: "Fry", value: "fish"},
{displayName: "Polliwog", value: "frog"}
],
wished_pets_list: [],
wished_pets_list_formatted: []
}),
Something I try on make it as HTML:
<div v-for="item in wished_pets_list">
<span #click="removeSelected(item.value)">{{item.displayName}}</span>
</div>
<div class="dropdown-list-container">
<div class="dropdown-list" v-for="(item, index) in animals">
<label :for="'givenID' + item.index" #click="pushSelect(item.value)">{{index}}{{item.displayName}}</label>
<input type="checkbox" v-model="wished_pets_list" :value="{'displayName': item.displayName, 'value': item.value}" :id="givenID' + item.index">
</div>
</div>
<!-- a hidden text field to submit the formatted as value only -->
<input type="text" v-model="wished_pets_list_formatted" name="anyName" v-show>
Two methods I think it should use:
methods: {
removeSelected(value){
this.wished_pets_list_formatted.push(value);
},
pushSelect(value){
this.wished_pets_list_formatted.splice(value);
}
},
Thanks, if you can, please make a similar codepen or jsfiddle.
Below is a implementation of the example codepen in Vue(didn't included the search part because I think it's irelevant in this case).
The template:
<div id="app">
<div data-reactroot="">
<main>
<div class="favourites">
<h4>Your Shortlist</h4>
<ul>
<li class="girl" v-for="(animal, index) in wished_pets_list" #click="removeFromList(index)">{{animal.displayName}}</li>
</ul>
<hr>
</div>
<ul>
<li v-for="(animal, index) in animals" :key="animal.value" class="boy" #click="addToList(index)">{{animal.displayName}}</li>
</ul>
</main>
</div>
</div>
The javascript part:
var vm = new Vue({
el: "#app",
data () {
return {
animals: [
{displayName: "Kitty", value: "cat"},
{displayName: "Puppy", value: "dog"},
{displayName: "Chick", value: "bird"},
{displayName: "Fawn", value: "Deer"},
{displayName: "Joey", value: "Kangaroo"},
{displayName: "Piglet", value: "pig"},
{displayName: "Fry", value: "fish"},
{displayName: "Polliwog", value: "frog"}
],
wished_pets_list: [],
wished_pets_list_formatted: []
}
},
methods: {
addToList(index) {
this.wished_pets_list.push(this.animals[index])
this.animals.splice(index, 1)
},
removeFromList(index) {
this.animals.push(this.wished_pets_list[index])
this.wished_pets_list.splice(index, 1)
}
}
});
For the CSS you can use the one from the codepen example.
Codepen fork
Base on #Allkin's answer, and my addition requirement, I tried to make such like Allkin's answer with an ordered list.
The template:
<div id="app">
<div>
<div class="favourites">
<h4>Your Shortlist</h4>
<ul>
<li class="girl" v-for="(animal, index) in wished_pets_list" #click="removeFromList(index, animal.value, animal.id)">{{animal.displayName}}</li>
</ul>
<hr>
</div>
<ul>
<li v-for="(animal, index) in animals" :key="animal.value" class="boy" #click="addToList(index, animal.value, animal.id)" v-show="!animal.checked">{{animal.displayName}}</li>
</ul>
<span>wished_pets_list_formatted:</span>
<div>{{wished_pets_list_formatted}}</div><br><br>
<span>animals:</span>
<div>{{animals}}</div>
</div>
</div>
js:
var vm = new Vue({
el: "#app",
data() {
return {
org_animal_list: [
{ displayName: "Kitty", value: "cat" },
{ displayName: "Puppy", value: "dog" },
{ displayName: "Chick", value: "bird" },
{ displayName: "Fawn", value: "Deer" },
{ displayName: "Joey", value: "Kangaroo" },
{ displayName: "Piglet", value: "pig" },
{ displayName: "Fry", value: "fish" },
{ displayName: "Polliwog", value: "frog" }
],
animals: null,
wished_pets_list: [],
wished_pets_list_formatted: []
};
},
methods: {
addToList(index, value, id) {
console.log("added: " + value);
this.wished_pets_list.push(this.animals[index]);
this.wished_pets_list_formatted.push(value);
this.animals[index].checked = !this.animals[index].checked;
},
removeFromList(index, value, id) {
var self = this;
this.wished_pets_list.splice(index, 1);
this.wished_pets_list_formatted.forEach(function(item, index) {
if (item == value) {
self.wished_pets_list_formatted.splice(index, 1);
}
});
for (var i = 0; i < this.animals.length; i++) {
if (self.animals[i].id == id) {
self.animals[i].checked = !self.animals[i].checked;
}
}
}
},
beforeMount: function() {
this.animals = this.org_animal_list;
for (var i = 0; i < this.animals.length; i++) {
this.$set(this.animals[i], "checked", false);
this.$set(this.animals[i], "id", i);
}
}
});
I added an original list first, then it will clone before Vue mount. This action allows the developer can use back the original data for other use.
For the full example, please check on codepen

How can I make a reusable "CheckAll" checkbox solution in Vue2

I am trying to create a reusable "Check All" solution for displaying a list of objects retrieved from an API.
I really like the get/set methods of computed properties that I use in this example here, https://codepen.io/anon/pen/aLeLOZ but I find that rewriting the same function over and over again and maintaining a seperate checkbox state list is tedious.
index.html
<div id="app">
<input type="checkbox" v-model="selectAll1"> Check All
<div v-for="person in list1">
<input type="checkbox" v-model="checkbox" :value="person.id">
<span>{{ person.name }}</span>
</div>
<hr/>
<input type="checkbox" v-model="selectAll2"> Check All
<div v-for="person in list2">
<input type="checkbox" v-model="checkbox2" :value="person.id">
<span>{{ person.name }}</span>
</div>
</div>
main.js
new Vue({
el: '#app',
data () {
return {
list1: [
{ id: 1, name: 'Jenna1'},
{ id: 2, name: 'Jenna2'},
{ id: 3, name: 'Jenna3'},
{ id: 4, name: 'Jenna4'}
],
list2: [
{ id: 1, name: 'Mary1'},
{ id: 2, name: 'Mary2'},
{ id: 3, name: 'Mary3'},
{ id: 4, name: 'Mary4'}
],
checkbox: [],
checkbox2: []
}
},
computed: {
selectAll1: {
get: function () {
return this.list1 ? this.checkbox.length === this.list1.length : false
},
set: function (value) {
let selected = []
if (value) {
this.list1.forEach(function (bf) {
selected.push(bf.id)
})
}
this.checkbox = selected
}
},
selectAll2: {
get: function () {
return this.list2 ? this.checkbox2.length === this.list2.length : false
},
set: function (value) {
let selected = []
if (value) {
this.list2.forEach(function (bf) {
selected.push(bf.id)
})
}
this.checkbox2 = selected
}
},
}
});
How can I make a resuable selectAll() function that will work in this example that can be included as often as needed?
Is it possible to make a class that can maintain the check box state for each list and still function as a computed property to make use of the v-model directive?
It's not the same at all, but a method based solution would be
methods: {
selectUs: function(){
if (this.checkbox.length <= this.list1.length) {
this.checkbox = Array.from(Array(this.list1.length + 1).keys())
} else {
this.checkbox = []
}
}
}
with #click="selectUs" instead of v-model="selectAll1"
(you could keep the get part of your computed properties to keep track of whether all are selected, and then use if (selectAll1) { etc } in the method)

How to delete a dynamically generated form based on the click of the delete button with respect to its ID in vuejs2

I am creating an application using Quasar and VueJS. I am able to generate a dynamic form on click of the add button, but not able to delete any of the newly generated form based on the click of the delete button.Find the code below:
<template>
<div v-for="h in htmlList">
<div v-for="r in h" >
<div v-html="r" v-on:click="useRemoveFromProject(1)" v-bind:id="r.id">
</div>
</div>
</div>
</template>
<script>
/*
* Root component
*/
import Vue from 'vue'
export default {
name: 'q-app',
data () {
return {
flag: 0,
htmlList: [],
select: 'fb',
select1: 'fb1',
multipleSelect: ['goog', 'twtr'],
usersInProject: [],
selectOptions: [
{
label: 'Google',
value: 'goog'
},
{
label: 'Select',
value: 'fb'
},
{
label: 'Twitter',
value: 'twtr'
},
{
label: 'Apple Inc.',
value: 'appl'
},
{
label: 'Oracle',
value: 'ora'
}
],
selectOptions1: [
{
label: 'Integer',
value: 'goog1'
},
{
label: 'Float',
value: 'fb1'
},
{
label: 'String',
value: 'twtr1'
}
]
}
},
methods: {
useRemoveFromProject: function (id) {
console.log('hi....')
Vue.delete(this.htmlList, id)
},
identifyMe: function (event) {
alert('hi - ' + event.target.id)
},
process: function () {
this.flag += 1
let temp = []
temp.push('<div class="card" id="a_' + this.flag + '"> <div class="card-content content-center "> <large id="l4">Expression LHS:</large> <input><br> <large id="l5">Operators:</large> <q-select type="radio" v-model="this.select" :options="this.selectOptions"></q-select><br><large id="l4">Expression RHS:</large> <input><br><large id="l5">Data type:</large> <q-select type="radio" v-model="select1" :options="selectOptions1"></q-select><br></div><button class="cordova-hide circular red " style="margin-bottom:5px; margin-right:30px;" v-on:click="userRemoveFromProject(i)"><i>delete</i></button><input value="click" type="button"> </div>')
let ids = ['a_' + this.flag]
console.log(ids)
this.htmlList.push(temp)
}
}
}
</script>
After looking to your code i noticed that you have some errors:
Call function useRemoveFromProject without the 'r' of 'user'
Call userRemoveFromProject when clicking on the element and not only the delete button
Call userRemoveFromProject(i) with a 'i' variable, but what is 'i' ?
Why using a double v-for? The first level is enough.
I propose to you a working example on a fiddle. Please let me know if it's useful for you (and mark it as resolve if it's the case).
EDIT: for Vue.js 2 https://jsfiddle.net/86216oko/