Set string value with formatting symbols in js/jsp - javascript

I have on jsp page:
<script type="application/javascript">
var test = {};
test.id = ${docId};
test.message = ${message};
</script>
If message equal:
'hello world'
I'll get error in page: "Uncaught SyntaxError: Invalid or unexpected token"
How set string value in js? if value have \n, \' or other formatting symbols

An Example on Glassfish4 server.
The following JSP:
<!DOCTYPE html>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>initJsObject</title>
</head>
<body>
<!-- prepare attributes, just for testing -->
<c:set var="docId" value="123"></c:set>
<c:set var="message" value="'hello world'"></c:set>
<c:set var="lines" value="'line1\nline2'"></c:set>
<c:set var="backslashN" value="'\\\\\n'"></c:set>
<textarea id="txt" style="height: 200px; width: 200px;"></textarea>
<script type="text/javascript">
var test = {};
test.id = ${docId};
test.message = ${message};
test.lines = ${lines};
test.backslashN = ${backslashN};
console.log(test);
document.getElementById("txt").value += "id: " + test.id + "\n";
document.getElementById("txt").value += "message:" + test.message + "\n\n";
document.getElementById("txt").value += "lines:\n"+ test.lines + "\n\n";
document.getElementById("txt").value += "backslashN: ("+ test.backslashN + ")\n\n";
</script>
</body>
</html>
generates the html:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>initJsObject</title>
</head>
<body>
<!-- prepare attributes fot testing -->
<textarea id="txt" style="height: 200px; width: 200px;"></textarea>
<script type="text/javascript">
var test = {};
test.id = 123;
test.message = 'hello world';
test.lines = 'line1\nline2';
test.backslashN = '\\n';
console.log(test);
document.getElementById("txt").value += "id: " + test.id + "\n";
document.getElementById("txt").value += "message:" + test.message + "\n\n";
document.getElementById("txt").value += "lines:\n"+ test.lines + "\n\n";
document.getElementById("txt").value += "backslashN: ("+ test.backslashN + ")\n\n";
</script>
</body>
</html>
And outputs in browser:
id: 123
message:hello world
lines:
line1
line2
backslashN: (\n)
As you see the \n in the attribute string 'line1\nline2' will be evaluated as new line.
On the other side, if you need the sting \n to be presented as text, you need to escape '\\\\\n'

Related

Uncaught Reference Error when trying to pass a function through a button in JavaScript?

