How do I make a textarea an ACE editor? - javascript

I'd like to be able to convert specific textareas on a page to be ACE editors.
Does anyone have any pointers please?
EDIT:
I have the the editor.html file working with one textarea, but as soon as I add a second, the second isn't converted to an editor.
EDIT 2:
I decided to scrap the idea of having several, and instead open one up in a new window. My new predicament is that when I hide() and show() the textarea, the display goes awry. Any ideas?

As far as I understood the idea of Ace, you shouldn't make a textarea an Ace editor itself. You should create an additional div and update textarea using .getSession() function instead.
html
<textarea name="description"/>
<div id="description"/>
js
var editor = ace.edit("description");
var textarea = $('textarea[name="description"]').hide();
editor.getSession().setValue(textarea.val());
editor.getSession().on('change', function(){
textarea.val(editor.getSession().getValue());
});
or just call
textarea.val(editor.getSession().getValue());
only when you submit the form with the given textarea. I'm not sure whether this is the right way to use Ace, but it's the way it is used on GitHub.

Duncansmart has a pretty awesome solution on his github page, progressive-ace which demonstrates one simple way to hook up an ACE editor to your page.
Basically we get all <textarea> elements with the data-editor attribute and convert each to an ACE editor. The example also sets some properties which you should customize to your liking, and demonstrates how you can use data attributes to set properties per element like showing and hiding the gutter with data-gutter.
// Hook up ACE editor to all textareas with data-editor attribute
$(function() {
$('textarea[data-editor]').each(function() {
var textarea = $(this);
var mode = textarea.data('editor');
var editDiv = $('<div>', {
position: 'absolute',
width: textarea.width(),
height: textarea.height(),
'class': textarea.attr('class')
}).insertBefore(textarea);
textarea.css('display', 'none');
var editor = ace.edit(editDiv[0]);
editor.renderer.setShowGutter(textarea.data('gutter'));
editor.getSession().setValue(textarea.val());
editor.getSession().setMode("ace/mode/" + mode);
editor.setTheme("ace/theme/idle_fingers");
// copy back to textarea on form submit...
textarea.closest('form').submit(function() {
textarea.val(editor.getSession().getValue());
})
});
});
textarea {
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.9/ace.js"></script>
<textarea name="my-xml-editor" data-editor="xml" data-gutter="1" rows="15"></textarea>
<br>
<textarea name="my-markdown-editor" data-editor="markdown" data-gutter="0" rows="15"></textarea>

You can have multiple Ace Editors. Just give each textarea an ID and create an Ace Editor for both IDS like so:
<style>
#editor, #editor2 {
position: absolute;
width: 600px;
height: 400px;
}
</style>
<div style="position:relative; height: 450px; " >
<div id="editor">some text</div>
</div>
<div style="position:relative; height: 450px; " >
<div id="editor2">some text</div>
</div>
<script src="ace.js" type="text/javascript" charset="utf-8"></script>
<script src="theme-twilight.js" type="text/javascript" charset="utf-8"></script>
<script src="mode-xml.js" type="text/javascript" charset="utf-8"></script>
<script>
window.onload = function() {
var editor = ace.edit("editor");
editor.setTheme("ace/theme/twilight");
var XmlMode = require("ace/mode/xml").Mode;
editor.getSession().setMode(new XmlMode());
var editor2 = ace.edit("editor2");
editor2.setTheme("ace/theme/twilight");
editor2.getSession().setMode(new XmlMode());
};
</script>

To create an editor just do:
HTML:
<textarea id="code1"></textarea>
<textarea id="code2"></textarea>
JS:
var editor1 = ace.edit('code1');
var editor2 = ace.edit('code2');
editor1.getSession().setValue("this text will be in the first editor");
editor2.getSession().setValue("and this in the second");
CSS:
#code1, code2 {
position: absolute;
width: 400px;
height: 50px;
}
They must be explicitly positioned and sized. By show() and hide() I believe you are referring to the jQuery functions. I'm not sure exactly how they do it, but it cannot modify the space it takes up in the DOM. I hide and show using:
$('#code1').css('visibility', 'visible');
$('#code2').css('visibility', 'hidden');
If you use the css property 'display' it will not work.
Check out the wiki here for how to add themes, modes, etc... https://github.com/ajaxorg/ace/wiki/Embedding---API
Note: they do not have to be textareas, they can be whatever element you want.

