Algolia - How to customize the tags display name in the menuSelect dropdown list - html

I found this menuSelect widget in Algolia instantSearch and I implemented successfully. But currently the filter names it displayed are the tags directly from the indices config. Is there a way to replace those name with my own filters? e.g. instead of react_pwa, display React storefront Here is the html output.
<MenuSelect class="tags" attribute="tags" transformItems={items =>
items.map(item => ({
...item,
}))}/>
Does anyone know if I can play around with transformItemsprops to solve this problem? Thanks!

Build a custom menuSelect widget can do it.
const MenuSelect = ({ items, currentRefinement, refine }) => (
<select
value={currentRefinement || ''}
onChange={event => refine(event.currentTarget.value)}
>
<option value="">See all options</option>
{items.map(item => (
<option
key={item.label}
value={item.isRefined ? currentRefinement : item.value}
>
{item.label==="react_pwa" && 'React PWA Storefront'}
{item.label==="cloudops-aws" && 'CloudOps for AWS'}
{item.label==="commerce-manager" && 'Commerce Manager'}
{item.label==="cloudops-azure" && 'CloudOps for Azure'}
{item.label==="chatbot" && 'Reference Chatbot'}
{item.label==="alexa-skill" && 'Alexa Skill'}
{item.label==="account-management" && 'Account Management'}
</option>
))}
</select>
);
const CustomMenuSelect = connectMenu(MenuSelect);
then in the search class add <CustomMenuSelect attribute="tags" />

Related

Can't figure out a way to add two values from a select element in react

Scenario: I have a react component that allows users to select through different shipping rates. Once a user selects one I want the onChange to get the ID and the amount and I can only figure out how to get just the ID. The select element iterates through an array of rates that is structured like this:
rates = [ {id: 'r8f8hd8', amount: 45}, ...]
Here is the select element:
<select onChange={(e) => console.log(e.target.value)} className='w-8/12 h-14 rounded p-2'>
<option disabled selected hidden>
Pick a shipping rate
</option>
{rates.map((rate, index) => (
<option value={{ id: rate.rateId, amount: rate.amount }} key={index}>
{rate.service} {''}(${rate.amount})
</option>
))}
</select>
I tried setting the option value to an object with the rateId and amount but it just gives me a blank [Object object]
This should fix the issue. A word of advice I wouldn't set the key to just the index. Instead you should use the id that you assigned to the object.
The issue was you we're storing an object as the value. This lead to an issue because value automatically stores a string so your object is converted into a string hence [Object Object]. Mapping already sets its own pre defined object {value:someVal,key:someID}.
Taking your current case into account I believe this is a cleaner way to achieve what you wanted. I've added working code below. Also the extra item in rates was just for testing.
Feel free to comment any questions you have and i'll do my best to answer them.
let rates = [ {id: 'r8f8hd8', amount: 45},{id: 'r8f8hd', amount: 450}]
return (
<select onChange={(e) => console.log(e.target.value)} className='w-8/12 h-14 rounded p-2'>
<option disabled selected hidden>
Pick a shipping rate
</option>
{rates.map((rate) => (
<option value={rate.amount } key={rate.id}>
{rate.service} {''}(${rate.amount})
</option>
))}
</select>
)
Just incase your just dead set on storing multiple values here's a solution to that as well but I would go as far as saying this is just bad code but it does what you wanted. Since map has its own object as I mentioned we can mutate it and give it more characteristics hence id and trueVal that I added. We can use the index and store that as our value and instead of accessing our data through e.target.value we can instead utilize the e.target.options and simply cross reference the index value we stored to make sure we are always accessing the correct position in the array. However please take note of the +1 this is to take the first position into account which is held by the, "Pick a shipping rate".
let rates = [ {id: 'r8f8hd8', amount: 45},{id: 'r8f8hd', amount: 450}]
return (
<select onChange={(e) => console.log(e.target.options[e.target.value])} className='w-8/12 h-14 rounded p-2'>
<option disabled selected hidden>
Pick a shipping rate
</option>
{rates.map((rate, index) => (
<option value={index+1} trueVal={rate.amount} id={rate.id} key={index}>
{rate.service} {''}(${rate.amount})
</option>
))}
</select>
)
}
In html value prop is a string, so value={{ id: rate.rateId, amount: rate.amount }} is converted to string, that's why you are getting [Object object] .
Solution : change your component like this :
.....
const [option, setOption] = React.useState({});
const handlechange = (e)=>{
for (let i = 0; i < rates.length; i++) {
if (e.target.value === rates[i].id) {
setOption({ id: rates[i].id, amount: rates[i].amount });
}
}
}
return (
<select onChange={handlechange} className="w-8/12 h-14 rounded p-2">
<option disabled selected hidden>
Pick a shipping rate
</option>
{rates.map((rate, index) => (
<option value={rate.id} key={index}>
{rate.service} {""}(${rate.amount})
</option>
))}
</select>
);
Now your id and amount of selected option will be stored in option state
this is a demo in codesandbox

How to dynamically change the css style of a particular item inside a map function

