ion-autocomplete not displaying results case-sensitive - ionic-framework

I am using ionic and using ion-autocomplete to display my list of items.
if i have my result array like this
var homeworksingle = [
{id: '1', name: 'Maths'},
{id: '2', name: 'English'},
{id: '3', name: 'Physics'}
];
<input ion-autocomplete type="text" readonly="readonly" class="ion-autocomplete" autocomplete="off" ng-model="model" item-value-key="id" item-view-value-key="name" items-method="getTestItems(query)" items-method-value-key="items" placeholder="Enter test query ..." items-clicked-method="itemsClicked(callback)" items-removed-method="itemsRemoved(callback)"/>
$scope.getTestItems = function (query) {
var homeworksingle = [
{id: '1', name: 'Maths'},
{id: '2', name: 'English'},
{id: '3', name: 'Physics'}
];
var returnValue = { items: [] };
homeworksingle.forEach(function(item){
if (item.name.indexOf(query) > -1 ){
returnValue.items.push(item);
}
else if (item.id.indexOf(query) > -1 ){
returnValue.items.push(item);
}
});
return returnValue;
};
and when i try to search my list nd input 'm', it returns no result but when i input 'M' it returns data.
How do i set it to also acknowledge or search when input is lowercase or uppercase.
Thanks

Related

How to create reactive search input field in Vue.js?

I want to build a seach input field that sorts an object array while typing, using vue 3 with script setup.
input field:
<input type="search" placeholder="Search" v-model="state.search">
script setup:
const state = reactive({
search: ''
})
const array = [
{id: 1, title: 'Valhalla', content: '123'},
{id: 2, title: 'Wurstopia', content: '456'},
{id: 3, title: 'Brandon', content: '789'}
]
const search = computed(() => {
// sort array reactively according to search (use title as sorting criteria)
const result = sort(array['title'], state.search)
})
Is using computed the right approach for this? How do I reactively sort the array for search input ~ title?
If making this reactive is a problem, I am also happy with an approach of just submitting the input and sorting the array afterwards.
Edit:
I've tried the approach of #AdriHM but it produces exactly the same unsorted array:
const state = reactive({
search: '',
array: [
{id: 1, title: 'Valhalla', content: '123'},
{id: 2, title: 'Wurstopia', content: '456'},
{id: 3, title: 'Brandon', content: '789'}
]
})
function mySort(searchKey){
let matchedKeys = [], notMatchedKeys = [];
for(let i = 0; i < state.array.length; i++) {
if (state.array[i]['title'].match(searchKey) ) {
matchedKeys.push(state.array[i])
} else{
notMatchedKeys.push(state.array[i])
}
}
}
console.log(mySort(state.search))
Output:
(3) [Proxy, Proxy, Proxy]
0: Proxy {id: 1, title: 'Valhalla', content: '123'}
1: Proxy {id: 2, title: 'Wurstopia', content: '456'}
2: Proxy {id: 3, title: 'Brandon', content: '789'}
length: 3
[[Prototype]]: Array(0)
If what you want to do is a sort you can do it like this:
<template>
<input type="search" placeholder="Search" v-model="state.search">
{{ state.array }}
</template>
<script lang="ts" setup>
import {reactive, watch} from "vue";
const state = reactive({
search: '',
array: [
{id: 1, title: 'Valhalla', content: '123'},
{id: 2, title: 'Wurstopia', content: '456'},
{id: 3, title: 'Brandon', content: '789'}
]
})
function mySort(searchKey: string){
let matchedKeys = [], notMatchedKeys = [];
for(let i = 0; i < state.array.length; i++) {
if (state.array[i]['title'].match(searchKey) ) {
matchedKeys.push(state.array[i])
} else{
notMatchedKeys.push(state.array[i])
}
}
return matchedKeys.concat(notMatchedKeys);
}
watch(() => state.search, () => {
// sort of filter
state.array = mySort(state.search)
})
</script>
It will only put at first position the element that match the query but you have the logic to make the array changing with watch.
If I understand correctly, the objective is to filter an array by a search term, and display the results sorted by title.
The sorting itself does not need to be reactive because the array is always sorted by title. The array can be sorted once, and then the sorted array can be filtered reactively in the computed prop.
Use Array.prototype.sort() to sort array[] by the title field.
In the computed prop, use Array.prototype.filter() to include only items whose title or content field contains state.search. filter() does not change the order of the results, so no additional sorting is needed.
<script setup>
import { reactive, computed } from 'vue'
const state = reactive({
search: '',
})
const array = [
{ id: 1, title: 'Valhalla', content: '123' },
{ id: 2, title: 'Wurstopia', content: '456' },
{ id: 3, title: 'Brandon', content: '789' },
]
1️⃣
array.sort((a, b) => a.title.localeCompare(b.title))
const results = computed(() => {
2️⃣
return array.filter(item => item.title.includes(state.search) || item.content.includes(state.search))
})
</script>
demo

