Semantic React - Form.Select how to use custom array options - forms

the semantic react docs about From.Select is to give it a prop options that needs to have a specific array like that :
const options = [
{ key: 'm', text: 'Male', value: 'male' },
{ key: 'f', text: 'Female', value: 'female' },
]
and using it like that :
<Form.Field control={Select} label='Gender' options={options} placeholder='Gender' />
if i want to use other array with custom keys and values like that for example :
const options = [
{ date: 'somedate', title: 'sometitle', },
{ date: 'somedate', title: 'sometitle', },
]
i am getting an error about using wrong props
my question is how can i use my own array with this Select Component
thanks !

You can reformat you options before sending it to semantic component:
import { get, map } from 'lodash'
const reformatOptions = options =>
map(options, e => ({
key: get(e, 'date'),
value: get(e, 'date'),
text: get(e, 'title'), // (or whatever other format you wish to use)
}))
And then pass the options=reformatOptions(options) to your semantic component

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

How to make sanity io array select as multiselect?

I have a lot of tags, and I need to select a lot for each document. It is uncomfortable to click one by one every time. Also I see selected elements. How can I remake it into somefield like a multiselect? It could be even native. Or how to select all tags at once?
I am using array:
{
title: 'Language',
name: 'language',
type: 'array',
options: {
layout: 'grid'
},
of: [{
type: 'reference',
title: 'Lang',
to: {
type: 'settingLanguages'
}
}],
},
Dropdown example (Add field to schema):
{
title: 'Genre',
name: 'genre',
type: 'string',
options: {
list: [
{ title: 'Sci-Fi', value: 'sci-fi' },
{ title: 'Western', value: 'western' },
],
},
},
This is currently not possible out of the box with the default array component, but you should be able to create an input like this by building a custom input for it with the behaviour you want.
More on how to build custom inputs: https://www.sanity.io/docs/extending/custom-input-widgets

How to add placeholder with dynamic options in ckeditor

I am using the ckeditor plugin and i need to replace the content with dynamic loaded options using placeholder, i have config.extraPlugins = 'placeholder'; in config.js and ckeditor/plugins/placeholder/plugin.js as follows:
'use strict';
CKEDITOR.dialog.add( 'placeholder', function( editor ) {
var lang = editor.lang.placeholder,
generalLabel = editor.lang.common.generalTab,
validNameRegex = /^[^\[\]<>]+$/;
return {
title: lang.title,
minWidth: 300,
minHeight: 80,
contents: [
{
id: 'info',
label: generalLabel,
title: generalLabel,
elements: [
// Dialog window UI elements.
{
id: 'name',
type: 'text',
style: 'width: 100%;',
label: lang.name,
'default': '',
required: true,
validate: CKEDITOR.dialog.validate.regex( validNameRegex, lang.invalidName ),
setup: function( widget ) {
this.setValue( widget.data.name );
},
commit: function( widget ) {
widget.setData( 'name', this.getValue() );
}
}
]
}
]
};
} );
I found this post that helped me atleast add static elements to a placeholder of type "Dropdown", Not sure if [enter link description here][1]
https://zolson.wordpress.com/2011/04/19/ckeditor-placeholder-select/

TinyMCE API v4 windowManager.open - What widgets can I configure for the body option?

