https://github.com/thavarshan/formlink
โ๏ธโ๐ฅ The source code of Formlink. A Fullstack TypeScript form handler library.
https://github.com/thavarshan/formlink
form formlink formlinkjs fullstack source source-code typescript typescript-library
Last synced: about 1 year ago
JSON representation
โ๏ธโ๐ฅ The source code of Formlink. A Fullstack TypeScript form handler library.
- Host: GitHub
- URL: https://github.com/thavarshan/formlink
- Owner: Thavarshan
- License: mit
- Created: 2023-09-20T11:28:23.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-11-15T07:03:39.000Z (over 1 year ago)
- Last Synced: 2025-04-03T14:39:27.342Z (about 1 year ago)
- Topics: form, formlink, formlinkjs, fullstack, source, source-code, typescript, typescript-library
- Language: TypeScript
- Homepage: https://thavarshan.com
- Size: 2.45 MB
- Stars: 9
- Watchers: 1
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: .github/CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Code of conduct: .github/CODE_OF_CONDUCT.md
- Security: .github/SECURITY.md
- Support: .github/SUPPORT.md
Awesome Lists containing this project
README
[](https://github.com/Thavarshan/formlink)
# Formlink
[](https://www.npmjs.com/package/formlink)
[](https://github.com/Thavarshan/formlink/actions/workflows/test.yml)
[](https://github.com/Thavarshan/formlink/actions/workflows/lint.yml)
[](https://www.npmjs.com/package/formlink)
[](https://www.typescriptlang.org/)
[](https://opensource.org/licenses/MIT)
Formlink is a type-safe form-handling library for Laravel + Vue.js applications. It abstracts away form submissions, file uploads, and validation error handling, offering seamless integration with Laravel and Vue.js applications, inspired by Inertia.js's simplicity.
## Features
- โจ **Type Safety**: Full TypeScript support with type inference
- ๐ **Zero Configuration**: Works out of the box with Laravel
- ๐ **Built-in CSRF Protection**: Automatic CSRF token handling
- ๐ **Progress Tracking**: Real-time file upload progress
- ๐ฏ **Smart Error Handling**: Automatic Laravel validation error management
- โก **Event Hooks**: Rich lifecycle hooks for form submission events
- ๐ฑ **Vue 3 Ready**: Reactive forms with Vue 3 composition API
- ๐ ๏ธ **Framework Agnostic**: Can be used with any backend, not limited to Laravel
- ๐ **HTTP Method Support**: Comprehensive support for all HTTP methods
- ๐งน **Form Reset & State Management**: Easily reset form data to initial state
- ๐ **Debounced Submissions**: Support for debounced form submissions
## Quick Start
### Installation
```bash
npm install formlink
# or
yarn add formlink
# or
pnpm add formlink
```
### Basic Usage
```typescript
import { useForm } from 'formlink';
interface ContactForm {
name: string;
email: string;
message: string;
}
const form = useForm({
name: '',
email: '',
message: ''
});
await form.post('/api/contact');
```
### Complete Example
```vue
{{ form.errors.name }}
{{ form.errors.email }}
{{ form.progress.percentage }}% uploaded
{{ form.processing ? 'Sending...' : 'Send Message' }}
import { useForm } from 'formlink';
interface ContactForm {
name: string;
email: string;
file: File | null;
}
const form = useForm<ContactForm>({
name: '',
email: '',
file: null
});
const handleFile = (e: Event) => {
const file = (e.target as HTMLInputElement).files?.[0];
if (file) {
form.file = file;
}
};
const submit = async () => {
await form.post('/api/contact', {
onBefore: () => {
console.log('Request starting');
},
onProgress: (progress) => {
console.log(`${progress.percentage}% uploaded`);
},
onSuccess: (response) => {
console.log('Submission successful', response.data);
},
onError: (errors) => {
console.log('Validation errors', errors);
},
onFinish: () => {
console.log('Request finished');
}
});
};
```
## Available `FormOptions`
The `FormOptions` object allows you to configure hooks and behaviors for form submissions. Here are the available options:
| Option | Type | Description |
|----------------|----------------------------------------------|-----------------------------------------------------------------------------|
| `resetOnSuccess` | `boolean` | Whether to reset the form to its initial state after a successful submission. |
| `onBefore` | `() => void` | Hook that is called before the form submission begins. |
| `onSuccess` | `(response: AxiosResponse) => void` | Hook that is called when the form submission is successful. |
| `onCanceled` | `() => void` | Hook that is called when the form submission is canceled. |
| `onError` | `(errors: Partial>)` | Hook that is called when validation errors occur (e.g., from a Laravel backend). |
| `onFinish` | `() => void` | Hook that is called when the form submission finishes, whether successful or not. |
| `onProgress` | `(progress: Progress) => void` | Hook that tracks file upload progress or long-running requests. |
### Example of Form Options
```typescript
await form.post('/api/contact', {
resetOnSuccess: true,
onBefore: () => console.log('Submitting...'),
onSuccess: (response) => console.log('Submitted', response.data),
onError: (errors) => console.error('Validation errors:', errors),
onFinish: () => console.log('Request finished'),
onProgress: (progress) => console.log(`Upload ${progress.percentage}% complete`),
});
```
## Advanced Features
### Form States
Formlink provides various reactive states:
```typescript
form.processing; // Is the form being submitted?
form.progress; // Upload progress data
form.errors; // Validation errors
form.isDirty; // Has the form been modified?
form.wasSuccessful; // Was the form submission successful?
form.recentlySuccessful; // Was the form submission successful recently?
```
### HTTP Methods
Formlink supports multiple HTTP methods:
```typescript
form.get(url); // GET request
form.post(url); // POST request
form.put(url); // PUT request
form.patch(url); // PATCH request
form.delete(url); // DELETE request
form.options(url); // OPTIONS request
```
### Data Transformation
You can transform form data before it is submitted:
```typescript
form.transform((data) => ({
...data,
name: data.name.trim().toLowerCase()
}));
```
### Error Handling
Set or clear errors manually:
```typescript
// Set a single error
form.setError('email', 'Invalid email format');
// Set multiple errors at once
form.setErrors({
email: 'Invalid email format',
name: 'Name is required',
formError: 'Please fix the errors before submitting'
});
// Clear all errors
form.clearErrors();
```
### Reset Functionality
Reset the form data to its initial state:
```typescript
// Reset all fields
form.reset();
// Reset specific fields
form.reset('email', 'name');
```
### Default Values
Set new default values for the form:
```typescript
// Set all current data as new defaults
form.setDefaults();
// Set a specific field's default value
form.setDefaults('email', 'default@example.com');
// Set multiple field defaults at once
form.setDefaults({
name: 'John Doe',
email: 'john@example.com'
});
```
### Validation
Formlink provides a simple validation system:
```typescript
// Define validation rules
form.rules = {
email: [
{ validate: (value) => !!value, message: 'Email is required' },
{ validate: (value) => /\S+@\S+\.\S+/.test(value as string), message: 'Invalid email format' }
],
name: [
{ validate: (value) => !!value, message: 'Name is required' }
]
};
// Run validation
const isValid = await form.validate();
if (isValid) {
await form.post('/api/contact');
}
```
### Debounced Submissions
For search forms or auto-save functionality:
```typescript
// Debounce form submission (default 300ms)
form.submitDebounced('get', '/api/search');
// Custom debounce time (1000ms)
form.submitDebounced('post', '/api/auto-save', {}, 1000);
```
### Cancellation
Cancel an ongoing form submission:
```typescript
// Start submission
const submissionPromise = form.post('/api/upload-large-file');
// Cancel it if needed
form.cancel();
```
### Custom Axios Instance
You can use a custom Axios instance for your form requests:
```typescript
import axios from 'axios';
const customAxios = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000,
headers: {
'X-Custom-Header': 'value'
}
});
const form = useForm(data, customAxios);
```
### Resource Cleanup
For single-page applications, ensure proper cleanup:
```typescript
// In your component's onUnmounted lifecycle hook
onUnmounted(() => {
form.dispose();
});
```
## Contributing
Contributions are welcome! See our [Contributing Guide](https://github.com/Thavarshan/formlink/blob/main/.github/CONTRIBUTING.md) for details.
To get started:
1. Fork the repository.
2. Create your feature branch (`git checkout -b feature/your-feature`).
3. Commit your changes (`git commit -m 'Add feature'`).
4. Push to your branch (`git push origin feature/your-feature`).
5. Open a pull request.
### Development Setup
```bash
# Clone the repository
git clone https://github.com/Thavarshan/formlink.git
# Install dependencies
npm install
# Run tests
npm test
# Build the package
npm run build
```
## License
Formlink is open-sourced software licensed under the [MIT license](LICENSE.md).
## Acknowledgments
Special thanks to [**Jonathan Reinink**](https://github.com/reinink) for his work on [**InertiaJS**](https://inertiajs.com/), which inspired this project.