I'm using Horsey plugin to create an autocomplete for my text input. I'm using the key/value pairs (3rd example here) and I want to POST the key value (id in my app), not the text value of my search.
horsey(document.querySelector('#search_field'), {
source: [{ list: [
{ value: 'banana', text: 'Bananas from Amazon Rainforest' },
{ value: 'apple', text: 'Red apples from New Zealand' },
{ value: 'orange', text: 'Oranges from Moscow' },
{ value: 'lemon', text: 'Juicy lemons from the rich Amalfitan Coast' }
]}],
getText: 'text',
getValue: 'value'
});
So I understand I have to call getValue function from somewhere but I'm not sure how.
You can use predictNextSearch(info) that runs when a tag is inserted.
horsey(document.querySelector('#search_field'), {
source: [{ list: [
{ value: 'banana', text: 'Bananas from Amazon Rainforest' },
{ value: 'apple', text: 'Red apples from New Zealand' },
{ value: 'orange', text: 'Oranges from Moscow' },
{ value: 'lemon', text: 'Juicy lemons from the rich Amalfitan Coast' }
]}],
getText: 'text',
getValue: 'value',
predictNextSearch(info) {
//get the suggestion selected by the user
console.log(info.selection.value);
}
});
Hope this help!
Related
I have an object with few items and I want to update the values of one property options from another object.
Object 1 :
structure = [
{
id: 'name',
label: 'Name',
filterType: 'text',
filterOn: 'contains'
},
{
id: 'address',
label: 'Address',
filterType: 'text',
filterOn: 'contains'
},
{
id: 'phone',
label: 'Phone',
filterType: 'select',
filterOn: 'contains',
options: [{ label: 'abc', value: 'abc' },
{ label: 'xyz', value: 'xyz' },
{ label: 'mno', value: 'mno' }]
}
];
if the id is phone then I want to get the values from the object 2 phoneList and assign it to the options instead of hard coding it.
options: [{ label: 'abc', value: 'abc' },
{ label: 'xyz', value: 'xyz' },
{ label: 'mno', value: 'mno' }]
}
];
object 2 is
this.props.phoneList = [{name: 'aaa', age: 11},{name : 'bbb' , age : 12}, and so on
]
label and values will be this.props.phoneList[i].name
how to loop over this and get the latest values from the other object
First use filter to identify the object with id phone. Then use map to transform this.probs.phoneList in the desired format and assign to options.
structure.filter (x => x.id == 'phone')[0].options = this.probs.phoneList.map (x => ({label: x.name, value: x.name}));
I am using this react-select: https://github.com/JedWatson/react-select
The format for options data that they require is:
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry'},
{ value: 'vanilla', label: 'Vanilla' }
];
My array is set up differently as follows:
const columns = [
{ name: 'OrderNumber', title: 'Order Number' },
{ name: 'strawberry', title: 'Strawberry' },
{ name: 'vanilla', title: 'Vanilla' }
]
I am not able to change my array. If try to use name or value in my option items, I encounter issues using them with select-react. If I change my name to value, the select options are populating, however I don't want to do that.
Can anyone teach me how can I change my array's name to value?
You could use the .map() function to make the data in columns suitable for use with react-select.
The .map() function is available on the Array type. It creates a new array from the array you call it on, and allows you to provide a function that transforms/changes each item as it is copied from the original array.
You can make use of it as follows:
const columns = [
{ name: 'OrderNumber', title: 'Order Number' },
{ name: 'strawberry', title: 'Strawberry' },
{ name: 'vanilla', title: 'Vanilla' }
]
const options = columns.map(function(row) {
// This function defines the "mapping behaviour". name and title
// data from each "row" from your columns array is mapped to a
// corresponding item in the new "options" array
return { value : row.name, label : row.title }
})
/*
options will now contain this:
[
{ value: 'OrderNumber', label: 'Order Number' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' }
];
*/
For more information, see the MDN documentation for .map()
If you just want to rename the name property to value you can use a map and destruct the name property as value and pick the rest.
const columns = [
{ name: 'OrderNumber', title: 'Order Number' },
{ name: 'strawberry', title: 'Strawberry' },
{ name: 'vanilla', title: 'Vanilla' }
];
const newColumns = columns.map( item => {
const { name: value, ...rest } = item;
return { value, ...rest }
}
);
console.log( newColumns );
But, I suspect that you would want this since react-select doesn't work (as far as I see) with title. It waits for a label prop I guess. If this is so, go with and change all the properties as #Dacre Denny suggested. I like arrow functions :) So:
const newColumns = columns.map( item =>
( { value: item.name, label: item.title } )
);
Use destructuring with renaming property will simplify.
const options = [
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" },
];
const columns = options.map(({ value: name, label: title }) => ({
name,
title,
}));
console.log(columns);
I'm creating a TinyMCE Plugin for Wordpress. It has a textbox and a listbox field, both staying in a modal window.
Code below:
(function () {
tinymce.create('tinymce.plugins.windowdata', {
init : function(ed, url) {
ed.addButton('showModal', {
title: 'Show Modal',
image: url + '/img/button.png',
onclick: function () {
ed.windowManager.open({
title: 'Minestra',
body: [
{type: 'textbox', name: 'Field', label: 'Number', value: '', tooltip: 'Tooltip', maxLength: 3, classes: 'i1n'}, //textbox
{type: 'listbox', label: 'Listbox', classes: 'i1lb', values: [
{text: '', value: ''},
{text: 'Number', value: 'lone_number'},
{text: 'Bar', value: 'bar'},
]}, //listbox
],
onsubmit: function () {
var n1 = document.getElementsByClassName('mce-i1n')[0].value; //textbox value
var t1 = document.getElementsByClassName('mce-i1lb')[0].getElementsByTagName('button')[0].getElementsByClassName('mce-txt')[0].innerHTML; //listbox value
ed.execCommand('mceInsertContent', 0, n1+' is of type '+t1) //write contents
}
})
}
});
}
)
My question is about how to get the field values. What i did works very well with the textbox (the n1 var inside the onsubmit() method), but the listbox gets the same text that is shown to TinyMCE user (the text var in each listbox item).
What i want is a way to get the value instead; plus, i suppose i didn't get the right way to do it, not even with textbox. Anyone can help me? Thank you.
Better way to generate content is:
onsubmit: function (e) {
// Insert content when the window form is submitted
e.insertContent('Textbox content: ' + e.data.Field);
e.insertContent('Listbox content: ' + e.data.Listbox)
}
I solved by my own: i had to give a name to all of my fields:
{type: 'textbox', name: 'Field', label: 'Number', value: '', tooltip: 'Tooltip', maxLength: 3, classes: 'i1n'}, //textbox
{type: 'listbox', name: 'Listbox', label: 'Listbox', classes: 'i1lb', values: [
{text: '', value: ''},
{text: 'Number', value: 'lone_number'},
{text: 'Bar', value: 'bar'},
]
At this point, to generate my content i got values this way:
onsubmit: function (e) {
e.data.Field;
e.data.Listbox;
}
and used this to write in TinyMCE textarea. To get values back i had to modify textbox field this way:
{type: 'textbox', name: 'Field', label: 'Number', value: '', tooltip: 'Tooltip', maxLength: 3, classes: 'i1n', value: ed.selection.getContent()}
Similarly with listbox
I have below code-
$(function() {
var fruits = [
{ value: 'Apple',id: '123', data: 'Apple' },
{ value: 'Pear', id: '543', data: 'Pear' },
{ value: 'Carrot', id: '123', data: 'Carrot' },
{ value: 'Cherry', id: '234', data: 'Cherry' },
{ value: 'Banana', id: '543', data: 'Banana' },
{ value: 'Radish', id: '3423', data: 'Radish' }
];
$("#autocomplete").autocomplete({
lookup: fruits,
onSelect: function (suggestion) {
alert('You selected: ' + suggestion.value + ', ' + suggestion.data);
},
});
});
I want to do search based on 'value' and 'id' both. There is lookupFilter function but i dont know how to use it. Here is original script - https://www.devbridge.com/sourcery/components/jquery-autocomplete/
and Here is something similer question - jQuery autocomplete (devbridge) search from beginning
Help please!
lookupFilter: function (suggestion, query, queryLowerCase) {} filter function for local lookups. By default it does partial string match (case insensitive).
Code:
var fruits = [{value: 'Apple',id: '123',data: 'Apple'}, {value: 'Pear',id: '543',data: 'Pear'}, {value: 'Carrot',id: '123',data: 'Carrot'}, {value: 'Cherry',id: '234',data: 'Cherry'}, {value: 'Banana',id: '543',data: 'Banana'}, {value: 'Radish',id: '3423',data: 'Radish'}];
$('#autocomplete').autocomplete({
lookup: fruits,
onSelect: function(suggestion) {
console.log('You selected: ' + suggestion.value + ', ' + suggestion.data);
},
lookupFilter: function(suggestion, query, queryLowerCase) {
var id = suggestion.id,
value = suggestion.value.toLowerCase();
return id.indexOf(query) === 0 || value.indexOf(queryLowerCase) === 0;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.devbridge-autocomplete/1.2.26/jquery.autocomplete.min.js"></script>
<input type="text" name="fruit" id="autocomplete"/>
There are 2 problems with the previous answers I'd like to correct.
Yosvel's solution only returns Strings starting exaclty with the query. Meaning, searching for "App" returns "Apple", but searching for "ple", doesn't return "Apple", which should be the default behaviour of devbridge-autocomplete we want to keep (if not desired otherwise).
vijayP's answer doesn't return, what we are searching. The less-than-oprator < has to be turned around to a greater-than-operator >, because wa want to return items where .indexOf(query) returned a value greater than -1, meaning the query has been found somewehere in either id, or value.
Thank you for helping me! Here's the correct solution:
var fruits = [
{ value: 'Apple',id: '123', data: 'Apple' },
{ value: 'Pear', id: '543', data: 'Pear' },
{ value: 'Carrot', id: '123', data: 'Carrot' },
{ value: 'Cherry', id: '234', data: 'Cherry' },
{ value: 'Banana', id: '543', data: 'Banana' },
{ value: 'Radish', id: '3423', data: 'Radish' }
];
$("#autocomplete").autocomplete({
lookup: fruits,
onSelect: function (suggestion) {
alert('You selected: ' + suggestion.value + ', ' + suggestion.data);
},
lookupFilter(suggestion, query, queryLowerCase) {
return suggestion.value.toLowerCase().indexOf(queryLowerCase) > -1 || suggestion.id.indexOf(query) > -1; //checking with both id as well as value
}
});
});
Can you try with below code:
$(function() {
var fruits = [
{ value: 'Apple',id: '123', data: 'Apple' },
{ value: 'Pear', id: '543', data: 'Pear' },
{ value: 'Carrot', id: '123', data: 'Carrot' },
{ value: 'Cherry', id: '234', data: 'Cherry' },
{ value: 'Banana', id: '543', data: 'Banana' },
{ value: 'Radish', id: '3423', data: 'Radish' }
];
$("#autocomplete").autocomplete({
lookup: fruits,
onSelect: function (suggestion) {
alert('You selected: ' + suggestion.value + ', ' + suggestion.data);
},
lookupFilter: function (suggestion, query, queryLowerCase) {
return suggestion.value.toLowerCase().indexOf(queryLowerCase) < -1 || suggestion.id.toLowerCase().indexOf(queryLowerCase) < -1; //checking with both id as well as value
}
});
});
Note: I couldn't able to test this code but i believe it should work for you.
Using lodash, I need to convert the following array:
[{
text: 'apple',
type: 'fruit'
}, {
text: 'pear',
type: 'fruit',
}, {
text: 'potato',
type: 'vegetable'
}, {
text: 'water',
type: 'beverage'
}]
Into the following format:
[{
text: 'fruit',
children: [{
text: 'apple',
type: 'fruit'
}, {
text: 'pear',
type: 'fruit'
}]
}, {
text: 'vegetable',
children: [{
text: 'potato',
type: 'vegetable'
}]
}, {
text: 'beverage',
children: [{
text: 'water',
type: 'beverage'
}]
}]
I've attempted to chain lodash methods like groupBy and transform, but am having a hard time getting to the resulting format I require.
Here's a skeleton of what direction I was heading:
_(arr).groupBy('type').transform(function(result, obj, type) {
return result.push({
name: type,
children: obj
});
}).value();
The issue I'm running into is groupBy turns my array into an Object, so I can no longer simply push onto an Array. Being relatively knew with lodash (around 4 or 5 months of experience), I wanted to see if others have already tackled such a requirement.
Use _.reduce() instead of transform, because it lets you state the end product format:
var arr = [{
text: 'apple',
type: 'fruit'
}, {
text: 'pear',
type: 'fruit',
}, {
text: 'potato',
type: 'vegetable'
}, {
text: 'water',
type: 'beverage'
}];
var results = _(arr)
.groupBy('type')
.reduce(function(array, children, key) {
array.push({
text: key,
children: children
});
return array;
}, []);
console.log(results);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>