I would like to create an input field that accept multiple email addresses (for example to send an invitation). How can I achieve this without the help of jQuery or an external plugin or package?
I used to rely on bootstrap-tagsinput but I want to get rid of it, but I have no idea how to achieve the same thing without it.
This solution is quite a carbon copy of how the bootstrap tags input behaves but uses vanilla js only and some style rules.
It captures the click event on the container to create a text input inside that when will loose focus, will create a .tag span inside its parent with its original value (unless that value is empty spaces).
You may also change that condition so that it will create the tag only if the typed text matches a regular expression describing a valid email address.
const emailInput = document.getElementById('emailInputContainer');
//creates a tag element with the given text
function createTag(text){
const tag = document.createElement('span');
tag.classList.add('tag');
tag.innerText = text;
const remove = document.createElement('span');
remove.classList.add('remove');
tag.append(remove);
remove.addEventListener('click', (event)=>{
event.currentTarget.parentElement.remove();
});
return tag;
}
//creates and returns an input element
function createNewInput(){
const newInput = document.createElement('input');
newInput.classList.add('tempinput');
newInput.addEventListener('focusout', (event)=>{
const target = event.currentTarget;
if(target.value.trim().length > 0){
const tag = createTag(target.value);
target.parentElement.append(tag);
}
target.remove();
});
return newInput;
}
//adds the click event listener to the input container
emailInput.addEventListener('click', (event)=>{
const target = event.currentTarget;
const newInput = createNewInput();
target.append(newInput);
newInput.focus();
});
body{
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
#emailInputContainer{
border: solid 1px;
background-color: #fff;
border: 1px solid #ccc;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
display: inline-block;
padding: 4px 6px;
color: #555;
vertical-align: middle;
border-radius: 4px;
line-height: 22px;
cursor: text;
width: 100%;
height: 1.5em;
}
.tag{
padding: 2px 5px;
margin-right: 5px;
background: #5bc0de;
color: white;
display: inline;
padding: .2em .6em .3em;
font-size: 75%;
font-weight: 700;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: .25em;
}
.tempinput{
border: none;
outline: none;
}
.tag > .remove{
margin-left: 8px;
cursor: pointer;
}
.tag > .remove::after{
content: "x";
padding: 0px 0px;
}
<div id="emailInputContainer" tabindex="0">
</div>
I have the below LESS stylesheet and I know there has to be a better way to organize this. Is the only option to create a map containing the classes and a mixin perhaps to repeat the styles?
// child div is injected by JS
.ddemrcontent > span, .blocksmarttemplate > span, .blocktoken > span {
display: inline-flex;
align-items: center;
min-height: 1.7rem;
margin-top: 0.2rem;
padding-left: 0.2rem;
}
.ddfreetext {
display: flex;
min-height: 1.7rem;
margin-top: 0.2rem;
}
.ddemrcontent > span:hover, .blocksmarttemplate > span:hover, .blocktoken > span:hover {
text-decoration: underline;
cursor: pointer;
}
.ddemrcontent > span {
border-left: 4px solid cadetblue;
}
.blocksmarttemplate > span {
border-left: 4px solid burlywood;
}
.blocktoken > span {
border-left: 4px solid #8a7090;
}
.ddfreetext {
border: 1px dashed black;
}
UPDATE
Here is the best I've been able to come up with. Since the & parent selector won't apply to each distinct parent selector (that are comma delimited) I think I am forced to use a mixin and call it to apply the rules for each parent I have.
Would love to hear if there's still a better way.
.dyndoccontent(#color) {
& > span {
display: inline-flex;
align-items: center;
min-height: 1.7rem;
margin-top: 0.2rem;
padding-left: 0.2rem;
border-left: 4px solid #color;
&:hover {
text-decoration: underline;
cursor: pointer;
}
}
}
// child div is injected by JS
.ddemrcontent {
.dyndoccontent(cadetblue);
}
.blocksmarttemplate {
.dyndoccontent(burlywood);
}
.blocktoken {
.dyndoccontent(#8a7090);
}
.ddfreetext {
display: flex;
min-height: 1.7rem;
margin-top: 0.2rem;
border: 1px dashed black;
}
I would definitely recommend mixin if you have multiple parts in your less files which use the same styles.
For you example i would go for a more nested way:
// child div is injected by JS
.ddemrcontent, .blocksmarttemplate, .blocktoken {
& > span {
display: inline-flex;
align-items: center;
min-height: 1.7rem;
margin-top: 0.2rem;
padding-left: 0.2rem;
&:hover {
text-decoration: underline;
cursor: pointer;
}
}
}
.ddfreetext {
border: 1px dashed black;
display: flex;
min-height: 1.7rem;
margin-top: 0.2rem;
}
.ddemrcontent > span {
border-left: 4px solid cadetblue;
}
.blocksmarttemplate > span {
border-left: 4px solid burlywood;
}
.blocktoken > span {
border-left: 4px solid #8a7090;
}
I'm using swiper.js in my project and sometimes (maybe 1 out of 10 times), navigation by clicking the associated bullet does not work - it instead goes to the previous slide. My swiper config object does contain clickable: true for the pagination.
Check this code. I think someone had the same problem here
HTML
<h1>Swipe 2</h1>
<div id='slider' style='max-width:500px;margin:0 auto' class='swipe'>
<div class='swipe-wrap'>
<div><b>1</b></div>
<div><b>2</b></div>
<div><b>3</b></div>
</div>
</div>
<div class="counter content" style='text-align:center;padding-top:20px;'>
<ul id='position'>
<li class="on"></li>
<li ></li>
<li ></li>
</ul>
</div>
<div style='text-align:center;padding-top:20px;'>
<button onclick='slider.prev()'>prev</button>
<button onclick='slider.next()'>next</button>
</div>
<script src='swipe.js'></script>
CSS
html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, del, dfn, em, img, ins, kbd, q, samp, small, strong, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, table, tbody, tfoot, thead, tr, th, td, article, aside, footer, header, nav, section {
margin:0;
padding:0;
border:0;
outline:0;
font-size:100%;
vertical-align:baseline;
background:transparent;
}
body {
-webkit-text-size-adjust:none;
font-family:sans-serif;
min-height:416px;
}
h1 {
font-size:33px;
margin:50px 0 15px;
text-align:center;
color:#212121;
}
h2 {
font-size:14px;
font-weight:bold;
color:#3c3c3c;
margin:20px 10px 10px;
}
small {
margin:0 10px 30px;
display:block;
font-size:12px;
}
a {
margin:0 0 0 10px;
font-size:12px;
color:#3c3c3c;
}
html, body {
background: #f3f3f3;
}
#console {
font-size: 12px;
font-family:"Inconsolata", "Monaco", "Consolas", "Andale Mono", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace;
color: #999;
line-height: 18px;
margin-top: 20px;
max-height: 150px;
overflow: auto;
}
#slider div b {
display:block;
font-weight:bold;
color:#14ADE5;
font-size:20px;
text-align:center;
margin:10px;
padding:100px 10px;
box-shadow: 0 1px #EBEBEB;
background: #fff;
border-radius: 3px;
border: 1px solid;
border-color: #E5E5E5 #D3D3D3 #B9C1C6;
}
.swipe {
overflow: hidden;
visibility: hidden;
position: relative;
}
.swipe-wrap {
overflow: hidden;
position: relative;
}
.swipe-wrap > div {
float:left;
width:100%;
position: relative;
}
.counter {
height: 55px;
ul {
text-align: center;
li {
// padding: 5px;
display: inline-block;
height: 10px;
width: 10px;
border: solid 2px #404041;
border-radius: 10px;
margin: 2.5px;
&.on {
background: #404041;
}
}
}
}
JAVASCRIPT
var elem = document.getElementById('slider');
var slider =
Swipe(document.getElementById('slider'), {
auto: 10000,
continuous: true,
callback: function(pos) {
var i = bullets.length;
while (i--) {
bullets[i].className = ' ';
}
bullets[pos].className = 'on';
}
});
var bullets = document.getElementById('position').getElementsByTagName('li');
$('li').on('click', function(event){
event.preventDefault();
var index = $("li").index(event.currentTarget);
slider.slide(index);
});
// with jQuery
// window.mySwipe = $('#mySwipe').Swipe().data('Swipe');
I am using the npm package https://www.npmjs.com/package/vuejs-paginate
to handle pagination in a vuejs application.
I would like to style this pagination component.
My styling successfully sets the background of page number buttons yellow when the user hovers over them, but fails to set the background of the current page to green. Why?
Here is my component tag with the props.
<paginate
:pageCount="totalPages"
:click-handler="paginateCallback"
:prevText="'Prev'"
:nextText="'Next'"
:containerClass="'pagination'"
class="pagination"
v-model="pageNumber"
></paginate>
And here is the css...
.pagination a {
float: left;
padding: 8px 16px;
text-decoration: none;
border: 1px solid #ddd;
background-color: white;
}
.pagination a.active {
background-color: green;
}
.pagination a:hover:not(.active) {background-color: yellow;}
.pagination a:first-child {
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
.pagination a:last-child {
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
By the way, in case it is relevant information, the application uses bootstrap-vue elsewhere.
Thanks to the first answer below, I was able to resolve this.
Here is the working css after adding the active-class prop to the component...
.pagination li {
float: left;
padding: 8px 16px;
text-decoration: none;
border: 1px solid #ddd;
color: white;
background-color: white;
font-size: 1em;
}
.pagination li.pagination-active {
background-color: green;
}
.pagination li:hover:not(.active) {background-color: yellow;}
Now, however, there is a border around the number of the active page button until the user clicks again anywhere on the page. How can we eliminate this border?
As the documentations says: there is an active class prop that you can set and style that class. see the props in the link above.
<paginate
:pageCount="totalPages"
:click-handler="paginateCallback"
:prevText="'Prev'"
:nextText="'Next'"
:active-class="myActiveBtn"
:containerClass="'pagination'"
class="pagination"
v-model="pageNumber"
></paginate>
style:
.myActiveBtn{
background-color: green;
}
I am trying to change the color of rows in datatable using the below CSS.
table.dataTable tr.odd { background-color: #E2E4FF; }
table.dataTable tr.even { background-color: white; }
This change doesnt seem to affect first column in datatables, I can see the new color in other columns.
Can someone please let me know the reason for this issue?
Solved the issue by using the below css.
table.dataTable td.sorting_1{ background-color: white; border:1px lightgrey; }
table.dataTable td{ background-color: white; border:1px lightgrey;}
table.dataTable tr.odd { background-color: white; border:1px lightgrey;}
table.dataTable tr.even{ background-color: white; border:1px lightgrey; }