javascript for all textarea - javascript

I want apply my JS on all my Textarea
$_PAGE->addJSOnLoad("
$('#textarea').keyup(function() {
var nombreCaractere = $(this).val().length;
var msg = nombreCaractere + ' caractére(s)';
$('#compteur').text(msg);
'<span id=compteur>' 0 caractére(s)'</span>';
});
");
This code is in constructor of my class textarea I wnat call him 1 times for all textarea

You should change the jquery selector from $('#textarea') to $('textarea') so as to target all textarea in the document.
Also you may want to use $('.compteur') in place of $('#compteur') so that your can have multiple counters, one for each textarea. Do not forget to update your html correspondingly
Edit: Please use $(this).find('.compteur') in place of $('.compteur') so that only the counter within the current textarea is affected

$('#textarea')
selects a HTML element with the ID "textarea". So this will be at max one textarea-element. The selector for all textareas would be just
$('textarea')

javscript event handlers can take a parameter (Event), so
$('textarea').keyup(function() {
var nombreCaractere = $(this).val().length;
var msg = nombreCaractere + ' caractére(s)';
// code for display, todo!
}
would put the event handler on every textarea (<textarea>) on your page. However, the display for the character count is a bit more difficult, unless it's one fixed element that scrolls along.
but let's say, your textareas all have an attribute data-charcount="[id]" that has the id of a div or something, that will display the character count.
Then you could replace
// code for display, todo!
with
$("#"+this.dataset.charcount).text(msg); // <- assuming this works
and your example textarea should look like this:
<textarea data-charcount="compteur"></textarea>
<span id="compteur"></span>
please note: every id should only appear once!
edit replace event.target with this, and fixed small error with string concat

Related

Format text as user inputs in a contenteditable div

I'm attempting to make a page that allows users to input text and it will automatically format the input -- as in a screenplay format (similar to Amazon's StoryWriter).
So far I can check for text with ":contains('example text')" and add/remove classes to it. The problem is that all of the following p tags inherit that class.
My solution so far is to use .next() to remove the class I added, but that is limited since there might be need for a line break in the script (in dialogue for instance) and that will remove the dialogue class.
$('.content').on('input', function() {
$("p.input:contains('INT.')").addClass("high").next(".input").removeClass("high");
$("p.input:contains('EXT.')").addClass("high").next(".input").removeClass("high");
});
I can't get || to work in the :contains parameter either, but that's the least of my issues.
I have a JS fiddle
I've worked on this for a while now, and if I could change only the node that contains the text (INT. or EXT. in this example) and leaves the rest alone that would work and I could apply it to the rest of the script.
Any help would be appreciated, I'm new to the stackoverflow so thank you.
See the comments in the code below for an explanation of what's going on.
Fiddle Example
JQuery
var main = function(){
var content = $('.content');
content.on('input', function() {
$("p.input").each(function() {
//Get the html content for the current p input.
var text = $(this).html();
//indexOf will return a positive value if "INT." or "EXT." exists in the html
if (text.indexOf('INT.') !== -1 || text.indexOf('EXT.') !== -1) {
$(this).addClass('high');
}
//You could include additional "if else" blocks to check and apply different conditions
else { //The required text does not exist, so remove the class for the current input
$(this).removeClass('high');
}
});
});
};//main close
$(document).ready(main);

Input field with attached text to the right

I'm doing a fancy comment list on my project, structured like this:
As you see, there's a comments list and at his bottom there's an input field (textarea) to submit a comment. Note that there's the current username attached to the right (let's call it a simple static appended text).
I just found this little JS to make an input field resize automatically by adapting it to the content.
function resizeInput() {
$(this).attr('size', $(this).val().length);
}
$('input[type="text"]').keyup(resizeInput).each(resizeInput);
But it's not enough. I need it for a textarea and I want it to behave correctly when a comment is long enough to wrap on another line. By definition, the input field is a box, and it obviously acts badly compared to what I want:
Instead, this should be the right behavior:
I looked everywhere and I can't think any way to implement this. Can somebody help me?
Here is a good plugin for textarea. But it using jQuery.
usage simple as always.
$(document).ready(function(){
$('textarea').autosize();
});
You could use the contenteditable attribute:
<span contenteditable="true">comment</span> by <span class="userName">someone</span>
It is supported in practically all browsers. Using the right CSS, you can underline the content and also limit the width.
I think you mean this
NOTE: No check for selection and bound to document. Exercise for the reader to bind to a specific field and swap it for a span
FiDDLE
$(document).keypress(function(e) {
var char = String.fromCharCode(e.which);
if (e.which==13) char = '<br/>'; // needs to handle backspace etc.
$("#textfield").append(char);
$("#hiddenfield").val($("#textfield").text()); // or .html if you want the BRs
e.preventDefault();
});
using
<span id="textfield"></span> - by My Username
If you make the field contenteditable you will get this in Chrome so some additional CSS may be needed
Use a <span> with contenteditable (supported in IE too). Here is a fiddle: http://jsfiddle.net/goabqjLn/2/
<span contenteditable>Insert a comment...</span> by My Username
Then, using JavaScript, attach an event listener that mirrors the inner text of the span into a hidden input field, so it gets submitted with your <form>.
Edit: I have updated the fiddle to also include the JS code. Here is the updated code:
<span class="editor" id="editor" contenteditable data-placeholder="Insert a comment...">Insert a comment...</span> by My Username
<!-- Hide this textarea in production: -->
<textarea type="text" id="comment"></textarea>
And the JS:
function mirror() {
var text = $('#editor').html().trim()
.replace(' ', ' ')
.replace(/<br(\s*)\/*>/ig, '\n') // replace single line-breaks
.replace(/<[p|div]\s/ig, '\n$0') // add a line break before all div and p tags
.replace(/(<([^>]+)>)/ig, ""); // remove any remaining tags
$('#comment').val(text);
}
$('#editor').focus(function () {
var editor = $(this);
if (editor.text() == editor.attr('data-placeholder')) {
editor.text('');
}
}).blur(function () {
var editor = $(this);
if (editor.text() == editor.attr('data-placeholder')) {
editor.text(editor.attr('data-placeholder'));
}
}).blur(mirror).keyup(mirror);

Dynamically created textarea with no .val()

I'm trying to allow users to edit the text of a paragraph in a website. I take a paragraph and replace the <p> tags with <textarea> tags using the .replaceWith() function. When I try to take the value of the textarea, it returns blank. Here's a JSfiddle.
HTML:
<p><a class="edit">Edit</a>I'm going to change this into a textarea field and retrieve the value.</p>
JS:
$(document).ready(function() {
$('.edit').hide();
var object = $('p');
object.on("mouseenter", function() {
$('.edit').show();
object.on('click','.edit',function(){
var oldText = object.text();
oldText = oldText.substr(4); // Exclude the word 'Edit'
object.replaceWith($("<textarea>").val(oldText).css("width",object.css('width')).css('height',object.css('height')));
var value = object.val();
alert("Value: "+value);
});
});
});
I'm a programming beginner, so if you have style or implementation tips, feel free to share. This is just my gut reaction to solving the problem; there may be a simpler way to accomplish the same thing.
EDIT: I should also mention that in my website, each paragraph comes from a database table that I'm displaying using an AJAX function. When the user is done editing, he can click a button, and the website will take the new value of the textarea field and UPDATE *table* SET *text*=newText WHERE *text* LIKE oldText;
Try just using contenteditable='true' instead of changing to a textarea. It will make the <p> editable.
Like this:
<p contenteditable='true'><a class="edit">Edit</a>
I'm going to change this into a textarea field and retrieve the value.</p>
If you want to make your text area editable when someone clicks 'Edit', you can create a function that sets the contenteditable attribute to true and then gives focus to the <p> element.
Your code is not trying to get the value of the <textarea>. Your call:
object.replaceWith( ... )
does not change the value of the variable "object" — it's still the jQuery object for the <p> tag, but after that it's out of the DOM. <p> tags don't have a "value" property.
It's almost always a bad idea to set up event handlers inside another event handler (well, an event handler for interaction events anyway). Event handlers accumulate, so each "mouseenter" event will add another "click" handler.
ckersch is right about an easier method being to use contenteditable, but if you're looking to a solution for your specific problem, change your selector from this:
var value = object.val();
To this:
var value = $("textarea").val();
Full code:
$(document).ready(function() {
$('.edit').hide();
var object = $('p');
object.on("mouseenter", function() {
$('.edit').show();
object.on('click','.edit',function(){
var oldText = object.text();
oldText = oldText.substr(4); // Exclude the word 'Edit'
object.replaceWith($("<textarea>").val(oldText).css("width",object.css('width')).css('height',object.css('height')));
var value = $("textarea").val();
alert("Value: "+value);
});
});
});
Fiddle
There are many ways you could make it more robust, including adding a class or id to your textarea, and then using it to be selected, such as this way:
object.replaceWith($("<textarea class='selectMe'>").val(oldText).css("width",object.css('width')).css('height',object.css('height')));
var value = $(".selectMe").val();
You are using the method replaceWith() wrong. The argument must be a string or a function that returns a string, not a jquery selector. Also, you should place the onclick event outside of the mouseenter event (this is valid for any event, never nest them)
$(document).ready(function() {
function makeTextarea(e) {
e.preventDefault();
var edit = $(e.currentTarget);
var parent = edit.parent();
edit.remove();
parent.replaceWith('<textarea>' + parent.text() + '</textarea>');
}
$('.edit').on('click', makeTextarea);
});
Fiddle: http://jsfiddle.net/U57v2/4/
"When the document is ready listen for clicks on .edit class. When clicked store a reference to the parent element (<p>) and then remove the edit element. Finally replace the parent element (<p>) with a textarea with the contents of the <p> element."
ckersh is absolutely right about the contenteditable, but if you're looking for a specific answer to your code, there are a few things you could improve.
There are a couple of issues with your code. First, you're rebinding the on('click') handler every time you mouse over the paragraph, so if you mouse over 5 times, you're executing the anonymous function 5 times. You only need to bind the on routine once. Second, the variable object never changes, so when you replace it with a textarea, you need a new selector to get the value.
I've updated your fiddle with the enhancements I've mentioned above. I also added a mouseleave event, because I figure you want to hide the "Edit" button when you leave the paragraph. The updated javascript can be seen below:
$(document).ready(function () {
$('.edit').hide();
var object = $('p');
object.on("mouseenter", function () {
$('.edit').show();
}).on("mouseleave", function () {
$('.edit').hide();
}).on("click", '.edit', function () {
var oldText = object.text();
oldText = oldText.substr(4); // Exclude the word 'Edit'
object.replaceWith($("<textarea>").val(oldText).css("width", object.css('width')).css('height', object.css('height')));
var value = $("textarea").val();
alert("Value: " + value);
});
});

Javascript - removeChild removes a whole cell of a table

I have table where I can add new rows with input fields. Also there's a possibility to remove an added input field. Deleting a complete row works, but there's a problem to delete single input fields inside a cell.
Here's the code:
cell1=document.getElementById('avz_tabelle').rows[par.rowIndex].cells;
var feld = document.createElement("input");
feld.setAttribute("name","avz_keywords" + avz_array + "[]");
feld.setAttribute("onblur","");
feld.setAttribute("type","text");
feld.setAttribute("size","30");
cell1[1].appendChild(feld);
var remove = document.createElement("a");
remove.setAttribute("href","#");
remove.setAttribute("onclick","this.parentNode.parentNode.removeChild(this.parentNode);");
remove.innerHTML = " X";
cell1[1].appendChild(remove);
var br = document.createElement("br");
cell1[1].appendChild(br);
The problem is that the remove action completly deletes the whole cell, instead of the related input field. The strange thing, that this works on the first tier of the table without problems.
Do you see the error? Thanks for any suggestions!
Ok, you are appending the anchor element remove to cell1[1], which is a single table cell of the row with index par.rowIndex. So the parentNode to the anchor element is the cell. With this.parentNode.parentNode.removeChild(this.parentNode) you are removing the parentNode of the anchor, which is the cell.
EDIT: removed a sentence that might have been offensive ... sorry :-)
EDIT2: Possible solution:
this.previousSibling.parentNode.removeChild(this.previousSibling);
because this.previousSibling might be the input element
Since you are building your HTML with the DOM, you don't have to set attributes for events:
replace remove.setAttribute("onclick"... by something like:
remove.onclick = function(ev){
feld.parentNode.removeChild(feld);
}
feld and the onclick function are defined in the same scope, you have a closure here. It makes feld available inside the function.

select created element

$(iframe).bind('keypress', function (e) {
if (e.which == 13) {
var range = iframe.getSelection().getRangeAt(0);
var nodeText = $(range.startContainer, iframe).parent().html();
var leftPart = nodeText.substr(0, range.endOffset);
var rightPart = nodeText.substr(range.endOffset);
$(range.startContainer, iframe).parent().replaceWith('<big>' + leftPart + '</big><p>' + rightPart + '</p>');
return false;
}
});
I've got iframe with some content, e.g:
<p>someText</p>
When i place cursor between "some" and "text", and press enter, i want it to be splitted into this:
<big>some</big><p>Text</p>
everything seems to be working ok, but I also need to change cursor position to the beginnings of this: <p>Text</p>
I know how to set cursor position, but I need to select that element. just $('p', iframe) won't work, because I can have multiply <p> items in iframe. any ideas?
This is an unholy mix of DOM, which considers everything in terms of nodes and offsets, and jQuery-ish HTML-as-strings. The two do not mix well. You've misunderstood the endOffset and startOffset properties of DOM Ranges: they're not offsets within the innerHTML of the container. I suggest looking at MDC or the spec and refactoring your code to only use DOM nodes and not strings of HTML.
Denis ,
Give a common class name to all of them , so that it will effect on the elements.
I would add a dynamic id attribute (or use the metadata plugin) using jQuery to identify the split paragraph. And based on the identified split string place the cursor before the <p> tag. Do make sure to remove the id attribute (or some metadata) once you are done placing the cursor, so that any other splits or a backspace on the same <p> doesn't result in unintended consequences
Hope that helps
I found a nice solution without adding id or class to element. i changed this:
$(range.startContainer, iframe).parent().replaceWith('<big>'+leftPart+'</big><p>'+rightPart+'</p>');
to this:
var leftObject = $('<big>'+leftPart+'</big>');
var rightObject = $('<p>'+rightPart+'</p>');
$(range.startContainer, iframe).parent().replaceWith(leftObject);
leftObject.after(rightObject);
now i got both elements selected in leftObject and rightObject

Categories

Resources