
Research
Security News
Lazarus Strikes npm Again with New Wave of Malicious Packages
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
armstrong-react
Advanced tools
An extended HTML form
React component to enable binding data objects to html forms.
Form
components are nestable - only the root Form
will render as an html form
, child Form
components will be rendered as an html div. This function is provided by putting a form
(IFormContext
) property onto the React components context.
This Form Context
contains the current IDataBinder and the parent Form Context
(if one exists).
You construct the Form
in the same way you would a standard HTML form
, the main differences are the additional data binding attributes required on both the Form
and the bound Form Element
's (that are described below the example)
import * as React from "react";
import {Form,TextInput, SelectInput, Button} from "armstrong-react";
import {IDataBinder} from "armstrong-react/dist/components/form/formCore";
export interface IPerson{
id: string
name: string
reputation?: number
divisionId?: number
}
export interface IPersonForm{
person: IPerson
}
export class PersonForm extends React.Component<IPersonForm,{binder: IDataBinder<IPerson>}>{
constructor(props: IPersonForm){
super(props)
this.state = {binder: Form.jsonDataBinder(props.person)}
}
componentWillReceiveProps(nextProps: IPersonForm){
if (nextProps.person !== this.props.person) {
this.setState({binder: Form.jsonDataBinder(nextProps.person)})
}
}
render(){
return (
<Form dataBinder={this.state.binder} onDataBinderChange={binder => this.setState({binder})}>
<div>
<TextInput {...Form.Bind.text("id")} />
</div>
<div>
<TextInput {...Form.Bind.textNumeric("reputation")} />
<TextInput {...Form.Bind.text("name")} />
<SelectInput {...Form.Bind.select("divisionId")} options={[{id:1, name:"D1"},{id:2, name:"D2"},{id:3, name:"D3"}]} />
</div>
<Button onClick={e => alert(JSON.stringify(this.state.binder.toJson()))}>Save</Button>
</Form>
)
}
}
A data binder (IDataBinder
) provides a formal read/write data model.
By default the Form
provides a function to create a simple JSON dataBinder
instance.
This dataBinder
provides a dot notation convention to access properties of the JSON object.
e.g.
// Create a Data Binder
const binder = Form.jsonDataBinder(dataObject)
// Sample dot notation
const name = binder.getValue("name") // name
const title = binder.getValue("addresses.0.title") // First address title
const mobile = binder.getValue("contact.mobile") // Mobile contact number
The Form
is a stateless component
(required) dataBinder
: a data binder that contains the data you want to bind to the Form
(optional) onDataBinderChange(dataBinder: IDataBinder) => void
: Notification with dataBinder, Called when bound Form
data changes: NOTE, this is called on every key stroke/interaction on any of the bound fields
(optional) onDataChanged(data: any) => void
: Notification with changed JSON data, Called when bound Form
data changes: NOTE, this is called on every key stroke/interaction on any of the bound fields
<Form dataBinder={Form.jsonDataBinder(this.props.jsonObject)}>
</Form>
As Form
is stateless, you should handle either onDataBinderChange
or onDataChanged
to trigger a refresh of your component.
If your keypresses and interactions are not reflected in the UI (feels like a locked or frozen form), its likely because you are not handling these events correctly.
It is recommended that you put your dataBinder
in component state, and use onDataBinderChange
to setState(...)
A Form
generally contains input
html elements to handle user interaction. The Form
provides a binding framework to allow simple assignment of core html element values to data (and vice versa).
The Form
also permits custom (3rd party) input elements to be bound (you need to author simple custom binders to permit this - see custom
binder below)
These Form Elements
need a Binding Injector to participate within the Form
lifecycle
To bind data to a Form Element
you just spread a binding object (IFormBinderInjector
) onto the element, you should supply the dot notation data path of the property you want to bind to.
<input {...Form.Bind.text("name")} />
<input {...Form.Bind.text("contact.mobile")} />
<input {...Form.Bind.checkbox("accept")} />
The Form
comes with a default set of Form Binder Injectors catering for input
and select
elements (accessed via Form.Bind.*
)
These Injectors effectively add a data-form-binder
property onto the Form Element
with the value being a IFormBinder
instance.
At runtime, the Form
component processes all its contained Form Element
- effectively inspecting each child until it finds a data-form-binder
property.
The Form
then uses the contained IFormBinder to bind the Form Element
to the data property specified (typically using value
and onChange
), along with any other attributes and event handlers that are needed
Bind a string
property name
to a hidden TextInput
(or html input
)
hidden(dataPath: string)
<TextInput {...Form.Bind.hidden("name")} />
<input {...Form.Bind.hidden("name")} />
Bind a string
property name
to a TextInput
(or html input
)
text(dataPath: string)
<TextInput {...Form.Bind.text("name")} />
<input {...Form.Bind.text("name")} />
Bind a 'secure' string
property password
to a TextInput
(or html input
)
password(dataPath: string)
<TextInput {...Form.Bind.password("password")} />
<input {...Form.Bind.password("password")} />
Bind a number
property reputation
to a TextInput
(or html input
)
textNumeric(dataPath: string)
<TextInput {...Form.Bind.textNumeric("reputation")} />
<input {...Form.Bind.textNumeric("reputation")} />
Bind a boolean
property accepts
to a CheckboxInput
(or html input
)
checkbox(dataPath: string)
<CheckboxInput labelContent="accepts" {...Form.Bind.checkbox("accepts")} />
<input {...Form.Bind.checkbox("accepts")} />
Bind a string
property userType
to a RadioInput
(or html input
)
radio(dataPath: string, radioValue: string)
<RadioInput labelContent="One" radioGroup="main" {...Form.Bind.radio("userType", "1")}/>
<RadioInput labelContent="Two" radioGroup="main" {...Form.Bind.radio("userType", "2")}/>
<RadioInput labelContent="Three" radioGroup="main" {...Form.Bind.radio("userType", "3")}/>
<input radioGroup="main" {...Form.Bind.radio("userType", "1")}/>
<input radioGroup="main" {...Form.Bind.radio("userType", "2")}/>
<input radioGroup="main" {...Form.Bind.radio("userType", "3")}/>
Bind a number
property userTypeNumeric
to a RadioInput
(or html input
)
radioNumeric(dataPath: string, radioValue: number)
<RadioInput labelContent="One" radioGroup="main" {...Form.Bind.radioNumeric("userTypeNumeric", 1)}/>
<RadioInput labelContent="Two" radioGroup="main" {...Form.Bind.radioNumeric("userTypeNumeric", 2)}/>
<RadioInput labelContent="Three" radioGroup="main" {...Form.Bind.radioNumeric("userTypeNumeric", 3)}/>
<input radioGroup="main" {...Form.Bind.radioNumeric("userTypeNumeric", 1)}/>
<input radioGroup="main" {...Form.Bind.radioNumeric("userTypeNumeric", 2)}/>
<input radioGroup="main" {...Form.Bind.radioNumeric("userTypeNumeric", 3)}/>
You can author simple Form Binders to allow 3rd party controls to be directly bound within your application
custom(formBinder: IFormBinder)
class SelectInputFormBinder implements IFormBinder<ISelectInputProps, any> {
constructor(private dataPath: string){}
// set the value property of the `SelectInput`
setElementProperty(props: ISelectInputProps, dataBinder: IDataBinder<any>): void{
props.value = dataBinder.getValue(this.dataPath)
}
// handle the change property of the `SelectInput` - setting the dataBinder value and notifying on change
handleValueChanged(props: ISelectInputProps, dataBinder: IDataBinder<any>, notifyChanged: () => void): void{
props.change = c => {
dataBinder.setValue(this.dataPath, c.id)
notifyChanged()
}
}
}
And apply them via the custom
method
<SelectInput {...Form.Bind.custom(new SelectInputFormBinder("divisionId"))} options={[{id:1, name:"D1"},{id:2, name:"D2"},{id:3, name:"D3"}]} />
FAQs
Rocketmakers Armstrong library of React components
The npm package armstrong-react receives a total of 29 weekly downloads. As such, armstrong-react popularity was classified as not popular.
We found that armstrong-react demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 7 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
Security News
Socket CEO Feross Aboukhadijeh discusses the open web, open source security, and how Socket tackles software supply chain attacks on The Pair Program podcast.
Security News
Opengrep continues building momentum with the alpha release of its Playground tool, demonstrating the project's rapid evolution just two months after its initial launch.