jQuery++, problems on .selection() - javascript

everybody.
I have a little problem; I'm trying to build a WYSIWYG, but I encountered some problems.
I have a contenteditable div with id = desc2, and some buttons. Let's take, for example, the button "bold".
<div class="magic" magic_id="desc2">
<div class="magicbutton one" magic="[b]%s[/b]">
<span style="font-weight:bold;">Bold</span>
</div>
</div>
And I have some jQuery++ selection application in:
$('#desc2').on('mouseup', function() {
var selection = $(this).selection(),
text = $(this).text().substring(selection.start, selection.end);
console.log(text);
});
I have erased the other part of the script, because if I manage to get this to work, I'm done :D
So, as I was saying, if I do this, everything is good: I sleect a part on the div and on the console is outputted the content.
But this is not what I want to do. I wrote this:
$('.magicbutton.uno').on('click', function(){
var id = $(this).parent().attr("magic_id");
var selection = $("#"+id).selection(),
text = $("#"+id).text().substring(selection.start, selection.end);
console.log(text);
});
Everytime I click, it takes the ID of the div to change and should output the selected text, but it doesn't.
The code is the same, and i checked that $(this) in the first script is the same as $("#"+id) in the second.
What can I do? Thanks!
EDIT: jsFiddle

When DIV loses focus, selection is nullified. As a workaround, you could use data object:
DEMO
$('.magicbutton.one').on('click', function(){
var id = $(this).parent().attr("magic_id"); //id = desc2, i used this because i could have multiple forms in a page
var selection = $("#"+id).data('selection');
alert(selection);
}); //This doesn't work
$('#desc2').on('mouseup', function() {
var selection = $(this).selection(),
text = $(this).text().substring(selection.start, selection.end);
$(this).data('selection', text);
});

Related

Content Editable Div, appending HTML causing issue. Every text typed after programatically appending HTML gets added to the last HTML tag

I am trying to make a content editable div that can be used to generate message templates for an app. Users can append placeholders for fields like names to a template by hitting a button. The placeholders can be removed by hitting an 'x' on them as well. Here's the working snippet.
var removePlaceholder = function(e){
e.parentNode.parentNode.removeChild(e.parentNode);
}
var appendPlaceHolder = function(field){
var e = document.getElementById("t");
e.innerHTML += ('<span class="tag">{'+field+'}<span onclick=removePlaceholder(this) class="remove">x</span></span>')
}
.tag {
background-color : blue;
color : white;
}
.remove {
color : red
}
<div id="t" contenteditable="true">Hello</div>
<button onclick=appendPlaceHolder("first_name")>Add first name</button>
The contenteditable part works just fine. But after I've added a placeholder using my appendPlaceHolder function, everything I type seem to get appended to the last inserted HTML element.
How can I prevent this. I have closed the tag properly. Is there any way to change this behaviour.
To recreate issue, run the snippet and hit the "Add First Name" Button, then continue typing in the area.
Update
Have added image to explain the situation
What you can do is add a space after the placeholder has been appended:
JavaScript
var removePlaceholder = function(e){
e.parentNode.parentNode.removeChild(e.parentNode);
}
var appendPlaceHolder = function(field){
var e = document.getElementById("t");
e.innerHTML += ('<span class="tag">{'+field+'}<span onclick=removePlaceholder(this) class="remove">x</span></span> ')
}
Note: The which has been added at the end of the span just creates a space.
Live Example
JSFiddle

Append text to currently selected div

