How can I test a MUI check box with no label using data-testid? - testing

I want to test a checkbox that has no label. The point is that there are other checkboxes as well so I cant use getByRole.
I have tried to use data-testid, but apparently, it's not working.
How am I supposed to check if that checkbox is checked(toBeChecked())?
<Checkbox
data-testid={item?.id}
key={item?.id}
id={item?.id.toString()}
color="secondary"
checked={item?.checked}
disabled={hasAll}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
if (item) {
item.checked = e.target.checked;
setFinalData(updateItemInArray(finalData, {
item,
index,
}));
}
}}
/>

The proper way to do this would be to add an aria-label to your checkbox, so it's announced correctly by screen readers:
<Checkbox inputProps={{ 'aria-label': 'Select row 1' }} />
This way, you'll be able to select it in your tests using getByLabelText.
If you want to use data-testid, you can place it on the checkbox similarly to aria-label:
<Checkbox inputProps={{ 'data-testid': 'checkbox1' }} />
Note that if you're using Typescript, you'd have to cast the inputProps to React.InputHTMLAttributes<HTMLInputElement> as data attributes are not a part of InputHTMLAttributes:
<Checkbox inputProps={{ 'data-testid': 'checkbox1' } as React.InputHTMLAttributes<HTMLInputElement>} />

Related

How to make Checkbox only activate function when checked

