changing selected state of fetched item from API - javascript

I have an API that returns me arrays. I implemented the code to search 3 of them like this:
{response !== undefined &&
search !== "" &&
response.InsuranceServiceList.filter((insurance) =>
insurance.Name.replace(/ي/g, "ی", /ا/, "آ").includes(search)
)
.slice(0, 3)
.map((filtered, i) => (
<EachInsurance
filtered={filtered}
key={i}
styles={scss}
DatePresence={DatePresence}
IdInsurance={IdInsurance}
TimePresence={TimePresence}
/>
))}
whenever user types something in search box, 3 of these matching arrays will get rendered.
but I have two problems with selecting them.
this is each insurance component:
<Container
className={styles.eachInsurance}
style={{
borderRight: `${selectInsurance ? "20px" : "1px"} solid #fcc4de`,
}}
>
<div
onClick={() => {
setSelectInsurance((prev) => !prev);
setCount(0);
}}
>
<p className={styles.NameService}>{filtered.Name.replace(/ي/g, "ی")}</p>
</div>
</Container>
whenever user clicks on element. it will have pinkish border with the width of 20px.
the problem is, when I type another thing to search another item. it shows that Item selected.
just like the clicked div is still there but the content inside of it has changed.
how can I prevent this problem?
I thought it would render a new div per each array. but it wasn't.
the second problem is search itself. if you delete what you've write completely (emptying search bar). everything you have selected before will get removed and you will need to reselect it again.
I want to prevent this too.

You need to pass the id from your back end to your front end. then add a border based on the ids you pass to the selectInsurance, in that way you will know if the element change the border will be gone.
I think for your second problem you can add a new state that will reserve the whole object of the insurance and you first render from that array so every time you re-render your search array your selected insurance array will stay the same so they will remain in your page

Related

Multiple Row Edit Functionality in React

I am trying to implement an edit row functionality in a react grid. I have attached 2 links. Link 1 is the GIF which shows the functionality that I have implemented using the below code.(For privacy reasons I cannot publish the actual code)
Link 2 is the functionality I am trying to achieve! How shall I do that?
return (
<>
<p>Sample Row Field</p>
{editId === Id && editRow === true ? (
<select options={options} handleChange={handleChange} />
) : (
existingRowValue
)}
</>
);
Link 1 - The Functionality I have (Individual Row)
https://i.stack.imgur.com/JJEL5.gif
Link 2 - The Functionality I want (Multiple Rows)
https://i.stack.imgur.com/w7ppb.gif
I'd assume editId is a local state variable, same for editRow
So what you'd need to do is change editId into a state called editIds as an array (because you want to edit multiple rows, not just one), and replace editId === Id with editIds.includes(Id)
onEditClick: should add the rowId into this state, like setEditIds(...editIds, rowId)
onSave/CancelClick: should remove the id from the state, like: setEditIds(editIds.filter((id) => id !== rowId))
I think following code sample will give you an idea of how you can achieve this when you move your editId to a local component state.
https://codesandbox.io/embed/hardcore-sid-pythne?fontsize=14&hidenavigation=1&theme=dark

Why is my JSX rendering a <tr> when it shouldn't?

