I have a webpage where admin users can edit the text on the page. But when they insert the text into the mysql database, it sometimes adds more and more white spaces before the acual content.
If you place your cursur before the first word on the page and spam backspace for a while, the whitespace in the database dissappears. But over time, the more you keep editing the page, more and more whitespaces are added again.
I did a lot of trouble shooting, but I just can't figure out what causes the whitespaces to be added. It does not always happen making it really difficult to troubleshoot.
Here's my code:
As my code is pretty long, I tried to translate most of the content to english.
If you want to translate something that in't already translated, the original language is Dutch.
over_ons.php - Shows edit button and page content from the database.
//Active page:
$pagina = 'over_ons'; ?>
<input type='hidden' id='pagina' value='<?php echo $pagina; ?>'> <!--Show active page to javascript--><?php
//Active user:
if(isset($_SESSION['correct_ingelogd']) and $_SESSION['functie']=='admin'){
$editor = $_SESSION['gebruikersnaam']; ?>
<input type='hidden' id='editor' value='<?php echo $editor; ?>'> <!--Show active user to javascript--><?php
} ?>
<!--Editable DIV: -->
<div class='big_wrapper'><?php
//Get eddited page content from the database
$query=mysql_query("SELECT inhoud FROM paginas WHERE naam_pagina='" .$pagina. "'");
while($inhoud_test=mysql_fetch_array($query)){
$inhoud=$inhoud_test[0];
}
//Show Content
?><div id='editedText'><?php echo $inhoud; ?></p></div>
<!--Show edit button-->
<?php
if(isset($_SESSION['correct_ingelogd']) and $_SESSION['functie']=='admin')
{?>
<div id='sidenote'>
<input type='button' value='Bewerken' id='sent_data' class='button' />
<div id="feedback" />
</div>
<?php }
javascript.js - Sents page content to the php file sent_data.php:
//If the system is in edit mode and the user tries to leave the page,
//let the user know it is not so smart to leave yet.
$(window).bind('beforeunload', function(){
var value = $('#sent_data').attr('value'); //change the name of the edit button
if(value == 'Verstuur bewerkingen'){
return 'Are you sure you want to leave the page? All unsaved edits will be lost!';
}
});
//Make content editable and send page content
$('#sent_data').click(function(){
var value = $('#sent_data').attr('value'); //change the name of the edit button
if(value == 'Bewerken'){
$('#sent_data').attr('value', 'Verstuur bewerkingen'); //change the name of the edit button
var $div=$('#editedText'), isEditable=$div.is('.editable'); //Make div editable
$div.prop('contenteditable',!isEditable).toggleClass('editable')
$('#feedback').html('<p class="opvallend">The content from<BR>this page is now<BR>editable.</p>');
}else if(value == 'Verstuur bewerkingen'){
var pagina = $('#pagina').val();
var editor = $('#editor').val();
var div_inhoud = $("#editedText").html();
$.ajax({
type: 'POST',
url: 'sent_data.php',
data: 'tekst=' +div_inhoud+ '&pagina=' +pagina+ '&editor=' +editor,
success: function(data){
Change the div back tot not editable, and change the button's name
$('#sent_data').attr('value', 'Bewerken'); //change the name of the edit button
var $div=$('#editedText'), isEditable=$div.is('.editable'); //Make div not editable
$div.prop('contenteditable',!isEditable).toggleClass('editable')
//Tell the user if the edditing was succesfully
$('#feedback').html(data);
setTimeout(function(){
var value = $('#sent_data').attr('value'); //look up the name of the edit button
if(value == 'Bewerken'){ //Only if the button's name is 'bewerken', take away the help text
$('#feedback').text('');
}
}, 5000);
}
}).fail(function() {
//If there was an error, let the user know
$('#feedback').html('<p class="opvallend">There was an error.<BR>Your changes have<BR>not been saved.<BR>Please try again.</p>');
});
}
});
And finally,
sent_data.php - Get page content from javascript,js and insert into database:
<?php
session_start();
include_once('./main.php');
include($main .'connectie.php');
//Look up which page has to be edited
$pagina=$_POST['pagina'];
//Get the name of the person who eddited the page
$editor=$_POST['editor'];
//Get content:
$tekst=$_POST['tekst'];
$tekst = mysql_real_escape_string($tekst);
$tekst = trim($tekst);
$query="UPDATE paginas SET naam_editer='" .$editor. "', inhoud='" .$tekst. "' WHERE naam_pagina='" .$pagina. "'";
}
if(mysql_query($query)){
echo "<p class='opvallend'>Successfully saves changes.</p>";
}else{
echo "<p class='opvallend'>Saving of changes failed.<BR>
Please try again.</p>";
}
?>
Extra information:
PHP version: 5.5.15
jQuery version: 1.11.1
Testing in browser: Chrome
Database: phpMyAdmin 5.5.39
The content is inserted in a VARCHAR type with space for 10000 caracters
Thanks in advance for you help!
SOLUTION
Thanks to the great help of a lot of people, and especially #avnishkgaur, it is working perfectly now. Here is what I ajusted (also changed it in my code above, so that's working code now).
1. Removed all the white spaces I had in my code between <div id='editable'> and <?php
2. Added $tekst = trim($tekst); to my PHP file to remove white spaces (didn't work)
3. Placed the editable text into another div as the code for getting the data from the database (was in the same div before)
4. Renamed the ID from the editable div to editedText. Also changed the name in the javascript file. This solution made it work perfectly (it was 'editable' before).
This was kind of an unexpected solution, so I think this could help others too.
As to why it is adding extra whitespace, I think it is because you are inserting the text from database into div directly (which contains some white space in html code, which is removed when page is rendered).
One efficient solution would be to insert your content in tag, probably like this:
<div class='big_wrapper'>
<p id='editable'></p>
</div>
Another solution is to trim the text before inserting into db. You can do that either at javascript post stage, or right before inserting in mysql db.
In jQuery, (which you are using) you can implement this :
data: 'tekst=' +$.trim(div_inhoud)+ '&pagina=' +pagina+ '&editor=' +$.trim(editor),
or in sent_data.php, you can use TRIM mysql function in your update query.
First of all, I would strongly suggest to use mysqli or PDO instead of the mysql functions in PHP, as these are deprecated. Please look into this on PHP.net.
As for your problem, I have no tried to reproduce the issue. I suggest you log and check what happens step by step, for example logging the div_inhoud var, are the spaces included at this stage already? And so on.
If you are in a hurry, you could also use the PHP function ltrim on the $tekst var in your sent_data.php, which would trim all spaces on the left side (Or any characters you would want to be trimmed from the string)
Try to add a trim() function in your send_data.php, this will help you to strip white spaces.
$tekst = trim($_POST['tekst']);
My guess is that the newlines after the <div id='editable'> and ?> and the indentation of <?php in over_ons.php is adding the extra whitespace. Specifically, a couple of extra /n's and also spaces from the indentation within the file.
You could trim the whitespace before saving it to your database, or alternatively, before the ajax call, or both.
In php, trim():
sent_data.php
$tekst = trim($tekst);
Or javascript, str.trim():
javascript.js
var div_inhoud = $("#editable").html().trim();
Also, you may want to consider using PHP Data Objects, instead of inserting variables directly into your SQL statements. It's actually really easy to use and in my opinion makes code easier to read and more reusable. There is a fantastic tutorial by Tuts+ that makes it easy to learn and get started. This will ensure you don't accidentally allow SQL injection issues into your application.
Related
I have a page that auto-populates a form based on some SQL data. The formatting of the form mirrors a form that some users are currently having to manually populate, so this is designed to make sure the form is populated completely and accurately from SQL instead, and save the users some time. As a result though, the formatting of the form has to be exactly like it currently is.
I then have a button that the user clicks at the bottom of the form, and it uses jsPDF and html2canvas to turn the 3 "page" divs into a 3 page PDF that is automatically sent to our s3 server for them to access through their files page.
Everything is basically working perfectly now, except, there is a column of checkboxes on the first page that are used to document if anything in the form has been "changed." You can see an example here. Basically, if the answer to any of the questions is "yes" it auto-checks the box "yes," but also there's a Javascript function that writes a SQL table if they (un)click a box and persists the change.
Example of Form w Checkbox
My scripts for jQuery, jsPDF, and html2canvas
<!-- jsPDF library -->
<script src="/jsPDF/dist/jspdf.debug.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js"></script>
Here's the HTML where the checkbox is:
<div class="filerow">
<div class="mcfcolumn"><b>Assignment of Benefits (AOB)</b></div>
<div class="response"><?php echo $aobVal; ?></div>
<div class="changebox"><input type="checkbox" class="checkbox" id="aob" onclick="checkboxClicked('aob')" value="<?php print_r($changeVals['aob']); ?>" <?php if($changeVals['aob'] == 'yes'){ ?> checked <?php } ?> ></div>
</div>
The PHP is echoing the results of some SQL queries.
At the bottom of the page is a button for the Javascript function that creates the PDF
<button class="submitbutton" id="createPdf" onclick="createPdf(<?php echo '\'' . $cid . '\', \'' . $title . '\''; ?>)">Generate PDF</button>
I used some code from this answer to create a recursive function for jsPDF
function createPdf(claimid, title) {
var pdf = new jsPDF('p', 'pt', 'a4');
var pdfName = 'test.pdf';
var options = {};
var $divs = $('.page') //jQuery object of all the myDivClass divs
var numRecursionsNeeded = $divs.length -1; //the number of times we need to call addHtml (once per div)
var currentRecursion=0;
//Found a trick for using addHtml more than once per pdf. Call addHtml in the callback function of addHtml recursively.
function recursiveAddHtmlAndSave(currentRecursion, totalRecursions){
//Once we have done all the divs save the pdf
if(currentRecursion==totalRecursions){
// pdf.save(pdfName);
var pdfFile = btoa(pdf.output());
$.ajax({
method: "POST",
url: "velocityform_s3save.php",
data: {
data: pdfFile,
claimid: claimid,
title: title,
},
}).done(function(data){
console.log(data);
});
}else{
currentRecursion++;
pdf.addPage();
//$('.page')[currentRecursion] selects one of the divs out of the jquery collection as a html element
//addHtml requires an html element. Not a string like fromHtml.
pdf.addHTML($('.page')[currentRecursion], 15, 20, options, function(){
console.log(currentRecursion);
recursiveAddHtmlAndSave(currentRecursion, totalRecursions)
});
}
}
pdf.addHTML($('.page')[currentRecursion], 15, 20, options, function(){
recursiveAddHtmlAndSave(currentRecursion, numRecursionsNeeded);
});
}
I have Ajax going to a php page that saves the form to s3 instead of just saving locally, but that's not really relevant, because when I use
pdf.save(pdfName);
I get a locally saved PDF which also does not render the checkboxes. When the PDF renders, it looks like this:
PDF Generated
Everything else is doing exactly what I need it to do, except this one detail. I used jsPDF instead of something like TCPDF because between the CSS, PHP, HTML, and Javascript it just wasn't able to render a remotely well formatted PDF. As of yet, jsPDF is the only thing I've found that's been able to render the 3 pages in proper formatting. Any help getting the checkboxes to render into the PDF is appreciated.
Thanks.
In case anyone has a similar problem, I found the issue was I needed to update my html2canvas link. I found the answer here .
<script src="https://raw.githubusercontent.com/CodeYellowBV/html2canvas/master/build/html2canvas.js"></script>
Immediately resolved the issue.
I have a table that displays items from a database. One of the items is a description so it can be very long.The thing I'm having the most problem with is how can I use JS and HTML smoothly in my controller class.
I want to be able to display a little bit of it if its longer than 100 char, and a button that looks like '...' where if the user clicks on it, it displays the trimmed text. I want to do this using javascript and here is what I tried, this code is in my controller, so I'm just sending these to the view.
The problem is when I press the button it doesn't display anything so what is wrong here? Some suggested to use jquery but I don't want to write my js script elsewhere and call it again since I'm not sure how I will do that in Phalcon controller.
$this->view->tblColumns = [
'element one',
'element two',
function (tablename $instance) {
if (strlen($desc = $instance->getDescription()) > 100) {
return $shortDesc = substr($instance->getDescription(), 0, 100) . '
<button style="background: none;border: none" onclick="(function(){
var desc= <?php echo
$desc; ?>; document.write(desc) ;
})()" >...</button>';
} else {
return $instance->getDescription();
}
},
do NOT use document.write after load of the page. It will wipe the page
your desc needs to be in single quotes and have no carriage returns.
you cannot use an IIFE in an onclick unless it returns a function
if your button is in a form, you will submit the form - it should be type=button
You MAY mean
<button type="button" onclick="var desc='<?php echo $desc; ?>';
document.querySelector('#someContainer').innerHTML=desc;"...>
but a better way is to toggle the existing text inside tags (span for example)
I find a way to do what I wanted, using the code for read more,read less from this link https://codepen.io/maxds/pen/jgeoA
The thing I was having trouble with in phalcon MVC, was that I didn't know I could my java-script, and css in the view of the controller and that's what I did.
I just used the js from that link, into my view file, the same for the css using tag and tag.
And in the function on the controller I wrote the following `
$this->view->tblColumns = [
'one',
'two',
function(tablename $link){
$desc=$link->getDescription();
$html=<<<HTML
<span span class="more"> $desc</span>
HTML;
return $html;
}`
First time here so apologies if I'm doing something wrong.
I have the following php code:
<?php
$quoteFile = "quotes.txt"; //File holding qoutes
$fp = fopen($quoteFile, "r"); //Opens file for read
$content = fread($fp, filesize($quoteFile));
$quotes = explode("\n",$content); //Put quotes into array
fclose($fp); //Close the file
srand((double)microtime()*1000000); // randomize
$index = (rand(1, sizeof($quotes)) - 1); //Pick random qoute
?>
The code fetches a random quote from a text file by randomly choosing one of the lines of the .txt file.
I then echo out the result using:
echo $quotes[$index];
However what I want to achieve and don't seem to be able to is to have a button (html) that when clicked executes the echo $quotes[$index]; to the current page. So that each time the button is clicked it prints/echo's out a random quote from the .text file.
I did mess about with just setting a button up to refresh the page which by default made a new random quote display but it sometimes just reloaded a blank so I'm hoping someone can help me achieve this better or prompt me in the right direction. Thank tou.
You can try saving that variable into a session variable like this:
$_SESSION['quote'] = $quote['index'];
Then create an anchor element that redirects to current page:
Refresh
And print the result on the page:
<span><?php echo $_SESSION['quote']; ?></span>
To do all of this, you need to set a session. At top of your php file write:
session_start();
Hope that helps. :)
Your TXT file might have an empty line in it at the end or anywhere else. A second explanation of this, is that the way you are generating randomness is quite questionable.
Check out this simple example by W3 Schools.
$a=array("red","green","blue","yellow","brown");
$random_keys=array_rand($a,1);
echo $a[$random_keys[0]]."<br>";
The array_rand() function returns a random key from an array, or it returns an array of random keys if you specify that the function should return more than one key.
Or, simply:
<?php
$a=array("a"=>"red","b"=>"green","c"=>"blue","d"=>"yellow");
print_r(array_rand($a,1));
?>
Full Post: http://www.w3schools.com/php/func_array_rand.asp
Happy coding !
JQuery seems to be blocked
Hello there, I've been confronting this problem for several days, I just can't find a way to get this fixed, or around it.
What I want to do is simple, I want to read out every sub-folder of a big Project folder. Then assign a thumbnail image and a figcapture to this folder. With a simple for loop, php builds this for me. Everything works perfect and quick. The only thing is that the jquery won't respond. Even though I have created various menus with this technique. As you can see in my code, in the "script" tags, I have the jquery code which doesn't seem to work.
I don't know wheter php puts in a space somewhere or I just looked too long at this code for seing the error.
I appreciate any help.
<?php
/*Because of the "ease of use" aspect of this site, I prefered to write it completely in PHP,
advantage of that:
Images are loaded directly out of the folder, so I can just drag and drop something onto the server without having to write aditional code.
As you see, it can save a lot of time.*/
echo "<h1>Referenzen</h1><br>";
$projects = scandir('../src/sub/credentials'); //The credentials directory is being scanned and converted into an array.
$projectsSize = count($projects); //$size is being created. It counts the number of objects in the array which has been created above.
$projectsCaptions = file('../src/sub/captionsOfCredentials.txt'); //Edit the name of the figcaption in the "captionsOfCredentials.txt".
for($i = 2; $i < $projectsSize; $i++){ /*Simple "for" loop, that creates $i with the size of two, because PHP is 0-index based and has the "dot" and the "dotdot" folder. The loop stops at the end of the array($size).*/
echo '<a href="index.php#PRJ'.trim($projectsCaptions[$i]).'" class="ID'.trim($projectsCaptions[$i]).'">
<div class="projectFolder">
<img src="src/sub/credentialsThumb/project_00'.$i.'.jpg" width="100%" />
<figcaption>'
.$projectsCaptions[$i].
'</figcaption>
</div>
</a>';
/*Project folder level starts here.*/
$images = scandir('../src/sub/credentials/project_00'.$i);
$imagesSize = count($images);
for($k = 3; $k < $imagesSize; $k++){
$tempID = ('ID'.trim($projectsCaptions[$i]).'.php'); //$tempID is the entire file name including the .php part.
$handle = fopen($tempID, "a") or die ('Unable to open '.$tempID.' , please contact admin A.S.A.P..');
$imagesCode = 'test';
fwrite($handle, $imagesCode);
}
//end second for-loop
echo "
<script>
$(document).ready(function () {
$('#ID".$projectsCaptions[$i]."').click(function () {
$('#mainContent').load('de-DE/".$tempID."');
});
});
</script>";
}
//end first for-loop
?>
You're selecting an element by id when you need to use class. Change the JS block to this:
$(document).ready(function () {
// Note ".ID" not "#ID"
$('.ID".$projectsCaptions[$i]."').click(function () {
$('#mainContent').load('de-DE/".$tempID."');
});
});
UPDATE
It seems like you've also got an illegal character in $projectsCaptions[$i]. It's most likely a newline character. Try wrapping the above reference above in trim():
$('.ID" . trim($projectsCaptions[$i]) . "').click(function () {
I build a code here.. that when he\she posts a comment the JavaScript will slide down a new comment block...
But i need to refresh after click the post button - then - there will be a new comment block under a post.
This is my code:
<script language="javascript" type="text/javascript">
//Sending the jquery comment
function SendComment(blab_id) {
var comment_txt = $("#Comment"+blab_id).val()
if(comment_txt == ""){
alert("Please Enter a Comment!");
}else{
$.post("scripts/send_comment.php", {Comment: comment_txt, bid: blab_id} ,function(data){
$("#new_comment"+blab_id).html(data);
$("#new_comment"+blab_id).slideDown(300);
$("#Comment"+blab_id).val("");
});
}
}
</script>
assuming your script works fine, except that u need to refresh page every time...
why cant you automatically refresh that particular div without loading overall page like this...
$('#Comment"+blab_id).load('yourpage.php');
What is "#Comment"+blab_id ? If that is just an input field, what is blab_id?
I think what you want is something like http://jqueryui.com/demos/dialog/#modal-form , but instead of a table a bunch of divs. I would have one div id=comments that contains all the comments, then you should be able to add more comments to the bottom of this. So instead of
$("#new_comment"+blab_id).html(data);
$("#new_comment"+blab_id).slideDown(300);
you would have $("comments").append(data).fadeIn(); (According to this) (Or prepend if you want the comment to appear at the top) (I haven't checked if this works though...)
where I assume data is
<div style="background-color:#f0f9fe";border-bottom:1px dashed #3A69B6; padding:5px; width:auto;">
<strong>'.$comment_user.' </strong>
<br/>'.$comment_txt.' <br/> ·'.$whenComment.'·
</div>
which is returned from scripts/send_comment.php