How to save and retrieve contenteditable data
Use a client-side language, such as JavaScript (or best, jQuery), to manage whether the input boxes could be edited.
Use AJAX to grab the field data and fire it off to a PHP file, which would stick the data in your database.
Here is a very simplified example of using jQuery to manage enabling/disabling the input fields:
jsFiddle Demo
$('.editable').prop('disabled',true);
$('.editbutt').click(function(){
var num = $(this).attr('id').split('-')[1];
$('#edit-'+num).prop('disabled',false).focus();
});
$('.editable').blur(function(){
var myTxt = $(this).val();
$.ajax({
type: 'post',
url: 'some_php_file.php',
data: 'varname=' +myTxt+ '&anothervar=' +moreTxt
});
});
PHP file: some_php_file.php
<?php
$myVar = $_POST['varname'];
$secondVar = $_POST['anothervar'];
//Now, do what you want with the data in the vars
Using AJAX is quite easy. I gave a very brief example of what it would look like. Don't look in the HTML or jQuery for the moreTxt
variable -- I added that to show how you would add a second var of data to the ajax.
Here are some basic examples to bring you up to speed on ajax:
AJAX request callback using jQuery
There is no short path to learning jQuery or AJAX. Read the examples and experiment.
You can find some excellent, free jQuery tutorials here:
http://thenewboston.com
http://phpacademy.org
UPDATE EDIT:
To respond to your comment inquiry:
To send data from a DIV to a PHP file, first you need an event that triggers the code. As you mentioned, on an input field, this can be the blur()
event, which triggers when you leave a field. On a <select>
, it can be the change()
event, which triggers when you choose a selection. But on a DIV... well, the user cannot interact with a div, right? The trigger must be something that the user does, such as clicking a button.
So, the user clicks a button -- you can get the content of the DIV using the .html()
command. (On input boxes and select controls, you would use .val()
, but on DIVs and table cells you must use .html()
. Code would look like this:
How to send DIV content after a button clicked:
HTML:
<div class='big_wrapper' contenteditable>
PAGE CONTENT
</div>
<input id="mybutt" type="button" value="Send Data" />
jQuery:
$('#mybutt').click(function(){
var myTxt = $('.big_wrapper').html();
$.ajax({
type: 'post',
url: 'some_php_file.php',
data: 'varname=' +myTxt+ '&anothervar=' +moreTxt
});
});
Getting values from HTML Content Editable, passing those values to Javascript and use AJAX to send to PHP file
A simple example of how to do this might be to assign a blur
event listener bound to all elements that have the contenteditable
attribute set and use fetch api to send the AJAX request using a FormData object to your backend PHP script.
const getparent=(e)=>{
let n=e.target;
while(n.tagName.toLowerCase()!='span' && n.className!='record'){
if(n.tagName=='BODY')return false;
n=n.parentNode;
}
return n;
}
document.querySelectorAll('[contenteditable="true"]').forEach(el=>{
el.addEventListener('blur',function(e){
let span=getparent(e);
if( !span )return;
let fd=new FormData();
fd.set('userid', span.querySelector('[name="userId"]').value );
fd.set('text', this.textContent );
fd.set('id', this.id );
fetch( 'https://www.example.com', { method:'post', body:fd, mode:'cors' })
.then( r=>r.text() )
.then( text=>{
console.log( 'Do something with returned response: %s',text )
})
})
})
.record{
display:block;
margin:1rem;
border:1px solid red;
padding:1rem;
}
<span class='record'>
<label id="label-1" contenteditable="true">Hello World</label>
<table>
<input type="hidden" name="userId" value="123456789">
<tr>
<td id="row-1" name="firstRow" contenteditable="true">This is first row</td>
</tr>
</table>
<div class="footer" contenteditable="true">A message from the Bottom</div>
</span>
<span class='record'>
<label id="label-2" contenteditable="true">World Hello</label>
<table>
<input type="hidden" name="userId" value="987654321">
<tr>
<td id="row-2" name="secondRow" contenteditable="true">This is second row</td>
</tr>
</table>
<div class="footer" contenteditable="true">A bottom from the Message</div>
</span>
Save changes made by content editable on any website
Here's a way you can do this using vanilla JS.
Here's JSFiddle since StackOverflow doesn't allow localStorage
to be executed on the website as a security feature.
How it works:
- Using
window.onload = function() {...}
, check if'content'
key
exists inlocalStorage
- If it does, load the data into
<div class="content">
- Upon pressing
Edit
button,contentEditable
is toggled - Here you can use any method to save the data. I used
content.contentEditable === 'false'
to save theinnerHTML
data to'content'
key.
To Note: localStorage
is saved in your browser locally, use databases or anything similar to display edits to all viewers.
// Load content onload if it exists in localStoragewindow.onload = function() { if(localStorage.getItem('content')) { document.querySelector('.content').innerHTML = localStorage.getItem('content'); }}
let editBtn = document.querySelector('#edit_content');let content = document.querySelector('.content');
editBtn.addEventListener('click', () => { // Toggle contentEditable on button click content.contentEditable = !content.isContentEditable; // If disabled, save text if(content.contentEditable === 'false') { localStorage.setItem('content', content.innerHTML); }});
.content { border: 1px solid; padding: 15px;}
<div class="content">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div><br><button id="edit_content">Edit</button>
Save content of a div contenteditable=true to my db through a form in Rails
You are setting the value the wrong way. You want to set the "post_content" value to the "content" innerHTML.
document.getElemenetById('post_content') = document.getElementById('content').innerHTML;
Also, you should use a hidden
input instead of a textarea
with display:none
.
And lastly, make sure the function is being triggered. I don't think the "onsubmit" callback is properly fireing since form_with intercepts the form submission and does an ajax request.
Personally I'd listen to the input
event on the contenteditable element so you don't depend on the form submission:
document.getElementById('content').addEventListener('input', function(ev){
document.getElementById('post_content').value = ev.target.innerHTML;
})
Now everytime you change the contenteditable content you get the input updated instantly.
how to save html contenteditable content as text file
I cleaned up and fixed what you had, here: http://pastebin.com/sJXVvRUB
I think it does what you want. You still have to restyle the link to look like a button, if you want. I've also only tested in Chrome, so it may need other small modifications.
As for your problems and how I fixed them:
- I'm not sure I completely understand the "spaces" part of the problem, unless you meant that all consecutive whitespace gets (incorrectly) saved as a single space. That's how HTML renders it, actually. I fixed that by replacing your
note = note.replace(" ", "");
withnote = note.replace(' ', ' ');
. You were replacing non-breaking spaces with nothing. For line breaks, I just escaped the note before saving:escape(note)
. I also tweaked the calls toreplace()
to be a bit simpler and more targeted (at least on Chrome). - For controlling the filename, I replaced the form+button with a link so I could use the "download" attribute, documented here: https://developer.mozilla.org/en-US/docs/HTML/Element/a#attr-download (also mostly only supported by Chrome at the moment).
Hope this helps!
contenteditable - JQuery save content just to webpage (as well as adding and removing)
Rather than making td
editable you could wrap div
inside td
and make it editable and assign fixed width
and height
to div.
.clEdit {
width: 200px;
/*Try chaging it as per need*/
overflow: hidden;
/* try scroll with more height */
height: 15px;
/*Try chaging it as per need*/
}
Now there are 2 options either allow overflow to be hidden or scroll. You could examine the behavior and select either one. As a user friendly experience you could assign tooltip to div on hover or click so that whenever values inside div are being overflown user could see what are the current values inside.
$(".clEdit").hover(function(e) {
$(this).prop("title", $(this).html());
});
Yes you could add/delete rows from table without DB if you know the values. id
can be calculated from previous id value.
Adding/removing from table does not guarantee DB will be updated you need handle that.
On adding rows you need to bind event for contenteditable as well.
$("#add").click(function() {
//LOGIC TO ADD ROW TO TABLE
var trRow = "<tr><td>" + ++idFirstCol + "</td><td>" + "SecondColValue" + "</td><td><div class='clEdit'>" + "ThirdColValue" + "</div></td> <td> " + "LastColValue" + " </td></tr>";
$("#ConTable").append(trRow);
$(".clEdit").hover(function(e) {
$(this).prop("title", $(this).html());
});
$(".clEdit").prop('contenteditable', true);
});
You could refer to JSFiddle here. http://jsfiddle.net/8mt6d7bz/
Lmk if that answers your question
contenteditable selected text save and restore
A typical use would be displaying some kind of widget or dialog to accept input from the user (thus potentially destroying the original selection) and restoring the selection after that widget has been hidden. Actually using the functions is quite simple; the biggest danger is trying to save the selection after it has already been destroyed.
Here's a simple example. It displays a text input and overwrites the selection in the editable <div>
with the text from that input. Note that this code has support for Internet Explorer <= 8 in the document.selection
branches which could be removed now, in 2022:
function saveSelection() {
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
return sel.getRangeAt(0);
}
} else if (document.selection && document.selection.createRange) {
return document.selection.createRange();
}
return null;
}
function restoreSelection(range) {
if (range) {
if (window.getSelection) {
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (document.selection && range.select) {
range.select();
}
}
}
function insertTextAtCursor(text) {
var sel, range, html;
if (window.getSelection) {
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
var textNode = document.createTextNode(text)
range.insertNode(textNode);
sel.removeAllRanges();
range = range.cloneRange();
range.selectNode(textNode);
range.collapse(false);
sel.addRange(range);
}
} else if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
range.pasteHTML(text);
range.select();
}
}
var selRange;
function displayTextInserter() {
selRange = saveSelection();
document.getElementById("textInserter").style.display = "block";
document.getElementById("textToInsert").focus();
}
function insertText() {
var text = document.getElementById("textToInsert").value;
document.getElementById("textInserter").style.display = "none";
restoreSelection(selRange);
document.getElementById("test").focus();
insertTextAtCursor(text);
}
#textInserter {
display: none;
}
<div id="test" contenteditable="true">Some editable text</div>
<input type="button" unselectable="on" onclick="displayTextInserter();" value="Insert text">
<div id="textInserter">
<input type="text" id="textToInsert">
<input type="button" onclick="insertText()" value="Insert">
</div>
Saving contenteditable data using jquery
Change the "textarea" element to "div" and add contenteditable="true". Then change text.value to text.innerHTML. Is that what you mean? It seems to work for me at this link.
<div id="editor" contentEditable="true" placeholder="Start writing..."></div>
...
[text.innerHTML || text.placeholder], {
...
session.text = text.innerHTML;
Related Topics
How to Display Woocommerce Category Image
How to Get a User's Instagram Feed
Easy Login Script Without Database
Does PHP Run Faster Without Warnings
How to Create a Logfile in PHP
Preserve and Display Text Exactly How It Is Typed and Submitted
Check If a PHP Cookie Exists and If Not Set Its Value
Magento Addfieldtofilter: Two Fields, Match as Or, Not And
What Is the Best Method to Prevent a Brute Force Attack
Securing a Rest API Accessible from Android
Automatically Trimming an Mp3 in PHP
Creating a Secure Login Using Sessions and Cookies in PHP
Use Curl with Sni (Server Name Indication)
Is This the Correct Way to Send Email with PHP