vue - Bootstrap-vue: Select row (primary-key) based on an object with the same key values

how can I select each rows with the same values from a separate object?
<b-table
:items="CurrentObject"
:select-mode="selectMode"
ref="selectableTable"
selectable
#row-selected="onRowSelected"
primary-key="uniqueID"
>
CurrentObject:
[
{name: 'A', uniqueID: 123, text: 'lorem ipsum'},
{name: 'B', uniqueID: 456, text: 'lorem ipsum'},
{name: 'C', uniqueID: 789, text: 'lorem ipsum'},
]
Separate Object:
[
{uniqueID: 123},
{uniqueID: 456},
{uniqueID: 789},
]
Using JavaScript's array.findIndex() and VueBootstrap's selectRow() seem to do it.
Template:
<template>
<b-container>
<div>
<h1>Current Object</h1>
<b-table
:items="currentObject"
:select-mode="selectMode"
ref="selectableTable"
selectable
#row-selected="onRowSelected"
primary-key="uniqueID"
>
</b-table>
<h2>Separate Object</h2>
<div v-for='object in separateObject' #click='selectMyRow(object.uniqueID);'>{{ object.uniqueID }}</div>
</div>
</b-container>
</template>
Script:
<script lang="ts">
import { Vue } from 'vue-property-decorator';
export default class HelloWorld extends Vue {
selectMode = 'single';
currentObject = [
{name: 'A', uniqueID: 123, text: 'lorem ipsum'},
{name: 'B', uniqueID: 456, text: 'lorem ipsum'},
{name: 'C', uniqueID: 789, text: 'lorem ipsum'},
];
separateObject = [
{uniqueID: 123},
{uniqueID: 456},
{uniqueID: 789},
];
selectMyRow(uniqueID) {
const row = this.currentObject.findIndex(x => x.uniqueID === uniqueID);
this.$refs.selectableTable.selectRow(row);
}
onRowSelected() {
// do something else
}
}
</script>
Working example:
If instead, you need similar functionality using select-mode multi, use the following:
selectMode = 'multi';
...
selectMyRow(uniqueID) {
const row = this.currentObject.findIndex(x => x.uniqueID === uniqueID);
const table = this.$refs.selectableTable
if (table.isRowSelected(row)) {
table.unselectRow(row);
} else {
table.selectRow(row);
}
}
OK, I have the first solution for me.
I couldn't update the jsfiddle yet ...
I have 2 watch functions, each with a for loop
the first loop checks whether in separateArray
var TableStore = this.TableStore; // -> ARRAY NO OBJECT
for (var i = 0; i < TableStore.length; i++) {
const row = this.CurrentArray.findIndex(x => x.unID === TableStore[i]);
this.$refs.selectableTable.selectRow(row);
}
the second checks whether not.
(filter / includes -> CurrentArray - SeparateArray)

What is the best way to combine two immutable lists?