I would like to fill the body of a modal dialog with custom HTML, generated by Javascript.
The documentation for this method is mostly empty.
I have only found examples for
loading an external file or
adding a textbox.
Is there a documentation for the available types? More specifically, is there a type to add general markup to the body of a dialog from a Javascript variable?
After I beautified the minified version of tinymce, i found that these may be some of the body types for windowManager.open. I'm not sure how to use them all, as all this info was gathered through trial and fail. Since the documentation is really bad, no real info can be gathered. Also here's a link which includes some good info on checkbox.
https://wordpress.stackexchange.com/questions/172853/how-disable-checkbox-when-listbox-value-changes-in-tinymce
It took me an hour or so to check and test all so I really hope this will save you the trouble of doing it yourself.
LE: textbox params: textbox settings table
https://www.tiny.cloud/docs-4x/api/tinymce.ui/tinymce.ui.textbox/
LE2: you can try and browse all the tinymce.ui.* elements mentioned down and check if it has a settings table, I think it may be used as a valid parameter for body if they have it
LE3: this is the old documentation http://archive.tinymce.com/wiki.php/api4:index, since it's more useful than the new one it's the only documentation available now https://www.tinymce.com/docs/api/
{
type : 'listbox',
name : 'listbox',
label : 'listbox',
values : [
{ text: 'Test1', value: 'test1' },
{ text: 'Test2', value: 'test2' },
{ text: 'Test3', value: 'test3' }
],
value : 'test2' // Sets the default
},
{
type : 'combobox',
name : 'combobox',
label : 'combobox',
values : [
{ text: 'Test', value: 'test' },
{ text: 'Test2', value: 'test2' }
]
},
{
type : 'textbox',
name : 'textbox',
label : 'textbox',
tooltip: 'Some nice tooltip to use',
value : 'default value'
},
{
type : 'container',
name : 'container',
label : 'container',
html : '<h1>container<h1> is <i>ANY</i> html i guess...<br/><br/><pre>but needs some styling?!?</pre>'
},
{
type : 'tooltip',
name : 'tooltip',
label : 'tooltip ( you dont use it like this check textbox params )'
},
{
type : 'button',
name : 'button',
label : 'button ( i dont know the other params )',
text : 'My Button'
},
{
type : 'buttongroup',
name : 'buttongroup',
label : 'buttongroup ( i dont know the other params )',
items : [
{ text: 'Button 1', value: 'button1' },
{ text: 'Button 2', value: 'button2' }
]
},
{
type : 'checkbox',
name : 'checkbox',
label : 'checkbox ( it doesn`t seem to accept more than 1 )',
text : 'My Checkbox',
checked : true
},
{
type : 'colorbox',
name : 'colorbox',
label : 'colorbox ( i have no idea how it works )',
// text : '#fff',
values : [
{ text: 'White', value: '#fff' },
{ text: 'Black', value: '#000' }
]
},
{
type : 'panelbutton',
name : 'panelbutton',
label : 'panelbutton ( adds active state class to it,visible only on hover )',
text : 'My Panel Button'
},
{
type : 'colorbutton',
name : 'colorbutton',
label : 'colorbutton ( no idea... )',
// text : 'My colorbutton'
},
{
type : 'colorpicker',
name : 'colorpicker',
label : 'colorpicker'
},
{
type : 'radio',
name : 'radio',
label : 'radio ( defaults to checkbox, or i`m missing something )',
text : 'My Radio Button'
}
Googling for this question I found an answer:
editor.windowManager.open({
title: 'My dialog',
body: [{
type: 'container',
html: "Hello world!"
}]
});
I've found this way of specifying modal dialog body:
var dialogBody = '<p>Whatever you want here</p>';
editor.windowManager.open({
title: 'Dialog Title',
html: dialogBody,
buttons: [{
text: 'Do Action',
subtype: 'primary',
onclick: function() {
// TODO: handle primary button click
(this).parent().parent().close();
}
},
{
text: 'Close',
onclick: function() {
(this).parent().parent().close();
}
}]
});

How to get data from fieldset in Sencha Touch 2?

I hava a fieldset in Sencha Touch 2 as follows:
{
id:'contactForm',
xtype: 'fieldset',
title: 'Information',
items: [
{
xtype: 'textfield',
label: 'First Name',
placeHolder: 'Your First Name',
name:'firstName',
id:'firstName',
},
{
xtype: 'textfield',
label: 'Last Name',
placeHolder: 'Your Last Name',
name:'lastName'
},
{
xtype: 'emailfield',
label: 'Email',
placeHolder: 'email#example.com'
},
{
xtype: 'button',
height: 37,
style: 'margin-left:35%',
width: 100,
iconAlign: 'center',
text: 'Submit',
action:'ContactSubmit'
},
{
xtype: 'hiddenfield',
id: 'HNumberOfBedRoom',
value:'2'
},
{
xtype: 'hiddenfield',
id: 'HPetFriendlyId',
value:'2'
}
]
}
In my controller,
I have the following:
refs: {
contactForm: '#contactForm'
}
I can retrive the value by using
var frmItems=this.getContactForm().getItems();
console.log(frmItems.items[1]._value);
This works fine but i want to retrieve the values something like
frm.get('name/id of component')
is there any way to achieve this?
Use a Ext.form.Panel as your primary container.
example snippet
Ext.define('App.view.ContactForm',
{
extend : 'Ext.form.Panel',
xtype : 'contactform',
id : 'contactForm',
config : {
items : [
{
xtype : 'fieldset',
items : [
{
{
xtype: 'textfield',
label: 'First Name',
placeHolder: 'Your First Name',
name:'firstName',
},
]
}
});
in your controller
refs : { contactForm : '#contactForm' }
then in your function you can either do
this.getContactForm().getValues().firstName
(uses the name value of the field)
or
var vals = this.getContactForm().getValues();
vals.firstName;
Avoid using Ext.getCmp() or a flat Ext.get() at the top level if you absolutely can help it. If you're building custom controls you might have to make use of those, otherwise you're making things too hard on yourself.
You should be able to assign an id to your field, and then Ext.getCmp('-yourId-'); or Ext.get('-yourId-');
( http://docs.sencha.com/touch/2-0/#!/api/Ext.Component-cfg-id )
Dont struggle too much
first assign the id to that field and get the value using id thats it..
{
xtype: 'textfield',
id: 'username', // id
name: 'username',
placeHolder: '------UserName------',
},
Ext.getCmp('username').getValue(); // now get value using that id..
refs:[
{
ref:'contentForm',
// selector:'#contentForm'
contentForm:'#contentForm'
}
],
-
var form = Ext.getCmp('contentForm');
console.log(form.getValues());
Assign itemId: firstName to textfield
And in Controller, where you want to get the value, use this:
Ext.ComponentQuery.query('textfield[itemId=firstName]')[0].getData();