I want replace the "Cancel" Text on the Searchbar button (See a screenshot on the bottom) with an Icon (See the code on the bottom).
This it the render part with the default props:
render() {
const _a = this.props, { theme, cancelButtonProps, cancelButtonTitle, clearIcon, containerStyle, leftIconContainerStyle, rightIconContainerStyle, inputContainerStyle, inputStyle, placeholderTextColor, showLoading, loadingProps, searchIcon, showCancel } = _a, attributes = __rest(_a, ["theme", "cancelButtonProps", "cancelButtonTitle", "clearIcon", "containerStyle", "leftIconContainerStyle", "rightIconContainerStyle", "inputContainerStyle", "inputStyle", "placeholderTextColor", "showLoading", "loadingProps", "searchIcon", "showCancel"]);
const { hasFocus, isEmpty } = this.state;
const { style: loadingStyle } = loadingProps, otherLoadingProps = __rest(loadingProps, ["style"]);
const { buttonStyle, buttonTextStyle, color: buttonColor, disabled: buttonDisabled, buttonDisabledStyle, buttonDisabledTextStyle } = cancelButtonProps, otherCancelButtonProps = __rest(cancelButtonProps, ["buttonStyle", "buttonTextStyle", "color", "disabled", "buttonDisabledStyle", "buttonDisabledTextStyle"]);
return (<View style={StyleSheet.flatten([
styles.container,
{ backgroundColor: theme.colors.white },
containerStyle,
])}>
<Input testID="searchInput" renderErrorMessage={false} {...attributes} onFocus={this.onFocus} onBlur={this.onBlur} onChangeText={this.onChangeText} ref={(input) => {
this.input = input;
}} inputStyle={StyleSheet.flatten([styles.input, inputStyle])} containerStyle={{
paddingHorizontal: 0,
}} inputContainerStyle={StyleSheet.flatten([
styles.inputContainer,
{ backgroundColor: theme.colors.platform.ios.searchBg },
hasFocus && { marginRight: this.state.cancelButtonWidth },
inputContainerStyle,
])} leftIcon={renderNode(Icon, searchIcon, defaultSearchIcon(theme))} leftIconContainerStyle={StyleSheet.flatten([
styles.leftIconContainerStyle,
leftIconContainerStyle,
])} placeholderTextColor={placeholderTextColor || theme.colors.platform.ios.grey} rightIcon={<View style={{ flexDirection: 'row' }}>
{showLoading && (<ActivityIndicator key="loading" style={StyleSheet.flatten([{ marginRight: 5 }, loadingStyle])} {...otherLoadingProps}/>)}
{!isEmpty &&
renderNode(Icon, clearIcon, Object.assign(Object.assign({}, defaultClearIcon(theme)), { key: 'cancel', onPress: this.clear }))}
</View>} rightIconContainerStyle={StyleSheet.flatten([
styles.rightIconContainerStyle,
rightIconContainerStyle,
])}/>
<View style={StyleSheet.flatten([
styles.cancelButtonContainer,
{
opacity: this.state.cancelButtonWidth === null ? 0 : 1,
right: hasFocus ? 0 : -this.state.cancelButtonWidth,
},
])} onLayout={(event) => this.setState({ cancelButtonWidth: event.nativeEvent.layout.width })}>
<TouchableOpacity accessibilityRole="button" onPress={this.cancel} disabled={buttonDisabled} {...otherCancelButtonProps}>
<View style={[buttonStyle, buttonDisabled && buttonDisabledStyle]}>
<Text style={[
styles.buttonTextStyle,
buttonColor && { color: buttonColor },
buttonTextStyle,
buttonDisabled &&
(buttonDisabledTextStyle || styles.buttonTextDisabled),
]}>
{cancelButtonTitle}
</Text>
</View>
</TouchableOpacity>
</View>
</View>);
}
}
SearchBar.defaultProps = {
value: '',
cancelButtonTitle: 'Cancel',
loadingProps: {},
cancelButtonProps: {},
showLoading: false,
onClear: () => null,
onCancel: () => null,
onFocus: () => null,
onBlur: () => null,
onChangeText: () => null,
searchIcon: { name: 'ios-search' },
clearIcon: { name: 'ios-close-circle' },
showCancel: false,
};
Its looking like this:
Now I want to replace this "Cancel" with an Icon:
const defaultCancelIcon = (theme) => ({
type: 'material',
size: 25,
color: theme?.colors?.platform?.android?.grey,
name: 'arrow-back',
});
Since I havent worked with edited react-native-elements yet, I dont dont really know how to do this. I tried to change the defaultProps, but it didnt change anything. How can I do this?
type
<YourIconName />
instead of 'cancel', like
SearchBar.defaultProps = {
value: '',
cancelButtonTitle: <YourIconName />,
loadingProps: {},
...
};
I think it should work
Related
Is that possible to fetch data or using function useEffect..I have tried all the way. any suggestion?**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
This is my processes.tsx file.
import React, { useEffect, useState } from 'react';
import { connect, ConnectedProps } from 'react-redux';
import { Link, RouteComponentProps, useHistory, withRouter } from 'react-router-dom';
import { People } from '#microsoft/mgt-react';
import { checkPermission } from '../../../config/permission-utils';
import { RootState } from '../../../config/store';
import { getDateFormatted, getQueryParams } from '../../../config/utils';
import { Modal } from '../../../components';
import __ from '../../../lang';
import {
addProcessAction,
clearSelectProcessAction,
deleteProcessAction,
makeProcessVersionAction,
searchProcessesAction,
selectProcessAction,
selectProcessByIdAction,
setMetaAction,
shareProcessAction,
updateProcessAction,
} from '../../../store/actions/process-actions';
import { addProcessInstanceAction, fetchModelingInstances } from '../../../store/actions/process-instance-actions';
import { Role, Department, Process } from '../../../ts/interfaces';
import { ProcessFilter } from '../process-filter';
import { ProcessForm } from './process-form';
import { SendForm } from './send-form';
import {
DetailsList,
DetailsListLayoutMode,
Selection,
SelectionMode,
IColumn,
IconButton,
PrimaryButton,
Text,
Stack,
TooltipHost,
DirectionalHint,
ActionButton,
ButtonType,
IDetailsRowStyles,
IDetailsListProps,
DetailsRow,
Spinner,
SpinnerSize,
} from '#fluentui/react';
import { Popover } from '../../../components';
import { getStyles, gridStyles } from './processes-styles';
import { ProcessActionsMenu } from './process-actions-menu';
import { useWindowSize } from '../../../hooks';
import { ProcessVersionsHistory } from '../../process-details/history/versions';
const Processes = (props: RouteComponentProps & PropsFromRedux) => {
const {
ProcessReducer: { processes, selected_process },
ProcessGroupReducer: { processgroups },
DepartmentReducer: { departments },
RoleReducer: { roles },
UserReducer,
location: { search },
selectProcessByIdAction,
clearSelectProcessAction,
selectProcessAction,
addProcessAction,
updateProcessAction,
shareProcessAction,
fetchModelingInstances,
addProcessInstanceAction,
makeProcessVersionAction,
deleteProcessAction,
searchProcessesAction,
} = props;
const [filterVisible, setFilterVisible] = useState(false);
const [modalVisible, setModalVisible] = useState(false);
const [sendVisible, setSendVisible] = useState(false);
const [enableDelete, setEnableDelete] = useState<boolean>(false);
const [selectedProcesses, setSelectedProcesses] = useState<Process[]>([]);
const [showSpinner, setShowSpinner] = useState<boolean>(false);
const [width] = useWindowSize({ checkDocumentSize: true });
const processesStyles = getStyles(width);
const [showHistoryModal, setShowHistoryModal] = useState<boolean>(false);
const history = useHistory();
const [selectedProcessId, setSelectedProcessId] = useState<number>();
const _rowsSelected: Selection = new Selection({
onSelectionChanged: () => _getSelectionDetails(),
});
const _getSelectionDetails = () => {
const selectionCount = _rowsSelected.getSelectedCount();
if (selectionCount > 0) {
setSelectedProcesses(_rowsSelected.getSelection() as Process[]);
setEnableDelete(true);
} else {
setSelectedProcesses([]);
setEnableDelete(false);
}
};
const columns: IColumn[] = [
{
key: 'process_name',
name: __('process'),
fieldName: 'process_name',
minWidth: 90,
maxWidth: 90,
isResizable: true,
onRender: (record: Process) =>
record && (
<Link className={processesStyles.cellText} to={`/process-management/processes/${record.id}`}>
{record.process_name}
</Link>
),
},
{
name: __('version'),
fieldName: 'version_number',
key: 'version_number',
minWidth: 30,
maxWidth: 60,
isResizable: true,
onRender: ({ version_number }: Process) => <div className={processesStyles.cellText}>{version_number}</div>,
},
{
name: __('process group'),
fieldName: 'group',
key: 'group',
minWidth: 90,
maxWidth: 120,
isResizable: true,
className: processesStyles.cellText,
onRender: (record: Process) =>
record.group && record.group.group_name.trim() !== '' ? (
<div className={processesStyles.cellText}>{record.group.group_name}</div>
) : (
<>
{
<div className="warning-icon blink">
<IconButton iconProps={{ iconName: 'Warning' }} onClick={() => onProcessEdit(record)} />
</div>
}
</>
),
},
{
name: __('department'),
fieldName: 'department',
key: 'department',
minWidth: 90,
maxWidth: 120,
isResizable: true,
onRender: (record: Process) =>
record.department.length > 0 ? (
record.department.map((item: Department, i: number) => (
<div className={processesStyles.cellText}>
{item.department_name}
{i < record.department.length - 1 ? ', ' : ''}
</div>
))
) : (
<div className="warning-icon blink">
<IconButton iconProps={{ iconName: 'Warning' }} onClick={() => onProcessEdit(record)} />
</div>
),
},
{
name: __('created at'),
fieldName: 'date_created',
key: 'date_created',
minWidth: 90,
maxWidth: 120,
isResizable: true,
onRender: ({ date_created }: Process) => (
<div className={processesStyles.cellText}>{date_created && getDateFormatted(date_created, 'lll')}</div>
),
},
{
name: __('location'),
fieldName: 'location',
key: 'location',
minWidth: 90,
maxWidth: 120,
isResizable: true,
onRender: ({ location }: Process) => <div className={processesStyles.cellText}>{location}</div>,
},
{
name: __('process owner'),
fieldName: 'process_owner',
key: 'process_owner',
minWidth: 90,
maxWidth: 120,
isResizable: true,
onRender: ({ process_owner, id }: Process) =>
process_owner && process_owner.length ? renderPersonsWithPopover(process_owner, id, 'process_owner') : '',
},
{
name: __('created by'),
fieldName: 'created_by',
key: 'created_by',
minWidth: 90,
maxWidth: 120,
isResizable: true,
onRender: ({ created_by }: Process) => created_by && <People userIds={created_by.username.split(',')}></People>,
},
{
name: __('sent to recording'),
fieldName: 'send_to',
key: 'send_to',
minWidth: 90,
maxWidth: 180,
onRender: ({ send_to, id }: Process) =>
send_to && send_to.length ? renderPersonsWithPopover(send_to, id, 'send_to') : '',
},
{
name: __('status'),
fieldName: 'status',
key: 'status',
minWidth: 200,
maxWidth: 200,
onRender: (record: Process) => {
return (
<>
<Stack wrap horizontal>
<Stack.Item>
<div className={processesStyles.tagStyles} style={{ background: record.status.color }}>
<Text variant={'smallPlus'}>{__(record.status.project_status_name)}</Text>
</div>
</Stack.Item>
<Stack.Item>
{record.status &&
checkPermission(UserReducer.permissions, 'change_processinstance') &&
record.status.project_status_name === 'in-process recording' && (
<TooltipHost content={__('view the process review')} directionalHint={DirectionalHint.bottomCenter}>
<Link to={`/process-management/processes/${record.id}/applications`}>
<IconButton iconProps={{ iconName: 'SingleColumnEdit' }} />
</Link>
</TooltipHost>
)}
{record.status &&
checkPermission(UserReducer.permissions, 'add_process') &&
(record.status.project_status_name === 'done' || record.status.project_status_name === 'rejected') &&
!hasCopiedProcess(record) && (
<Popover
content={__('are you sure to copy this process?')}
target={`process-${record.id}`}
enableConfirm={true}
onOk={() => onMakeVersion(record)}
>
<TooltipHost content={__('make new version')} directionalHint={DirectionalHint.bottomCenter}>
<IconButton id={`process-${record.id}`} iconProps={{ iconName: 'Copy' }} />
</TooltipHost>
</Popover>
)}
</Stack.Item>
</Stack>
</>
);
},
},
{
name: '',
key: 'actions',
minWidth: 30,
maxWidth: 30,
onRender: (record: Process) => {
const actions = [];
if (record.status && checkPermission(UserReducer.permissions, 'change_process')) {
{
(record.status.project_status_name === 'in-process recording' ||
record.status.project_status_name === 'new') &&
actions.push(
<TooltipHost content={__('edit process')} directionalHint={DirectionalHint.bottomCenter}>
<IconButton onClick={() => onProcessEdit(record)} iconProps={{ iconName: 'Edit' }} />
</TooltipHost>,
);
}
}
return actions;
},
},
];
useEffect(() => {
clearSelectProcessAction();
}, []);
here we can make something different..
useEffect(() => {
getProcesses();
}, [search]);
const getProcesses = () => {
const query =
search === '' ? '?order_by=-date_created&outdated=false' : `${search}&order_by=-date_created&outdated=false`;
searchProcessesAction(query);
};
/**
* checks if
* #param record a process in the process list
* #returns
*/
const hasCopiedProcess = (record: Process): boolean => {
const unDoneCopy = processes.find((process) => {
if (process && !process.root_version) {
return false;
}
return (
(process?.root_version?.id === record.id || process?.root_version?.id === record?.root_version?.id) &&
process.status.project_status_name !== 'done'
);
});
return unDoneCopy ? true : false;
};
const showProcessModal = () => {
selectProcessByIdAction(0);
setModalVisible(true);
};
const onProcessSend = (item: Process): void => {
selectProcessByIdAction(item.id);
setSendVisible(true);
};
const mapRaciFields = (process: any) => {
let { accountable, consulted, informed, responsible } = process;
// here a RACIField is overwritten bei {departments:string[]; roles:string[]; employees[string]}. Should be improved to be more readable
const fields = [accountable, consulted, informed, responsible];
[accountable, consulted, informed, responsible] = fields.map((field) => {
if (field) {
return {
departments: field.departments && field.departments.map((i: Department) => i.resource_uri),
roles: field.roles && field.roles.map((i: Role) => i.resource_uri),
employees: field.employees,
};
} else {
return null;
}
});
return [accountable, consulted, informed, responsible];
};
const startModeling = (process: Process) => {
fetchModelingInstances(process.id, (res: any) => {
if (res.data.objects.length) {
const redirect = `/process-management/processes/${res.data.objects[0].id}/modeling-tool/`;
history.push(redirect);
} else {
const { resource_uri, description, process_name } = process;
const [accountable, consulted, informed, responsible] = mapRaciFields(process);
const data = [
{
responsible: responsible ? { ...responsible, id: null } : null,
accountable: accountable ? { ...accountable, id: null } : null,
informed: informed ? { ...informed, id: null } : null,
consulted: consulted ? { ...consulted, id: null } : null,
source_process: resource_uri,
description: description ? description : null,
instance_name: process_name,
is_in_modeling: true,
is_sent: true,
},
];
addProcessInstanceAction({ objects: data }, (res: any) => {
const redirect = `/process-management/processes/${res.data.objects[0].id}/modeling-tool/`;
history.push(redirect);
});
}
});
};
//------------------
const onMakeVersion = (record: Process) => {
if (record.approved_by) {
delete record.approved_by;
}
setShowSpinner(true);
makeProcessVersionAction(record, (res) => {
setShowSpinner(false);
getProcesses();
});
};
const onProcessEdit = (item: Process) => {
selectProcessByIdAction(item.id);
setModalVisible(true);
};
const onDeleteProcesses = () => {
for (const process of selectedProcesses) {
deleteProcessAction(process);
}
getProcesses();
setEnableDelete(false);
};
const renderPersonsWithPopover = (persons: string, id: number, columnName: string) => {
const peopleArray = (persons && persons.split(',')) || [];
const popoverContent = peopleArray?.length > 3 ? getPopoverContent(peopleArray) : null;
return [
popoverContent ? (
<Popover content={popoverContent} target={`${columnName}-${id}`}>
<People id={`${columnName}-${id}`} userIds={peopleArray} showMax={3}></People>
</Popover>
) : (
<People userIds={peopleArray} showMax={3}></People>
),
];
};
const getPopoverContent = (peopleArray: string[]) => {
return <People userIds={peopleArray.slice(3)} showMax={peopleArray.length - 3}></People>;
};
const showProcessInstances = (id: number) => {
setSelectedProcessId(id);
};
const renderProcessesBtns = () => {
return (
<div className={processesStyles.btnsHolderContainer}>
<div className={processesStyles.btnsHolder}>
<Stack horizontal>
{selectedProcesses.length === 1 && (
<div className={processesStyles.processActions}>
<ProcessActionsMenu
UserReducer={UserReducer}
process={selectedProcesses[0]}
sendProcess={() => onProcessSend(selectedProcesses[0])}
// startModelling={() => onStartModeling(selectedProcesses[0])}
startModeling={() => startModeling(selectedProcesses[0])}
/>
</div>
)}
{enableDelete && checkPermission(UserReducer.permissions, 'delete_process') && (
<Popover
title={__('delete selected processes')}
content={__('are you sure to delete this processes?')}
target={'delete-processes'}
enableConfirm={true}
onOk={() => onDeleteProcesses()}
>
<ActionButton
id="delete-processes"
iconProps={{ iconName: 'Delete' }}
style={{ margin: '5px', float: 'right' }}
buttonType={ButtonType.default}
>
{__('delete')}
</ActionButton>
</Popover>
)}
{
<TooltipHost content={__('filter processes')} directionalHint={DirectionalHint.bottomCenter}>
<ActionButton
iconProps={{ iconName: 'Filter' }}
style={{ margin: '5px', float: 'right' }}
onClick={() => setFilterVisible(true)}
/>
</TooltipHost>
}
{
<TooltipHost content={__('History')} directionalHint={DirectionalHint.bottomCenter}>
<ActionButton
iconProps={{ iconName: 'History' }}
style={{ margin: '5px', float: 'right' }}
onClick={() => setShowHistoryModal(true)}
/>
{showHistoryModal && (
<Modal
title={__('history')}
isModalOpen={showHistoryModal}
hideFooter={true}
onCancel={() => {
setShowHistoryModal(false);
}}
>
<ProcessVersionsHistory selected_process={selected_process} showProcessInstances={showProcessInstances} />
</Modal>
)}
</TooltipHost>
}
{checkPermission(UserReducer.permissions, 'add_process') && (
<PrimaryButton
onClick={() => showProcessModal()}
style={{ margin: '5px', float: 'right' }}
iconProps={{ iconName: 'Add' }}
>
{__('new')}
</PrimaryButton>
)}
</Stack>
</div>
<div className={processesStyles.clear}></div>
</div>
);
};
const _onRenderRow: IDetailsListProps['onRenderRow'] = (props) => {
const customStyles: Partial<IDetailsRowStyles> = {};
if (props) {
customStyles.root = {
zIndex: 0,
transition: 'z-index 2s',
'&:hover': {
zIndex: 1000,
},
};
return <DetailsRow {...props} styles={customStyles} />;
}
return null;
};
return (
<>
{renderProcessesBtns()}
<div className={processesStyles.tableWrapper}>
<Stack className={processesStyles.table}>
<DetailsList
items={processes}
columns={columns}
selectionMode={SelectionMode.multiple}
setKey="none"
layoutMode={DetailsListLayoutMode.justified}
isHeaderVisible={true}
selection={_rowsSelected}
onRenderRow={_onRenderRow}
styles={gridStyles}
/>
</Stack>
</div>
{filterVisible && <ProcessFilter filterVisible={filterVisible} setFilterVisible={setFilterVisible} />}
{modalVisible && (
<ProcessForm
visible={modalVisible}
setVisible={setModalVisible}
add={addProcessAction}
update={updateProcessAction}
select={selectProcessAction}
selected={selected_process}
departments={departments}
roles={roles}
groups={processgroups}
UserReducer={UserReducer}
/>
)}
{sendVisible && selected_process && (
<SendForm
visible={sendVisible}
setVisible={setSendVisible}
select={selectProcessAction}
selected={selected_process}
departments={departments}
roles={roles}
send={shareProcessAction}
afterSend={() => getProcesses()}
mapRaciFields={mapRaciFields}
/>
)}
{showSpinner && (
<div className={processesStyles.spinnerOverlay}>
<Spinner size={SpinnerSize.large} className={processesStyles.spinner} />
</div>
)}
</>
);
};
type PropsFromRedux = ConnectedProps<typeof connector>;
const mapStateToProps = ({
UserReducer,
ProcessReducer,
ProcessGroupReducer,
StatusReducer,
DepartmentReducer,
RoleReducer,
}: RootState) => ({
UserReducer,
ProcessReducer,
ProcessGroupReducer,
StatusReducer,
DepartmentReducer,
RoleReducer,
});
const connector = connect(mapStateToProps, {
setMetaAction,
selectProcessByIdAction,
clearSelectProcessAction,
selectProcessAction,
addProcessAction,
updateProcessAction,
shareProcessAction,
fetchModelingInstances,
addProcessInstanceAction,
makeProcessVersionAction,
deleteProcessAction,
searchProcessesAction,
});
export default connector(withRouter(Processes));
for start and visible model is working but data can not be displayed.
What i want, a "reset/clear" button on the first page to refresh the searchable drop down list of react-select with Formik.This is the first page,the one after is the second,the problem iam facing is to refresh the code from a clear button in the first page,i tried everything i can to change,i added some props that are not needed.
<SearchableDropDownList
onChange={(value) =>
formik.setFieldValue('formDay', value || null)}
resetValue={resetValue}
value={formik.values.formDay}
options={dayOptions}
formik={formik}
/>
import React from 'react';
import Select from 'react-select';
import CreatableSelect from 'react-select/creatable';
import chroma from 'chroma-js';
import { StylesConfig } from 'react-select';
// https://codesandbox.io/s/1j4zxl8bq
export default ({ inputRef, onChange, options, value, className, resetValue, onBlur, formik }) => {
// -----------Creating design for react-select----------------------------For Creatable--umust
// --u must set this line as well : const color = chroma(data.color ?? 'black'); because there is no data on creatable
// so i must handle the empty created by the user input
const dot = (color = 'white') => ({
alignItems: 'center',
display: 'flex',
':before': {
backgroundColor: color,
borderRadius: 10,
content: '" "',
display: 'block',
marginRight: 8,
height: 10,
width: 10,
},
});
const colourStyles = {
control: (styles) => ({
...styles,
backgroundColor: '#212529',
borderRadius: 10,
borderColor: '#323232',
}),
option: (styles, { data, isDisabled, isFocused, isSelected }) => {
const randomColor = 'black';
const color = chroma(data.color ?? 'black');
return {
...styles,
backgroundColor: isDisabled
? undefined
: isSelected
? randomColor
: isFocused
? color.alpha(0.1).css()
: undefined,
color: isDisabled
? '#ccc'
: isSelected
? chroma.contrast(color, 'white') > 2
? 'white'
: 'blue'
: randomColor,
cursor: isDisabled ? 'not-allowed' : 'default',
':active': {
...styles[':active'],
backgroundColor: !isDisabled
? isSelected
? randomColor
: color.alpha(0.3).css()
: undefined,
},
};
},
input: (styles) => ({
...styles,
...dot(),
color: 'grey',
borderColor: '#6c5dd3',
text: 'john#domain.com',
}),
placeholder: (styles) => ({
...styles,
...dot('#ccc'),
borderColor: '#6c5dd3',
text: 'john#domain.com',
}),
singleValue: (styles, { data }) => ({
...styles,
...dot('white'),
color: 'grey',
borderColor: '#6c5dd3',
text: 'john#domain.com',
}),
};
if (resetValue === true) {
value = null;
// formik.setFieldValue('formDay', null)
resetValue = false;
}
const handleChange = (event) => {
// Overwrite the event with your own object if it doesn't exist
if (!event || value === null) {
event = {
target: inputRef,
value: '',
};
}
onChange(event);
};
const defaultValue = (options, value) => {
return options ? options.find((option) => option.value === value) : null;
// return {value:'developer',label:'Software Developer'};
};
// const randomColor = `#`.concat( Math.floor(Math.random()*16777215).toString(16))
// const color = chroma.random();
// const color = chroma(data.color ?? 'black');
// https://nibes.cn/blog/22525
return (
<div className={className}>
<CreatableSelect
value={defaultValue(options, value)}
styles={colourStyles}
onChange={handleChange}
isClearable
ref={inputRef}
options={options}
/>
</div>
);
};
I wanted to how to solve this error... this is not my code I am fixing bugs in someone else's code. "I wanted to how to dispatch to store with use effect Hook".
as I researched it says it says I can dispatch to store inside a function without a use effect Hook I wanted to know how to modify it in this code,
also if someone know how to getrid of "MapStateToProps" with the useSelect hook that will also be more helpfull for me inorder to improve this code...
LoginScreen.js
import React, { Component } from 'react';
import {
View, Text,
Image,
Dimensions,
ImageBackground,
SafeAreaView,
Alert,
Modal, Button,
StatusBar,
TextInput,
TextInputComponent,
Linking,
StyleSheet
} from 'react-native';
// import { PropTypes } from 'prop-types';
// import NetInfo from "#react-native-community/netinfo";
import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen';
// import * as Animatable from 'react-native-animatable';
import AsyncStorage from '#react-native-community/async-storage'
import { showMessage, hideMessage } from "react-native-flash-message";
const { width, height } = Dimensions.get('window');
import styles from './styles';
import Buttons from '../../../uiElements/Buttons/RoundButtons'
import VerificationCodeText from '../../../uiElements/VerificationCodeText'
import { connect } from 'react-redux';
import startUpActions from '../../../redux/StartUp/actions';
import Loading from '../../../uiElements/Loading';
import { ScrollView, TouchableHighlight, TouchableOpacity } from 'react-native-gesture-handler';
import { textFocusColor, textDefaultColor } from '../../../contents'
import TextInputField from '../../../uiElements/TextInput';
const { loginApp, getCustomerDetailsByEmail, clearProps, getAgentExposableId } = startUpActions;
const imageWidth = Dimensions.get('window').width;
// const imageWidth = Dimensions.get('window').width;
class StartScreen extends Component {
constructor(props) {
super(props);
this.state = {
hasFocusPhoneNo: false,
iseyeactivenew: true,
iseyeactivecurrent: true,
userId: '',
password: '',
hasFocusUsername: false,
hasFocusPassword: false,
}
}
static getStateFromProps(props, state) {
if (props.jwttoken != undefined) {
if (props.jwttoken == 'errlogin') {
}
}
}
static getDerivedStateFromProps(props, state) {
if (props.jwttoken != undefined) {
if (props.jwttoken == 'errlogin') {
showMessage({
textStyle: { paddingLeft: 10 },
titleStyle: { paddingLeft: 10 },
message: "Error",
description: "Username or Password incorrect",
type: "default",
backgroundColor: "red", // background color
color: "#ffffff",
duration: 3850
});
_storeAccess = async () => {
props.dispatch(clearProps())
}
_storeAccess()
} else {
_storeAccess = async () => {
await AsyncStorage.setItem('access_token', props.jwttoken);
const appIdRequest = await AsyncStorage.getItem('appIdrequest')
props.dispatch(getCustomerDetailsByEmail(props.jwttoken, '', state.userId))
//props.dispatch(clearProps())
}
_storeAccess();
}
}
if (props.customerDetailsAllResult != undefined) {
// console.log(props.customerDetailsAllResult.responseDto.customerDetailsId)
if (props.customerDetailsAllResult.responseDto == null) {
props.dispatch(clearProps())
} else {
_storeAccess = async () => {
await AsyncStorage.setItem('customerWalletId', props.customerDetailsAllResult.responseDto.agentSenderDetailsId.toString());
await AsyncStorage.setItem('email', props.customerDetailsAllResult.responseDto.email.toString()) //not change
await AsyncStorage.setItem('useremail', props.customerDetailsAllResult.responseDto.email.toString()) //when change coporate mail this will change
await AsyncStorage.setItem('agentSenderDetails', JSON.stringify(props.customerDetailsAllResult.responseDto))
const access_token = await AsyncStorage.getItem('access_token')
Console.log("navigate", access_token)
if (access_token != null) {
props.navigation.navigate('TabView')
}
// props.navigation.navigate('MoneyTransfer2')
props.dispatch(clearProps())
}
_storeAccess();
}
}
if (props.agentExposableId != undefined) {
if (props.agentExposableId == null) {
props.dispatch(clearProps()) //loginurl https://qabankingauth.monexfintech.com/v1/auth/authenticate
} else {
_storeAccess = async () => { await AsyncStorage.setItem('agentExposableId', props.agentExposableId); }
// props.navigation.navigate('MoneyTransfer2')
props.dispatch(clearProps())
}
_storeAccess();
}
return null;
}
componentDidMount() {
// console.log('lll')
}
componentDidUpdate(prevProps, prevState) {
if (prevProps.customerDetailsAllResult !== this.props.customerDetailsAllResult) {
}
if (prevProps.jwttoken !== this.props.jwttoken) {
console.log(this.props.jwttoken)
}
}
getData = async () => {
try {
const accesstoken = await AsyncStorage.getItem('access_token')
if (accesstoken !== null) {
this.props.dispatch(userShow(accesstoken))
this.setState({ islogin: true })
console.log('jjj')
// this.props.navigation.navigate('TabView')
} else {
this.props.dispatch(getBranchesList())
this.setState({ islogin: false })
// this.props.navigation.navigate('TabView')
}
} catch (e) {
console.log(e)
}
}
onChangeText = (key, val) => {
this.setState({ [key]: val }, () => {
})
}
onpressphoneno = () => {
this.setState({ hasFocusPhoneNo: true })
this.setState({ postcodeerror: false })
}
btnPress = async () => {
this.props.navigation.navigate('LoginScr')
if (this.state.userId == '' || this.state.password == '') {
showMessage({
textStyle: { paddingLeft: 10 },
titleStyle: { paddingLeft: 10 },
message: "Error",
description: "Please enter Username and Password",
type: "default",
backgroundColor: "red", // background color
color: "#ffffff",
duration: 3850
});
} else {
try {
const obj = {
username: this.state.userId,
password: this.state.password,
grantType: 'Agent Customer',
agentRegNumber: 'MXAG01'
}
await AsyncStorage.setItem('email', this.state.userId);
await AsyncStorage.setItem('useremail', this.state.userId);
await AsyncStorage.setItem('password', this.state.password);
await AsyncStorage.setItem('access_token', ' eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJjaGF0aHVyYW5nYUBjb2RlbGFudGljLmNvbSIsInVzZXJfaWQiOjMsImV4cCI6MTYxNTQzODI4NywiaXNfdGZhX2VuYWJsZWQiOm51bGwsImlhdCI6MTYxNTQzNDY4NywidGZhRGVmYXVsdFR5cGUiOm51bGwsImNsaWVudF9jb2RlIjoiTU4ifQ.lncV1VQ-T0dNPsME0_FvRF-2TQShHiwP66aFoT0fhV58QaR-Sn0ZVEBPSiGxxQ9NWnzbaCpev61Hkex6EPBxNA');
// this.props.dispatch(getFirstValue());
this.props.dispatch(getAgentExposableId());
this.props.dispatch(loginApp(obj))
this.props.dispatch(clearProps());
} catch (error) {
console.log(error);
}
//this.props.navigation.navigate('LoginScr')
}
}
clickPrivacypolicy() {
Linking.canOpenURL("https://spoton.money/policy-procedures-refund-terms-gdpr").then(supported => {
if (supported) {
Linking.openURL("https://spoton.money/policy-procedures-refund-terms-gdpr");
} else {
console.log("Don't know how to open URI: " + this.props.url);
}
});
}
render() {
// const { navigate } = this.props.navigation;
return (
<SafeAreaView style={style.container}>
<ScrollView style={{ backgroundColor: '#343A4F', }}>
<View style={{ backgroundColor: '#343A4F', height: '100%' }}>
<ImageBackground source={require('../../../images/ellipse.png')} style={{ width: '100%', height: '60%' }}>
<View style={{ alignItems: 'center', paddingTop: wp('15%') }}>
<Image
style={{ width: wp('45%'), height: wp('15%') }}
source={require('../../../images/spotonmoneylogo.png')}
/>
</View>
{this.props.loading && <Loading navigation={this.props.navigation} animating={true} />}
<View style={{ paddingLeft: wp('5%'), paddingRight: wp('5%'), backgroundColor: '#343A4F', marginTop: wp('50%') }}>
{/* <TextInput
placeholder="Username"
placeholderTextColor={textDefaultColor}
onFocus={() =>this.setState({ hasFocusUsername: true })}
onBlur={() => this.setState({ hasFocusUsername: false })}
onChangeText={(val) => this.setState({ userId: val })}
style={
this.state.hasFocusUsername ?
styles.focusedTextInput :
styles.txtstyle
}
/> */}
<TextInputField
placeholdertext="Username"
valuetext={this.state.email}
onFocusFunc={() => this.setState({ hasFocusUserName: true })}
onBlurFunc={() => this.setState({ hasFocusUserName: false })}
onChangeTextFunc={value => this.onChangeText('userId', value)}
iserrortext={this.state.errorlastnamestate}
editabletext={false}
keyboardType1='email'
// texterror={this.state.errorlastnametextstate}
// hasFocustext={this.state.hasFocusUserName}
/>
<TextInputField
placeholdertext="Password"
valuetext={this.state.password}
onFocusFunc={() => this.setState({ hasFocusPassword: true })}
onBlurFunc={() => this.setState({ hasFocusPassword: false })}
onChangeTextFunc={value => this.onChangeText('password', value)}
iserrortext={this.state.errorlastnamestate}
editabletext={false}
secureTextEntrytxt={true}
// texterror={this.state.errorlastnametextstate}
hasFocustext={this.state.hasFocusPassword}
/>
{/* <TextInput
placeholder="Password"
placeholderTextColor={textDefaultColor}
secureTextEntry={true}
onFocus={() => this.setState({ hasFocusPassword: true })}
onBlur={() => this.setState({ hasFocusPassword: false })}
onChangeText={(val) => this.setState({ password: val })}
style={
this.state.hasFocusPassword ?
styles.focusedTextInput :
styles.txtstyle
}
/> */}
</View>
<View style={{ paddingTop: wp('10%'), alignItems: 'center' }}>
<TouchableOpacity onPress={() => this.props.navigation.navigate('Verification')}>
<Text style={{ color: 'white' }}>Forgot Password</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => this.btnPress()}>
<Buttons text="Log In" btnfontSize={wp('4%')}
btnbackgroundColor='#F15622'
btntxtncolor="#ffffff"
btnMarginRight={imageWidth / 1000}
btnMarginLeft={imageWidth / 1000}
onPress={() => this.btnPress()} />
</TouchableOpacity>
<View style={{ paddingTop: wp('4%') }}>
<Text style={{ color: 'white', fontSize: wp('4%') }}>Don't have an account?
<TouchableOpacity onPress={() => this.props.navigation.navigate('VerificationSignUp')}>
<Text style={{ color: '#2793E1', fontWeight: 'bold', textDecorationLine: 'underline' }}>
Sign Up
</Text>
</TouchableOpacity>
</Text>
</View>
<View style={{ padding: wp('4%'), marginTop: hp('4%'), alignContent: 'center' }}>
<TouchableOpacity >
<Text style={{ color: 'white', fontSize: wp('3%') }}>By logging in you agree to the Spoton money
<TouchableOpacity onPress={() => this.clickPrivacypolicy()}>
<Text style={{ color: '#2793E1', fontSize: wp('3%'), paddingTop: wp('1%') }}>
Privacy policy .
</Text>
</TouchableOpacity>
and acknowledge our
<TouchableOpacity onPress={() => this.clickPrivacypolicy()}>
<Text style={{ color: '#2793E1', fontSize: wp('3%'), paddingTop: wp('1%') }}>
Terms & Conditions.
</Text>
</TouchableOpacity>
</Text>
</TouchableOpacity>
</View>
</View>
</ImageBackground>
</View>
</ScrollView>
</SafeAreaView>
);
}
}
const mapStateToProps = state => {
return {
...state.startUpReducer
}
// loading: state.startUpReducer.loading,
// jwttoken: state.startUpReducer.jwttoken,
// customerDetailsAllResult: state.startUpReducer.customerDetailsAllResult,
// agentExposableId: state.startUpReducer.exposable_id
};
export default connect(mapStateToProps)(StartScreen);
const style = StyleSheet.create({
container: {
backgroundColor: '#343A4F',
height: wp()
}
})
redux/Actions.js
loginApp: (value) => ({
type: actions.LOGIN_SCREEN,
value
}),
redux/reducer.js
case startUpActions.LOGIN_SCREEN:
return{
...state,
loading:true
}
case startUpActions.LOGIN_SCREEN_RESULT:
return{
loading:false,
jwttoken:action.result.jwttoken
}
case startUpActions.LOGIN_SCREEN_ERROR:
return{
loading:false,
jwttoken:'errlogin'
}
redux/saga.js
export function* loginApp(){
yield takeEvery(actions.LOGIN_SCREEN, function* (payload) {
const requestBody=payload.value
const url = loginURL;
console.log(requestBody);
console.log(url);
try {
const response = yield fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(requestBody)
});
console.log(response)
const result = yield response.json();
console.log(result)
if (response.ok) {
yield put({ type: actions.LOGIN_SCREEN_RESULT, result });
} else {
yield put({
type: actions.LOGIN_SCREEN_ERROR,
result
});
}
} catch (error) {
yield put({ type: actions.LOGIN_SCREEN_ERROR });
}
});
}
I'm trying to execute a function and navigate to the next screen using React-navigation and creating an Axios post
I've already tried combining both function's but It doesn't seem to execute the createOrder function
If I run the createOrder function alone it does work
onPress={
() => {
this.createOrder
this.props.navigation.navigate('Cart', {
order : this.state.order
});
}
}
import React from 'react';
import {
View,
StyleSheet,
Text,
Image,
TouchableOpacity
} from 'react-native';
//Redux
import { connect } from 'react-redux';
import { addItemToCart, removeItem } from '../../actions/ProductActionCreators';
//Products
import Products from '../../components/products/Products';
// Api Url
import ApiUrl from '../../helpers/ApiUrl'
//UI LIBRARY
import { Input, Button } from 'react-native-elements';
import {LinearGradient} from "../../components/LinearGradient";
import { ButtonGroup } from 'react-native-elements';
import Icon from "react-native-vector-icons/Ionicons";
//AXIOS
import axios from 'axios';
export class ProductsListView extends React.Component {
constructor(props) {
super(props);
const { rows } = this.props.navigation.state.params;
const arrays = Object.values( {rows});
this.state = {
arrays,
filteredProducts: arrays,
selectedIndex: 2
};
this.updateIndex = this.updateIndex.bind(this)
}
createOrder () {
axios.post( ApiUrl + 'api/order/post', {
code: "4f",
status: "waiting",
user_name: "salman",
user_id: 1,
club_id: 1,
})
.then(response => {
this.setState({
order: response.data,
});
console.log('created order',this.state.order)
})
.catch(function (error) {
console.log('error',error);
})
}
updateIndex (selectedIndex) {
this.setState({selectedIndex})
}
filterAll(){
}
filterStrong(){
this.setState({
arrays: this.state.arrays[0].products.filter(item => item.type == "strong" )
})
console.log(this.state.arrays)
}
filterNormal(){
}
render() {
const component1 = () => <Icon
name="ios-star"
size={15}
color="gold"
/>
const component2 = () => <Icon
name="ios-beer"
size={15}
color="gold"
onPress={() => this.filterStrong}
/>
const component3 = () => <Icon
name="ios-wine"
size={15}
color="gold"
/>
const buttons = [{ element: component1 }, { element: component2 }, { element: component3 }]
const { selectedIndex } = this.state
return (
<View style={styles.container} >
<Image
style={styles.imageCard}
source={
{
uri:
this.state.arrays[0].image
}
}
/>
<Text style={styles.title} >
{this.state.arrays[0].name}
</Text>
<Products
products={this.state.arrays[0].products}
addItemToCart={this.props.addItemToCart}
removeItem={this.props.removeItem}
/>
<View style={{
justifyContent:'center',
width: '100%',
padding: 50,
paddingTop:20,
}}>
<Button
title="Go to my cart"
containerStyle={{ flex: -1 }}
buttonStyle={styles.signUpButton}
linearGradientProps={{
colors: ['#dd016b', '#dd016b'],
start: [1, 0],
end: [0.2, 0],
}}
ViewComponent={LinearGradient}
titleStyle={styles.signUpButtonText}
// onPress={this.createOrder}
onPress={
() => {
this.createOrder
this.props.navigation.navigate('Cart', {order : this.state.order});
}
}
/>
</View>
</View>
)
}
}
const mapDispatchToProps = {
addItemToCart,
removeItem
}
export default connect(null, mapDispatchToProps) (ProductsListView);
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
width:'100%',
backgroundColor: 'black',
},
signUpButtonText: {
// fontFamily: 'bold',
fontSize: 13,
},
signUpButton: {
width: 250,
borderRadius: 50,
height: 45,
},
title: {
color:'white',
fontSize:32,
height: 100,
position: 'relative',
backgroundColor: '#00000054',
width: "100%",
textAlign: 'center',
paddingTop: 30,
},
imageCard:{
height:100,
width:'100%',
position: "absolute",
top: 0,
backgroundColor: 'white'
},
button: {
padding: 5,
borderRadius: 25,
margin: 5,
backgroundColor: '#DD016B',
color: 'white',
alignItems: 'center',
justifyContent: 'center',
},
})
I'm trying to navigate to the next screen with the data from I get from my Axios post.
You are not calling the createOrder function.
Try this:
<Button
title="Go to my cart"
containerStyle={{ flex: -1 }}
buttonStyle={styles.signUpButton}
linearGradientProps={{
colors: ["#dd016b", "#dd016b"],
start: [1, 0],
end: [0.2, 0]
}}
ViewComponent={LinearGradient}
titleStyle={styles.signUpButtonText}
// onPress={this.createOrder}
onPress={this.onGoToMyCartPressed}
/>;
And onGoToMyCartPressed would look like:
onGoToMyCartPressed = () => {
this.createOrder(); // <- Call the function
this.props.navigation.navigate("Cart", { order: this.state.order });
};
And, if you want to navigate after the order has been created, then, have your createOrder return the promise, and you can chain off of it in the onGoToMyCartPressed
Like so:
createOrder() {
// Return the promise from here
return axios.post( ApiUrl + 'api/order/post', {
code: "4f",
status: "waiting",
user_name: "salman",
user_id: 1,
club_id: 1,
}).then(response => {
this.setState({
order: response.data,
});
console.log('created order',this.state.order)
}).catch(function (error) {
console.log('error',error);
})
}
And modify the onGoToMyCartPressed to use the promise returned.
onGoToMyCartPressed = () => {
// CHange the page once the order has been craeted
this.createOrder().then(() => {
this.props.navigation.navigate("Cart", { order: this.state.order });
})
};
Any idea why {this.state.showTabBar === true ? this._renderTabBar : null} fails in SampleApp component? Works fine if render just <TabBarExample />.
My goal is to use this.state.showTabBar to decide when to show TabBarIOS.
Here's a React Native Playground link:
https://rnplay.org/apps/5pQC9A
'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
TabBarIOS,
TouchableHighlight,
} = React;
var SampleApp = React.createClass({
getInitialState: function() {
return {
showTabBar: true // I will eventually use this to decide
// if TabBarIOS will be visible.
};
},
_renderTabBar: function() {
return (
<TabBarExample />
);
},
render: function() {
return (
// This line fails.
{this.state.showTabBar === true ? this._renderTabBar : null}
// <TabBarExample /> // This will work if uncomment.
);
}
});
var TabBarExample = React.createClass({
statics: {
title: '<TabBarIOS>',
description: 'Tab-based navigation.',
},
displayName: 'TabBarExample',
getInitialState: function() {
return {
selectedTab: 'blueTab',
notifCount: 0,
presses: 0,
};
},
_renderContent: function(color: string, pageText: string, num?: number) {
return (
<View style={[styles.tabContent, {backgroundColor: color}]}>
<Text style={styles.tabText}>{pageText}</Text>
<Text style={styles.tabText}>{num} re-renders of the {pageText}</Text>
</View>
);
},
render: function() {
return (
<TabBarIOS
tintColor="white"
barTintColor="darkslateblue"
translucent={true}>
<TabBarIOS.Item
title="Blue Tab"
systemIcon="search"
selected={this.state.selectedTab === 'blueTab'}
onPress={() => {
this.setState({
selectedTab: 'blueTab',
});
}}>
<MyViewOne />
</TabBarIOS.Item>
<TabBarIOS.Item
title="Red Tab"
systemIcon="history"
badge={this.state.notifCount > 0 ? this.state.notifCount : undefined}
selected={this.state.selectedTab === 'redTab'}
onPress={() => {
this.setState({
selectedTab: 'redTab',
notifCount: this.state.notifCount + 1,
});
}}>
{this._renderContent('#783E33', 'Red Tab', this.state.notifCount)}
</TabBarIOS.Item>
<TabBarIOS.Item
systemIcon="contacts"
title="More Green"
selected={this.state.selectedTab === 'greenTab'}
onPress={() => {
this.setState({
selectedTab: 'greenTab',
presses: this.state.presses + 1
});
}}>
{this._renderContent('#21551C', 'Green Tab', this.state.presses)}
</TabBarIOS.Item>
</TabBarIOS>
);
}
});
var MyViewOne = React.createClass({
render: function() {
return (
<View style={[styles.tabContent, {backgroundColor: 'orange'}]}>
<Text style={styles.tabText}>I like Iron Maiden</Text>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
tabContent: {
flex: 1,
alignItems: 'center',
},
tabText: {
color: 'white',
margin: 50,
},
button: {
backgroundColor: 'green',
margin: 10,
}
});
AppRegistry.registerComponent('SampleApp', () => SampleApp);
Like Gortem said, you are not calling the function. React will not do it for you.
Also, instead of a ternary, your could do:
{this.state.showTabBar && this._renderTabBar()}
Or directly:
{this.state.showTabBar && (<TabBarExample />)}
I think you should make showTabBar one of your state:
getInitialState: function(){
return{
showTabBar: {false}
};
}
and use
this.setState({showTabBar:{true}});
to update
You should have your logic outside of the return statement like this:
render: function() {
if (this.state.showTabBar) {
return (this._renderTabBar());
} else {
return (<View />);
}
}
It's also good to note that you will always need to return a component, even if it is a blank View.
Here is the working example: https://rnplay.org/apps/-TjJ7w