I'm having issues with my checkbox, I can't seem to figure out how to get the function to only run when the box is checked. I understand why it is happening but I'm having trouble writing a statement to require the checked state to be true
<Checkbox
disabled={false}
value='MultiEdit'
aria-label="Close"
onChange={() => onChangeValue(item) }
>
</Checkbox>
```

Is using conditional accessibility label text good?

I have this code in my React Native app that renders a list of types. Selected and not selected types have different backgrounds. Is it okay to make accessibility label text conditional?
<View style={styles.typesList}>
{types.map(type => {
return (
<TouchableOpacity
key={type}
style={[
styles.type,
{
backgroundColor: filterTypes.includes(type)
? Colors.white
: Colors.lightYellow
}
]}
onPress={() => {
handleFilterTypesChange(type);
}}
testID='type'
accessibilityLabel={`${
filterTypes.includes(type) ? 'Unselect' : 'Select'
} ${type} filter`}
>
<Text>{type}</Text>
</TouchableOpacity>
);
})}
</View>
The screen readers by default read-out if a checkbox is selected or not. So no need to put conditional text to just read out it. If you have multiple select boxes it is advised to use fieldsel and legend which will give details to visually challenged persons.
<fieldset>
<legend>Select your pizza toppings:</legend>
<input id="ham" type="checkbox" name="toppings" value="ham">
<label for="ham">Ham</label><br>
<input id="pepperoni" type="checkbox" name="toppings" value="pepperoni">
<label for="pepperoni">Pepperoni</label><br>
</fieldset>
The contains the group of checkboxes, and the labels the group. Screen readers may repeat the legend for each control in the group, so the legend text should be brief and descriptive.

Image and text will now not show up anymore on profile page after a change in code

I was able to create a search bar, where you can filter the characters, for my directory. However, when I click on that particular profile, the profile image and the text for it do not appear. It was there before I created the searchbar, now it disappeared. Anyone know why that may be?
Prior to having this problem, this is how I had it set up. This is with the searchbar present, but not being able to filter out.
{characters.map((data, index) => (
<Button
text={data.name}
key={data.name}
title={`${data.name}`}
onPress={() => {
this.props.navigation.navigate("CharacterProfiles", {
item: data
});
}}
/>
))}
Then I made some changes to be able to filter out my options and I switched it to this:
{this.state.data.map((data, index) => (
<Button
text={data.name}
key={data.name}
title={`${data.name}`}
onPress={() => {
this.props.navigation.navigate("CharacterProfiles", {
item: data
});
}}
/>
))}
After the above happened, now the data such as the image and text will not appear dynamically anymore. Anybody know why?
In android some times image not load beacause of memory issue..
In Androidmanifest application tag set..
<application
...
android:largeHeap="true"
android:hardwareAccelerated="true"
...

How to replace the checkbox from the UI Fabric DetailsList component

How can I replace the circle checkbox of a DetailsList in office-ui-fabric-react with a normal square CheckBox component? I see onRenderCheckbox so I try something like this:
onRenderCheckbox={(props) => (<Checkbox checked={props.checked} />)}
or
onRenderCheckbox={(props) => (<Checkbox {...props} />)}
I can see the square checkbox but I can't select it.
What it the proper way to do this?
Thanks in advance...
When you render the Checkbox component, it handles the click itself (and thus it won't percolate up to the row so it can toggle selection accordingly), so you need to prevent it with the pointer-events: none style.
onRenderCheckbox(props) {
return (
<div style={{ pointerEvents: 'none' }}>
<Checkbox checked={props.checked} />
</div>
);
}
Check it out here: https://codepen.io/anon/pen/zQXEPr

React-Admin | Bulk-Select with ReferenceField

In our application, we're trying to use Datagrid within ReferenceField to create/modify/delete related records, as shown in https://marmelab.com/blog/2018/07/09/react-admin-tutorials-form-for-related-records.html
All the functionality shown in the tutorial works well, except the bulk-actions added in a recent react-admin update. Clicking these checkboxes gives
Uncaught TypeError: _this.props.onToggleItem is not a function
I believe this is because the onToggleItem prop is normally provided by the List component, however in this application, Datagrid doesn't have a parent List component.
Adding a List component between ReferenceManyField and Datagrid allows bulk select/delete to work after some changes to the style, however this causes another issue: the current displayed page (i.e. records 1-10, 11-20, etc) is stored per-resource in the store, and so it is possible to have a situation where the store says we're on page 2, and displays page 2, which is empty because there are only enough related items to fill one page.
Am I missing something here? Or is bulk-select inside ReferenceManyField not possible at the moment?
export const NetworksShow = (props) => (
<Show title={<NetworksTitle />} actions={<NetworksShowActions />} {...props}>
<ReferenceManyField addLabel={false} target="ipid" reference="acl-network">
<List style={{ margin: '0px -24px -16px -24px' }} {...props} actions={<NetworkACLCardActions ipid={props.id}/>} filter={{ ipid: _.has(props, 'id') ? props.id : undefined }}>
<Datagrid hasBulkActions={true}>
<ReferenceField label="Network" source="ipid" reference="networks">
<TextField source="name" />
</ReferenceField>
<TextField label="URL" source="url" />
<BWChip label="Action" source="wb" />
<EditButton />
<DeleteButton />
</Datagrid>
</List>
</ReferenceManyField>
</Show>
);
As a side-effect of https://github.com/marmelab/react-admin/pull/2365, it is now possible to use ReferenceManyField -> List -> Datagrid in the way described in the question.
For example, we're now doing the following:
<ReferenceManyField addLabel={false} target="groupid" reference="users">
<List
style={{ margin: '0px -24px -16px -24px' }}
filter={{ groupid: id }}
{...props}
>
<Datagrid hasBulkActions>
<LinkField label="Name" source="name" />
<LinkField label="Username" source="email" />
<FlexibleBooleanField label="Email" source="allowemail" />
<ACLChip label="User Access" source="aclid" />
</Datagrid>
</List>
</ReferenceManyField>
Bulk actions works with the above, and any issues with pagination are avoided as react-admin now checks and modifies pagination if nothing appears on the current page.
As I've understood from the documentation, Datagrid is just an iterator "dumb component".
It just "shows" things that the parent - usually List (connected component) or in your case ReferenceManyField - element previously has fetched.
Thus I think that BulkActions can only be functional when provided by a List element.
For the second part of your issue, Lists should be used top-level and not within other elements that's why it breaks your pagination.
I implemented "DumbList" which takes data from parent component instead of loading it itself. This solves the problem:
import React from 'react';
import { ListController } from 'ra-core';
import { ListView } from 'ra-ui-materialui/esm/list/List';
export const DumbList = props =>
<ListController {...props}>
{controllerProps => {
let { data } = props
const ids = Object.keys(data || {})
const total = ids.length
return <ListView
{...props}
// This is important, otherwise bulkActionsToolbar ends up on very top of the page
classes={{ card: 'relative' }}
{...Object.assign(controllerProps, { data, ids, total })} />
}}
</ListController>