For anyone that just wants a minimal, working example of using Ace from the CDN:
<!DOCTYPE html>
<html lang="en">
<body style="margin:0">
<div id="editor">function () {
console.log('this is a demo, try typing!')
}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.01/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
var editor = ace.edit("editor");
editor.setTheme("ace/theme/monokai");
editor.getSession().setMode("ace/mode/javascript");
document.getElementById("editor").style.height = "120px";
</script>
</body>
</html>

Related

Drop event from outside window only fires the second time

I am drag-and-dropping some text from a proprietary application into an HTML <textarea> element. This software cannot copy-paste; drag-and-drop is the only option. However, the drag and drop can be simulated by simply typing a few lines in Word, then dragging them into the browser.
I have a jsfiddle with my code. However, when I drag some lines from the program into the text box the first time, I get "undefined" returned. When I try it again without reloading the page (when the text area already has contents), it works great.
How can I get it to work the first time?
You need to put the line
$('#return').html(dropstr);
inside of the getAsString callback.
var dropstr;
$( document ).ready(function() {
$('#dropbox').on('drop', function(e) {
e.originalEvent.dataTransfer.items[0].getAsString(function(str){
dropstr=str;
console.log(dropstr);
$('#return').html(dropstr);
});
});
});
#return{
border:1px solid black;
width: 200px;
height: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="dropbox" contenteditable="true" id="dropbox">
<textarea></textarea>
</div>
<div id="return">
</div>
You were appending outside of callback which itself is not needed at least in your case. fiddle
<div id="dropbox" contenteditable="true" id="dropbox">
<textarea></textarea>
</div>
<div id="return">
</div>
and here is js.
var dropstr;
$(document).ready(function() {
$('#dropbox').on('drop', function(e) {
var str = e.originalEvent.dataTransfer.getData('Text');
console.log(str);
$('#return').html(str);
});
});

jQuery append method inserting text rather than HTML

