I am having a tough time covering all areas with special chars that could possibly break the variable in JavaScript. So for context I am pulling information from a database and then echoing it to JavaScript variable that will display the data which is text that has been entered by a user and stored to the table.
The php variable is $letter see the code below that I used to try to keep it from breaking
$letter = $order["letter"];
$letter = str_replace("'", "\'", $letter);
$letter = str_replace("\"", "\"", $letter);
$letter = str_replace("\r\n", "\\n",$letter);
Below is the line of code where I attempt to decode it so that it will display in an html format
$(".fa-eye").click(function () {
//clear pager html
$(".pager").html('');
$("#text-pager").html('<p class="text-left prevdescription"></p>');
//clear pager html
var parentTd = $(this).parent().parent('td');
var letterContent = parentTd.find('#letterTxt').val();
var pagerHtml = '<p class="controls"><a class="tp-control-arrow-left unactive"><span><</span></a><a class="tp-control-arrow-right"><span>></span></a><ul class="pager"></ul></p>';
$(".prevdescription").html(letterContent.replace(/\r?\n/g, '<br/>'));
It produces the output in the image below...what am I missing?
You may write me down in history\nWith your bitter, twisted lies,\nYou may tread me in the very dirt\nBut still, like dust, I\ ............. This is what it outputs. not showing all of the content.
Use json_encode(), it converts a PHP value to the equivalent JavaScript literal.
<script>
var letter = <?php echo json_encode($order['letter']); ?>;
</script>
Related
php:
$str1 = "AAA\r\nBBBB\\CCC";
echo"<textarea id='aa1' onfocus='erase(\"".$str1."\", \"aa1\");'></textarea>";
$str2 = "AAABBBB\\CCC";
echo"<textarea id='aa2' onfocus='erase(\"".$str2."\", \"aa2\");'></textarea>";
$str3 = "AAABBBB\CCC";
echo"<textarea id='aa3' onfocus='erase(\"".$str3."\", \"aa3\");'></textarea>";
$str4 = "AAABBBBCCC";
echo"<textarea id='aa4' onfocus='erase(\"".$str4."\", \"aa4\");'></textarea>";
javascript:
function erase(str, id)
{
alert("good");
var field = document.getElementById(id);
if(field.value == str)
{
field.value = '';
}
}
If I click on textarea id='aa1', nothing happens.
If I click on textarea id='aa2' or textarea id='aa3', 'good' is printed but nothing happens to field.value.
If I click on textarea id='aa4', 'good' is printed and field.value is ''.
I want a string like AAA\r\nBBBB\\CCC to work like textarea id='aa4.
How can I do that?
I read the post below but it does not seem to help my situation:
Javascript parameter
Javascript Line Break Textarea
update:
I've replaced $str1 with json_encode($str1), So alert(); works fine now. (Thanks to Jordan Running.)
But the field.value part still does not work.
code refactoring is too hard in my situation... Is there any way to handle the field.value problem without code refactoring?
If quotes corrupt my HTML, I can putting $str1 in htmlspecialchars() and displaying it in <textarea>.
Generally speaking it's a bad idea to use string concatenation to build JavaScript. Your PHP code produces the following HTML:
<textarea id='aa1' onfocus='erase("AAA
BBBB\CCC", "aa1");'></textarea>
That's valid HTML, but the code in your onfocus attribute is not valid JavaScript. In JavaScript, you can't have a line break in the middle of a string literal. You can have a line break in a template literal (i.e. `one of these`), but that's not the right solution here.
A quick but short-sighted fix
When you need to "inject" some data into a block of JavaScript, you should always use json_encode:
$str1 = "AAA\r\nBBBB\\CCC";
echo "<textarea id='aa1' onfocus='erase(" . json_encode($str1) . ", \"aa1\");'></textarea>";
Make careful note of the quotation marks above. Because json_encode wraps strings in quotation marks, you don't need additional quotes around . json_encode($str1) ..
This will produce the following HTML:
<textarea id='aa1' onfocus='erase("AAA\r\nBBBB\\CCC", "aa1");'></textarea>
...whose onfocus handler works correctly, as you can see in this snippet:
function erase(...args) { console.log('erase called with', args); }
<textarea id='aa1' onfocus='erase("AAA\r\nBBBB\\CCC", "aa1");'></textarea>
A better way
The above is still fragile. What if your data has a ' in it? That'll break your HTML. The correct solution is to move your data out of the HTML entirely. Consider if you refactored your code to look something like this:
<textarea id="aa1"></textarea>
<textarea id="aa2"></textarea>
<textarea id="aa3"></textarea>
<textarea id="aa4"></textarea>
<?php
$erase_map = [
'aa1' => "AAA\r\nBBBB\\CCC",
'aa2' => "AAABBBB\\CCC",
'aa3' => "AAABBBB\CCC",
'aa4' => "AAABBBBCCC",
];
?>
<script>
const ERASE_MAP = <?php echo json_encode($erase_map); ?>;
function erase(event) {
if (event.target.value == ERASE_MAP[event.target.id]) {
event.target.value = '';
}
}
document.querySelectorAll('textarea').forEach(textarea => textarea.addEventListener('focus', erase));
</script>
In the above code, all of the data is in one place—a single associative array—instead of scattered around your HTML. It generates HTML code with a <script> tag into which the data is injected as a JSON object and assigned to a JavaScript variable:
<textarea id="aa1"></textarea>
<textarea id="aa2"></textarea>
<textarea id="aa3"></textarea>
<textarea id="aa4"></textarea>
<script>
const ERASE_MAP = {"aa1":"AAA\r\nBBBB\\CCC","aa2":"AAABBBB\\CCC","aa3":"AAABBBB\\CCC","aa4":"AAABBBBCCC"};
function erase(event) {
if (event.target.value == ERASE_MAP[event.target.id]) {
event.target.value = '';
}
}
document.querySelectorAll('textarea').forEach(textarea => textarea.addEventListener('focus', erase));
</script>
Im getting data from sql and using php to generate javascript for an edit button for each entry. The edit interface uses a text input in a form. When the generated edit button is clicked, the text within this field is set to equal the name of the entry from sql.
This works fine in all cases expect when the name contains double quotes ("), in which case the quotes are replaced with " in the text field.
The php genertaed javascript is below:
function editButton($suffix,$name)
{
echo "<button class=\"edit\" onclick=\"editMode$suffix()\">Edit</button>";
echo "<script>
<!--
function editMode$suffix(){
document.getElementById(\"title\").innerHTML = \"Edit Artist\"
var main = document.getElementById(\"main\");
main.style.display = 'none';
var edit = document.getElementById(\"edit\");
edit.style.display = 'block';
//Set the input of the edit interface to be equal to the current name
document.getElementById(\"editInput\").value = \"$name\";
document.getElementById(\"artEdit\").value = \"$name\";
}
-->
</script>";
}
The $name variable is sanitized via htmlentities() before being passed to the function. Without doing so, the edit interface for entries with quotes will not even display.
I found this which sounds like the same issue but no solutions (https://code.google.com/archive/p/embeddedjavascript/issues/19) :/
IF anyone has a solution or can point out some stupid thing im doing thats causing this it would be very appreciated. At this point im going to have to just disable database entry for double quotes and limit to singles.
Just change all the double-quotes in the JavaScript portion to single-quotes, then use addslashes() on the $name variable:
function editButton($suffix, $name)
{
$name = addslashes( html_entity_decode($name) );
echo "<button class='edit' onclick='editMode$suffix()'>Edit</button>";
echo "<script>
<!--
function editMode$suffix() {
document.getElementById('title').innerHTML = 'Edit Artist'
var main = document.getElementById('main');
main.style.display = 'none';
var edit = document.getElementById('edit');
edit.style.display = 'block';
//Set the input of the edit interface to be equal to the current name
document.getElementById('editInput').value = '$name';
document.getElementById('artEdit').value = '$name';
}
-->
</script>";
}
*Also added html_entity_decode() to converts the entities back to their initial state. Consider removing the htmlentities() altogether, in which case, you can remove the html_entity_decode() from the above script.
Hello fellow Overflows,
So im in the middle of creating a toplist script, ready to launch to the public,
I'm stuck on one perticualr subject.
Displaying X amount of content from A database field.
<?php echo $server_data['description']; ?>
As you can see in this image below, That wouldn't be a good idea to display the full amount.
http://i.imgur.com/IhLs7L7.png
What do i need?
Instead of it displaying all of the database field, i just want it to display 150 characters of the field.
It is best to limit characters while you are selecting from database because it will improve performance a bit. You can limit characters on select with mysql LEFT() function.
Here is how to do it:
SELECT LEFT(description, 150), another_col FROM ......
Try this:
$string = substr($server_data['description'], 0, 150);
substr() will only return a certain amount of characters. If you want a certain amount of words then you could use the following:
<?php
function excerpt($content = '',$number_words = 125){
$content = strip_tags($content);
$contentWords = substr_count($content," ") + 1;
$words = explode(" ",$content,($number_words+1));
$excerpt = join(" ",$words);
return $excerpt;
}
echo excerpt($server_data['description'], 125);
I am using the replaceWith() function in jQuery to update my web page. I receive the data from a C# web service program that extracts data from a database to build my HTML code. It works fine except when I replace large amounts of data. In the example that's not working, I replace code in my web page with 39000 bytes of data. After that, none of my links work when clicking on a span to calls a JavaScript function. Is there a limit on the size of data used in the replaceWith() function? The html code I am replacing looks like this:
<td align=left valign=top>
<div id="showitems" class="showitems" style="display:inline; float:left"></div>
</td>
The javascript code looks like this:
function ShowDinerItems() {
var gps = document.getElementById("selectdiner").value;
var pos = gps.indexOf(";");
var len = gps.length;
var latitude = document.getElementById("Hiddenlat").value;
var longitude = document.getElementById("Hiddenlng").value;
var dinerkey = gps.substring(0, pos);
PageMethods.CallShowDinerItems(dinerkey, latitude,longitude, OnShowDinerComplete, OnShowDinerError, dinerkey);
}
function OnShowDinerComplete(result) {
var htmlcode = result[0];
if (result == 'none') {
document.getElementById("Message").value = "Search returned no items";
}
else {
var htmlcode = result[0];
htmlcode = "<div id=\"showitems\" class=\"showitems\" style=\"display:inline\">" + htmlcode + "</div>";
$('.showitems').replaceWith(htmlcode); // size of htmlcode is 39849 bytes
var locations = result[1].split(";");
var lat = locations[0];
var lng = locations[1];
markDiner(lat, lng, "", 'map_canvas');
}
}
The reason I am using jquery to build my webpage is to avoid page reloads. I could easily program the webdata content in my C# program which may be more efficient but page reloads are to be avoided as dictated by the people who own the website. I am will try the recommendations given.
Note: I used the following code to make it work.
$('.showitems').html(result[0]);
Using .text will not work as it displays raw data and not html data. Thanks to those who contributed.
To be honest I think you're going about this the wrong way here.
It seems to me that you're using ReplaceWith to completely overwrite the matched tag when you could just as simply change its properties with jQuery.
For example:
var htmlcode = result[0];
htmlcode = "<div id=\"showitems\" class=\"showitems\" style=\"display:inline\">" + htmlcode + "</div>";
$('.showitems').replaceWith(htmlcode); // size of htmlcode is 39849 bytes
Could easily be changed to this:
$('.showitems').css('float','none').text(result[0]);
Just how many showItems are there going to be by the way, and how do you know how it compares to how many results you get back from the C# call ?
Edit 2: Sorry, didn't realise that the CSS display attribute wasn't actually changing.
I am using this code to generate hidden HTML code in Facebook :
echo "<div id=\"y257y\" style=\"display:none;\">".$fdesc."</div>";
And, I am trying to get this element back in JS using the following code
newVal=document.getElementById('y257y').getValue();
But, I am getting an error: Undefined
Can anyone kindly help me out ?
Thanks.
-
ahsan
Instead of:
newVal = document.getElementById('y257y').getValue();
try using:
newVal = document.getElementById('y257y').innerHTML;
Are you using any JavaScript library, like jQuery or Prototype? If you're using jQuery:
newVal = $('#y257y').html();
Other suggestions:
Use hidden form element:
echo "<input type=hidden id=y257y value=\"$fdesc\">";
and in JavaScript:
newVal = document.getElementById('y257y').value;
Or just output a <script> tag:
echo "<script>newVal = \"$fdesc\";</script>";
and there's no need to find the value in the DOM – it's already in JavaScript.
Try using a textarea? Since at least that may have a getValue method if you are really lucky:
$fdesc = str_replace('<', '<', $fdesc);
$fdesc = str_replace('>', '>', $fdesc);
echo "<textarea id=\"y257y\" style=\"display:none;\">".$fdesc."</textarea>";
newVal=document.getElementById('y257y').getValue();
newVal = newVal.replace(">", ">")
newVal = newVal.replace("<", "<")
But something tells me that is not going to work for you, facebook may not like it.
Seems easier just to do this:
$fdesc = <<<EOD
<div>Here is your html</div>
<p>And some more </p>
EOD;
$fdesc = str_replace("'", "\'", $fdesc); //Escape single quotes
$fdesc = str_replace("\n", "";', $fdesc); //Get rid of line breaks
echo "var fdesc = '$fdesk';";