Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
ampersand-expanding-textarea-view
Advanced tools
A small ampersand.js tool to create an expanding textarea view for an ampersand-form-view
A view module for rendering a textarea that expands in height to fit the text within it. Works well with ampersand-form-view.
It does the following:
It's built on ampersand-view so it can be extended with extend
as you might expect.
npm install ampersand-expanding-textarea-view
var FormView = require('ampersand-form-view');
var ExpandingTextAreaView = require('ampersand-expanding-textarea-view');
module.exports = FormView.extend({
fields: function () {
return [
new ExpandingTextAreaView({
label: 'Address',
name: 'address',
value: this.model.address || '',
required: false,
placeholder: '2000 Avenue of the Stars, Los Angeles CA',
parent: this
})
];
}
});
AmpersandInputView.extend({ })
Since this view is based on ampersand-state it can be extended in the same way.
To create an InputView class of your own, you extend AmpersandInputView and provide instance properties and options for your class. Typically here you will pass any properties (props
, session
and derived
) of your state class, and any instance methods to be attached to instances of your class.
If you're wanting to add an initialize function for your subclass of InputView, note that you're actually overwriting initialize
which means you'll want to call its parent class's initialize
manually like so:
var AmpersandInputView = require('ampersand-input-view');
var MyCustomInput = AmpersandInputView.extend({
initialize: function () {
// call its parent's initialize manually
AmpersandInputView.prototype.initialize.call(apply, arguments);
// do whatever else you need to do on init here
}
});
new AmpersandInputView([opts])
When creating an instance of an input view, you can pass in the initial values of the attributes which will be set on the state. Unless extraProperties is set to allow
, you will need to have defined these attributes in props
or session
.
false
): whether this field is required or not.'This field is required'
): message to use if required and empty.[]
): test function to run on input (more below).'input-valid'
): class to apply to input if valid.'input-invalid'
): class to apply to input if invalid.inputView.render()
Renders the input view. This gets handled for you if used within a parent ampersand-form-view.
inputView.template
This can either be customized by using extend
or by passing in a template
property as part of your constructor arguments.
It can be a function returning an HTML string or DOM or it can be just an HTML string.
But the resulting HTML should contain the following hooks:
data-hook="input-primary"
attribute (the textarea visible to users)data-hook-"input-mirror"
attribute (the textarea used to calculate the height)data-hook="label"
attributedata-hook="message-container"
attribute (this we'll show/hide)data-hook="message-text"
attribute (where message text goes for error)Creating a new class:
// creating a custom input that has an alternate template
var CustomInput = AmpersandInput.extend({
template: [
'<label>',
'<textarea data-hook="input-primary"></textarea>',
'<textarea data-hook="input-mirror"></textarea>',
'<span data-hook="label"></span>',
'<div data-hook="message-container" class="message message-below message-error">',
'<p data-hook="message-text"></p>',
'</div>',
'</label>'
].join('');
});
// Then any instances of that would have it
var myCustomInput = new CustomInput();
Setting the template when instantiating it:
// Or you can also pass it in when creating the instance
var myInput = new AmpersandInput({
template: myCustomTemplateStringOrFunction
});
new AmpersandInput({ value: 'something' })
If passed when creating the original input it will be set in the input element and also be tracked as startingValue
.
This is also the value that will be reverted to if we call .reset()
on the input.
var myInput = new AmpersandInput({
name: 'company name',
value: '&yet'
});
myInput.render();
console.log(myInput.input.value); //=> '&yet'
myInput.setValue('something else');
console.log(myInput.input.value); //=> 'something else'
myInput.setValue('something else');
myInput.reset();
console.log(myInput.input.value); //=> '&yet'
value
If you need to decouple what the user enters into the form from what the resulting value is that gets passed by the form you can do that by overwriting the value
derived property.
Say you're making a validated address input. You may have a single text input for address that you do an API call to attempt to match to a real known address. So you have a single input, but you want the value
of this input view to actually be an object of the resulting address fields from that API.
Do it by overwriting the value
derived property as follows:
var VerifiedAddressInput = AmpersandInput.extend({
initialize: function () {
// call parent constructor
AmpersandExpandingTextareaView.prototype.initialize.call(apply, arguments);
// listen for changes to input value
this.on('change:inputValue', this.validateAddress, this);
},
props: {
verifiedAddress: {
type: 'object'
}
},
derived: {
value: {
// in you want it re-calculated
// when the user changes input
// make it dependent on `inputValue`
deps: ['verifiedAddress'],
fn: function () {
// calculate your value here
return this.verifiedAddress;
}
},
// you may also want to change what
// deterines if this field should be
// considerd valid. In this case, whether
// it has a validated address
valid: {
deps: ['value'],
fn: function () {
if (this.verifiedAddress) {
return true;
} else {
return false;
}
}
}
},
// run our address verification
validateAddress: function () {
// validate it against your API (up to you how)
validateIt(this.inputValue, function (result) {
this.verifiedAddress = result;
});
}
});
InputView.extend({ tests: [test functions] });
or new InputView({ tests: [] })
Tests can be extended onto a new constructor for the input or can be passed in on init.
This should be an array of test functions. The test functions you supply will be called with the context of the input view and with the input value as the argument.
The tests should return an error message if invalid and a falsy value otherwise (or just not return at all).
var myInput = new ExpandingTextareaView({
name: 'tweet',
label: 'Your Tweet',
tests: [
function (value) {
if (value.length > 140) {
return "A tweet can be no more than 140 characters";
}
}
]
});
note: you can still do required: true
and pass tests. If you do it will check if it's not empty first and show the requiredMessage
error if empty. Note that the input will only show one error per field at a time. This is to minimize annoyance. We don't want to show "this field is required" and every other error if they just left it empty. We just show the first one that fails, then when they go to correct it, it will change as they type to the other error or the error will disappear once valid.
expandingTextareaView.setValue([value], [skipValidation|bool])
Setter for value that will fire all appropriate handlers/tests. Can also be done by user input or setting value of input
manually.
Passing true
as second argument will skip validation. This is mainly for internal use.
expandingTextareaView.reset()
Set value to back original value. If you passed a value
when creating the view it will reset to that, otherwise to ''
.
expandingTextareaView.clear()
Sets value to ''
no matter what previous values were.
Created by @beardfury.
MIT
FAQs
A small ampersand.js tool to create an expanding textarea view for an ampersand-form-view
We found that ampersand-expanding-textarea-view demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 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
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.