How can I have a multivalue global filter in react-table v7? - react-table

I have a search bar as a globalfilter but I want to know if in react-table v7 it is possible to have multivalue in it for example.
I want to search words and it search in all my columns not the exact string but each word in each column.
This is my search input
const TableSearchFilter = ({ preGlobalFilteredRows, globalFilter, setGlobalFilter }) => {
return (<Input
value={globalFilter || ""}
onKeyDown={(e) => {
if (e.keyCode ==13) {
e.preventDefault()
}
}}
onChange={(e) => {
setGlobalFilter(e.target.value)
}}
startAdornment={<i className="fas fa-search" style={{ marginRight:'10px' }}></i>}
/>)
}

Related

If the value in one dropdown changed, how to reload the values for the second dropdown? How to do Partial Reload in InertiaJs

Q: If the value in one dropdown changed, how to reload the values for the second dropdown?
When user change the category dropdown, then I want to show the subcategory in the dropdown
Frontend: VueJs (v3)
Server Side Rendering: IneratiaJs
Backend: Laravel (v9)
VueComponent
const props = defineProps({
errors: Object,
categories: Object,
subcategories: Object,
})
const form = useForm({
category_id: '',
subcategory_id: '',
name: '',
price: '',
discount: '',
image: 'sample',
description: ''
});
let getSubcategory = (event) => {
if(event.target.value !== "") {
Inertia.reload({
'category_id': event.target.value
},
{ only: ['subcategories'],
onSuccess: page => {
alert();
console.log('onSuccess');
console.log(props.categories);
console.log(props.subcategories);
console.log(page);
}
}
);
}
}
const submit = () => {
form.post(route('store.subcategory'), {
onFinish: () => form.reset(),
});
};
Vue Template
<template>
<Head title="Add Product" />
<BreezeAuthenticatedLayout>
<template #header>
<form #submit.prevent="submit">
<div class="mt-4">
<BreezeLabel for="category_id" value="Category Name" />
<select #change="getSubcategory" v-model="form.category_id" id="category_id" class="block mt-1 w-full">
<option value="">Select Category</option>
<option v-for="category in categories" :value="category.id">{{ category.name }}</option>
</select>
<div v-if="errors.category_id" class="text-red-400">
{{ errors.category_id }}
</div>
</div>
<div class="mt-4">
<BreezeLabel for="subcategory_id" value="Subcategory Name" />
<select v-model="form.subcategory_id" id="subcategory_id" class="block mt-1 w-full">
<option value="">Select Sategory</option>
<option v-for="subcategory in subcategories" :value="subcategory.id">{{ subcategory.name }}</option>
</select>
<div v-if="errors.subcategory_id" class="text-red-400">
{{ errors.subcategory_id }}
</div>
</div>
</form>
</BreezeAuthenticatedLayout>
</template>
Laravel Route: routes/web.php
Route::get('/create/product/{category_id?}', [ProductController::class, 'create'])->name('create.product'); //Form: Create Product
Product Controller: ProductController.php
public function create($category_id = null)
{
return Inertia::render('Product/Create', [
//I want Evaluated immediately on Page Load.
'categories' => $categories = Category::all(),
//Want Lazy load here.
'subcategories' => function(){
if(!empty($category_id)){
$category = Category::find($category_id);
$subcategories = $category->subcategories()->get();
}
},
]);
}
After fixing Create method in Product Controller and script setup it's working
public function create($category_id = null)
{
return Inertia::render('Product/Create', [
// ALWAYS included on first visit - OPTIONALLY included on partial reloads - ALWAYS evaluated
'categories' => Category::has('subcategories')->get(),
// NEVER included on first visit - OPTIONALLY included on partial reloads - ONLY evaluated when needed
'subcategories' => Inertia::lazy(fn () =>
Subcategory::with('category')->where('category_id', '=', $category_id)->get()
),
]);
}
Vue SCRIPT: I was sending wrong parameters. Then I saw correct way of partial relaod on official site
let getSubcategory = (event) => {
if(event.target.value !== "") {
Inertia.visit(
route('create.product', {
category_id: event.target.value
}),{
only: ['subcategories'],
preserveState: true,
preserveScroll: true,
}
);
}
}