I'm trying to write a navigation bar at the top of my web app to change a parameter in backend, but when I call the function it always return an unexpected end of input or an uncaught reference error that says my function was not defined on click. Can someone please help me figure out what I'm doing wrong?
JS File:
let typearray=["supermarkets_and_groceries", "churches", "cafes"];
let type = "supermarkets_and_groceries";
function changeType(randomstring){
console.log('ok');
type = randomstring;
console.log(type);
}
let str = '<div class="topnav">';
for(let count = 0; count < typearray.length; count++){
str = str +
'<button onclick ="changeType("'+typearray[count]+'")" title = " '+ typearray[count] + '">' +typearray[count] +'</button>';
}
str = str + '</div>' +
'</div>';
console.log(str);
document.getElementById('navbar').innerHTML = str;
HTML File(includes the rest of the program)
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1">
<meta charset="utf-8">
<style>
#map {
height: 75%;
width: 75%;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<script src = getlocation.js></script>
<!-- this implements the navbar-->
<div id="navbar"></div>
<script type = "module" src = navbar.js></script>
<!-- this implements the map-->
<div id="map"></div>
<script src = index.js> </script>
<!-- this implements the list-->
<div id="list"></div>
<script type = "module" src = rankedstores.js></script>
<script src="https://maps.googleapis.com/maps/api/js?key=000000000000000000
&callback=initMap"></script>
</body>
</html>
Looks like you just had some errors when building str. Try this
let typearray = ["supermarkets_and_groceries", "churches", "cafes"];
let str = '<div class="topnav">';
for (let count = 0; count < typearray.length; count++) {
str += `<button onclick="changeType('${typearray[count]}')" title ="${typearray[count]}"> ${typearray[count]} </button>`;
}
str += "</div>";
console.log(str);
use properly Template literals (Template strings)
str += `<button onclick="changeType('${typearray[count]}')" title ="${typearray[count]}"> ${typearray[count]} </button>`;
let typearray=["supermarkets_and_groceries", "churches", "cafes"];
let type = "supermarkets_and_groceries";
function changeType(randomstring){
console.log('ok');
type = randomstring;
console.log(randomstring);
}
let str = '<div class="topnav" />';
for(let count = 0; count < typearray.length; count++){
str += `<button onclick="changeType('${typearray[count]}')" title ="${typearray[count]}"> ${typearray[count]} </button>`;
}
str = str + '</div>' +
'</div>';
console.log(str);
document.getElementById('navbar').innerHTML = str;
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1">
<meta charset="utf-8">
<style>
#map {
height: 75%;
width: 75%;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<script src = getlocation.js></script>
<!-- this implements the navbar-->
<div id="navbar"></div>
<script type = "module" src = navbar.js></script>
<!-- this implements the map-->
<div id="map"></div>
<script src = index.js> </script>
<!-- this implements the list-->
<div id="list"></div>
<script type = "module" src = rankedstores.js></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyD2c7P_IihiITITslXAk-wWy9z067xjFQU
&callback=initMap"></script>
</body>
</html>
use properly Template literals (Template strings)
str += `<button onclick="changeType('${typearray[count]}')" title ="${typearray[count]}"> ${typearray[count]} </button>`;
Just for understanding purpose:
The problem here is that a html attribute value has to be wrapped around single or double quotes. With your code, the quotes that wrap around the value of the button's onlick attribute end not there where you want because you start with double quotes but wrap the function with double quotes as well so the element at the end looks like this:
<button onclick="changeType(" supermarkets_and_groceries")"="" title=" supermarkets_and_groceries">supermarkets_and_groceries</button>
to fix this either use double and single quotes:
str = str +
"<button onclick='changeType(" + '"' + typearray[count] + '"' + ")' title = ' " + typearray[count] + "'>" + typearray[count] + "</button>";
or use template literals (already mentioned by the other answers):
str = str + `<button onclick="changeType('${typearray[count]}')" title ="${typearray[count]}"> ${typearray[count]} </button>`;
template literals explanation
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
Modified Code Snippet
let typearray = ["supermarkets_and_groceries", "churches", "cafes"];
let type = "supermarkets_and_groceries";
function changeType(event) {
type = event.target.getAttribute("type");
console.log(type);
}
let navHtml = document.createElement("div");
for (let count = 0; count < typearray.length; count++) {
let btn = document.createElement("button");
btn.setAttribute("type", typearray[count]);
btn.setAttribute("title", typearray[count]);
btn.innerText = typearray[count];
btn.addEventListener("click", changeType);
navHtml.appendChild(btn);
}
document.getElementById("navbar").appendChild(navHtml);

Button being triggered twice and element not being rendered anymore

