I'm using this jquery plugin to create a wysiwyg text editor,
I created a textarea in PHP where:
<textarea name="body" id="body"><?php echo $body?></textarea>
and
<script type="text/javascript">
$(document).ready( function() {
$("#body").Editor();
});
</script>
Now i need to get value of this area for send it to SQL
if (isset($_POST['add-article'])) {
unset($_POST['add-article']);
$_POST['user_id'] = $_SESSION['id'];
$_POST['username'] = htmlentities($_SESSION['username']);
$_POST['published'] = isset($_POST['published']) ? 1 : 0;
// I need this line
$_POST['body'] = htmlentities($_POST['body']);
When I put text into this editor, it doesn't enter (value) into the textarea.
I have to have value before I press the add-article button, beacuse now it gives me an empty text.
I found something like this
function displayText(){
alert($("#body").Editor("getText"));
}
This causes it to return text ( i think only display by JS ) but i completely dont know how to use in my PHP scripts.
Second thing is when i write article and make a mistake something like ( Article title already exist ) ( in one session ) text in textarea stayed, but now doesn`t work it.
I think about if there is an error for example "Title already exist" follows:
} else {
$title = $_POST['title'];
$body = $_POST['body'];
$category_id = $_POST['category_id'];
$published = isset($_POST['published']) ? 1 : 0;
}
In my honest opinion i need something like:
add-article.addEventListener('click', function {
$body (from PHP) = alert($("#body").Editor("getText"))(from JS);
}
Thank you in advance for help.
On the plugin page you referenced, I see this is one of the recommendations. Capture the value you want when the click button is pressed, before the form submits.
Add a script to your form submit to put the texteditor content into this element
<form onsubmit='return getItReady()'>
Add an element to the form you'll use as a proxy element and keep it hidden, something like
<textarea id='txtEditorContent' name='txtEditorContent' style='visibility:hidden;height:0px' tabindex="-1"></textarea>
Then add the script to prepare it
<script>
function getItReady() {
console.log('The content:', $('#body').Editor("getText"));
$('#txtEditorContent').val($('#body').Editor("getText"));
return true;
}
</script>
Then in your PHP, it will come through as $_POST['txtEditorContent'].
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>
I am echoing out a form (foreach) from my filemaker records which will result in the items ID, Name, a Checkbox and then an image.
In my understanding i will have to use classes or the elements will all have the same id.
My Code;
foreach($result->getRecords() as $record){
$id = $record->getField('Record_ID_PHP');
$name = $record->getField('DB_Name');
$pic = $record->getField('Photo_Path');
echo '"'.$id.'"<br>';
echo $name.'<br>';
echo '<input type="checkbox" class="check" value="Invoices/Photos/RC_Data_FMS/Invoices_db/Photos/'.$pic.'">';
echo '<div class="pics">';
echo '<img style="width:200px;" src="Invoices/Photos/RC_Data_FMS/Invoices_db/Photos/'.$pic.'"><br>';
echo '<hr>';
echo '</div>';
}
Which results in a page full of the records, a checkbox and the relating image.
I wish to only show these images when the checkbox is checked but cannot find a solution, i have tried many jquery scripts, to no avail.
The images will then populate the next page as a pdf to be printed.
I am hoping not to have to grab the checkbox's values as an array to then use the get method with 100's of if statements but cant see another way ?
The jquery ive used.
$(document).ready(function () {
$('.pics').hide();
$('.check').click(function () {
$('pics').show;
});
$('.pics').hide;
});
and
$(function() {
$(".check").click(function(e) {
e.preventDefault();
$('.pics').hide();
$('.pics').show();
});
});
Plus many similar alternatives.
Is there something obvious i am missing ?
Query to filemaker method;
I have changed the path field to a calculated value which works great, thank you, although with 1000's of records, i would need lots of php code to echo the checkbox's to the website and lots more to be able to edit them from the website.
I have done this previously with the value held within the checkbox in filemaker.
$sesame = $print->getField('Allergens::Allergens[11]'); if ($sesame == "Sesame") { $sesame = "checked" ;} else if ($sesame !== "Sesame") {$sesame = "" ;}
This displays the checkbox synced with filemaker.
if ($_POST['Sesame'] == 'Sesame'){ $a_sesame = 'Sesame';} else { $a_sesame = 'No Sesame'; }
This is sent as a variable to my script.
if($a_sesame == "Sesame"){$contains_sesame = "Yes";} else { $contains_sesame = "No";}
This grabs the new value from the form.
Which all work great, but then i am writing a script in filemaker too to enable the to and from of the different names for each checkbox state.
which is for this part 120 lines long, this is a sample which i have to repeat for each repetition of this field.
Set Variable [ $sesame; Value:GetValue ( Get ( ScriptParameter ) ; 11 ) ]
If [ $sesame = "Sesame" ]
Set Field [ Allergens::Allergens[11]; "Sesame" ] Commit Records/Requests
[ Skip data entry validation; No dialog ]
Else If [ $sesame = "No Sesame" ]
Clear [ Allergens::Allergens[11] ] [ Select ]
Commit Records/Requests
[ Skip data entry validation; No dialog ]
Refresh Window
[ Flush cached join results; Flush cached external data ]
End If
This would be far too large to write for so many records, just for these 14 fields used 120 in filemaker and 400 plus in the php.
I am not 100% sure what you are trying to do but this should work. First add an extra div that closes input and div pics like below.
foreach($result->getRecords() as $record){
$id = $record->getField('Record_ID_PHP');
$name = $record->getField('DB_Name');
$pic = $record->getField('Photo_Path');
echo <<<TEXT
'{$id}'<br>
{$name}<br>
<div>
<input type='checkbox' class='check' value='Invoices/Photos/RC_Data_FMS/Invoices_db/Photos/{$pic}'>
<div class='pics'>
<img style='width: 200px;' src='Invoices/Photos/RC_Data_FMS/Invoices_db/Photos/{$pic}'><br>
<hr>
</div>
</div>
TEXT;
}
then change your java to this
$(document).ready(function() {
$(".pics").hide();
$(".check").click(function() {
$(this).siblings().toggle();
});
});
well I hope this helps
Another alternative would be to set up a simple calculated container field in FileMaker, with a calculated value of:
If ( checkbox; imageField )
This would only pass the image when the checkbox was ticked for a record. This should be faster than handling this in JavaScript, since you'd be limiting the number of images being sent over the wire.
Note: For performance, you might try this with this calculated container field stored and unstored. I suspect stored v unstored should make little difference, in which case I'd suggest leaving this unstored to minimize disk space consumed.
You can use the toggle()function:
$(function() {
$('.pics').hide();
$(".check").is(':checked',function(e) {
e.preventDefault();
$('.pics').toggle();
});
});
I am working with PHP's Yii framework and having issues clearing or deleting the uploaded file from the textfield. Currently, it will delete the content from the fileField, but can't get it to delete the textfield. Any ideas?
UPDATE
I can now clear my textField because I've hard coded my clearFileInputField function by adding $('.getFile').val(""); I reference this in my HTML by adding the 'class' => 'getName' in the input section. While this clears the data, it doesn't remove the file after saving. Any suggestions?
HTML
<div id = "clearContent">
<?php echo $form->labelex($model,'info'); ?>
<?php echo $form->textfield($model,'info', array(placeholder => "No file chosen", readonly => true, 'class' => 'getName')); ?><br>
<?php echo $form->fileField($model,'info'); ?>
<?php echo $form->error($model,'info'); ?>
<input type="checkbox" onclick = "clearFileInputField('clearContent')" href="javascript:noAction();"> Remove File
</div>
JavaScript:
<script>
function clearFileInputField(tagId) {
document.getElementById(tagId).innerHTML = document.getElementById(tagId).innerHTML;
$('.getFile').val("");
}
</script>
I am not sure if I understood the problem you are having correctly. If I understood the question completely wrong, please elaborate and I will try to improve my answer.
If you want to remove the the content (the value attribute) of a text and file input you can use code like the following:
// listen to the click on the #clearnbtn element
document.getElementById('clearbtn').addEventListener('click', function() {
// Remove the value of the #foo and #bar elements
document.getElementById('foo').value = "";
document.getElementById('bar').value = "";
});
If you would like to remove an entire field you can do that like so:
// Retrieves the input element, gets its parents and removes itself from it
var fooElement = document.getElementById('foo');
fooElement.parentElement.removeChild(fooElement)
Or you can set the innerHTML attribute of the parent element to an empty string ('').
document.getElementById('clearContent').innerHTML = "";
https://jsfiddle.net/osjk7umh/1/
I'm having a simple commenting system, where i want the user should not type any html special chars, if they done like that they should give an alert of "html tags not allowed". How to do it?
while submitting, a ajax call is passed to another page to store it in db.
So in the javascript itself(before ajax call), how to find is there any html tags in the entered comment.
Any suggestion.
To check you can create an element in the DOM, inject the comment into it and use [element].getElementsByTagName('*') to check for any html element. If its length is not 0, there are html elements in the comment. Something like:
document.querySelector('#check').addEventListener('click', doCheck);
function doCheck(e) {
var chkEl = document.createElement('div'),
isok,
report,
value = document.querySelector('#testing').value;
if (!value.length) {return true;}
chkEl.innerHTML = value;
report = document.querySelector('[data-report]');
isok = !chkEl.getElementsByTagName('*').length;
report.setAttribute( 'data-report',
!isok
? 'you can\'t enter html here!'
: 'text looks ok' );
report.style.color = isok ? 'green' : 'red';
}
[data-report]:before {
content: attr(data-report);
}
<textarea id="testing" placeholder="type some stuff"></textarea>
<span data-report=""></span>
<br>
<button id="check">check for html</button>
Disclaimer: you should always check server side too.
You can use the following statement with regex:
if (/<[a-z][\s\S]*>/i.test(textareaContent)) {
alert("html tags not allowed");
}
Kooilnc is right. You should always check user input on server side as well.
Please see this question Check if a string is html or not
removing html tags in comment
function sanitizeString(str) {
str = str.replace(/[^a-z0-9áéíóúñü \.,_-]/gim, " ");
return str.trim();
}
I'm dealing with some legacy HTML/JavaScript. Some of which I have control over, some of which is generated from a place over which I have no control.
There is a dynamically generated form with hidden fields. The form itself is generated via a Velocity template (Percussion Rhythmyx CMS) and JavaScript inserts additional hidden form fields. The end result is hidden form fields generated with the same 'name' attribute. The data is being POSTed to Java/JSP server-side code about which I know very little.
I know that form fields sharing the same 'name' attribute is valid. For some reason the POSTed data is not being recognized the back end. When I examine the POST string, the same-name-keys all contain no data.
If I manipulate the code in my dev environment such that only a single input field exists for a given name, the data IS POSTed to the back end correctly. The problem is not consistent, sometimes, it works just fine.
Is there something I can do to guarantee that the data will be POSTed? Can anyone think of a reason why it would not be?
I should really update my answer and post code here, because POST requests without
variable strings indicates the problem is on the client side.
How about this:
<script type="text/JavaScript">
function disableBlankValues()
{
var elements = document.getElementById("form1").elements;
for (var i = 0; i < elements.length; i++)
{
if (elements[i].value == "")
elements[i].disabled = true;
}
}
</script>
<form action="page.php" method="POST" onsubmit="disableBlankValues()" id="form1">
<input type="hidden" name="field1" value="This is field 1."/>
<input type="hidden" name="field1" value=""/>
</form>
EDIT
I now realize the actual problem (multiple variables with the same name should be passed to JSP as an array) and my solution is probably not what the OP is looking for, but I'm leaving it here just in case it happens to help someone else who stumbles upon this post.
you could use something like:
var form = document.getElementById('yourformid');
var elements = form.getElementsByName('repeatedName');
var count = 0;
for(var item in elements){
elements[item].name += count++;
}
this way you will get each hiddenfield with the names:
name0
name1
name2
...
I've worked out a brute-force solution. Note that I'm pretty aware this is a hack. But I'm stuck in the position of having to work around other code that I have no control over.
Basically, I've created an ONSUBMIT handler which examines the form for the repeated hidden fields and makes sure they are all populated with the correct data. This seems to guarantee that the POST string contains data regardless of how the form gets rendered and the Java back end appears to be happy with it as well.
I've tested this in the following situations:
Code generates single instances of the hidden fields (which does happen sometimes)
Code generates multiple instances of the hidden fields
Code generates no instances of the hidden fields (which should never happen, but hey...)
My 'else' condition contains a tiny bit of MooTools magic, but it's otherwise straight-forward stuff.
Maybe someone else will find this useful one day...
Thanks for the help!
<form method="post" name="loginform" id="loginform" action="/login" onsubmit="buildDeviceFP(this);">
<script type="text/javascript">
function insertFieldValues( fields, sValue )
{
if ( 'length' in fields )
{
// We got a collection of form fields
for ( var x = 0; x < fields.length; x++ ) {
fields[x].value = sValue;
}
}
else
{
// We got a single form field
fields.value = sValue;
}
}
function buildDeviceFP( oForm )
{
// Get the element collections for Device Fingerprint & Language input fields from the form.
var devicePrintElmts = oForm.elements.deviceprint;
var languageElmts = oForm.elements.language;
// 'devicePrintElmts' & 'languageElmts' *should* always exist. But just in case they don't...
if ( devicePrintElmts) {
insertFieldValues( devicePrintElmts, getFingerprint() );
} else if ( oForm.deviceprint ) {
oForm.deviceprint.value = getFingerprint();
} else {
$('logonbox').adopt(
new Element( 'input', {'type':'hidden', 'name':'deviceprint', 'value':getFingerprint()} )
);
}
if ( languageElmts) {
insertFieldValues( languageElmts, getLanguage() );
} else if ( oForm.language ) {
oForm.language.value = getLanguage();
} else {
$('logonbox').adopt(
new Element( 'input', {'type':'hidden', 'name':'language', 'value':getLanguage()} )
);
}
}
</script>