I currently have two map functions to render a board for a chess game like this:
<div className='board'>
{rows.map((item) => (
<div key={item} className='row'>
{item.map((square) => (
# The square <div> => <div key={square[0]} className='square' onClick={() => {
board.select !== null &&
checkColour(board.select[1]) !== checkColour(square[1]) && dispatch(move(square))
}}>
{isNaN(square[1]) && <img src={square[1]} alt={square[1]}
onClick={() => { board.turns === checkColour(square[1]) && dispatch(select(square)) }}
className={board.select === square ? 'piece-selected' : 'piece'} />}
</div>
))}
</div>
))}
</div>
Now, I want to change the css style of certain squares <div> after I selected a pawn piece in order to forecast a shadow for showing the possible moves. I want to know is it possible to access the css style of that particular square <div> using the key of that <div>?
Feel free the drop a comment below if you have any insight or idea. Let me know if you want more info. Much appreciated.

Render products grouped by dynamic category [duplicate]

This question already has answers here:
Render products grouped by category
(2 answers)
Closed 2 years ago.
I have a catalog page with a sidebar which contains a dynamic list:
This sidebar lists products.category and updates whenever there is a new category created/removed.
What I want to achieve
Is to be able to show the filtered table based on category that was clicked. Kind of like using props so I can use products.category to automatically fill the filter without hardcoding each category.
I may be approaching this problem wrong.
const showTable = (props) => {
return (
<>
{products && products.length !== 0 ? (
products
.filter((item) => item.category === props.table) // Kind of like this
.map((product) => ExtendedProduct(product))
) : (
<Loader />
)}
</>
);
};
const TableRoutes = () => {
return (
<>
{products &&
productCategories.map((product) => (
<Tab.Pane key={product.category} eventKey={product.category}>
<ShowTable table={product.category} />
</Tab.Pane>
))}
</>
);
};
The productCategories is where I remove the duplicated categories so they won't be doubled when rendered.
The code above is a functional component.
I'm using https://react-bootstrap.netlify.app/components/tabs/#tabs-custom-layout which explains Tab.Pane.
Things I've looked into:
Render products grouped by category [class-based]
After ~12 hours of fiddling around, apparently the solution is quite the same in the linked question.
Render products grouped by category
const TableRoutes = () => {
return (
<>
<Tab.Pane eventKey="default">
<ExtendedTable
data={
products && products.map((product) => ExtendedProduct(product))
}
/>
</Tab.Pane>
{/* Table filtered by product categories */}
{products &&
productCategories.map((categories) => (
<Tab.Pane key={categories.category} eventKey={categories.category}>
<ExtendedTable
data={
products &&
products
.filter((pane) => pane.category === categories.category)
.map((product) => ExtendedProduct(product))
}
/>
</Tab.Pane>
))}
{/* Table filtered by product types */}
{products &&
productTypes.map((types) => (
<Tab.Pane key={types.type} eventKey={types.type}>
<ExtendedTable
data={
products &&
products
.filter((pane) => pane.type === types.type)
.map((product) => ExtendedProduct(product))
}
/>
</Tab.Pane>
))}
</>
);
};
I guess this can be marked as duplicate...

Yii2 add extra attribute in select > options list

How I can add an extra attribute like in below screenshot state_id=1 in options list for all.
<?= $form->field($model, 'district_id')->dropDownList(ArrayHelper::map($Districts, 'id', 'name')) ?>
You need to iterate through the $Districts array and associate all the attributes you want to add to the <option> of the dropdown, i assume that your $Districts array has something like below
$Districts=[
1=>"North Andaman",
2=>"South Andaman"
3=>"Nicobar"
];
Now you need to iterate that array and associate the attributes with every option
foreach ($Districts as $id => $name) {
$optionAttributes[$id] = ['my-attr' => 'value'];
}
The above will show you something like
Array
(
[1] => Array
(
[my-attr] => value
)
[2] => Array
(
[my-attr] => value
)
[3] => Array
(
[my-attr] => value
)
)
Now when creating your dropdown you should pass this array to the options option of the dropdownList() see below
echo $form->field($model, 'district_id')->dropDownList(
$Districts,
['options' => $optionAttributes]
);
Now if you see the source of the page it will show you the dropdown like below
<select id="contacts-district_id" name="Contacts[district_id]" class="form-control">
<option value="1" my-attr="value">North Andaman</option>
<option value="2" my-attr="value">South Andaman</option>
<option value="3" my-attr="value">Nicobar</option>
</select>

Conditionally deciding which option is selected in blade

Im displaying a form as a representation of data in my database. Im using a form because the data is editable by certain users.
The form contains a dropdown list:
<select name="Status" id="Status">
<option id="confirmed" value="Confirmed">Confirmed</option>
<option id="completed" value="Completed">Completed</option>
<option id="released" value="Released">Released</option>
<option id="deleted" value="Deleted">Deleted</option>
</select>
When loading the view I pass in a variable '$status' which is from the database. How do I set the 'selected' attribute for which ever option $status is equal to?
Im using blade tempting engine
if you're using blade template you may want to use the Form helper to build your form fields, pass an array of items to be listed as dropdown options on the 2nd parameter and at the 3rd parameter pass your selected value, see the code below for reference
From controller:
$selectedValue = "confirmed";
$statuses = array(
array("id"=> "confirmed", "value" => "Confirmed"),
array("id"=> "completed", "value" => "Completed"),
array("id"=> "released", "value" => "Released"),
array("id"=> "deleted", "value" => "Deleted"),
);
return view("yourview")->with("statuses", $statuses)->with("selectedValue", $selectedValue);
On your view you could do something like below:
{!! Form::select('status', $statuses , $selectedValue, ['class' => 'form-control', 'id' => 'status']) !!}
Note: the code is untested but should work in your case.
Also please check https://laravelcollective.com/docs/5.2/html