I want append an input text in my html page. I use JQuery to do that.
My JQuery script :
$(document).ready(function(){
$(".reply").click(function(){
var tempat=$(this).parent().parent().next(".komentar-balasan");
console.log(tempat[0]);
var html=
tempat[0].append('<input type="text"></input>');
});
});
And the HTML :
<div class="isi">
<div class="like-comment">
<div class="kotak"></div>
<div class="kotak-jumlah">
</div>
<div class="kotak"><button class="reply"></button></div>
</div><div class="komentar-balasan"></div>
The Fiddle
I Don't know why, but instead of displayed the input text box. The browser just display <input type="text"></input>. It's like the browser didn't recognize the HTML code.
It's because tempat[0] is accessing the underlying DOM node rather than the jQuery wrapper. It works fine if you omit the array access and just call append on tempat.
You don't need it here but the right way to get a jQuery wrapped element of a jQuery selector list is to use eq
The problem is that you aren't calling the append element on a jQuery object (which treats strings as HTML), but instead on a native DOM element. The experimental ParentNode#append method treats strings as text, so you are seeing text.
If you omit the [0] before calling append, your code runs perfectly:
$(document).ready(function() {
$("#post-komentar").click(function() {
console.log($(this).siblings('.editor-komentar').val());
});
$(".reply").click(function() {
var tempat = $(this).parent().parent().next(".komentar-balasan");
console.log(tempat[0]);
var html =
tempat.append('<input type="text"></input>');
});
});
.reply {
background-color: #fff;
width: 20px;
height: 20px;
margin: 0;
padding: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="isi">
<div class="like-comment">
<div class="kotak"><</div>
<div class="kotak-jumlah">
</div>
<div class="kotak"><button class="reply"></button></div>
</div>
<div class="komentar-balasan"></div>
Hello,
Check if this is what you need:
You need to create an element and only then add it.
Here is an example:
$(document).ready(function(){
$(".reply").click(function(){
var tempat=$(this).parent().parent().next(".komentar-balasan");
console.log(tempat[0]);
var newEl = document.createElement('input');
newEl.type = "text";
tempat.append(newEl);
});
});
I hope I have helped!
Remove the [0]. You are dereferencing your jQuery object by doing that.
This works: tempat.append('<input type="text"></input>');

javascript - one image,two actions

I am looking for javascript command that would do the following:
Click on image -> open spoiler
Click on image again -> hide spoiler
Here is what I got so far:
javascript in my html
<script>
function myFunction() {
document.getElementById("prvy").innerHTML = document.getElementById('spoiler_id').style.display='';}
</script>
Spoiler
<a id="show_id"
onclick="document.getElementById('spoiler_id').style.display=''; document.getElementById('show_id').style.display='none';"
class="link"></a><span id="spoiler_id"
style="display: none">[Show]<button onclick="document.getElementById('spoiler_id').style.display='none';
document.getElementById('show_id').style.display='';"
class="link">[Hide]</button>
<br><h1 id="bz">Heading</h1><br><br><p>text</p></span>
And my button:
<div id="prvy" onclick="myFunction()"></div>
What I managed to do, is to click on a image, wich will open spoiler. Hovewer, I've been unable to do the second part, onclick again it will close the spoiler.
I also did serach for solution alredy, nothing worked for me, not even this: Link
I also tired if{} else{} statement but didn't work for me either.
Help would be really appreciated, as I am getting desperate on this one.
You can use jQuery .toggle() to toggle show/hide
$("#prvy").click(function() {
$("#spoiler_id").toggle();
});
Note : You need to include jQuery in your document as
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Working snippet :
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="show_id"
onclick="document.getElementById('spoiler_id').style.display=''; document.getElementById('show_id').style.display='none';"
class="link"></a><span id="spoiler_id"
style="display: none">[Show]<button onclick="document.getElementById('spoiler_id').style.display='none';
document.getElementById('show_id').style.display='';"
class="link">[Hide]</button>
<br><h1 id="bz">Heading</h1><br><br><p>text</p></span>
<div id="prvy" onclick="myFunction()">button</div>
<script>
$("#prvy").click(function() {
$("#spoiler_id").toggle();
});
</script>
In the JavaScript where you click the button use the simple jQuery function toggle.
$('#spoiler_id').toggle();
Toggle will hide the element selected if it is currently shown or display the element if it is currently hidden.
you would need some state that flips when the function is called.
like this.
<script>
var state = false;
function myFunction() {
state = !state;
if(state){
//do something
}else{
//do something else
}
}
</script>
Is that all of your code, it would be easier for you and less confusing too if you just gave the buttons an on click function and then called that function in your js.
Can I see all of your html
I am giving an example to concerned question using javascript.
HTML:
<script type="text/javascript">
var permit = 'true';
function showhide() {
var getcont = document.getElementsByClassName('hidshowcont');
if (permit === 'true') {
permit = 'false';
getcont[0].style.display = 'block';
}
else {
permit = 'true';
getcont[0].style.display = 'none';
}
}
</script>
<style type="text/css">
.hidshowcont{
height: 200px;
width: 300px;
border: 1px solid #333333;
display: none;
}
</style>
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR1cSDTn18ufwjuMihttTvCPJOnFY-4hxbPcaOVd87nSPaQakbP9IERaQ" />
<br />
<br />
<div class="hidshowcont">
This is an example of hide and show the container by clicking of an image.
</div>
This will help u much

Copying stored text in a table and then display it back into a textarea

I need your help,
How can I go about copying text (with the line breaks included) from my table and put it back into the textarea “newtext”
My existing coding doesn't seem to be working.
<html>
<head>
<style type="text/css">
.box { width: 400px; height: 50px; }
</style>
<script type="text/javascript">
function ta() {
taValue = document.getElementById("ta").value
taValue = taValue.replace(/\n/g, '<br/>')
document.getElementById("tatext").innerHTML = taValue
}
function text2area() {
document.getElementById("newtext").innerHTML = document.getElementById("tatext").innerHTML
}
</script>
</head>
<textarea class="box" id="ta" onkeyup="ta()"></textarea>
<table id="tatable"><tr><td><div id="tatext"></div></td></tr></table>
<br>
<input type="button" onclick="text2area()" value="move text">
<br><br>
<textarea class="box" id="newtext"></textarea>
</html>
Instead of using the function innerHTML, grab the value of the text area you want to capture, and set the value of the new text area to this. You are already using value for the variable taValue. Also, it's better practice to use addEventListener for your clicks and keyups.
function ta() {
taValue = document.getElementById("ta").value
taValue = taValue.replace(/\n/g, '<br/>')
document.getElementById("tatext").value = taValue;
}
function text2area() {
taValue = document.getElementById("ta").value;
document.getElementById("newtext").value = taValue;
}
document.getElementById("ta").addEventListener ("onkeyup", ta, false);
document.getElementById("move-text").addEventListener ("click", text2area, false);
JSFiddle: http://jsfiddle.net/tMJ84/1/
textarea does not have an innerHTML. Notice how you grabbed the value? Set it the same way! It is like this because it is a form element.
document.getElementById("tatext").value = taValue; //semi-colons are just good practice
and here:
document.getElementById("newtext").value = document.getElementById("tatext").value;

Javascript creating <div> on the fly

I have a a link that looks similar to this
Blog
As you can the link has an ID of 'blog' what I want to do is to create an div on the fly with the ID from the link that was clicked so if the 'blog' is clicked, then the markup would be
<div id="blog">
<!--some content here-->
</div>
Like wise if for instance the news link is clicked then I would like,
<div id="news">
<!--some content here-->
</div>
to be created in the markup if this possible? and how Im pretty new to jQuery.
Try this:
$("a").click(function(){
$("#wrapper").append("<div id=" + this.id + "></div>");
});
Not tested, should work ;)
where: #wrapper is parent element, work on all a as you see.
You will need to give the div a different ID. Perhaps you could give it a class instead:
$("#blog").click(function() {
$(this).after("<div class='blog'>...</div>");
return false;
});
That's just one of many ways to create a div. You probably also want to avoid duplicates however in which case, use something like this:
$("#blog").click(function() {
var content = $("#blog_content");
if (content.length == 0) {
content = $("<div></div>").attr("id", "blog_content");
$(this).after(content);
}
content.html("...");
return false;
});
As for how to handle multiple such links I would do something like this:
Blog
News
Weather
<div id="content"></div>
with:
$("a.content").click(function() {
$("#content").load('/content/' + this.id, function() {
$(this).fadeIn();
});
return false;
});
The point is this one event handler handles all the links. It's done cleanly with classes for the selector and IDs to identify them and it avoids too much DOOM manipulation. If you want each of these things in a separate <div> I would statically create each of them rather than creating them dynamically. Hide them if you don't need to see them.
Try This :
<a id="blog">Blog</a>
<a id="news">news</a>
<a id="test1">test1</a>
<a id="test2">test2</a>
$('a').click(function()
{
$('<div/>',{
id : this.id,
text : "you have clicked on : " + this.id
}).appendTo("#" + this.id);
});
First of all you should not make 2 elements with same ID. At your example a and div will both have id="blog". Not XHTML compliant, plus might mess up you JS code if u refernce them.
Here comes non-jquery solution (add this within script tags):
function addDiv (linkElement) {
var div = document.createElement('div');
div.id = linkElement.id;
div.innerHTML = '<!--some content here-->';
document.body.appendChild(div); // adds element to body
}
Then add to HTML element an "event handler":
Blog
This question describes how to create a div. However, you shouldn't have two elements with same IDs. Is there any reason why you can't give it an id like content_blog, or content_news?
Unfortunately if you click on a link the page you go to has no idea what the idea of the link you clicked was. The only information it knows is what's contained in the URL. A better way to do this would be to use the querystring:
Blog
Then using the jQuery querystring plugin you could create the div like:
$("wrapper").add("div").attr("id", $.query.get("id"));
You shouldn't have elements in your page with the same ID. Use a prefix if you like, or perhaps a class.
However, the answer is as follows. I am imagining that your clickable links are within a div with the ID "menu", and your on-the-fly divs are to be created within a div with the ID "content".
$('div#menu a').click(function(){
$('div#content').append('<div id="content_'+this.id+'"><!-- some content here --></div>');
});
Any problems, ask in the comments!
Also the following statement is available to create a div dynamically.
$("<div>Hello</div>").appendTo('.appendTo');
Working fiddle: https://jsfiddle.net/andreitodorut/xbym0bsu/
you can try this code
$('body').on('click', '#btn', function() {
$($('<div>').text('NewDive').appendTo("#old")).fadeOut(0).fadeIn(1000);
})
#old > div{
width: 100px;
background: gray;
color: white;
height: 20px;
font: 12px;
padding-left: 4px;
line-height: 20px;
margin: 3px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
<link rel="stylesheet" href="./index.css">
</head>
<body>
<div>
<!-- Button trigger modal -->
<button type="button" id="btn">Create Div</button>
<div id="old">
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</body>
</html>

Categories