How to fix in smartclient listgrid images sometimes not loading? - smartclient

Here is the listGrid component.
https://smartclient.com/smartclient/showcase/?id=fetchOperationFS
It has no examples with images, at least I did not find.
So when you scroll the grid, it fetches from server that part of items, as I understand bit wider than visible area.
But problem is - sometimes images do not load when scroling:
As you can see on the right column (Options) - there should be 3 images in every row. Sometimes they load later. Sometimes they do not load unless you do something, like checking network tab in chrome dev tools, clicking on other images. Also after you scroll up and down, it probably redraws and those images load.
How can this be?
There is such method which draws those images:
private _createListGridRecordComponent(record, colNum: number) {
let result: isc.ICanvas | null = null
switch (this.listGrid.getFieldName(colNum)) {
case "#state":
if(record["#invoiceIsValid"]) {
result =
<HLayout height={25} width={25} membersMargin={2}>
<Img width={25} src={component.icons.small.correct}/>
</HLayout>
} else {
result =
<HLayout height={25} width={25} membersMargin={2}>
<Img width={25} src={component.icons.small.warning}/>
</HLayout>
}
break
case "#options":
result =
<HLayout height={25} width={25} membersMargin={2}>
<Img width={25} src={component.icons.small.preview}
click={() => this._events.onPreviewClicked.fire(record)}/>
<Img width={25} src={component.icons.small.send_mail}
click={() => this._events.onSendEmailClicked.fire(record)}/>
<Img width={25} src={component.icons.small.generate_xml}
click={() => this._events.onGenerateXmlClicked.fire(record)}/>
</HLayout>
break
default:
// do nothing
}
return result
}
You can see '#options' case.
I have tried to 'cache' this code
const icons =
<HLayout height={25} width={25} membersMargin={2}>
<Img width={25} src={component.icons.small.preview}
/>
<Img width={25} src={component.icons.small.send_mail}
/>
<Img width={25} src={component.icons.small.generate_xml}
/>
</HLayout>
by assigning it to variable and then pass icons to _createListGridRecordComponent and assigne icons to result variable.
but then it did not render images at all.
Of course if I cache this way, I would need a solution with click events, because every row needs different record object. But first I would need to somehow make always render images.
Update
Noticed one intereting detail:
Here is the details page when we click on eye icon:
So invoice number ends with 10022.
But eye icon which I clicked to open this details page is in row other than invoice ending 10022. The invoice ending 10022 is the last row in this case, which does not have eye icon.
So it means the icons are in wrong rows.
List grid is created this way:
{this.listGrid =
<ListGrid dataSource={InvoiceDataSource.sc()}
useAllDataSourceFields={false}
selectionAppearance="checkbox"
rowDoubleClick={(record: InvoiceDataSource.Record) => {
const refresh = (r: InvoiceDataSource.Record|null) => {
if (!r) return
const rowNum = this.listGrid.getRecordIndex(r)
if (rowNum !== -1) this.listGrid.refreshRow(rowNum)
};
const lastRecord = this._activeRecord
this._activeRecord = record
refresh(lastRecord)
this._events.onPreviewClicked.fire(record)
refresh(this._activeRecord)
}}
showRecordComponents
showRecordComponentsByCell
createRecordComponent={(record, colNum) => this._createListGridRecordComponent(
record,
colNum,
preview,
sendMail,
xml
)}
mixin={mixin.client_management.AirportMixin()}
hilites={[
{
cssText: "background: #E53935;"
}
]}
getCellCSSText={(record: InvoiceDataSource.Record) => {
if (this._activeRecord && record.id === this._activeRecord.id) {
return "background: #F5F7F7;"
}
return ""
}}
>
<ListGridField name={"#state"}
title={translation.title.state}
/>
<ListGridField name={"#invoiceNo"}/>
<ListGridField name={"client"}/>
<ListGridField name={"name"}/>
<ListGridField name={"invoiceType"}/>
<ListGridField name={"validFrom"}/>
<ListGridField name={"validTo"}/>
<ListGridField name={"scheduledForSending"}/>
<ListGridField name={"mustBePaid"}/>
<ListGridField name={"status"}/>
<ListGridField name={"notified"}/>
<ListGridField name={"lastUpdatedTime"}/>
<ListGridField name={"insertedTime"}/>
<ListGridField name={"#options"}
title={translation.title.options}
canFilter={false}
canSort={false}
/>
</ListGrid>
}
And little bit update function of icons creaion, tried using svg, save them into variable and pass them to function which generates icons, but looks like not image problem at all but position problem.
private _createListGridRecordComponent(record, colNum: number, preview: string, sendMail: string, xml: string) {
let result: isc.ICanvas | null = null
switch (this.listGrid.getFieldName(colNum)) {
case "#state":
if(record["#invoiceIsValid"]) {
result =
<HLayout height={25} width={25} membersMargin={2}>
<Img width={25} src={component.icons.small.correct}/>
</HLayout>
} else {
result =
<HLayout height={25} width={25} membersMargin={2}>
<Img width={25} src={component.icons.small.warning}/>
</HLayout>
}
break
case "#options":
result =
<HLayout height={25} width={25} membersMargin={2}>
{/*<Img width={25} src={component.icons.small.preview}*/}
{/* click={() => this._events.onPreviewClicked.fire(record)}/>*/}
{/*<Img width={25} src={svg}*/}
{/* click={() => this._events.onPreviewClicked.fire(record)}/>*/}
<HTMLFlow width={25} contents={ preview } click={() => this._events.onPreviewClicked.fire(record)} />
{/*<HTMLFlow contents={ preview } click={() => this._events.onPreviewClicked.fire(record)} />*/}
{/*<HTMLFlow contents={ preview } click={() => this._events.onPreviewClicked.fire(record)} />*/}
<HTMLFlow width={25} contents={ sendMail } click={() => this._events.onSendEmailClicked.fire(record)} />
{/*<HTMLFlow contents={ xml } click={() => this._events.onGenerateXmlClicked.fire(record)} />*/}
{/*<Img width={25} src={component.icons.small.send_mail}*/}
{/* click={() => this._events.onSendEmailClicked.fire(record)}/>*/}
{/*<Img width={25} src={component.icons.small.generate_xml}*/}
{/* click={() => this._events.onGenerateXmlClicked.fire(record)}/>*/}
</HLayout>
break
default:
// do nothing
}
So how can there be wrong position of icons?

Related

Implementing react-hook-forms and react-select with radio buttons and multi inputs combo

Ready for a complicated one?
Using react-hook-forms and react-select using creatable (user creates multiple inputs on the fly)
I'm trying to implement a form that uses an option on 4 radio buttons, 2 of which reveal multi inputs (inputs that use react-select where the user can create multiple entries, not a dropdown) and trying to keep track of both the radio inputs and the multi inputs in the final useForm() object. I also need to be able to remove them if the user changes their mind or resets the form in total. Right now, the key values of registrationTypes changes when I change radioTwo and enter inputs. I also don't know how to remove user inputs. I'm using Controller to read the entries (although I've heard if you're using native HTML checkbox input, you have to use Register?) . Here's the code:
import styled from 'styled-components'
import Creatable from 'react-select/creatable'
import { Controller } from 'react-hook-form'
import { ErrorRow } from '../util/FormStyles'
import { FormRulesProps } from '../util/formRuleTypes'
import FormError from './FormError'
const registrationTypes = [
{
label: 'Allow anyone with the link to register',
value: 'radioOne',
},
{
label: 'Allow anyone with this email domain to register:',
value: 'radioTwo',
},
{ label: 'Allow anyone with this code to register:', value: 'radioThree' },
{
label: 'Define eligible users manually through eligibilty file.',
value: 'radioFour',
},
]
const RegistrationEligibilty = () => {
const {
control,
reset,
handleSubmit,
formState: { errors },
} = useForm<any>()
const [selectedRadio, setSelectedRadio] = useState({ regType: '' })
const onSubmit = (data: any) => {
console.log(data)
}
const handleSelected = (value: string) => {
setSelectedRadio({ ...selectedRadio, regType: value })
}
return (
<RegistrationEligibiltyContainer>
<form onSubmit={handleSubmit(onSubmit)}>
<FormRow>
<RadioWrapper>
{registrationTypes.map((rt) => (
<Controller
key={rt.value}
control={control}
name="radio"
render={({ field: { onChange, value } }: any) => (
<RadioGroup
// #ts-ignore
value={value}
onChange={(e: any) =>
onChange(e.target.value, handleSelected(rt.value))
}
>
<Radio
name={rt.value}
type="radio"
value={rt.value}
checked={selectedRadio.regType === rt.value}
/>
<TextRow
text={rt.label}
style={{ paddingLeft: '10px' }}
/>
{selectedRadio.regType === 'radioTwo' &&
rt.value === 'radioTwo' && (
<FormRow>
<div style={{ width: '90%' }}>
<Controller
name={rt.value}
control={control}
render={({ field }) => (
<Creatable
{...field}
isMulti
options={field.value}
value={field.value}
placeholder="Select domains"
/>
)}
/>
</div>
</FormRow>
)}
{selectedRadio.regType === 'radioThree' &&
rt.value === 'radioThree' && (
<FormRow>
<div style={{ width: '90%' }}>
<Controller
name={rt.value}
control={control}
render={({ field }) => (
<Creatable
{...field}
isMulti
options={field.value}
value={field.value}
placeholder="Select codes"
/>
)}
/>
</div>
</FormRow>
)}
</RadioGroup>
)}
/>
))}
</RadioWrapper>
</FormRow>
</FormContent>
</form>
</RegistrationEligibiltyContainer>
)
}
export default RegistrationEligibilty
The result looks like this:
https://imgur.com/a/6oGhqRb
I also need to be able to remove them if the user changes their mind or resets the form in total
If the component is unmounted, the value of the component is not included in the result. Make sure your Creatable is unmounted when the relevant radio is not selected

How to delete Call code from a phone number in React Native?

I'm using react-native-phone-number-input and i want to delete the call code from the number if the user types it.
my solution is :
class PhoneUserInput extends PureComponent {
...
<PhoneInput
ref={this.myRef}
onChangeFormattedText={(value) => {
if (value.substr(`+${this.myRef.current?.getCallingCode()}`.length)
.startsWith(`+${this.myRef.current?.getCallingCode()}`)) {
value = value.substr(`+${this.myRef.current?.getCallingCode()}`.length)
.replace(`+${this.myRef.current?.getCallingCode()}`, ''));
}
onChangeFormattedText(value);
console.log('formated value'+value);
}
}}
/>
}
I tried to the same thing on onChangeText props but it's doesn't give the effect instantly on the component.
Please try to do your work with
onChangeText={ (_text)=>{ //Your code} }
AND add :
value={value}
Here is a working example :
<PhoneInput
ref={phoneInput}
defaultValue={value}
value={value}
defaultCode="FR"
layout="first"
placeholder={label}
containerStyle={styles.phoneContainer}
onChangeText={(text) => {
setValue(text)
}}
onChangeFormattedText={(text) => {
setFormattedValue(text)
}}
withDarkTheme
withShadow
/>

Validator for password not working on react native

I am working on latest react-native version.
I'm trying to implement a custom validator to check if the password and password confirm are equal. The problem is that the validator function is not working.
Library Link react-reactive-form
Code
MatchPassword(AC: AbstractControl) {
let password = AC.get('new_password').value; // to get value in input tag
let confirmPassword = AC.get('confirm_password').value; // to get value in input tag
if (password !== confirmPassword) {
AC.get('confirm_password').setErrors({ mismatch: true });
} else {
return null;
}
}
changePasswordForm = FormBuilder.group({
new_password: ['', [Validators.required]],
confirm_password: ['', [Validators.required]],
}, {
validator: this.MatchPassword,
});
render() {
return (
<Fragment>
<FieldGroup
control={this.changePasswordForm}
render={() => {
return (
<Fragment>
<FieldControl
name="new_password"
render={({ handler, touched, hasError, ...props }) => (
<Fragment>
<TextInput {...props} label="New Password" placeholder="Password" handler={handler} type="password" secureTextEntry />
{(touched && hasError('required')) && <ErrorText message="This Field Should Not Be Empty." />}
</Fragment>
)}
/>
<FieldControl
name="confirm_password"
render={({ handler, touched, hasError, ...props }) => (
<Fragment>
<TextInput {...props} label="Confirm Password" placeholder="Confirm Password" handler={handler} type="password" secureTextEntry />
{(touched && hasError('required')) && <ErrorText message="This Field Should Not Be Empty." />}
{(touched && hasError('mismatch')) && <ErrorText message="Password No Match!" />}
</Fragment>
)}
/>
<Button onPress={() => this.handleSubmit()} variant="success" block large style={[mb0, mr15, flex1]}>Submit</Button>
</Fragment>
);
}}
/>
</Fragment>
);
}
Please tell me how to do this?
Actually, you have used the react JS packages to validate the form. React JS packages can't be used for react-native projects. You should check this here
Abstract of your problem:
react library actually does not have anything related to Browser DOM HTML. Anything related to it separated into react-dom package. React Native does not and cannot use this library, because you don't have DOM underneath a react native application. However you can use most of the code/functionality you wrote for your mobile app in the browser
You can validate your form using these packages:
https://www.npmjs.com/package/react-native-form-validator
https://www.npmjs.com/package/react-native-validator-form
https://github.com/jeffraux/react-native-validate-form

Navigation problem in react with ionic framwork

I am using Ionic react I have below tabs on the bottom of my app and want to navigate from job and messages to different components associated with tabs on the click of tabs. But the issue is Page do not render on the click of tabs but if I refresh my page then navigation works fine. I don't know what I am missing here.
render() {
const { _token } = this.state;
let isJobActive = Global.myJobActive();
let isMessageActive = Global.messageActive();
let isMoreActive = Global.moreActive();
let isAddJobActive = Global.addJobActive();
return (
<IonReactRouter>
<IonPage>
<Route exact path="/" render={() => <Redirect to="/home" />} />
<IonTabs>
<IonRouterOutlet>
{/* message */}
<Route
path="/messages"
component={WithRouterPath(MessagesHome)}
exact={true}
/>
{/* jobs */}
<Route
path="/add-job"
component={WithRouterPath(PostJob)}
exact={true}
/>
<Route
path="/my-jobs"
component={WithRouterPath(MyJobs)}
exact={true}
/>
<Route
path="/more-option"
component={WithRouterPath(MoreOptions)}
exact={true}
/>
</IonRouterOutlet>
{/* <div className="footer_menu"> */}
<IonTabBar slot="bottom">
<IonTabButton
tab="addjob"
href="/add-job"
onClick={() => {
this.setState({
isJobActive: 0,
isMessageActive: 0,
isMoreActive: 0,
isAddJobActive: 1
});
}}
>
<AddJob isActive={isAddJobActive} />
<IonLabel>Add Job</IonLabel>
</IonTabButton>
<IonTabButton
tab="myjobs"
href="/my-jobs"
onClick={() => {
this.setState({
isJobActive: 0,
isMessageActive: 0,
isMoreActive: 0,
isAddJobActive: 1
});
}}
>
<MyJob isActive={isJobActive} />
<IonLabel>My Jobs</IonLabel>
</IonTabButton>
<IonTabButton
tab="messages"
href="/messages"
onClick={() => {
this.setState({
isJobActive: 0,
isMessageActive: 1,
isMoreActive: 0,
isAddJobActive: 0
});
}}
>
<Message isActive={isMessageActive} />
<IonLabel>My Messages</IonLabel>
</IonTabButton>
<IonTabButton
tab="more-option"
href="/more-option"
onClick={() => {
this.setState({
isJobActive: 0,
isMessageActive: 0,
isMoreActive: 1,
isAddJobActive: 0
});
}}
>
<More isActive={isMoreActive} />
<IonLabel>More</IonLabel>
</IonTabButton>
</IonTabBar>
{/* </div> */}
</IonTabs>
</IonPage>
</IonReactRouter>
);
}
So this is my code when I click any tab it redirects to that URL but didn't render the component.
This all happened after I update ionic version
In my package.json
"#ionic/react": "^4.11.4",
"#ionic/react-router": "^4.11.4",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
and my WithRouterPath component is like below
const WithRouterPath = (WrappedComponent, options = {}) => {
const HOC = class extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
Global.isFooterVisible();
}
componentDidUpdate(prevProps) {
Global.isFooterVisible();
}
render() {
return <WrappedComponent {...this.props} />;
}
};
return HOC;
};
export default WithRouterPath;
I had this issue. I am new to Ionic and React, so I don't really know if this issue is the same as mine, but I will let you know what I found. In my app I had a router setup in the app file that redirected /tabs to a page called mainTabs. The Tabs were actually setup in that mainTabs page. The problem was that in the router settings for redirecting traffic to the tabs page I had "exact={true}" set. This doesn't allow you to pass /tab/* as possibilities. When I took "exact={true}" off the route going to my tabs it fixed it.

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"
...