I'm trying to achieve exact same result as here : https://veeva-subject-lines.tomasino.org/
It is using vue.js, but I'm looking for a simple jquery or javascript solution. Here's what I've managed to do so far :
In a keyup function, I create an array of all inputs value, separated by a "|". All inputs values are displayed in a "result" div. Then, with an "add" or "remove" buttons, I add a new input with specific ID, or I delete the added input.
What I'm trying to achieve :
The '|" divider is added with join() function. When deleting an input and associated text in the restult div, the divider is still there. How can I delete it ?
Here is my code :
$('body').on('input', '.custom', function(event) {
var tokens='';
var i = 0;
var token = $('.custom').map(function() {
i++;
return '<span id="custom-'+ i +'">' + this.value + '</span>';
}).get().join('|');
tokens += token;
$('#token').html(tokens);
//remove related input value in the result div
$('.remove').click(function(){
$('#custom-'+ i +'').remove();
i--;
});
});
// I add a new input on add click, with a specific ID starting from 3 as there are already two harcoded input
var count = 3;
$('.add').click(function() {
var y = '<div class="flex-row"><label><input id="custom_text_' + (count++) + '" class="custom" type="text" name="" placeholder="custom text"></label><button class="remove">-</button>';
$(y).insertBefore('.add');
});
$('body').on('click','.remove', function(){
$(this).parent('.flex-row').remove();
})
});
<body>
<div class="container">
<div class="wrapper">
<article>
<section>
<div class="flex-row">
<label for="custom_text_one"><input id="custom_text_1" class="custom" type="text" name="" placeholder="custom text"></label>
<button class="remove">-</button>
</div>
<div class="flex-row">
<label for="custom_text_two"><input id="custom_text_2" class="custom" type="text" name="" placeholder="custom text 2"></label>
<button class="remove">-</button>
</div>
<button class="add">+</button>
<div class="flex-row">
<div>customText{{[<span id="token"></span>]}}</div>
</div>
</section>
</article>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js" integrity="sha512-aVKKRRi/Q/YV+4mjoKBsE4x3H+BkegoM/em46NNlCqNTmUYADjBbeNefNxYV7giUp0VxICtqdrbqU7iVaeZNXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</body>
EDIT : thanks to Twisty I managed to add the remove function, and now I can also delete inputs and outputs together.. here is the final code :
$("#inputs").on('input', 'input[type=text]', function(event) {
var i = $(this).closest(".flex-row").index();
var v = (i == 0) ? $(this).val() : "|" + $(this).val();
$("#custom_wrapper .output").eq(i).html(v);
});
$('.add').click(function() {
var count = $("#inputs input").length;
count++;
var row = $("<div>", {
class: "flex-row"
}).insertBefore(this);
$("<label>").appendTo(row);
$("<input>", {
type: "text",
class: "input",
placeholder: "custom text " + count,
id:"custom-text-" +count,
tabindex: count
}).appendTo($("label", row));
$("<button>", {
class: "remove"
}).html("-").appendTo(row);
$("<span>", {
class: "output",
dataid:"custom-text-" +count,
}).insertAfter($("#custom_wrapper .output:last"));
});
$('body').on('click','.remove', function(){
$(this).parent('.flex-row').remove();
var j =$(this).parent().find('.input').attr("id");
$('#custom_wrapper .output[dataid="'+ j +'"').empty();
})
Consider using .html()
instead of .append()
.
$(function() {
$(".container").on('input', 'input[type=text]', function(event) {
var i = $(this).closest(".flex-row").index();
var v = (i == 0) ? $(this).val() : "|" + $(this).val();
$("#custom_wrapper .output").eq(i).html(v);
});
$('.add').click(function() {
var count = $("input").length;
count++;
var row = $("<div>", {
class: "flex-row"
}).insertBefore(this);
$("<label>").appendTo(row);
$("<input>", {
type: "text",
class: "input",
placeholder: "custom text " + count,
tabindex: count
}).appendTo($("label", row));
$("<button>", {
class: "remove"
}).html("-").appendTo(row);
$("<span>", {
class: "output"
}).insertAfter($("#custom_wrapper .output:last"));
});
});
.flex-row label {
padding-right: 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<div class="container">
<div class="wrapper">
<article>
<section>
<div class="flex-row">
<label><input class="input" type="text" name="" placeholder="custom text" tabindex="1" /></label><button class="remove">-</button>
</div>
<div class="flex-row">
<label><input class="input" type="text" name="" placeholder="custom text 2" tabindex="2"></label><button class="remove">-</button>
</div>
<button class="add">+</button>
<div class="flex-row">
<div>customText{{[<span id="custom_wrapper"><span class="output"></span><span class="output"></span></span>]}}</div>
</div>
</section>
</article>
</div>
</div>
This adds text to from your input
to specific parts of your string, separating output
with the pipe character (|
). Each input
corresponds to an output
.