I have this weather page that every time I click the button it changes from Celcius to Fahrenheit or vice-versa.
What is happening is that once I click the first time, it works fine, but then if I click it again or more times, my console log shows that it executes it twice and does not render the element anymore (#link).
$("#data").on('click', '#link', function () {
var html2 = "";
html2 += '<button class="temp" id="link">'
if (flag == 0){
console.log("c to f");
html2 += "<h1>" + celciusToFahrenheit(Math.round(json.main.temp)) + " °F</h1>";
flag = 1;
} else if (flag == 1){
console.log("f to c");
html2 += "<h1>" + Math.round(json.main.temp) + " °C</h1>";
flag = 0;
}
html2 += "</button>"
$("#link").html(html2);
});
I am including the entire file bellow:
$(document).ready(function() {
function getCurrentLocation(callback) {
if (!navigator.geolocation) return;
navigator.geolocation.getCurrentPosition(function(position) {
latitude = position.coords.latitude;
longitude = position.coords.longitude;
url = ('http://api.openweathermap.org/data/2.5/weather?lat=' + latitude + '&lon=' + longitude + '&units=metric&appid=b464bb8dd84e7e7d36103593a472ae9a');
callback(url);
});
}
function celciusToFahrenheit(celcius) {
var fahrenheit = celcius * (9 / 5) + 32;
return fahrenheit;
}
getCurrentLocation(function(currLocMap) {
$.getJSON(url, function(json) {
var html = "";
var flag = 0;
html += '<button class="temp" id="link">'
html += "<h1>" + Math.round(json.main.temp) + " °C </h1>";
html += "</button>"
html += "<h1>" + json.name + "</h1>";
html += "<h3>" + json.weather[0].main + "</h3>";
html += "<h3>" + json.weather[0].description + "</h3>";
$("#data").on('click', '#link', function () {
var html2 = "";
html2 += '<button class="temp" id="link">'
if (flag == 0){
console.log("c to f");
html2 += "<h1>" + celciusToFahrenheit(Math.round(json.main.temp)) + " °F</h1>";
flag = 1;
console.log(flag);
} else if (flag == 1){
console.log("f to c");
html2 += "<h1>" + Math.round(json.main.temp) + " °C</h1>";
flag = 0;
console.log(flag);
}
html2 += "</button>"
$("#link").html(html2);
});
console.log(json);
console.log(json.name);
console.log(json.main.temp);
console.log(json.weather[0].main);
console.log(json.weather[0].description);
console.log(json.weather[0].icon);
$("#data").html(html);
});
});
});
button#link { background:none;border:none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Weather</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="style.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="script.js"></script>
<!-- <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script> -->
</head>
<body>
<div id="data">
<h4>You are here:</h4>
</div>
</body>
</html>
That's because you're recreating the button inside the click event handler. You should change the content of the h1 tag in your handler instead of recreating the entire button, something like so:
$("h1",$(this)).html("new content");

Firefox Javascript debugger doesn't work - buttons grayed out

I'm trying to debug a JavaScript in Firefox's debugger, and it won't let me set any breakpoints, and all the step buttons (step into, step out) are grayed out. I also tried Firebug, and I have the exact same results - no breakpoints, step buttons grayed out. What gives? This is my first post here, and I apologize for my messy code here. Anywho, here's my code:
<?xml version - "1.0" encoding = "utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Page 452 - Exercise 11.7</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial scale=1.0">
<script>
function buttonClicked() {
var article = ["the", "a", "one", "some", "any"];
var noun = ["boy", "girl", "dog", "town", "car"];
var verb = ["drove", "jumped", "ran", "walked", "skipped"];
var preposition = ["to", "from", "over", "under", "on"];
var story = "Once upon a time, ";
var sentence = "";
alert (sentence);
var output = document.getElementById("textArea");
output.value = "";
for (var i=0; i<=3; i++){
sentence += article[Math.floor(Math.random()*article.length)] + " ";
alert(sentence.charAt(0));
alert("Story is " + story);
/* if (charAt(sentence[0-3]) == ".") {
sentence +=
} */
sentence += noun[Math.floor(Math.random()*noun.length)] + " ";
sentence += verb[Math.floor(Math.random()*verb.length)] + " ";
sentence +=
preposition[Math.floor(Math.random()*preposition.length)] + " ";
sentence += article[Math.floor(Math.random()*article.length)] + " ";
sentence += noun[Math.floor(Math.random()*noun.length)] + ". ";
story += sentence;
output.value = story;
window.alert (sentence);
window.alert (story);
// sentence ="";
}
story += "THE END";
// output.value = sentence;
}
</script>
</head>
<body>
<p>Click the button for a funny story!<br/>
<input type="button" id="go" onclick="buttonClicked()" value="Go!"/><br/></p>
<textarea id="textArea" rows="10" cols="30"></textarea>
</body>
</html>

Javascript Autocomplete - ColdFusion - with unique identifier

I have found this tidbit of code - which works fine.
But I also need an associated Identification ID pass along with the name.
So example has state say "California" - but I also have a unique ID associated to Califonrnia say "yye4" etc...
I can create my list easily with coldfusion as below.
var getStates = function(){
return [<cfoutput query=ulist>"#username#",</cfoutput>];
}
But I also need to pass a unique number in the form as well that is also associated to each username.
Thoughts?
<html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
<cfajaximport tags="cfinput-autosuggest">
<script>
var init = function()
{
autosuggestobj = ColdFusion.Autosuggest.getAutosuggestObject('state');
autosuggestobj.itemSelectEvent.subscribe(foo);
}
var foo = function(event,args)
{
var msg = "";
msg = msg + "Event: " + event + "\n\n";
msg = msg + "Selected Item: " + args[2] + "\n\n";
msg = msg + "Index: " + args[1]._nItemIndex + "\n\n";
alert(msg);
}
var getStates = function(){
return ["California","Connecticut","Colorado","Illinois","Alabama","Iowa","Utah","Alaska"];
}
</script>
</head>
<body>
<h3>Attaching an event handler to the autosuggest object</h3>
<cfform name="mycfform" method="post" >
State:<BR>
<cfinput
type="text"
name="state"
autosuggest="javascript:getStates({cfautosuggestvalue})"
autosuggestMinLength=1
autosuggestBindDelay=1>
<cfset ajaxOnLoad("init")>
</cfform>
</body>
</html>
This, roughly? I used a text box rather than a hidden field so you could see it in action.
<html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
<cfajaximport tags="cfinput-autosuggest">
<script>
// itcodes would contain the unique numbers instead of sample names.
var itCodes = ["Callie","Connie","Col","Illiana","Allie","Fred","Daphne","Alex"];
var itNames = [];
var init = function()
{
autosuggestobj = ColdFusion.Autosuggest.getAutosuggestObject('state');
autosuggestobj.itemSelectEvent.subscribe(foo);
}
var foo = function(event,args)
{
var msg = "";
var nameIndex = itNames.indexOf(document.getElementById('state').value);
msg = msg + "Event: " + event + "\n\n";
msg = msg + "Selected Item: " + args[2] + "\n\n";
msg = msg + "Index: " + args[1]._nItemIndex + "\n\n";
document.getElementById('hCodes').value = itCodes[nameIndex];
alert(msg);
}
var getStates = function(){
itNames = ["California","Connecticut","Colorado","Illinois","Alabama","Iowa","Utah","Alaska"];
return itNames;
}
</script>
</head>
<body>
<h3>Attaching an event handler to the autosuggest object</h3>
<cfform name="mycfform" method="post" >
State:<BR>
<cfinput
type="text"
name="state" id="state"
autosuggest="javascript:getStates({cfautosuggestvalue})"
autosuggestMinLength=1
autosuggestBindDelay=1>
<input type="text" id="hCodes" name="hCodes" value="">
<cfset ajaxOnLoad("init")>
</cfform>

Apply special tags to textarea in all selected text even if there are newline capturing all contents in cursor poisition

The example below writes tag [code] and [/code] to selected text in textarea but only applied to begin and at the end of the string... I'd like to have [code] and [/code]
applied to every part of the strings considerating newline as new string...
example posted performs:
[code]test
test
test[/code]
I'd like to apply instead:
blablabla...
[code]test[/code]
[code]miao miao[/code]
[code]this is teh 3rd string[/code]
etcetera, some extra string
as you can see I'd like to apply code only selected string considerating a new string with newline... it's possible in pure javascript? No jquery or mootools, please only standalone script...
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<title>[javascript code]</title>
<script language="JavaScript" type="text/javascript">
var myValueBefore = "[code]";
var myValueAfter = "[/code]";
function applyCode(myField, myValueBefore, myValueAfter) {
if (document.selection) {
myField.focus();
document.selection.createRange().text = myValueBefore + document.selection.createRange().text + myValueAfter;
} else if (myField.selectionStart || myField.selectionStart == '0') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos)+ myValueBefore+ myField.value.substring(startPos, endPos)+ myValueAfter+ myField.value.substring(endPos, myField.value.length);
}
}
</script>
</head>
<body>
<br><br><br>
<table align="center" border="0" cellpadding="15" cellspacing="0" width="70%">
<tr>
<td>
<form action="#" method="post">
<input type="button" value="Apply Code" onclick="javascript:applyCode(test, myValueBefore, myValueAfter);"><br>
<textarea rows="5" cols="130" name="test"></textarea>
</form>
</td>
</tr>
</table>
</body>
</html>
You can develope this codesnippet further:
var myValueBefore = '[code]',
myValueAfter = '[/code]';
function applyCode(myField, myValueBefore, myValueAfter) {
var newLine = new RegExp('\n|\r\n', 'g'), range, selectedText, beforeSelectedText, afterSelectedText;
if (document.selection) {
range = document.selection.createRange();
range.text = myValueBefore + range.text.replace(newLine, myValueAfter + '\n' + myValueBefore) + myValueAfter;
return;
} else {
beforeSelectedText = myField.value.substring(0, myField.selectionStart);
afterSelectedText = myField.value.substr(myField.selectionEnd);
selectedText = myField.value.substring(myField.selectionStart, myField.selectionEnd);
myField.value = beforeSelectedText + myValueBefore + selectedText.replace(newLine, myValueAfter + '\n' + myValueBefore) + myValueAfter + afterSelectedText;
}
return;
}
A live demo at jsFddle.

Categories

Resources