function doUpdate() {
intendedLength = $(".counter_string_length").val() * 1;
mySep = $(".separator").val();
if (mySep.length == 0) { mySep = '_'};
repeatedStr = $(".repeatedStr").val();
repeatedPrefix = $(".repeatedPrefix").val();
myPrefix = $(".prefix").val();
mySuffix = $(".suffix").val();
myPrefix = myPrefix.replace(/\s/g, mySep);
result = "";
counter = intendedLength;
if (mySuffix.length > 0) {
result = mySuffix;
counter = intendedLength - result.length - repeatedStr.length - repeatedPrefix;
}
while (result.length < intendedLength) {
if (counter <= 1 + repeatedStr.length + repeatedPrefix.length) {
result = mySep.repeat(counter) + result;
} else {
result = repeatedPrefix + counter + repeatedStr + mySep + result;
}
counter = intendedLength - result.length;
}
// only use prefix if it can fit
var logMsg = ""
var lengthOfLastNumber = ('' + intendedLength).length
if ((myPrefix.length > 1) && (myPrefix.length < (intendedLength - lengthOfLastNumber - 1))) {
var regex = new RegExp("^([^" + mySep + "]*)");
remainingResult = result.substring(myPrefix.length);
matchPart = regex.exec(remainingResult);
matchPart = matchPart[0].replace(/./g, mySep);
result = myPrefix + matchPart + remainingResult.substring(matchPart.length);
}
$('#result').val(result);
updateLengthCount();
}
function updateLengthCount() {
var len = $('#result').val();
$('#actualLength').text(len.length);
}
$(function () {
$(".input input").on("change keyup click", function () {
doUpdate();
});
$("#result").on("click", function () {
$(this).select(); // make it easier to copy the result by selecting it when they click inside.
});
$('#result').on("change keypress keyup paste", function () {
setTimeout(function () {
updateLengthCount();
}, 100);
});
$('.counter_string_length').bind("keydown", function (e) {
var input = $('.counter_string_length');
var addend = 0;
var multiplier = 1;
let currentVal = parseInt(input.val(), 10);
if (e.keyCode === 38) /*up key*/ {
if (e.shiftKey) {
input.val(currentVal + 1);
} else {
input.val(currentVal * 2);
}
} else if (e.keyCode === 40) /*down key*/ {
if (e.shiftKey) {
input.val(currentVal - 1);
} else {
input.val(Math.round(currentVal / 2));
}
}
});
$('[name=setupEmail]').on("click", setupEmail);
$('[name=setupSimple]').on("click", setupSimple);
doUpdate();
});
function setupEmail() {
$(".counter_string_length").val('255').focus();
$(".separator").val("_");
$(".repeatedStr").val("");
$(".prefix").val("Test against RFC email max by exceeding 254 characters");
$(".suffix").val("test@example.com");
// see https://stackoverflow.com/questions/386294/what-is-the-maximum-length-of-a-valid-email-address
doUpdate();
}
function setupSimple() {
$(".counter_string_length").val('256').focus();
$(".separator").val(".");
$(".repeatedStr").val("");
$(".prefix").val("");
$(".suffix").val("");
// see https://stackoverflow.com/questions/386294/what-is-the-maximum-length-of-a-valid-email-address
doUpdate();
}
<b> This generates self-referential counter strings. Anywhere in the string, the separator character is at the position indicated by the number to its left. </b>
<br/>This is useful for testing string length limits in form fields for all kinds of applications.
<br/>
<br/>
<div class="defaults">Default setups:
<input type="button" name="setupEmail" value="Email 254+" />
<input type="button" name="setupSimple" value="Simple 256" />
</div>
<div class="input">
<label for="counter_string">Length</label>
<input type='text' class='counter_string_length' name='counter_string_length' value="256" />
<span class="hint">Use up/down & shift-up/down to change.</span>
</div>
<div class="input">
<label for="prefix">Prefix</label>
<input type='text' class='prefix' name="prefix" value="Self-referential counting string" />
</div>
<div class="input">
<label for="separator">Separator</label>
<input type='text' class='separator' name="separator" value="." maxlength="1" />
</div>
<div class="input">
<label for="repeatedPrefix">Before each number</label>
<input type='text' class='repeatedPrefix' name="repeatedPrefix" value="" />
</div>
<div class="input">
<label for="repeatedStr">After each number</label>
<input type='text' class='repeatedStr' name="repeatedStr" value="->" />
</div>
<div class="input">
<label for="suffix">Suffix</label>
<input type='text' class='suffix' name="suffix" value="" />
</div>
<br/>Result to copy to clipboard (or paste your own text to measure its length):
<br/>
<textarea id='result' style="width: 90%" rows="10">(please change the text boxes above to see a result)</textarea>
<div>Actual length: <span id="actualLength">?</span> (paste text above to measure its length)</div>
label {
width: 12em;
}
.input {
padding: 3px;
}
.input input {
width: 200px;
left: 12em;
position: absolute;
}
.input .hint {
left: calc(12em + (3px * 4) + 200px);
position: absolute;
color: gray;
font-size: small;
}
.defaults {
float: right;
clear: none;
margin-right: 10em;
}
.defaults input {
display: block;
}