Can I make a TextInput required? - validation

I have a lot of code like
if (myTextInput.text != "") {
handleEvent();
}
Does TextInput have some property I can use to automatically check for an empty string? Similar to how if I set it like :
<s:TextInput id="myInput" enter="myInputHandler()" restrict="A-Za-Z0-9"/>
then myInputHandler() only gets called if the text is alphanumeric. I'd like to add an additional restriction that length is greater than 0.
I know about the validators, but I still have to call them manually.

To make a TextInput component "required", you can, for example, create your own text input component and use a property to indicate if the control is required or not, and some event listeners like for FocusEvent.FOCUS_OUT event to force your user to enter something in that input.
For that, take this example :
package myComponent
{
import flash.events.FocusEvent;
import spark.components.TextInput;
public dynamic class MyTextInput extends TextInput
{
private var _required:Boolean = false;
public function MyTextInput()
{
super();
this.addEventListener(FocusEvent.FOCUS_OUT, on_KeyDown);
}
public function set required(required:Boolean): void {
this._required = required;
}
public function get required(): Boolean {
return this._required;
}
private function on_KeyDown(e:FocusEvent): void {
if(this.text == '' && this._required){
this.setFocus();
}
}
}
}
Of course this is just an example, you can use any behavior you want when your user left the input empty ...
Then to use that new component :
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
<!-- don't forget to include the namespace definition for your custom component -->
xmlns:MyComponent="myComponent.*">
<MyComponent:MyTextInput required="true" restrict="A-Za-z0-9"/>
</s:Application>
For more about creating your own components, take a look here.
Hope that can help.

Try :
if ( String(myTextInput.text).length > 0 )
{
handleEvent();
}
If that's all the code you need (no extra commands) then just do as one-line :
if ( String(myTextInput.text).length > 0 ) { handleEvent(); }

Maybe, this is not the kind of solution but, you can put the TextField into a FormItem, which has the "required" field

Related

Which rule can I use to change variable name?

I need to replace all occurencies of $connection with $link?
I know I could do with a regexp replacement using my IDE, but I need to be able to re-run the sostitution automatically.
So I want to use rector.
Is there a way to replace a var name ? Which is the rule name?
There are a couple of potentially suitable rules & sets:
RenamePropertyRector
There is also the '\Rector\Set\ValueObject\SetList::NAMING' set that can be enabled in rector.php that will perform some similar rules, like renaming variables according to the type.
The complete set of basic rules (not including framework or library-specific) are at https://github.com/rectorphp/rector/blob/main/docs/rector_rules_overview.md
I create a custom rule, very specific for my needs
<?php
namespace Rules;
use PhpParser\Node;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use PhpParser\Node\Expr\Variable;
class ReplaceConnectionVarNameWithLink extends AbstractRector
{
public function getNodeTypes(): array
{
return [
Variable::class
];
}
public function getRuleDefinition(): \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
{
return new RuleDefinition(
'rename $connect into $link',
[]
);
}
public function refactor(\PhpParser\Node $node)
{
if (!$this->isName( $node, 'connection')) {
// return null to skip it
return null;
}
$node->name = "link";
return $node;
}
}

How to create custom floating filter component in ag-grid that uses "inRange" filter type

I'm trying to build a custom filter component that takes a range from a text input control (e.g. '3-5') to filter the data. To do so I have modified the example given in the ag-grid documentation (see code below).
When changing the type in onFloatingFilterChanged() to 'equals', 'greaterThan', 'lessThan' etc. everything works fine. But with type 'inRange' no filtering is performed.
Working example can be found on Plunkr: https://plnkr.co/edit/oHWFIaHgWIDXP0P5
import { Component } from '#angular/core';
import {
IFloatingFilter,
IFloatingFilterParams,
NumberFilter,
NumberFilterModel,
} from '#ag-grid-community/all-modules';
import { AgFrameworkComponent } from '#ag-grid-community/angular';
export interface RangeFloatingFilterParams extends IFloatingFilterParams {
value: number;
}
#Component({
template: `
<input
type="text"
[(ngModel)]="currentValue"
(ngModelChange)="valueChanged()"
style="width: 70px;"
/>
`,
})
export class RangeFloatingFilter
implements IFloatingFilter, AgFrameworkComponent<RangeFloatingFilterParams> {
private params: RangeFloatingFilterParams;
public currentValue: string;
agInit(params: RangeFloatingFilterParams): void {
this.params = params;
this.currentValue = '';
}
valueChanged() {
let valueToUse = this.currentValue === 0 ? null : this.currentValue;
this.params.parentFilterInstance(function(instance) {
(<NumberFilter>instance).onFloatingFilterChanged(
'inRange',
valueToUse
);
});
}
onParentModelChanged(parentModel: NumberFilterModel): void {
if (!parentModel) {
this.currentValue = 0;
} else {
// note that the filter could be anything here, but our purposes we're assuming a greater than filter only,
// so just read off the value and use that
this.currentValue = parentModel.filter;
}
}
}
Faced the same issue with custom floating datepicker. I used setModelIntoUi method instead of onFloatingFilterChanged:
instance.setModelIntoUi({
type: 'inRange',
dateFrom: moment(value.min).format('YYYY-MM-DD'), // you have to use exactly this date format in order for it to work
dateTo: moment(value.max).format('YYYY-MM-DD'),
});
And in your case with numbers it'll be:
instance.setModelIntoUi({
type: 'inRange',
filter: value.min,
filterTo: value.max,
});
UPD: Added this line
instance.onUiChanged(true);
after the setModelIntoUi method, because of the bug: filter model wasn't updating on second use.
The code inside instance.onFloatingFilterChanged() only sets the first from value.
Use these lines below to get the correct result, as it is the only way to get inRange working.
instance.setTypeFromFloatingFilter('inRange');
instance.eValueFrom1.setValue(this._input1.value);
instance.eValueTo1.setValue(this._input2.value);
instance.onUiChanged(true);