I'm working on this website www.betamaths.eu
When a user had clicked inside one of the divs that have placeholder text and then click a button on the left, I would like the text from that button to append inside the div.
I have this code from another user which appends or prepends text ouside the div (not what I am looking for. You can test it with the lowercase alpha button in the menu on the left of the webpage listed above if you wish to get a better understanding.
<script type="text/javascript">
var No = 0;
var focusedElement;
$(document).ready(function() {
$('#answer_step1').on('click','div',function() {
focusedElement = this;
});
$('#alpha').on('click',function() {
$('#answer_step1').prepend('<div>Test'+No+'</div>');
No++
});
});
If I change the line
$('#answer_step1').append('<div>Test'+No+'</div>');
to
$('#answer_step1').append('Test'+No);
nothing happens. Any help is appreciated. If I can get one of these working, the rest will be easy.
You must have a syntatically error in your code, because I used your same code and was able to accomplish the append();
HTML:
<button id="alpha">
Click
</button>
<div id="answer_step1">
hi
</div>
Javascript:
var No = 0;
var focusedElement;
$(document).ready(function() {
$('#answer_step1').on('click','div',function() {
focusedElement = this;
});
$('#alpha').on('click',function() {
$('#answer_step1').prepend('Test' + No);
No++
});
});
https://jsfiddle.net/typtzr7z/

jQuery clone() input value function

I have created a clone function to clone a selection of elements. I have managed to get the basics of the clone function working. CLICK HERE
I have a bug in this function. When the user types text into the input field, it clones the last inputted text and changes the text value for all cloned items.
$('.add-item').on('click', function() {
var value = $('input').val();
if ($('#items-field').val()) {
$('.list-items p').text(value)
$('.list-items:first').clone().appendTo("#items").addClass('isVisible');
$('input').val('');
event.preventDefault();
}
})
Does anyone know how this problem can be resolved?
Clear the value of inputs after you clone(). You can use the find() method to get all the inputs inside the cloned item.
var c = $('.list-items:first').clone();
c.find("input").val(""); // find all inputs and clear
c.appendTo("#items").addClass('isVisible');
Here is a working jsbin sample
Also, In your code, you are reading the input value and setting it to all the p tags's text. You should be setting it only to the p tag of the cloned div.
$(function(){
$('.add-item').on('click', function(e) {
event.preventDefault();
var value = $('#items-field').val();
if (value!="") {
var c = $('.list-items:first').clone();
c.find("input").val(""); // find all inputs and clear
c.appendTo("#items").addClass('isVisible');
c.find("p").text(value);
}
});
})
Here is a working sample of the complete solution

Trimmed input value displayed in div

I have an unknown number of input boxes with unknown IDs. I would like to be able to click on an input box and have a trimmed version of the value populate a div.
JSFiddle
My code all works as expected once the input field is edited, but I want to have the value displayed on first click/focus.
This is the JS function I wrote.
JS
$('input').each(function() {
var $tthis = $(this),
defaultValue = $tthis.val();
defaultValue = defaultValue.substring(keyed.indexOf("|") + 1);
defaultValue = defaultValue.substring(0, defaultValue.length - 2)
$("#target").html(defaultValue);
});
HTML
<input
id='thistext$index'
type='text'
onclick='this.select();'
onfocus="
document.getElementById('show_hide').style.display='block';
document.getElementById('show_hide2').innerHTML = 'Copy this text into the wiki, it will display as: ';"
onblur="document.getElementById('show_hide').style.display='none';" value='&#91[http://www.example.com/$dirArray[$index]|$dirArray[$index]]]' />
<div id='show_hide'>
<div id='show_hide2'>
</div>
<div id='target'>
</div>
</div>
I restructured your code a bit from the first fiddle.
I threw out all inline javascript and it's handlers, the onFocus, onBlur, onClick and replaced with jQuery equivalents and I think I got what you wanted.
I used jQuery's on() method to do the same thing which cleaned up the HTML a lot.
Then I used a function within show() to trigger a few other functions.
This could be more procedural but I thought it was nice and clean.
And lastly I extracted out the trimming and substringing to it's own function so that you can reuse it later on.
A fiddle here and the code below:
$('input').on('click', function() {
var $input = $(this);
$('#show_hide').show(function(){
$('#show_hide2').text('Copy this text into the wiki, it will display as:');
var text = trimInputValue($input);
$('#target').text(text);
});
});
function trimInputValue($input) {
var text = $input.val();
text = text.substring(text.indexOf("|") + 1);
text = text.substring(0, text.length - 2);
return text;
}
$('input').on('focusout', function() {
$('#show_hide').hide();
});
Now you might wonder where your select() went off to.
Don't worry, just include it in your on('click', function(){ select(); }); and it should execute.

Jquery get readout of text area live

I was wondering if I could get a little help. I want to get a live preview of what is in my text area above it.
Each new line in the text area will display as a list above it, so something like this:
test
test2
test3
Text area:
test
test2
test3
How I want it to work is that on load it reads the contents of the text area and displays the contents above in a list. Then when the contents of the text area changes it also changes the list above it.
Here is my code: http://jsfiddle.net/spadez/9sX6X/
<h4>Placeholder</h4>
<ul id="tst"></ul>
<textarea rows="4" cols="50" placeholder="Test" id="test"></textarea>
This is how far I got:
$('#test').bind('input propertychange', function() {
if(this.value.length){
Rerender list to show contents
}
});
This is one of my first scripts so could someone please give me some guidance on how this should be achieved?
Fiddle
var list = $('#tst');
$('#test').on('keyup', function() {
list.empty();
if(this.value.length){
$.each(this.value.split("\n"), function(i, val){
list.append($('<li></li>').text(val));
});
}
});
$('#test').trigger('keyup'); // required to make it do the update onload
Because of my usage of .text(), this will handle special characters such as < and > without a problem. Also note how I have only selected the <ul> a single time, instead of re-selecting it over and over.
Side note: as of jQuery 1.7, .on() is preferred instead of .bind().
is this what you are looking for? http://jsfiddle.net/9sX6X/2/
CODE
$('#test').bind('keyup', function () {
if (this.value.length) {
var inp = this.value.split("\n");
$("#list").empty();
for(var x = 0; x < inp.length; x++){
$("#list").append("<li>"+inp[x]+"</li>")
}
}
});
Hope it helps
You could do this:
$('#test').on('change', function () {
var lines = $(this).val().split('\n');
$('#tst').empty();
for (var i = 0;i < lines.length;i++){
$('#tst').append('<li>' + lines[i] + '</li>');
}
});
Note: this code works on the change event of the textarea, thus you need to click outside of the textarea for the event to fire. If you want to do it on every key press, you should change the event from change to keyup. However, this does lead to far less performance.
You can see the updated fiddle here: http://jsfiddle.net/xv73p/

Categories

Resources