I have two lists and i'm trying to combine them to a new list so that the existing ids are updated and the new ones are added to list and after that sorted by the id. Is there a better or more efficient way to do this?
// Original list
const list = Immutable.List([
{ id: 1, name: 'List Item 1' },
{ id: 2, name: 'List Item 2' },
{ id: 3, name: 'List Item 3' },
]);
// One updated item and two new items
const newList = Immutable.List([
{ id: 2, name: 'Updated List Item 2' },
{ id: 4, name: 'New List Item 4' },
{ id: 5, name: 'New List Item 5' },
]);
// Get updated ids
const ids = newList.map((item) => item.id);
// Filter out updated ids from orignial list
const filteredList = list.filterNot(item => ids.includes(item.id));
// Concat and sort by id
const concatList = newList
.concat(filteredList)
.sortBy(item => item.id);
console.log(concatList.toJS());
/* Outputs as desired
[
{ id: 1, name: "List Item 1" },
{ id: 2, name: "Updated List Item 2" },
{ id: 3, name: "List Item 3" },
{ id: 4, name: "New List Item 4" },
{ id: 5, name: "New List Item 5" }
]
*/
This is how I would do it, using reduce and merge:
function reduceToMap(result, item) { return result.set(item.id, item) }
const list = Immutable.List([
{ id: 1, name: 'List Item 1' },
{ id: 2, name: 'List Item 2' },
{ id: 3, name: 'List Item 3' },
]).reduce(reduceToMap, Immutable.Map());
// One updated item and two new items
const newList = Immutable.List([
{ id: 2, name: 'Updated List Item 2' },
{ id: 4, name: 'New List Item 4' },
{ id: 5, name: 'New List Item 5' },
]).reduce(reduceToMap, Immutable.Map());
console.log(...list.merge(newList).values())
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.js"></script>

how do i get a w2ui grid cell value?

i want to get my "id" value of w2ui grid. The record came from a database
columns: [
{ field: 'id', caption: 'ID', size: '50px' },
{ field: 'name', caption: 'Name', size: '300px'},]
my function
onDblClick: function (event) {
var grid = this;
event.onComplete = function () {
var sel = grid.getSelection();
console.log('my id value ' + sel.id);
}
but nothing appear. i do it wrong?
grid.getSelection() returns an array of selected recids, see the documentation.
You should change your code as follows:
$(function() {
$('#grid').w2grid({
name: 'grid',
columns: [
{ field: 'id', caption: 'ID', size: '50px' },
{ field: 'name', caption: 'Name', size: '300px' }
],
records: [
{ recid: 1, id: '1', name: 'Name 1' },
{ recid: 2, id: '2', name: 'Name 2' }
],
onDblClick: function(event) {
var grid = this;
event.onComplete = function() {
var sel_rec_ids = grid.getSelection();
if (sel_rec_ids.length) {
var sel_record = grid.get(sel_rec_ids[0]);
console.log('selected ID:', sel_record.id, '/ selected Name:', sel_record.name);
} else {
console.log("Nothing selected!");
}
}
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://rawgit.com/vitmalina/w2ui/master/dist/w2ui.js"></script>
<link href="https://rawgit.com/vitmalina/w2ui/master/dist/w2ui.css" rel="stylesheet" />
<div id="grid" style="width: 100%; height: 150px;"></div>
Also let me quote something, that some else commented on one of your questions in 2013:
I see you've not accepted any answer to your questions. That kinda defeats the goal of Stack Overflow. It would be great if you could review all the questions you've asked, accept correct answers and give feedback on proposed solutions that don't work

MongoDb array intersection

Let's assume we have
post1.tags = [ '1', '2', '3' ];
post2.tags = [ '2', '4', '5' ];
post3.tags = [ '1', '3', '4' ];
post4.tags = [ '1', '3', '4', '5', '6' ];
I'm trying to find posts which are containing 2 or more of the given tags [ '1', '3', '5' ].
The result should be post1, post3 and post4. How can write a mongodb query to achieve this?
It sounds like there might be a better way to implement what you're trying to do, but without more information it's difficult to make high-level suggestions.
Here is a query that will get what you're looking for:
{
$or:
[
{
tags:
{
$all: ['1', '3']
}
},
{
tags:
{
$all: ['3', '5']
}
},
{
tags:
{
$all: ['1', '5']
}
}
]
}
You'll notice that it involves listing every combination of pairs of tags that you're searching for, so it won't scale well to larger queries.
Edit: Simplified the query by using $all instead of $and.
If you want to do this from the shell, you can use javascript. Create a javascropt file with the following code:
use test;
var initialArray = [1, 2, 3];
for (i = 0; i < initialArray.length; i++) {
for(j = initialArray.length-1; j>=i; j--) {
if(i!=j) {
var matchingArray = [initialArray[i].toString(), initialArray[j].toString()];
print("\nResults using array: " + matchingArray);
var result = db.posts.find({tags: {$all: matchingArray}});
while(result.hasNext()){
printjson(result.next());
}
}
}
}
And run the command
C:\> mongo < query.js
note: you can optimize it to get unique results.