I have a table that fills its rows and <td> tags on its own. It does this fine as shown below:
The table is generated by mapping through an array.
{objInnerValues[shopIndex].map((thing, outerIndex) => (
// Ternary operator to stop creating rows from element 0
(outerIndex === 0) ? console.log("outerIndex WAS 0") : (outerIndex %2 === 0) ?
Object.values(thing).map((innerThing, innerIndex) => (
<>
{/* Tooltip popup for item blurb */}
<HtmlTooltip title={
//a tooltip component, from MUI. Gets a string to display
}
>
{/* Table rows for each record */}
<TableRow
//style definitions, then an id for the row...
id = {"rowID-"+thing[0][0]}
>
{AR_RowRefs.push("rowID-"+thing[0][0])}
{/* Indidivual td elements to display each item in a row*/}
<SuperTD NoHoverTD>
{//Items name}
</SuperTD>
<SuperTD NoHoverSmallTxtTD>
{//category the item belongs to}
<Button>
//a visibility button, part of what I'm trying to work on
</Button>
</SuperTD>
<SuperTD NoHoverSmallTxtTD>
{
//Get weight of item from array and format it
}
</SuperTD>
<SuperTD NoHoverSmallTxtTD>
{
//Get price from array and format it
}
</SuperTD>
{/* Checkbox for if item is available */}
<SuperTD>
<input type="checkbox" defaultChecked={innerThing[6]}/>
</SuperTD>
{/* Checkbox for if item is limited */}
<SuperTD>
<input type="checkbox" defaultChecked={innerThing[7]}/>
</SuperTD>
</TableRow>
</HtmlTooltip>
</>
Above my return block I have an array I want to use to store the ID of each table row that is generated. I have a function (fired from an onClick of each visibility button).
I wrote this in my return block, inside the array map:
{AR_RowRefs.push("rowID-"+thing[0][0])}
However, when I save this and it renders, it creates an extra column of data:
I thought that an extra <td> would only render if I put tags around it. This is just a JSX snippet so is there any particular reason its creating its own <td>? Can I still have this snippet push ids to an array without rendering an extra element?
I thought that an extra <td> would only render if I put tags around it. This is just a JSX snippet so is there any particular reason its creating its own <td>?
The browser is attempting to recover from your error of putting a number (which gets converted to a string) as a child of a tr.
Can I still have this snippet push ids to an array without rendering an extra element?
The quick and dirty approach (which I haven't tested) would be to change the expression so it doesn't evaluate as a number.
{void AR_RowRefs.push("rowID-"+thing[0][0])}
The sensible approach would be to split your data manipulation logic and your display logic.
Object.values(thing).map((innerThing, innerIndex) => {
AR_RowRefs.push("rowID-"+thing[0][0]);
return <>
...
</>;
};

Scroll to individual mapped header names in React

I have a tab list of 4 names which I am mapping over the data for in the first map and I am trying to implement a link for each one so that it scrolls to the same header name in the second mapping.
The current anchor link seems to just take me to the first heading when I click on each of the tab names at the moment. I am not sure if I possibly need to use a ref to somehow get each data name to link to individually.
<FormGroupWrapper>
{props.groups.map((group) => {
return (
<DisplayNameTab>
{group.displayNames}
</DisplayNameTab>
)
)
</FormGroupWrapper>
<FormGroupWrapper>
{props.groups.map((group) => {
return (
<DisplayNameTab>
<h1 id="heading">{group.displayNames}</h1>
<p>{group.description}</p>
</DisplayNameTab>
)
)
</FormGroupWrapper>

Material-ui autocomplete not changing its value based on value prop

I had to generate multiple rows, where each row has a dropdown (Autocomplete) that was searchable through API, and other fields too. All is working perfectly, except when I delete a row from the middle somewhere, just the autocomplete component displays the same value as earlier, however, I get correct data in my state.
So if I had an array with the following items.
And now if I delete Row 2 which is Brite – (500 g), I get this display on the screen.
However, all other items of the rows are correctly displayed, so I'm assuming there is nothing wrong with my logic of handling the array, but due to autocomplete showing wrong value(however it holds the correct object passed into its value prop), it seems that all items have suddenly changed their Qty and prices, and the last item was deleted (instead of 2nd one).
If I sum up the problem, although the component was re-rendered based on new array in the state, that was obtained after deleting a row, autocomplete still displays its previous value which is nowhere is the data now.
<Autocomplete
options={skuItems}
getOptionLabel={option => option.name}
renderInput={params => (
<TextField {...params} label="SKU" variant="outlined" />
)}
value={selectedSkuItems[index]}
onChange={(e, val) => orderItemHandleChange(e, val, index)}
onInputChange={skuSearch}
/> (edited)
The issue resides where you have the map function. The key must be something unique. If it involves the index, is bad. Because you remove items by index and then another item takes that indexes place, and a proper rewrite of the DOM is failing.
As seen bellow:
collection.map((value, index) => { <div key={something unique}> </div>}

search results highlight results using reactjs

I was trying to achieve search results like YouTube. Just trying, but there are some problems I'm encountering. I have made the working application in codesandbox here.
I am having a search box when you type anything it will show search results like a dropdown, for an example when you search in youtube you will be able to see results below, same thing/
The problems I'm facing are:
Assume i type "a", now you will be able to see total 6 results in the searched results div having a scroll.
1) So the 1st result itself will show the highlighted css. When i hover or when i navigate with key only the higlight css should come how can i achieve this.
2) so now if i hover on the second or result highlight css will show in the second or third but the 1st result also will show the css. i just want the higlight css at a time only one. (The same feature is there in youtube search)
3) right now only three elements are visible the remaining three are you need to scroll, when i navigate through arrow keys, the scroll is not happening how can i achieve this with scrollIntoView API
4) In 6 results the search string is "a", how can i make that string to be strong so it remains as highlighted so whatever you search it should be highlighted
Any help is appreciated! Please let me know if you have any queries
With consideration of the code that we updated in this sandbox: https://codesandbox.io/s/react-codesandbox-5fvk9
All you really need is a onMouseEnter() event-handler to get everything working.
Handler
handleMouseEnter = index => {
this.setState({
cursor: index,
})
}
Markup
{searchResults.map((item, index) => {
return (
<li
ref={ref => (this.itemRefs[index] = ref)}
onClick={() => this.goToItem(index)}
className={cursor === index ? 'active' : null}
onMouseEnter={() => this.handleMouseEnter(index)}
>
<label className="first-lb">{item.id}</label>
<label className="second-lb">{item.name}</label>
<label className="third-lb">{item.address}</label>
</li>
)
})}
With this, only one of hover-over or arrow-down/arrow-up will take effect at a time. So only one list-item will ever be highlighted.

Categories

Resources