I'm trying to change the gameBoard array upon selection of a number, but I'm having trouble with passing the id of the cell to change the appropriate index. Specifically, I would like to take the id of the parent cell-empty, and use that to compare it to the gameBoard array and change it to the value inputted. I'm struggling right now with passing on the id.
<template>
<div>
<div class = "wrapper"> <div class= "list" v-for="(n,index) in gameAnswer">
<div v-bind:id= "index" class = "cell-empty" v-if= "randomNumber(index)">
<input type="text">
</div>
<div class = "cell" v-else> {{n}} </div>
</div>
<br>
<br>
<div class = "list" v-for="n in gameBoard"> {{n}} </div>
<br>
<br>
<div class = "list" v-for="n in gameAnswer"> {{n}} </div>
</div>
</div>
</template>
<script>
export default {
name: 'sudoku',
data: function(){
return{
gameAnswer: [4,3,5,2,6,9,7,8,1,6,8,2,5,7,1,4,9,3, 1,9,7,8,3,4,5,6,2, 8,2,6,1,9,5,3,4,7, 3,7,4,6,8,2,9,1,5,9,5,1,7,4,3,6,2,8,5,1,9,3,2,6,8,7,4, 2,4,8,9,5,7,1,3,6,7,6,3,4,1,8,2,5,9],
gameBoard: [4,3,5,2,6,9,7,8,1,6,8,2,5,7,1,4,9,3, 1,9,7,8,3,4,5,6,2, 8,2,6,1,9,5,3,4,7, 3,7,4,6,8,2,9,1,5,9,5,1,7,4,3,6,2,8,5,1,9,3,2,6,8,7,4, 2,4,8,9,5,7,1,3,6,7,6,3,4,1,8,2,5,9],
}
},
computed: {
}
},
methods:{
randomNumber: function(index){
// console.log(index);
var val = Math.floor(Math.random()*3);
if(val == 0){
this.gameBoard[index] = 0;
return true;
} else{
return false;
}
},
changeVal(index){
console.log(index);
}
},
};
</script>
Due to limitations in JavaScript, Vue cannot detect the following changes to an array:
When you directly set an item with the index, e.g. vm.items[indexOfItem] = newValue When you modify the length of the array, e.g. vm.items.length = newLength
For example:
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // is NOT reactive
vm.items.length = 2 // is NOT reactive
To overcome caveat 1, both of the following will accomplish the same as vm.items[indexOfItem] = newValue, but will also trigger state updates in the reactivity system:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
Source
https://v2.vuejs.org/v2/guide/list.html#Caveats
Example
I havent tested this but should work
<script>
export default {
name: 'sudoku',
data () {
return {
gameAnswer: [4, 3, 5, 2, 6, 9, 7, 8, 1, 6, 8, 2, 5, 7, 1, 4, 9, 3, 1, 9, 7, 8, 3, 4, 5, 6, 2, 8, 2, 6, 1, 9, 5, 3, 4, 7, 3, 7, 4, 6, 8, 2, 9, 1, 5, 9, 5, 1, 7, 4, 3, 6, 2, 8, 5, 1, 9, 3, 2, 6, 8, 7, 4, 2, 4, 8, 9, 5, 7, 1, 3, 6, 7, 6, 3, 4, 1, 8, 2, 5, 9],
gameBoard: [4, 3, 5, 2, 6, 9, 7, 8, 1, 6, 8, 2, 5, 7, 1, 4, 9, 3, 1, 9, 7, 8, 3, 4, 5, 6, 2, 8, 2, 6, 1, 9, 5, 3, 4, 7, 3, 7, 4, 6, 8, 2, 9, 1, 5, 9, 5, 1, 7, 4, 3, 6, 2, 8, 5, 1, 9, 3, 2, 6, 8, 7, 4, 2, 4, 8, 9, 5, 7, 1, 3, 6, 7, 6, 3, 4, 1, 8, 2, 5, 9]
}
},
methods: {
randomNumber (index) {
var val = Math.floor(Math.random() * 3)
if (val === 0) {
this.$set(this.gameBoard, index, 0)
return true
} else {
return false
}
},
changeVal (index, number) {
this.$set(this.gameBoard, index, number)
}
}
}
</script>
<template>
<div>
<div class="wrapper">
<div class="list" v-for="(number,index) in gameAnswer" :key="index">
<div v-bind:id="index" class="cell-empty" v-if="randomNumber(index)">
<input type="text" v-on:keyup="changeVal( index, number)">
</div>
<div class="cell" v-else>
{{number}}
</div>
</div>
<div class="list" v-for="(number, index) in gameBoard" :key="index">
{{number}}
</div>
<div class="list" v-for="(number, index) in gameAnswer" :key="index">
{{number}}
</div>
</div>
</div>
</template>
Related
I'm using Vue3.0 with element-plus.
I want to set an el-date-picker and make sure the startTime can not be earlier than tomorrow.
How to add a validation or date-options?
Here is my component:
<el-form-item label="choose date">
<el-date-picker
v-model="timeArray"
type="datetimerange"
start-placeholder="startTime"
end-placeholder="endTime"
:default-time="defaultTime"
>
</el-date-picker>
</el-form-item>
data() {
return {
defaultTime: [
new Date(2021, 1, 1, 12, 0, 0),
new Date(2021, 2, 1, 12, 0, 0)
],
}
}
Thanks for looking! I'm really appreciate.
Use de disabledDate method
<el-form-item label="choose date">
<el-date-picker
v-model="timeArray"
type="datetimerange"
start-placeholder="startTime"
end-placeholder="endTime"
:default-time="defaultTime"
:disabled-date="disabledDate"
>
</el-date-picker>
</el-form-item>
data() {
return {
defaultTime: [
new Date(2021, 1, 1, 12, 0, 0),
new Date(2021, 2, 1, 12, 0, 0)
],
disabledDate(time) {
return time.getTime() <= Date.now()
},
}
}
EDIT: I just noticed that the error is coming from the v-model on the first div which is not supported by vue. However, I still don't know how to solve this.
I'm trying to generate a list of file. Each file has a choice for a material. Based on the material choice, the choices of thicknesses should change and the selection should also be saved to my object.
I currently got this working, but I'm getting an error from vue that v-model is not support on this element type.
I got a fiddle of how I implemented this here: jsFiddle
How do I solve this error or is there a better way to implement this?
I'll also paste the code bellow for those who rather read it here.
<div id="app">
<div v-for="(file,i) in files" v-model="file.fileId = i">
<p>{{file.filename}}</p>
<select v-model="file.selectedMaterial">
<option disabled selected>Select material</option>
<optgroup v-for="(alloys, name) in materials" :label="name">
<option v-for="(thickness, alloy) in alloys" :value="[alloy, thickness]">{{alloy}}</option>
</optgroup>
</select>
<select v-model="file.selectedThickness">
<option disabled selected>Select thickness</option>
<option v-for="thickness in file.selectedMaterial[1]">{{thickness}}</option>
</select>
<br><br>
</div>
<p v-for="file in files">{{file}}</p>
</div>
var app = new Vue({
el: '#app',
data: {
files: [
{"filename": "a.dxf", "selectedMaterial":"","selectedThickness":"", "fileId":NaN},
{"filename": "b.dxf", "selectedMaterial":"","selectedThickness":"", "fileId":NaN},
],
materials: {
"Aluminium": {
"AW1050":[1, 1.5, 2, 2.5, 3],
"AW5754":[1, 1.5, 2, 3, 4, 5, 6],
"AW5083":[1, 1.5, 2, 3, 4, 5, 6]
},
"Stainless Steel": {
"304 / EN 1.4301": [0.5, 0.8, 1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10, 12],
"316 / EN 1.4404": [0.5, 0.8, 1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10, 12]
},
},
test:""
}
})
The problem is, you're using v-model on a div, which is not a form input, as stated in the docs:
You can use the v-model directive to create two-way data bindings on form input, textarea, and select elements.
First you then need to remove the v-model from the div.
Then you'll get an warning due to setting a selected value by default via HTML, so just remove the selected attribute from <option disabled selected>.
The below snippet has the changes that I've mentioned.
var app = new Vue({
el: '#app',
data: {
files: [
{"filename": "a.dxf", "selectedMaterial":"","selectedThickness":"", "fileId":NaN},
{"filename": "b.dxf", "selectedMaterial":"","selectedThickness":"", "fileId":NaN},
],
materials: {
"Aluminium": {
"AW1050":[1, 1.5, 2, 2.5, 3],
"AW5754":[1, 1.5, 2, 3, 4, 5, 6],
"AW5083":[1, 1.5, 2, 3, 4, 5, 6]
},
"Stainless Steel": {
"304 / EN 1.4301": [0.5, 0.8, 1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10, 12],
"316 / EN 1.4404": [0.5, 0.8, 1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10, 12]
},
},
test:""
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.1/vue.js"></script>
<div id="app">
<div v-for="(file,i) in files">
<p>{{file.filename}}</p>
<select v-model="file.selectedMaterial">
<option disabled>Select material</option>
<optgroup v-for="(alloys, name) in materials" :label="name">
<option v-for="(thickness, alloy) in alloys" :value="[alloy, thickness]">{{alloy}}</option>
</optgroup>
</select>
<select v-model="file.selectedThickness">
<option disabled>Select thickness</option>
<option v-for="thickness in file.selectedMaterial[1]">{{thickness}}</option>
</select>
<br><br>
</div>
<p v-for="file in files">{{file}}</p>
</div>
I was reading that I can use "SET" as a solution to remove duplicated values in an array. This works on a basic example, but what If I have more data in my array and also want this data to be found inside of my vue model as opposed to an external const, how do I make it work. I have 2 users that have the Job title dentist, it is supposed to bring back 2 unique values instead of all 3, what am I missing?
//const numbers = [2, 3, 4, 4, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 5, 32, 3, 4, 5]
const People =[{Name:"Adam", Age:"22",Job:"Dentist"},{Name:"Bill", Age:"32",Job:"Teacher"},{Name:"Peter", Age:"42",Job:"Dentist"}]
new Vue({
el: "#app",
data: {
numbers:[2, 3, 4, 4, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 5, 32, 3, 4, 5],
People:[{Name:"Adam", Age:"22",Job:"Dentist"},{Name:"Bill", Age:"32",Job:"Teacher"},{Name:"Peter", Age:"42",Job:"Dentist"}]
},
methods: {
toggle: function(){
alert("this");
console.log([new Set(People)]);
},
mounted:function(){
this.toggle();
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Todos:</h2>
<button v-on:click="toggle">
Click
</button>
</div>
Extract the Job property from each object and then apply Set, i.e. [...new Set(People.map(p => p.Job))]
const People =[{Name:"Adam", Age:"22",Job:"Dentist"},{Name:"Bill", Age:"32",Job:"Teacher"},{Name:"Peter", Age:"42",Job:"Dentist"}]
uniqueJobs = [...new Set(People.map(p => p.Job))]
console.log(uniqueJobs)
Demo with vue.js:
new Vue({
el: "#app",
data: {
numbers:[2, 3, 4, 4, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 5, 32, 3, 4, 5],
People:[{Name:"Adam", Age:"22",Job:"Dentist"},{Name:"Bill", Age:"32",Job:"Teacher"},{Name:"Peter", Age:"42",Job:"Dentist"}]
},
methods: {
toggle: function(){
console.log([...new Set(this.People.map(p => p.Job))]);
},
mounted:function(){
this.toggle();
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Todos:</h2>
<button v-on:click="toggle">
Click
</button>
</div>
I can’t figure out in this case how manipulate with v-model change amounts array.
With this code i generated inputs for each item and i want with this inputs change amounts for each item in array eg: if write first input 10 first item amounts array will be 10, 10, 10, 10, 10, 10
I tried to make dynamic v-model prop with index but its not worked.
here is my fiddle : http://jsfiddle.net/eywraw8t/532119/ can someone help me?
category: [{
id: 0,
sub: 'a1',
types: [{
id: 1,
value: "P A",
amounts: [20, 32, 20, 12, 12, 2]
},
{
id: 2,
value: "P B",
amounts: [0, 32, 20, 12, 12, 2]
},
{
id: 3,
value: "P C",
amounts: [30, 32, 20, 12, 12, 2]
},
{
id: 4,
value: "P D",
amounts: [50, 32, 12, 30, 12, 2]
}
]
}]
<div id="app">
<div v-for="item in category">
<h1>
{{item.sub}}
</h1>
<div v-for="type in item.types">
{{type.value}}
<input type="text" v-model="someModel">
<div>
<ul>
<li v-for="amount in type.amounts">{{amount}}</li>
</ul>
</div>
</div>
</div>
</div>
You never want to v-model a value that you have not defined.
In this case, you don't need to v-model anything, you just want to respond to change events and call a method to reset the amounts.
new Vue({
el: "#app",
data: {
category: [
{
id: 0,
sub: 'a1',
types: [{
id: 1,
value: "P A",
amounts: [20, 32, 20, 12, 12, 2]
},
{
id: 2,
value: "P B",
amounts: [0, 32, 20, 12, 12, 2]
},
{
id: 3,
value: "P C",
amounts: [30, 32, 20, 12, 12, 2]
},
{
id: 4,
value: "P D",
amounts: [50, 32, 12, 30, 12, 2]
}
]
},
{
id: 0,
sub: 'a2',
types: [{
id: 1,
value: "P A",
amounts: [20, 32, 20, 12, 12, 2]
},
{
id: 2,
value: "P B",
amounts: [0, 32, 20, 12, 12, 2]
},
{
id: 3,
value: "P C",
amounts: [30, 32, 20, 12, 12, 2]
},
{
id: 4,
value: "P D",
amounts: [50, 32, 12, 30, 12, 2]
}
]
}]
},
methods: {
toggle: function(todo){
todo.done = !todo.done
},
setAllAmounts(type, event) {
type.amounts = type.amounts.map((_) => event.target.value);
}
}
})
<script src="https://unpkg.com/vue#latest/dist/vue.js"></script>
<div id="app">
<div v-for="item in category">
<h1>
{{item.sub}}
</h1>
<div v-for="type in item.types">
{{type.value}}
<input type="text" #change="setAllAmounts(type, $event)">
<div>
<ul>
<li v-for="amount in type.amounts">{{amount}}</li>
</ul>
</div>
</div>
</div>
</div>
I have the following slider setup:
$("#experience-filter").ionRangeSlider({
values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, '15+'],
grid: true,
force_edges: true,
step: 5,
onFinish: function (data) {
$("#experience-filter").parent().find('.check input[type="checkbox"]').prop('checked',true);
}
});
I prefer not to have all the values in my grid. But have it like 0, 5, 15+. is this possible?
In your case, it would be much easier to try a different approach:
var $range = $(".js-range-slider");
var $result = $(".js-result");
function transform (n) {
if (n > 15) {
return "15+";
}
return n;
}
$range.ionRangeSlider({
type: "single",
min: 0,
max: 16,
grid: true,
grid_snap: true,
step: 5,
prettify: function (n) {
return transform(n);
}
});
<!-- include jQuery, and rangeslider -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.3.0/css/ion.rangeSlider.min.css" integrity="sha256-nv5vSBJAzPy+07+FvRvhV2UPpH87H/UnWMrA6nbEg7U=" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ion-rangeslider/2.3.0/js/ion.rangeSlider.min.js" integrity="sha256-eXdxIh/sjKTNi5WyC8cKHekwPywORiomyiMFyZsowWw=" crossorigin="anonymous"></script>
<div class="range-slider">
<input type="text" class="js-range-slider" value="" />
</div>