How to change material-ui elements style(color/fill) dynamically while creating them in map function

I am trying to change the style (colors) of elements in list items as they are created from a map function, which provides the rgb-color.
Using classes works, but to get it right dynamically, sofor the data/color provided by the object array is a problem.
The attempts beneath do show e.g. fill="rgb(48, 183, 0)", but the classes which define it's style still override the dynamically added style
<Select
multiple
value={filterList[index]}
renderValue={(selected) => selected.join(", ")}
onChange={(event) => {
filterList[index] = event.target.value;
onChange(filterList[index], index, column);
}} >
{ processStatusColorsArr.map(({ id, name, color} ) =>(
MenuItem key={id} value={name} style={{ fill: `${color}%`, color: `${color}%` }} >
<Checkbox
fill={color} style={{ fill: `${color}%`, color: `${color}%` }} />
<ListItemText primary={name}
color= {color} />
<IconButton color={color}
fill={color}
style={{ fill: `${color}%`, color: `${color}%` }} />
</MenuItem>
))}
</Select>
I have also tried this,
{render_filter_process_status_colors(color)} in place of '<IconButton ..../>'
where I have (above this)
const render_filter_process_status_colors = (value, tableMeta, updateValue) => {
if(value === undefined) return;
return (
<div>
<FontAwesomeIcon icon={"square"} style={value} size={"lg"} fixedWidth/>
</div>
);
}
but no luck.
Thx
By using the function
{render_filter_process_status_colors(color)}
which is defined as
const render_filter_process_status_colors = (value, tableMeta, updateValue) => {
if(value === undefined) return;
const iconColor = {color: value}
return (
<div>
<FontAwesomeIcon icon={"square"} style={iconColor} size={"lg"} fixedWidth/>
</div>
); }
I get the icon with the color from my array of rgb colors.

make input search box full screen overlay on click on mobile device

I am using buefy autocomplete input fields in my nuxtjs project, this is location search box, what i want is just for mobile device, when i click the input field, it should overlay on full screen with suggestion like i attached screenshot below and after select suggestion, it should close and return to normal.
here is my simple auto complete input field code.
<template>
<b-autocomplete
v-model="pickupairport"
:data="airports"
name="pickupairport"
class="ttc-search-input"
icon="map-marker-outline"
placeholder="Pickup Airport"
field="name"
:loading="isFetching"
#typing="getairports"
#select="(option) => (aptselected = option)"
>
<template slot-scope="props">
<div class="media">
<div class="media-content">
{{ props.option.name }}
<br />
<small> {{ props.option.cityName }}, {{ props.option.countryName }} </small>
</div>
</div>
</template>
</b-autocomplete>
</template>
<script>
import { debounce } from 'lodash'
export default {
data() {
return {
pickupairport: '',
airports: [],
aptselected: null,
isaptFetching: false,
}
},
methods: {
getairports: debounce(function (pickupairport) {
const aptsearchq = this.pickupairport
if (!pickupairport.length) {
this.airports = []
return
}
this.isaptFetching = true
fetch(`https://api.myurl.com/api/transfers/aplist?querystring=${aptsearchq}`)
.then((response) => {
return response.json()
})
.then((data) => {
this.airports = []
data.response.forEach((item) => this.airports.push(item))
})
.catch((error) => {
this.airports = []
throw error
})
.finally(() => {
this.isaptFetching = false
})
}, 500),
},
}
</script>
What I want to achieve is like this GIF - https://i.imgur.com/zOYPwBI.gif
What I have now is like this GIF - https://imgur.com/9ZBZzxa
i tried to find something related, but couldn't find, if any suggestion on how to achieve that, it would be helpful for me.

