1

I have this for loop which everytime creates a new div that's contenteditable:

for($i=0; $i<$something; $i++){
   echo '<div id='.$value[$i].' contenteditable></div>';
}

Now I want to get each div their own value out of it and use that. This shouldn't be that hard but I've never worked with this attribute and there is not a lot of information about this attribute. Also I'd like the value to show up whenever something is changed. So basically an onchanged event. These values will be used in a query. The thing is I cant seem to figure out how to work with this(also I dont have a lot of experience in javascript).

How would I get the value of these divs everytime they change and show them with their div id's?

Loko
  • 6,539
  • 14
  • 50
  • 78
  • do you have any js so far? – atmd Jul 23 '15 at 07:37
  • @atmd No. I cant seem to figure out how to proceed. There is enough information about getting the value in javascript like this question: http://stackoverflow.com/questions/11238508/how-to-get-value-of-a-div-using-javascript , but I dont understand how I would use my id's in that answer. Also if anything changes with the conteditable? – Loko Jul 23 '15 at 07:42
  • i'd suggest initially giving the elements a common class, so you can listen for changes based on the class rather then try to get the `id`'s. You can always get the `id` in the event listener if you need it. [this answer might help](http://stackoverflow.com/questions/1391278/contenteditable-change-events) – atmd Jul 23 '15 at 07:44
  • @atmd This still means the class= php values depending on the state of the loop. How would I use this in javascript? – Loko Jul 23 '15 at 07:46
  • the class would be hard coded, for example `echo '
    ';` then you'd add your listener to the `.editable-area` class rather then each `id` see @verjas's answer
    – atmd Jul 23 '15 at 08:16

2 Answers2

1

First, you could to put a "class" to all your divs to get fast access to them:

for ($i=0; $i<$something; $i++){
   echo '<div id='.$value[$i].' class="editable" contenteditable></div>';
}

The you can use jQuery to get the "input" event on a div and retrieve the value and the id - example: http://jsfiddle.net/se2nj78L/

$(".editable").on("input",function(){
        var id=$(this).attr("id");
        var html="<p>Content changed in div with id="+id+"</p>";
        html+=$(this).html();
       $("#feedback").html(html);
});

To use only JS, it would be something like:

var editable_divs= document.getElementsByClassName("editable");

for (var i=0; i<editable_divs.length; i++) {
    editable_divs[i].addEventListener("input",
        function () { /* some function */}
        ,false);
}

For simple JS: http://jsfiddle.net/87vv4vg1/1/

EDIT:

To get all div contents that were changed, you can change the function to something like here: http://jsfiddle.net/7me8okgd/

Basically you put all the changes in a big object, where for each id you have the changed content of the div - example:

var div_changes = {};
/* var div_changes = {
     1: "Content from div with id='1'",
     2: "Content from did with id='2'",
     ...
 } 
 */

for (var i=0; i<editable_divs.length; i++) {
    editable_divs[i].addEventListener("input",
        function () { 
            div_changes[this.id]=this.innerHTML;
        }
        ,false);
}

You can use this object for multiple purposes afterwards (like send it through AJAX).

verjas
  • 1,793
  • 1
  • 15
  • 18
  • This is almost it, but in your jsfiddle it only shows the result of the last editted one though. – Loko Jul 23 '15 at 08:21
  • Well, I wasn't sure what was the final result you wanted. You can update the function anyway you want. Do you want to store all the div contents in a variable to send by AJAX? – verjas Jul 23 '15 at 09:07
  • Just show all the variables updated whenever it's changed on screen. So like it is now but show all instead of the last changed. – Loko Jul 23 '15 at 09:13
1

This would be an option. Just add a keyup listener to all editable elements and then collect the innerHTML of each element. To get the current editable elements id just use this in the keyup handler.

Sure you will get the idea.

var editableElems = document.querySelectorAll('.edit'),
    output = document.getElementById('output'),
    crntId = document.getElementById('current-id');

function collectData() {
  var editableElemsArray = Array.prototype.slice.call(editableElems);
  output.innerHTML = "";
  editableElemsArray.forEach(function(value, index, array) {
    output.innerHTML += value.innerHTML;
  });
}

function editKeyUpHndl() {
  crntId.innerHTML = this.getAttribute('id');
  collectData();
}

for(var i = 0;  i < editableElems.length; i++) {
  editableElems[i].addEventListener('keyup', editKeyUpHndl, false);
}
html {
  box-sizing: border-box;
  font-family: sans-serif;
}
*, *:before, *:after {
  box-sizing: inherit;
}

.edit {
  width: 100%;
  background-color: #f1f1f1;
  border: 1px solid #ccc;
  border-radius: 3px;
  box-shadow: inset 1px 1px 1px #fff, inset 0 -1px 2px #111;
  color: #888;
  min-height: 100px;
  padding: 2px 6px;
  margin-bottom: 6px;
  font-family: sans-serif;
  font-size: 85%;
  overflow: auto;
}

.container {
  position: relative;
}

#output {
  width: 100%;
  border: 1px solid #ccc;
  min-height: 100px;
  border-radius: 3px;
  padding: 4px;    
}

#current-id {
  position: absolute;
  top: 2px;
  right: 2px;
  background: #ddd;
  height: 34px;
  min-width: 120px;
  width: auto;
  border: 1px solid #ccc;
  border-radius: 3px;
  opacity: 0.6;
  text-align: center;
  padding: 6px;
  font-size: 80%;
  color: red;
}
<div class="edit" id="edit-box-01" contenteditable>
  <p>Edit One</p>
</div>

<div class="edit" id="edit-box-02" contenteditable>
  <p>Edit Two</p>
</div>

<div class="edit" id="edit-box-03" contenteditable>
  <p>Edit Three</p>
</div>

<div class="container">
  <div id="current-id"> </div>
  <div id="output"></div>    
</div>
DavidDomain
  • 14,976
  • 4
  • 42
  • 50