2

I am trying to do something specific and I am not sure it is possible. I have seen it answered how to do with a textarea but not as I am asking.

My code loads a text file and sets a bullet list based on the content. The bullet list is both able to be sorted (drag & drop) using JQuery-UI and edited with contenteditable="true". Here is the code that accomplishes this:

window.onload = function() {
var fileInput = document.getElementById('fileInput');
var fileDisplayArea = document.getElementById('fileDisplayArea');

$(function() {
$("#sortable1").sortable({
    items: "li:not(.ui-state-disabled)"
});
$("#sortable2").sortable({});
});

fileInput.addEventListener('change', function(e) {
var file = fileInput.files[0];
var textType = /text.*/;
if (file.type.match(textType)) {
var reader = new FileReader();
reader.onload = function(e) {
var file = reader.result;
var ul = document.createElement('ol');
test = file.replace(/(\})/gim, "\n</li>")
           .replace(/\{/gim, "")
           .replace(/!Variable=(\w+)\s*\n/gim, "<li class='ui-state-default'>$1</li>\n").split(/\s*\n\s*\n/)
           .map(v => v = '\n<li class="ui-state-default ui-state-disabled" style="color:blue; margin-left: 0; opacity:1;">' + v)
           .join('');
console.log(ul.innerHTML);
htmlcontent = "<ul contenteditable='true' id='sortable2'>" + test + "</ul>";
ul.innerHTML = htmlcontent;
fileDisplayArea.innerHTML = ul.innerHTML;
console.log(htmlcontent);

$("#sortable1").sortable({
     items: "li:not(.ui-state-disabled)"
});

$("#sortable2").sortable({
     cancel: ".ui-state-disabled"
});

$("#sortable1 li, #sortable2 li").disableSelection();

if (localStorage.userEdits != null)
document.getElementById("edit").innerHTML = localStorage.userEdits;
}

reader.readAsText(file);
} else {
fileDisplayArea.innerText = "File not supported!"
}
});
}
#sortable1,
#sortable2 {
  list-style-type: none;
  margin: 0;
  padding: 0;
  zoom: 1;
}

#sortable1 li,
#sortable2 li {
  margin: 0 5px 5px 20px;
  padding: 3px;
  width: 90%;
}

.ui-state-disabled li {
  color: green;
  margin: 0 5px 5px 0px;
}

.ui-state-default li {
  margin-left: 10%;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">

  <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

  <body>
    <input type="file" id="fileInput">
    <div id="fileDisplayArea"></div>
  </body>

</html>

The code loads a text file formatted like this:

FAVORITE SITES {
!Variable=eBay
!Variable=Google
}

AVOIDED SITES {
!Variable=Yahoo
!Variable=CraigsList
}

OTHER SITES {
!Variable=Alexa
!Variable=Amazon
!Variable=Jet
}

MORE SITES {
!Variable=StackOverflow
!Variable=Expedia
!Variable=MouseCity
}

And the bullet list is outputted as a result. Using the sort and the edit I can re-arrange the list and edit/add bullets (you can see if you test snippet and save the text example to be loaded). The question is, after I make sorts and edits is there a way to save the changes back to the text file? I know there are limitations but it could even be saved as a new file or with a prompt so I can choose the save location and overwrite the old file. But is this possible and any idea on how to save the HTML edits?

I suppose there are two functions needed. One would be to output the changes in the format consistent with the data file loaded and the other would be to save them. If this doesn't make sense please comment and I can clarify. It should be noted this is done in a completely local environment.

Paolo Forgia
  • 6,572
  • 8
  • 46
  • 58

1 Answers1

0

This code works to save the changed HTML as a text file.

function savehtml() {
    var htm = document.body.appendChild(
        document.createElement("htm")
    );
    htm.download = "demo.txt";
    htm.href = "data:text/plain," + document.getElementById("fileDisplayArea").innerHTML;
    htm.click();
}

With this function call:

<button onClick="savehtml()">Save HTML as Text</button>