Is there a way to let Apollo Client globally insert empty strings during loading?

I'm using Apollo Client to receive the GraphQL data for my application. Over time, I see a pattern emerging where for every value I'm querying, I have to include a conditional statement to handle the moment where my data is still loading.
Assume a query looks like this:
query TestQuery($userId: Int!) {
getUser(id: $userId) {
name
}
}
Then, in every place where I want to display the user name, I have to write something like:
{ !this.props.data.loading && this.props.data.getUser.name }
or
{ this.props.data.getUser && this.props.data.getUser.name }
I don't want to display "Loading..." or a rotating spinner in any of these places. Is there a way to avoid this conditional statement by globally replacing all this.props.data.x.y.z values with null or an empty String during loading?
If so, how? Would this be considered an antipattern or bad practice?
If not, which of the above two forms is preferred?
Thanks.
How about this approach?
class GraphqlComponent extends React.Component {
renderError(){
// ...
}
renderLoading(){
// ...
}
renderLoaded(){
}
render(){
const { loading, error } = this.props;
if(error){
return renderError();
}
if(loading){
return renderLoading();
}
return renderLoaded();
}
}
class MyComponent extends GraphqlComponent{
renderLoaded(){
// your logic goes here
}
}

How do I make a reusable form component group with Redux-Form v6?

I'm trying to make a reusable form component group (section?) for use with Redux-Form v6. Ideally I don't want it to be aware of where it is used within a form, so that I can use it anywhere within a form (at the root or nested). How can I do this?
For example, I have an Address component that uses Redux-Form's Field for address1, city, state, zip, etc, like this:
class Address extends React.Component {
render() {
return (
<Field
component={MyReduxFormInput}
name="address1" // <== How to name for generic case?
/>
)
}
}
Here's a simplified MyReduxFormInput:
module.exports = field => {
return <input {...field.input} />
}
I'm creating a form where I need to collect the user's address, as well as multiple addresses from some professional references. So, I want to use Address once at the root and multiple times in a nested fashion. The trick is, I can't simply use Address as I've written it above, because while that will work for the root address, it won't work for nested situations. As shown in the FieldArray example docs, the name supplied to Field needs to be name={`${member}.address1`}. But then that wouldn't work at the root.
One idea which just occurred to me is for the Address component to take a member argument, which would be blank at the root. I'll try that and report back. But I was thinking Redux-Form Field components would be automatically aware of their nesting level; they should look up their hierarchy and be able to know their necessary name prefix.
My idea of my component taking a member prop (as in, a name prefix depending on the nesting) works great. Wish I would've thought of it many hours ago.
Here's what Address looks like:
class Address extends React.Component {
static propTypes = {
member: PropTypes.string
}
static defaultProps = {
member: ''
}
render() {
const { member } = this.props
const name = n => `${member}${n}`
return (
<Field
component={MyReduxFormInput}
name={name('address1')}
/>
)
}
}
And here's how it might be used:
const references = ({ fields }) => {
return (
<div>
fields.map((member, index) => {
return <Address member={member} key={index} />
})
</div>
)
}
<Address />
<FieldArray name="professionalReferences" component={references} />

In a Grails domain object, is it possible to validate a field based on another field?

I have a Grails domain object that looks like this:
class Product {
Boolean isDiscounted = false
Integer discountPercent = 0
static constraints = {
isDiscounted(nullable: false)
discountPercent(range:0..99)
}
I'd like to add a validator to discountPercent that will only validate if isDiscounted is true, something like this:
validator: { val, thisProduct ->
if (thisProduct.isDiscounted) {
// need to run the default validator here
thisProduct.discountPercent.validate() // not actual working code
} else {
thisProduct.discountPercent = null // reset discount percent
}
Does anyone know how I can do this?
This is more or less what you need (on the discountPercent field):
validator: { val, thisProduct ->
if (thisProduct.isDiscounted)
if (val < 0) {
return 'range.toosmall' //default code for this range constraint error
}
if (99 < val) {
return 'range.toobig' //default code for this range constraint error
} else {
return 'invalid.dependency'
}
You can't both have a special validator that relies on something else and have a special validator, as you can't run a single validator on a field (that I know of), only on single properties. But if you run a validation on this property, you'll depend on yourself and go into endless recursion. Therefore I added the range check manually. In your i18n files you can set up something like full.packet.path.FullClassName.invalid.dependency=Product not discounted.
Good luck!

Resources