Created
June 11, 2021 07:58
-
-
Save juno-w/988ab8fe8232712747263d4e3df885c8 to your computer and use it in GitHub Desktop.
Multiple emails input just with Tailwind CSS and Alpine.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div> | |
<div class="flex items-center px-1 bg-white border border-gray-300 rounded-md"> | |
<div class="flex flex-wrap items-center flex-1 py-1 space-x-1"> | |
<template x-for="(recipient, index) in recipients"> | |
<div x-bind:class="{ | |
'bg-blue-100 rounded-full': recipient.valid, | |
'border-b border-dashed border-red-500': !recipient.valid | |
}" class="inline px-2 py-px text-sm text-gray-800 "> | |
<span x-text="recipient.email"></span> | |
<button x-on:click.prevent="removeEmail(index)" class="text-gray-700 focus:outline-none hover:text-red-500">×</button> | |
</div> | |
</template> | |
<textarea | |
id="emails" | |
placeholder="Add email..." | |
x-ref="emails" | |
rows="1" | |
class="flex-grow py-1.5 leading-none bg-transparent border-none resize-none focus:ring-0 focus:border-none" | |
x-model="sendTo" | |
x-on:keydown.,.prevent="addEmail" | |
x-on:keydown.backspace="backspace" | |
x-on:keydown.enter.prevent="addEmail" | |
x-on:blur.prevent="addEmail" | |
x-on:paste="handlePasteEmails"></textarea> | |
</div> | |
</div> | |
<x-jet-input-error for="sendTo" class="mt-2" class="!text-xs mt-1" /> | |
</div> | |
@push('scripts') | |
<script> | |
window.hapiForm = function() { | |
return { | |
sendTo: '', | |
recipients: @entangle('sendTo'), | |
// Method to validate input and push to recipients, return void | |
addEmail: function() { | |
if (this.isValidEmail(this.sendTo) && this.sendTo.length) { | |
this.recipients.push({ | |
email: this.sendTo, | |
valid: true | |
}); | |
this.sendTo = ''; | |
this.$refs.emails.focus(); | |
} else if (!this.isValidEmail(this.sendTo) && this.sendTo.length) { | |
this.recipients.push({ | |
email: this.sendTo, | |
valid: false | |
}); | |
this.sendTo = ''; | |
this.$refs.emails.focus(); | |
} | |
}, | |
// Check if the input is a valid email address, return boolean | |
isValidEmail: function(input) { | |
if (/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(input)) { | |
return (true); | |
} | |
return (false); | |
}, | |
// Remove email address from list, return new recipients array | |
removeEmail: function(index) { | |
this.recipients = this.recipients.filter((recipient, i) => i !== index) | |
}, | |
// Remove recipients last item if input is empty | |
backspace: function() { | |
if (this.sendTo.length == 0 && this.recipients.length > 0) { | |
this.recipients.pop(); | |
} | |
}, | |
// On paste emails john@mail.com, jimmy@mail.com, janet@mail.com, | |
handlePasteEmails: function(e) { | |
const clipboard = e.clipboardData.getData('text'); | |
const emails = clipboard.split(',') | |
.filter(email => email) | |
.map(emailAddress => { | |
const trimmedEmail = emailAddress.trim() | |
return { | |
email: trimmedEmail, | |
valid: this.isValidEmail(trimmedEmail) | |
} | |
}) | |
this.$refs.emails.blur(); | |
this.recipients = emails; | |
setTimeout(() => this.$refs.emails.focus(), 150); | |
} | |
} | |
} | |
</script> | |
@endpush |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment