Javascript medium-editor markdown append image and update content - javascript

<div class="editable" contenteditable="true"></div>
<textarea name="markdown" class="markdown" /></textarea>//display none
new MediumEditor('.editable', {
extensions: {
markdown: new MeMarkdown(function (md) {
document.querySelector(".markdown").textContent = md;
}),
img: new imgButton()
}
$('.editable').append("<img src='abc' />");
I have a div use medium-editor & medium-editor markdown
when user type inside of .editable, textarea will sync.
I also have a button click, it will append an image into .editable
my problem is markdown only update when .editable keypress
so if I append text, textarea wont sync, unless I press any key inside of .editable again
anyone know how to tell markdown to update after append image

try this
function updateTextArea(index,editable){
var textarea = editable.parentNode.querySelector('textarea[medium-editor-textarea-id="' + editable.getAttribute('medium-editor-textarea-id') + '"]');
if (textarea) {
textarea.value = editable.innerHTML.trim();
}
}
$('.editable').append("<img src='abc' />");
$('.editable').each(updateTextArea);
The updateTextArea function will update a text area corresponds to editable area.
Here is the code I tried
var editor = new MediumEditor('.editable', {
buttonLabels: 'fontawesome'
});
function updateTextArea(index,editable){
var textarea = editable.parentNode.querySelector('textarea[medium-editor-textarea-id="' + editable.getAttribute('medium-editor-textarea-id') + '"]');
if (textarea) {
textarea.value = editable.innerHTML.trim();
}
}
$("#addImage").click(function(){
$('.editable').append("<img src='abc' />");
$('.editable').each(updateTextArea);
});
$('.editable').change(updateTextArea);
<link href="http://yabwe.github.io/medium-editor/bower_components/medium-editor/dist/css/themes/tim.min.css" rel="stylesheet"/>
<link href="http://netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.css" rel="stylesheet"/>
<link href="http://yabwe.github.io/medium-editor/bower_components/medium-editor/dist/css/medium-editor.min.css" rel="stylesheet"/>
<script src="http://yabwe.github.io/medium-editor/bower_components/medium-editor/dist/js/medium-editor.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<h1>Medium Editor</h1>
<textarea class="editable medium-editor-textarea" name="markdown" id="markdown"><p>Textarea is now supported</p></textarea>
<input type="button" id="addImage" value="Add Image">
<input type="button" value="Alert textarea content" onclick="alert(document.getElementById('markdown').value)">
</div>

If you use the setContent() method of the editor (documentation here), this will allow you to add content and the editor will detect the change and fire all the proper events. This should include notifying the markdown extension that the content has changed and that should update the markdown.
So, instead of this:
$('.editable').append('<img src="abc" />');
Try this:
editor.setContent(editor.getContent() + '<img src="abc" />');
This also leverages the getContent() method (documentation here).
NOTE: These examples assume you're only using a single editor element for MediumEditor. If you are passing multiple elements into a single instance of MediumEditor, you may need to specify a value for the index parameter to both setContent() and getContent()

Related

How to change textarea value dynamically?

I got a problem in updating the value within <textarea> tags. The procedure is like this, there is an initial value inside textarea, then the user changes it. If I want to use a js script (implemented by a button) to modify the value further, it does not work at all. However, if we do nothing on the textarea, the button works perfectly. So weird to me. Could anyone shed any light on this? The code is posted below.
$(document).ready(function() {
$("#mybutton").click(function() {
var mystring = "The previous textarea value is <br><em>" + $("#myarea").val() + "</em>";
$("#myarea").html("Star wars"); // this line doesn't work after editting the textarea but works if you do not edit anything, why?
$("#placeholder").html(mystring);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<body>
<div>Input whatever you want</div>
<textarea id="myarea" style="width: 300px; height: 70px">Initial text</textarea>
<div>
<button id="mybutton">Click after editing</button>
<br> The button is supposed to change the text to <em>Star wars</em>.
</div>
<div id="placeholder"></div>
</body>
$(document).ready(function() {
$("#mybutton").click(function() {
var mystring = "The previous textarea value is <br><em>" + $("#myarea").val() + "</em>";
$("#myarea").val("Star wars"); //The changes have to be made on this line
$("#placeholder").html(mystring);
});
});
Inorder to change the value of textarea use val() , instead of html().

jquery javascript how to show some html in the closest div after a textarea

I have 3 textareas and 3 divs under each in which some html should be showed.
<textarea class="tinymce" rows="2" cols="20"></textarea><br />
<div class="character_count"></div>
<textarea class="tinymce" rows="2" cols="20"></textarea><br />
<div class="character_count"></div>
<textarea class="tinymce" rows="2" cols="20"></textarea><br />
<div class="character_count"></div>
When i am typing some text, in the div with class character_count below the textarea i am typing in, should the characters be displayed. I do not succeed in it:
This is my js:
tinymce.init({
selector: '.tinymce',
width: 400,
setup: function (ed) {
ed.on('keyup', function (e) {
var count = CountCharacters();
$(this).closest(".character_count").text("Characters: " + count); // find the closest div with class .character_count and show the html
});
}
});
function CountCharacters() {
var body = tinymce.activeEditor.getBody();
var content = tinymce.trim(body.innerText || body.textContent);
return content.length;
};
Fiddle to test: https://jsfiddle.net/4vron96z/3/
BTW: $(".character_count").text("Characters: " + count); does work but then the html is displayed in all the 3 divs...
tinymce.init({
selector: '.tinymce',
width: 400,
setup: function (ed) {
ed.on('keyup', function (e) {
var count = CountCharacters();
$(this.targetElm).closest('.wrapper')
.find('.character_count').text("Characters: " + count);
});
}
});
function CountCharacters() {
var body = tinymce.activeEditor.getBody();
var content = tinymce.trim(body.innerText || body.textContent);
return content.length;
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://tinymce.cachefly.net/4.2/tinymce.min.js"></script>
<span class="wrapper">
<textarea class="tinymce" rows="2" cols="20"></textarea><br />
<div class="character_count"></div>
</span>
<span class="wrapper">
<textarea class="tinymce" rows="2" cols="20"></textarea><br />
<div class="character_count"></div>
</span>
<span class="wrapper">
<textarea class="tinymce" rows="2" cols="20"></textarea><br />
<div class="character_count"></div>
</span>
Ok, so StackOverflow doesn't seem to like the tinymce library so I pulled it out of the runnable, but here is the version I got working in your jsfiddle.
Since the this inside your setup callback is some tinymce object, it will not work with jQuery. However, the this.targetElm appears to be the element that the tinymce was initialized for and is processing the event for.
So, using that, we could potentially use $(this.targetElm).next('div') to get your element, BUT, your next element is not the div. It is a <br /> you have in there. Which means you could do next().next('div') to get it, but that is ugly and fragile, SO!
The modified version of your html now has a wrapper around each textarea and div pairing. Changing the markup to be that, we can then use the closest('.wrapper').find('.character_count') logic to navigate up to the parent element of both the textarea and the div, and then find the nested div, no matter where it resides.
TinyMCE has a wordcount plugin that can tell you this without having to calculate the value. For example you could do something like:
tinymce.activeEditor.plugins.wordcount.body.getCharacterCount()
...or...
tinymce.activeEditor.plugins.wordcount.body.getCharacterCountWithoutSpaces()
Here is a running example:
http://fiddle.tinymce.com/Gmhaab

Dynamically add and initialise multiple text editors using textAngular

I'm currently trying to dynamically add a new textAngular when clicking on the "Add" button.
As the first textAngular element is already present in the HTML page, the initialisation works fine using wysiwyg function and I'm able to use the toolbar and see the result in the corresponding textarea.
When I click on the "Add" button, I would like to have another textAngular editor along with its corresponding textarea, which I manage to have and to initialise but as soon as I do this the previous textAngular editor doesn't work and isn't linked to its textarea anymore. The toolbar is also unclickable.
I get the following result :
Here's the code of the index.html page :
<body>
<div id="mainContainer">
<div ng-app="textAngularTest" ng-controller="wysiwygeditor" class="container app">
<div name="cours" id="textbox1">
<h3>TextBOX 1</h3>
<div text-angular="text-angular" name="htmlcontent" ng-model="htmlcontent" ta-disabled="disabled"></div>
<h3>HTML BRUT 1</h3>
<textarea ng-model="htmlcontent" style="width: 100%"></textarea>
<br>
<button id="btn1" onclick="displayEditor()">Add</button>
</div>
</div>
</div>
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js'></script>
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular-sanitize.min.js'></script
<script src='https://cdnjs.cloudflare.com/ajax/libs/textAngular/1.1.2/textAngular.min.js'></script
</body>
<!-- partial -->
<script src="./textbox.js"></script>
The style.css:
.ta-editor {
min-height: 300px;
height: auto;
overflow: auto;
font-family: inherit;
font-size: 100%;
}
And here is the code of textbox.js :
angular.module("textAngularTest", ['textAngular']);
function wysiwygeditor($scope) {
console.log($scope);
$scope.orightml = 'Hello';
$scope.htmlcontent = $scope.orightml;
$scope.disabled = false;
};
function displayEditor() {
var number = Math.random();
document.getElementById("mainContainer").innerHTML += '<div ng-app="textAngularTest' + number + '" ng-controller="myController' + number + '" class="container app" id="mainContainer' + number + '"><h3>TextBox2</h3><div text-angular="text-angular" id="htmlcontent" name="htmlcontent" ng-model="htmlcontent" ta-disabled="disabled"></div><h3>HTML BRUT 2</h3><textarea ng-model="htmlcontent" style="width: 100%"></textarea>';
angular.module('textAngularTest' + number, ['textAngular'])
.controller('myController' + number, function ($scope) {
$scope.orightml = 'Hey';
$scope.htmlcontent = $scope.orightml;
});
angular.bootstrap(document.getElementById('mainContainer' + number), ['textAngularTest' + number]);
}
Explanation of the code : When I click on the "Add" button, I build the HTML of the new textAngular editor and its textarea giving them unique attributes so they are independant with the previous ones. When I add this new HTML content on the DOM, I initialise the new angular module with its own controller. But as soon as I do this and as I said it above, the previous textAngular editors don't work anymore.
Does anyone know how to reach that goal and initialise multiple textAngular editors without breaking the previous ones ?

How can I hand over an <image id> for jquery?

When the user clicks on a picture on my site. Now the jQuery should get the id of the clicked image and change the image to another image:
Here's my jquery:
function changeCircle() {
// div "holen" var object =
// var object = document.getElementById("Kuchen");
// var id = obj;
// object.src="img/icon-check.png";
// $("#GarantienFrage1").attr('src', "img/icon-check.png");
$("id").attr('src', "img/icon-check.png");
// $(this.id).attr('src', "img/icon-check.png");
}
Here's my HTML:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id="Kuchen">
<img id="GarantienFrage2" class="maus_pointer" alt="AAA" src="img/icon-uncheck.png" style="height: auto; width: auto;" onclick="javascript:changeCircle();" />
</div>
How can I get the image to change when I click on it?
perhaps you need to know who is this
in your case is not being the <img> tag
therefore, I've put a target param to your function
function changeCircle(target) {
console.log('this is: ' + this);
console.log('BEFORE: ' + $(target).attr('src'));
$(target).attr('src', 'img/icon-check.png');
console.log('AFTER: ' + $(target).attr('src'));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id="Kuchen">
<img id="GarantienFrage2" class="maus_pointer" alt="AAA" src="img/icon-uncheck.png" style="height: auto; width: auto;" onclick="javascript:changeCircle(this);" />
</div>
Your selector is not targeting the image, its targeting the first <id> element on your DOM.
Change this:
$("id").attr('src', "img/icon-check.png");
to this:
$("img.maus_pointer").attr("src", "img/icon-check.png");
This selects that <img> element who's class is maus_pointer and changed the value of its src attribute.
Also, make sure that your new image source is relatively accessible from the page's location as you're not using an absolute path to target the new image.

Node Webkit How to save the value of a div as a .txt file

I've been through a lot of tutorials and I can never get this to work:
I want to save the content of a div (with contenteditable enabled) to a .txt file with node webkit. That part looks like this:
<div id="editor" class="textbox" contenteditable></div>
And I have the input field that allows me to select the file:
<input type="file" nwsaveas="untitled.txt" style="display:none;"/>
However I can't find any resources on how to save the value of the editor div as a .txt file on the user's computer.
I tried this tuts plus tutorial that briefly explains it however it didn't seem to work when I tried it on my own project: http://code.tutsplus.com/tutorials/introduction-to-html5-desktop-apps-with-node-webkit--net-36296
Does anyone know how I can achieve this?
You have to make file dialog open with emulating click event of an input, then get innerHTML of #editor, and finally use node's fs.writeFile to save content.
Here is full working example:
<!DOCTYPE html>
<html>
<head>
<script>
var initInputFile = function() {
document.getElementById('inputFile').addEventListener('change', function() {
var path = this.value; //get fullpath of chosen file
var content = document.getElementById('editor').innerHTML; //get editor's content
content = (' ' + content).slice(1); //hack to prevent strange bug of saving just half of the content
require('fs').writeFile(path, content, function(err) {
if (err) throw err;
console.log('done');
});
var wrapper = document.getElementById('inputFileWrapper');
wrapper.innerHTML = wrapper.innerHTML; //hack to make "change" event trigger...
initInputFile(); //...when choosing the same file
});
}
window.onload = function() {
initInputFile();
document.getElementById('saveBtn').addEventListener('click', function() {
var event = document.createEvent('MouseEvents');
event.initMouseEvent('click');
document.getElementById('inputFile').dispatchEvent(event);
});
}
</script>
</head>
<body>
<div id="editor" class="textbox" style="width:400px; height:100px;" contenteditable></div>
<div id="inputFileWrapper" style="display:none;">
<input type="file" id="inputFile" nwsaveas="untitled.txt"/>
</div>
<input type="button" id="saveBtn" value="Save" />
</body>
</html>
Hope this helps.

Categories