react-select Is it possible to move selected values from isMulti?

I want to position selected items from Select isMulti elsewhere.
What I did before was hide the selected values, and save the selected values on some state and display in other place.
But this way I don't have the clear indicator for this element.
handleChange = (event) => {
this.setState({secondarySelectedOptions: event});
};
render() {
const { secondarySelectedOption } = this.state;
return (
<>
<Select
isMulti
name="secondary"
options={this.state.options}
styles={{
multiValue: base => ({
...base,
display: "none"
}),
}}
onChange={this.handleChange}
value={secondarySelectedOption}
/>
</>
)
<div className='half-width'>
{this.state.secondarySelectedOptions.map((item) => (
<div>{item.value}</div>
))}
</div>

Material UI Selected Option Not Showing in Select Box

I have the following:
--- before render ---
const fontArray = [
["Standard", "Standard"], ["Abril FatFace", "'Abril Fatface', cursive"],
["Alfa Slab One", "'Alfa Slab One', cursive"],
["Chonburi", "'Chonburi', cursive"], ["Comfortaa", "'Comfortaa', cursive"],
["Lobster", "'Lobster', cursive"], ["Pacfico", "'Pacifico', cursive"]
]
--- in render ---
<FormControl style={{margin: '10px'}}>
<InputLabel htmlFor="select-font">Font</InputLabel>
<Select
value={this.state.font[0]}
onChange={(evt)=>this.handleFontChange(evt)}
inputProps={{
name: 'font',
id: 'select-font',
}}
>
{fontArray.map((font, index)=>{
return(
<MenuItem key={font} value={font}>
<div style={{fontFamily: `${font[1]}`}}>
{font[0]}
</div>
</MenuItem>
)
})}
</Select>
</FormControl>
And as you can guess the current font is held in state.
--- Here is how I handle select change ---
handleFontChange = (event) => {
this.setState({ font: event.target.value })
};
So what I want is to be able to have a font select, where the font is shown. It almost works. For example, when I click the select I get:
However, the select itself is empty (even when I've confirmed that state is populated:
What am I doing wrong? Maybe material-ui can't handle stylized default text?
EDIT: The two answers below seem close, but not quite right for what I'm trying to do.
If you replace
<MenuItem key={font} value={font}>
with
<MenuItem key={font} value={font[0]}>
It does replace the font with the correct selected value. Great!
...but it also then replaces this.state.font with this.state.font[0]. I'm currently attempting to get this to work by changing the handle function like this:
handleFontChange = (event, fontArray, stateData) => {
let newFont = fontArray.filter(i=>{
if(i[0]==event.target.value){
return i
}
})
this.setState({ font: newFont })
};
Which seems to set this.state.font correctly, but it again doesn't
seem to want to make the select box show the selected font.
Hmmm....
SOLVED
Here is a modification of a solution below:
Using
renderValue = (value) => {
return(
<div style={{fontFamily: `${value[1]}`}}>
{value[0]}
</div>
)
}
and
<...>
<Select
value={this.state.font}
renderValue={() => this.renderValue(this.state.font)}
<...>
Gives...
You can use renderValue to solve this.
renderValue = (value) => {
return value && value[0];
}
in render method
<FormControl style={{margin: 10}}>
<InputLabel htmlFor="select-font">Font</InputLabel>
<Select
value={this.state.font}
renderValue={() => this.renderValue(this.state.font)}
onChange={evt => this.handleFontChange(evt)}
inputProps={{
name: "font",
id: "select-font"
}}
>
{fontArray.map((font, index) => {
return (
<MenuItem key={index} value={font}>
<div style={{fontFamily: `${font[1]}`}}>
{font[0]}
</div>
</MenuItem>
);
})}
</Select>
</FormControl>
<...>
<Select
value={this.state.font?this.state.font :defaultvlue}
renderValue={() => this.renderValue(this.state.font)}
<...>
you can use ternary operator ,if you have data show data else default value

Resources