Caesars Cipher to web browser

I am trying to create a basic web interface to use Caesars Cipher. I am using the code from the basic solution given by this forum (which is similar to my own). My question: How do I pass the return statements to replace the text in “inputbox”? My understanding is that the return statements pass to the caller which i think should replace the text in “inputbox” upon click and once the function has completed? Stuck on this.

First off, I’m not sure the input box is bound to that click like you think it might be. The ’this’ that your onclick is using is likely the window object. Try changing your onlick function to a function that simply does a console.log(this) and you should find this to be true. Knowing that, you might have better luck grabbing the element, extracting it’s value and then applying the function to it on click.

Once your rot13 function runs however it’s still not going to just show up until you tell the browser how to display this… if you want it to show up in the text box and replace the text that was there you’d do something like this:

<body>
	<h1>Caesar's Cipher</h1>
	<form>
	  <input type="text" name="inputbox" id="textInput">
  	<input type = "button" value = "Encrypt"
    onclick = "rotify();"/>
	</form>
	<script type="text/javascript" src="app.js"></script>
</body>
function rot13(str) {
  return str.split('').map.call(str, function(char) {
    x = str.charCodeAt(0);
    if (x < 65 || x > 90) {
      return String.fromCharCode(x);
    } else if (x < 78) {
      return String.fromCharCode(x + 13);
    }
      return String.fromCharCode(x-13);
  }).join('');
};


function rotify(){
 	const textInput = document.getElementById('textInput');
	const textInBox = textInput.value;
	textInput.value = rot13(textInBox);
}

However, I’m not sure this rot13 function is working as expected however so maybe look at that again… try replacing the function with something like this and it should work as expected…

function rot13(str) {
  var input     = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
  var output    = 'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm';
  var index     = x => input.indexOf(x);
  var translate = x => index(x) > -1 ? output[index(x)] : x;
  return str.split('').map(translate).join('');
}

fork of your pen here

1 Like

Doing this logs: <input type=​"button" value=​"Encrypt" onclick=​"console.log(this)​">​

But, putting " onclick = “console.log(this.form.inputbox.value)” ". logs the text entered. The text entered is what I am looking for, which is what I am getting, so I am not sure where the problem is.

To advance I added your rotify function and I found

As you said, It seems the rot13() function is not working correctly. If I put in “hide” I get a return of “hhhh”, I will have to look at it more. This doesn’t make sense to me as the function passes the fcc test and it is also the basic solution given by this forum.

Thanks for the example of a working rot13() function but it is not the solution I am looking for. I would like to use charCode because I want to try to give the user the option of how many characters the text is displaced. I am sure this may be possible with your function but it’s syntax is a bit above my current level.

updated codepen

Doing this logs: <input type=​"button" value=​"Encrypt" onclick=​"console.log(this)​">​

I meant to log it from within the function itself i.e. outside of the scope of your inline element.

But, putting " onclick = “console.log(this.form.inputbox.value)” ". logs the text entered. The text entered is what I am looking for, which is what I am getting, so I am not sure where the problem is.

Still a beginner myself so I’m not very knowledgable in inline handlers but I’ve been taught to keep HTML separate from JS. My guess would be it’s a scoping thing. Console logging this.form.inputbox.value might give you what you want when popped into the inline onclick directly but once you try to pass that to a function in a script tag or separate js file it will return undefined. Therefore, your rot13 function likely does not have access to the value and will return undefined. There might be a way to bind the element to the function, but I honestly don’t know of one. Maybe someone else has the answer for you on that front!

Separately, I’ve compared your rot13 function to the basic solution and found an error which perhaps is why you are getting the inconsistent results?

function rot13(str) {
  return str.split('')
  .map.call(str, function(char) {

   // Line below should be "x = char.charCodeAt(0);" not str

    x = str.charCodeAt(0); 
    if (x < 65 || x > 90) {
      return String.fromCharCode(x);
    } else if (x < 78) {
      return String.fromCharCode(x + 13);
    }
      return String.fromCharCode(x-13);
  }).join('');
};

Lastly, in order for the rot13 function to work as expected I found it was necessary to apply a toUpperCase and toLowerCase so the rot13 function could do it’s thing. I’m not 100% on this since I haven’t looked over the basic solution too closely but I suspect the rot13 function possibly isn’t looking for lowercase letters just characters from A-Z so in order for it to work correctly you’ll need to pass it a string of uppercase letters otherwise it will just spit back the original string at you.

taken from the description of the basic solution:

If it’s the uppercase English alphabet, we’ll subtract 13 from it’s ascii code.

Updated pen with my changes.