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("[email protected]"); // 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; }