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'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>
I am using dgrid 0.4.0 (latest) and dstore 1.1.0. Now I have a filtering on my dgrid like
myDgrid.set('collection', myStore.filter(new myStore.Filter({includeInUI: true}).or( {fruit: /apple|banana|orange/i}, {forceSell: true} )) );
myStore has 20 rows in which forceSell is not true for any row. fruit field has different values in it but few rows meet the above condition. All of the rows have 'includeInUI' set to true. I expect only the rows that are apple or banana or orange should be displayed but when I apply above filter all 20 rows get displayed.
Is the logical OR is not functioning? Or Am I doing something wrong? Also I add rows to the grid when I receive data from web socket. (using dgrid.put).
I would appreciate any help. Thanks!.
IncludeInUI was already set in my code. So the following statement works.
myDgrid.set('collection', myStore.filter(new myStore.Filter().or(new myStore.Filter().eq('fruit','apple'), new myStore.Filter().eq('forceSell', true))));
Note: looks like RegExp is not accepted in Filter operators. So the multiple values case may go
grid.set('collection', store.filter(new store.Filter().or(new store.Filter().in('fruit', ['apple', 'grape']),
new store.Filter().eq('forceSell', true))));
complete code is:
<head>
<meta charset="utf-8">
<title>Test Simple Grid Creation</title>
<meta name="viewport" content="width=570">
<style>
#import "dojo/dojo/resources/dojo.css";
#import "dojo/dijit/themes/claro/claro.css";
.heading {
font-weight: bold;
padding-bottom: 0.25em;
}
.dgrid {
margin: 10px;
}
/* add styles to size this grid appropriately */
#grid {
height: 20em;
}
#grid .field-order {
width: 7%;
}
#grid .field-name {
width: 18%;
}
</style>
<script src="dojo/dojo/dojo.js"
data-dojo-config="async: true"></script>
<script>
var columns = {
id: "ID",
fruit: "Fruit",
includeInUI: "includeInUI",
forceSell: "forceSell"
};
require(["dgrid/OnDemandGrid", "dstore/Memory", "dojo/domReady!"], function(Grid, Memory){
var data1 = [
{id: 1, fruit:"apple", includeInUI:true, forceSell: false},
{id: 2, fruit:"banana", includeInUI:true, forceSell: false},
{id: 3, fruit:"grape", includeInUI:true, forceSell: false},
{id: 4, fruit:"apple", includeInUI:true, forceSell: false},
{id: 5, fruit:"banana", includeInUI:true, forceSell: false},
{id: 6, fruit:"apple", includeInUI:false, forceSell: false},
{id: 7, fruit:"banana", includeInUI:true, forceSell: false},
{id: 8, fruit:"grape", includeInUI:true, forceSell: false},
{id: 9, fruit:"apple", includeInUI:true, forceSell: false},
{id: 10, fruit:"banana", includeInUI:true, forceSell: false}
];
var store = new Memory({data: data1});
window.grid = new Grid({
columns: columns,
collection: store.filter({includeInUI: true}),
idProperty: "id",
id: "myGrid"
}, "grid");
});
</script>
<script>
function filterData() {
require(["dgrid/Grid", "dijit/registry", "dojo/domReady!"], function(Grid, registry){
//var grid = registry.byId('myGrid');
console.log('filterData: ', grid);
var store = grid.collection;
grid.set('collection', store.filter(new store.Filter().or(new store.Filter().eq('fruit','apple'), new store.Filter().eq('forceSell', true))));
});
}
</script>
</head>
<body class="claro">
<h2>A basic grid rendered from an array</h2>
<div id="grid"></div>
<div>Buttons to test filter:
<button onClick="filterData();">Filter</button>
</div>
</body>
</html>
Hope this helps someone.
I read api doc and find individual column searching to filter data by column row, great but i just need add one dropdown filter by name on top (beside number filter)
Current setup (use tabletool and bootstrap)
$('table').DataTable({
'aLengthMenu': [[25, 50, 75, -1], [25, 50, 75, 'All']],
'iDisplayLength': 25,
'stateSave': true,
'oLanguage': {
'sLengthMenu': 'Show : _MENU_',
'sSearch': 'Search : _INPUT_',
},
'oTableTools': {
'sSwfPath': 'media/swf/copy_csv_xls_pdf.swf'
},
/*
'order': [[ 1, 'asc' ]],
'aoColumnDefs': [
{
'bSortable': false,
'aTargets': [ -1, 0 ]
}
]
*/
});
If you are using Datatables Version 1.10 and upwards you want to use the DOM option to position a div in the header where you want to add your filter and add your select to it.
var table;
$(document).ready(function () {
table = $('#example').dataTable({
"dom": "l<'#myFilter'>frtip"
});
var myFilter = '<select id="mySelect">'
+ '<option value="1">Searchval 1</option>'
+ '<option value="2">Searchval 2</option>'
+ '<option value="3">Searchval 3</option>'
+ '</select>';
$("#myFilter").html(myFilter);
table.fnDraw();
});
Then add a custom filter function.
$.fn.dataTable.ext.search.push(
function (settings, data) {
//your filter stuff belongs here
return true;
});
And redraw the table everytime you change your filter.
$("body").on("change", "#mySelect", function () {
table.fnDraw();
});
See this JSFiddle for an example of what more or less should fit your requirements.
That idea is implemented in this DataTables plug-in, you may check out working DEMO:
$(document).ready(function () {
//Source data definition
var tableData = [
{item: 'banana', category: 'fruit', color: 'yellow'},
{item: 'pear', category: 'fruit', color: 'green'},
{item: 'cabbage', category: 'vegie', color: 'green'},
{item: 'carrot', category: 'vegie', color: 'red'},
{item: 'apple', category: 'fruit', color: 'red'},
{item: 'kiwi', category: 'fruit', color: 'brown'}
];
//DataTable definition
window.dataTable = $('#mytable').DataTable({
sDom: 'tF',
data: tableData,
columns: [{
data: 'item',
title: 'Item'
}, {
data: 'category',
title: 'Category'
}, {
data: 'color',
title: 'Color'
}]
});
});
<!doctype html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.mfilter.tk/js/mfilter.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.mfilter.tk/css/mfilter.min.css">
</head>
<body>
<table id="mytable"></table>
</body>
</html>