I have a javascript variable with parameters, but I don't know how to pass it into my html code. The javascript code is taken from https://gist.github.com/EvanHahn/2587465:
var caesarShift = function(str, amount) {
// Wrap the amount
if (amount < 0)
return caesarShift(str, amount + 26);
// Make an output variable
var output = '';
// Go through each character
for (var i = 0; i < str.length; i ++) {
// Get the character we'll be appending
var c = str[i];
// If it's a letter...
if (c.match(/[a-z]/i)) {
// Get its code
var code = str.charCodeAt(i);
// Uppercase letters
if ((code >= 65) && (code <= 90))
c = String.fromCharCode(((code - 65 + amount) % 26) + 65);
// Lowercase letters
else if ((code >= 97) && (code <= 122))
c = String.fromCharCode(((code - 97 + amount) % 26) + 97);
}
// Append
output += c;
}
// All done!
return output;
};
I want to pass it on to my HTML obviously. I have done some research, and have come across ways such as:
<p id="output"></p>
and then
document.getElementById('output').innerHTML = lengthOfName;
but I don't know how to add it all together. How do I call the variable? For the string, I have a text area input box, and maybe a clicker for the second argument, the amount, but I don't know how to put it all together in the HTML.
In my previous question, How do I make a javascript function a html attribute?, and my answer was an HTTP form. But I'm trying to create a site that has a lot of ways to decrypt 1 string. So if the user has to click submit every time, especially 25 times in this case, that's not going to be that helpful. Is there any way to make it live without a submit button? This is what I'm kind of going for, https://cryptii.com/pipes/caesar-cipher.
You need to prevent the default event after clicking the button.
e.preventDefault(); // Do not submit!
Also, I polished the logic in the cipher to account for negative shifts.
Note: there is no reason to call shift, if the amount it zero, just return the incoming message... unless you actually want it to clean the message of non-alpha characters.
Update: Added a dynamic form without a button.
Pay attention to the addEventListeners
convenience function I created below. It lets you add an event to multiple element for many different types of events. It is rudimentary at best, but it saves you time adding every event listener. A better approach would be an object. I will probably add an alternate example at the bottom.
const caesarShift = (str, amount) => {
const LOWER_A = 'a'.charCodeAt(0) , LOWER_Z = 'z'.charCodeAt(0),
UPPER_A = 'A'.charCodeAt(0) , UPPER_Z = 'Z'.charCodeAt(0),
SIZE = LOWER_Z - LOWER_A ;
if (amount === 0) return str;
let output = '';
for (let i = 0; i < str.length; i++) {
let c = str[i];
if (c.match(/[a-z]/i)) {
let offset = -1, code = str.charCodeAt(i);
if (code >= LOWER_A && code <= LOWER_Z) {
offset = LOWER_A;
} else if (code >= UPPER_A && code <= UPPER_Z) {
offset = UPPER_A;
}
if (offset !== -1) {
c = String.fromCharCode(offset + ((code - offset) + amount + SIZE) % SIZE);
}
}
output += c;
}
return output;
};
const form = document.forms['caesar-1'];
form.querySelector('button').addEventListener('click', (e) => {
form.result.value = caesarShift(
form.message.value,
parseInt(form.amount.value, 10)
);
e.preventDefault(); // Do not submit!
});
const form2 = document.forms['caesar-2'];
addEventListeners('input, textarea', 'change keyup', (e) => {
form2.result.value = caesarShift(
form2.message.value,
parseInt(form2.amount.value, 10)
);
}, form2);
// Initial change events
triggerEvent(form.querySelector('button'), 'click');
triggerEvent(form2.message, 'change');
// Custom functions to make life easier...
function addEventListeners(selector, eventNames, eventFn, scope) {
scope = scope || document;
const names = eventNames.split(/\s+/g);
selector.split(/\s*,\s*/).forEach(sel => {
Array.from(scope.querySelectorAll(sel)).forEach(el => {
names.forEach(eventName => el.addEventListener(eventName, eventFn));
});
});
}
function triggerEvent(el, eventName) {
let event = document.createEvent('HTMLEvents');
event.initEvent(eventName, true, false);
el.dispatchEvent(event);
}
hr { margin: 1em 0; }
.form-field {
margin-bottom: 0.5em;
}
.form-field label {
display: inline-block;
width: 4em;
font-weight: bold;
}
form button {
margin-left: 5em;
margin-bottom: 0.5em;
}
.form-field-stacked {
display: inline-block;
vertical-align: top;
margin-right: 0.5em;
}
.form-field-stacked label {
display: block;
margin-bottom: 0.25em;
width: auto;
}
.form-field-stacked input[type="number"] {
width: 3em;
}
<h2>Button Form</h2>
<form name="caesar-1">
<div class="form-field">
<label>Message</label>
<input name="message" type="text" value="Hello World"/>
</div>
<div class="form-field">
<label>Amount</label>
<input name="amount" type="number" value="13" />
</div>
<button>Rotate</button>
<div class="form-field">
<label>Output</label>
<input name="result" type="text" disabled="disabled" />
</div>
</form>
<hr />
<h2>Dynamic Form</h2>
<form name="caesar-2">
<div class="form-field form-field-stacked">
<label>Message</label>
<textarea name="message" rows="4" cols="24">Hello World</textarea>
</div>
<div class="form-field form-field-stacked">
<label>Amount</label>
<input name="amount" type="number" value="13" />
</div>
<div class="form-field form-field-stacked">
<label>Output</label>
<textarea name="result" rows="4" cols="24" disabled="disabled"></textarea>
</div>
</form>
A more dynamic event listener function.
const caesarShift=(t,e)=>{if(r="a".charCodeAt(0),a="z".charCodeAt(0),o="A".charCodeAt(0),c="Z".charCodeAt(0),h=a-r,0===e)return t;let C="";for(let d=0;d<t.length;d++){let A=t[d];if(A.match(/[a-z]/i)){let C=-1,f=t.charCodeAt(d);f>=r&&f<=a?C=r:f>=o&&f<=c&&(C=o),-1!==C&&(A=String.fromCharCode(C+(f-C+e+h)%h))}C+=A}return C};
const form = document.forms['caesar'];
const handleUpdate = (e) => {
form.result.value = caesarShift(
form.message.value,
parseInt(form.amount.value, 10)
);
}
addEventListeners({
selector : 'input',
listeners : {
'change' : handleUpdate,
'keyup' : handleUpdate
},
scope: form
}, {
selector : 'textarea',
listeners : {
'change' : handleUpdate,
'keyup' : handleUpdate
},
scope: form
});
// Initial change events
triggerEvent(form.message, 'change');
// Custom functions to make life easier...
function addEventListeners(...configs) {
configs.forEach(config => {
let options = config.options || {};
let els = Array.from((config.scope || document).querySelectorAll(config.selector));
Object.keys(config.listeners || {}).forEach(eventName => {
els.forEach(el => {
el.addEventListener(eventName, config.listeners[eventName], options)
});
});
});
}
function triggerEvent(el, eventName) {
let event = document.createEvent('HTMLEvents');
event.initEvent(eventName, true, false);
el.dispatchEvent(event);
}
.form-field {
margin-bottom: 0.5em;
}
.form-field label {
font-weight: bold;
}
.form-field-stacked {
display: inline-block;
vertical-align: top;
margin-right: 0.5em;
}
.form-field-stacked label {
display: block;
margin-bottom: 0.25em;
width: auto;
}
.form-field-stacked input[type="number"] {
width: 3em;
}
<h2>Dynamic Form</h2>
<form name="caesar">
<div class="form-field form-field-stacked">
<label>Message</label>
<textarea name="message" rows="4" cols="24">Hello World</textarea>
</div>
<div class="form-field form-field-stacked">
<label>Amount</label>
<input name="amount" type="number" value="13" />
</div>
<div class="form-field form-field-stacked">
<label>Output</label>
<textarea name="result" rows="4" cols="24" disabled="disabled"></textarea>
</div>
</form>