set character limit for editable div [duplicate] - javascript

This question already has answers here:
textarea character limit
(10 answers)
Closed 8 years ago.
I have a div element .userbio , which is used to display "About me". When you click on the element, it becomes a textarea, where i can edit the information. But it should stop, when the character limit reaches 180. A plugin is being used for editing the "about me" section https://code.google.com/p/jquery-in-place-editor/
On clicking the .userbio element, .editInPlace class of the plugin gets attached to the .userbio element. So i've tried setting css .editInPlace textarea { maxlength:180 }, it doesn't work.
What happens now is that, i can type in as many characters i can and it overflows the entire page. I want the editing to stop, when it reaches the limit of 180 characters. Even tried some Jquery code snippets, but it doesn't work. Thank You

I would consider adding the code for maxlength to the jquery plugin. From what I can see this is controlled in the function createEditorElement so just add that
createEditorElement: function() {
if (-1 === $.inArray(this.settings.field_type, ['text', 'textarea', 'select']))
throw "Unknown field_type <fnord>, supported are 'text', 'textarea' and 'select'";
var editor = null;
if ("select" === this.settings.field_type)
editor = this.createSelectEditor();
else if ("text" === this.settings.field_type)
editor = $('<input type="text" ' + this.inputNameAndClass()
+ ' size="' + this.settings.text_size + '" maxlength="' + this.settings.text_max + '" />');
else if ("textarea" === this.settings.field_type)
editor = $('<textarea ' + this.inputNameAndClass()
+ ' rows="' + this.settings.textarea_rows + '" '
+ ' cols="' + this.settings.textarea_cols + '" maxlength="' + this.settings.textarea_max + '"/>');
return editor;
}
Then add the default values for text_max and textarea_max to the top default settings object
$.fn.editInPlace.defaults = {
text_max: 180,
textarea_max: 180,
.... rest of defaults ....
}

You could bind a keyup event and substring the text if it exceeds the character count limit...
var limit = 180;
$("textarea").on("keyup", function() {
var val = $("textarea").val();
if(val.length > limit)
$("textarea").val(val.substr(0, limit));
});
textarea {
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<textarea>text</textarea>

We have to find a way to add :
$(".editInPlace").attr("maxLength", 180);
Somewhere.
So we have to find a "hook" to set this attribute to the textarea when it pops out. I tried to look for this kind of hook in the documentation of the plugin but did not find one.
If nobody finds a better way to solve your problem, you can change the library's source code directly.
createEditorElement: function() {
if (-1 === $.inArray(this.settings.field_type, ['text', 'textarea', 'select']))
throw "Unknown field_type <fnord>, supported are 'text', 'textarea' and 'select'";
var editor = null;
if ("select" === this.settings.field_type)
editor = this.createSelectEditor();
else if ("text" === this.settings.field_type)
editor = $('<input type="text" ' + this.inputNameAndClass()
+ ' size="' + this.settings.text_size + '" />');
else if ("textarea" === this.settings.field_type)
editor = $('<textarea ' + this.inputNameAndClass()
+ ' rows="' + this.settings.textarea_rows + '" '
+ ' cols="' + this.settings.textarea_cols + '" />');
return editor;
},
And before returning "editor", add something like this:
if(this.settings.textarea_maxLength) {
editor.attr("maxLength", this.settings.textarea_maxLength);
}
Then you'll have to set the "maxLength" attribute as an option field when you instantiate the editInPlace:
$("#editme1").editInPlace({
/* the options you had before */
textarea_maxLength: 180
});
But it seems a bit tricky and I didn't test it, maybe you should consider asking the plugin's developer directly.
oops I didn't refresh the page before posting, sorry. This is basically the same solution as #pln

In jQuery, you can achieve the effect by disabling the input when the length of the inner text exceeds 179 characters:
if ( $('.userbio').text().length > 179 ) {
$('.userbio').prop('disabled', true);
}
Alternatively, HTML5 supports a maxlength property on textarea elements: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea

Related

Changing text color using replace method

I am using the following code inside my click handler (shown in JSFiddle below) to replace a text when a user clicks on a cell value:
var value = event.args.value;
var color = "#FF0000";
var highlighted = text.replace(
' ' + value + ' ',
"<span style='color:" + color + ";'</span> "
);
panel.jqxPanel('clearcontent');
panel.jqxPanel('append', highlighted);
Q1:
It is behaving in a different manner. I mean when I click on the first cell value, it converts everything to red color, clicking on other values makes it behave in different manner as can be seen in my JSFiddle here
Q2. What can I use to preserve the html formatting? I mean using var text = panel.html(); instead of var text = panel.text(); didn't work for me.
You are missing the closing > on your span tag, and you are omitting the value that you obtained from var value = event.args.value; so the word goes missing.
var highlighted = text.replace(
' ' + value + ' ',
' <span style="color:' + color + ';">' + value + '</span> '
// ^ ^^^^^
Note I also changed the quote characters used so the HTML can have the double-quotes " which are more commonly used in markup, and javascript doesn't care about single or double quotes for strings — use whichever you like, just be consistent, for your own sanity.
Try the updated fiddle I created, changing only that line, and you will see the word you click on get highlighted.
That said, it is generally better to avoid inline styles like color="#FF0000" and use classes and CSS styles for them instead. You could instead have simpler code that doesn't have to work the var color into it:
var highlighted = text.replace(
' ' + value + ' ',
' <span class="selected">' + value + '</span> '
Your CSS would have a rule span.selected { color: #FF0000; } ... then, restyling your highlight color from red to something else you just change the CSS instead of having to change your javascript code.

How to check if html element is visible is(":visible") not working the way I need it to

I know is(":visible") will return false if a parent is invisible, so I know why the test I'm writing fails. My question is how to get around that.
The Test:
QUnit.module("updateLabel", function() {
QUnit.test("true value", function(assert) {
var key = "exchangestatus";
var value = true;
var element = $("#" + key + "-" + value);
assert.ok($(element).is(":hidden"), key + "-" + value + " should be hidden before updating");
MyCompany.updateLabel(key, value);
assert.ok($(element).is(":visible"), key + "-" + value + " should be visible after updating");
//THE ABOVE FAILS!
});
});
the html:
This label is in a div, which is in a div, which is in a form, which is in a div, which is in a div... The html has too much company specific stuff, so I'm omitting it, but this html is in deeply nested tags.
<label type="label" value="connected" name="ExchangeStatus" id="exchangestatus-true" class="control-label label-btn-success fusionconnect" style="padding: 8px 12px;">{{si011}}</label>
The JavaScript being tested:
updateLabel: function(key, value) {
var selectInput = "#" + key + "-" + value;
if (value) {
$(selectInput).show();
$("#" + key + "-false").hide();
} else {
$(selectInput).show();
$("#" + key + "-true").hide();
}
}
As I said in the first sentence, my assertion fails because its parent isn't visible. How do I check if that specific element has called .show(); irrespective of if it's actually visible because of its parent's visibility.

Stop additional click events on specific element ID - JQuery

I have a snippet of my jQuery code;
$('#elements').on('click', '.items', function () {
var content, id, tag;
tag = this.tagName;
id = $('#' + this.id);
content = id.html();
switch (tag.substr(0, 1)) {
case "P":
id.html("<textarea id='" + this.id + "In' class='" + tag + "In' type='text'>" + content + "</textarea>");
break;
case "H":
id.html("<input id='" + this.id + "In' class='" + tag + "In' value='" + content + "' >");
break;
}
});
The purpose of this is when I click on a paragraph tag, it will add a text area inside of the paragraph tag (with the content inside it ready for editing). When I click a heading tag, it will create an 'input' tag with the content inside it for editing.
Unfortunately, when i click twice on the paragraph, it adds a text area with the content inside it as it should but on the second click it adds another text area inside of that, now the 'content' of the textarea is: <textarea id="2In" class="PIn" type="text">Paragraph one. and with every click it adds: <textarea id="2In" class="PIn" type="text">
I understand this is happening as it should given the code but I want to stop the click event on that specific ID (this.id) but keep the click event active on the other elements with the class '.items'.
**Additionally: **
I'm sure this is bad practice to approach this by creating the editiable tags inside of the old ones so if anyone has a better approach be sure to let me know.
Many thanks,
Mike
I'd probably solve it by adding a :not(.clicked) to the selector, and adding that class when you add the input. E.g.:
$('#elements').on('click', '.items:not(.clicked)', function () {
$(this).addClass("clicked");
// ...your current handling...
});
But you could solve it by checking for the existence of the field, provided the input or textarea you're adding is the only one the paragraph will have:
$('#elements').on('click', '.items', function () {
if (!$(this).find("input, textarea")[0]) {
// ...your current handling...
}
});
Or actually jQuery extends CSS to provide :has and to allow :not to have more complex contents, so in theory this would work:
$('#elements').on('click', '.items:not(:has(input)):not(:has(textarea))', function () {
// ...your current handling...
});
...but that selector is getting a bit unwieldy...
What about using .one?
By using one, the click event can only be triggered once. Here's an example.
$('#elements > *').one('click', function () {
var content, id, tag;
tag = this.tagName;
id = $('#' + this.id);
content = id.html();
switch (tag.substr(0, 1)) {
case "P":
id.html("<textarea id='" + this.id + "In' class='" + tag + "In' type='text'>" + content + "</textarea>");
break;
case "H":
id.html("<input id='" + this.id + "In' class='" + tag + "In' value='" + content + "' >");
break;
}
});
But it seems you are trying to do something like allowing a user to edit text and saving the new input. I'd advise using a combination of contenteditable and localStorage.

onmouseover for the last of several generated divs will not work in IE

I have a JavaScript function:
function addTool(id, text, tool, pic) {
var container = getById('infobox');
var origimg = getById('tempimg').src;
container.innerHTML += "<div id='" + id + "' class='toolText'>" + text + "<br><img class='toolImg' src='img/tools/" + tool + "'></div>";
getById(id).setAttribute('onMouseOver', "mOver('"+ id +"', '" + pic + "');");
getById(id).setAttribute('onMouseOut', "mOut('"+ id +"', '" + origimg + "');");
getById(id).setAttribute('href', 'javascript:mClick(id);');
}
Which generates several divs, using this code:
addTool("1p", "Bar", "tool1.jpg", 'img/p&g-part-2_skiss1-2.jpg');
addTool("2p", "Tube", "tool1.jpg", 'img/p&g-part-2_skiss1-2.jpg');
addTool("3p", "Rotating", "tool1.jpg", 'img/p&g-part-2_skiss1-2.jpg');
The mouse events work fine in all major browsers except IE. It seems that all divs except the last will have the mouse event in lowercase which will have the mouse event exactly as written, with upper case letters.
All mouse events will fire except for the last div, even if I write onmouseover instead of say ONmouseOVER, which works fine on all except the last.
Do not use setAttribute to add events. Use attachEventListener/addEvent
The problem you have is adding the elements to the div. You are basically wiping it away each time when you are adding the new elements. That is bad. You should be using appendChild to add new content to the div.
Basic idea:
function attachEvent(elem, eventName, fn) {
if ( elem.attachEvent ) {
elem.attachEvent( 'on' + eventName, fn);
} else {
elem.addEventListener( eventName, fn, false );
}
}
function addTool(text, message) {
var container = document.getElementById('infobox');
var newTool = document.createElement("a");
newTool.innerHTML = text;
newTool.href="#";
var myClickFnc = function(e) {
alert(message);
return false;
}
attachEvent(newTool, "click", myClickFnc);
container.appendChild(newTool);
}
addTool("cat","meow");
addTool("dog","bark");
addTool("pig","oink");
running example
Just as #epascarello pointed out, it seems that the setAttribute was the culprit, so I resolved it by setting the events in inline, such as this:
function addTool(id, text, tool, pic) {
var container = getById('infobox');
var origimg = getById('tempimg').src;
container.innerHTML += "<div id='" + id + "' class='toolText'" +
"onmouseover=\"mOver('"+ id +"', '" + pic + "');\" " +
"onmouseout=\"mOut('"+ id +"', '" + origimg + "');\" " +
"onclick=\"mClick(id);\"" +
">" + text + "<br><img class='toolImg' src='img/tools/" + tool + "'></div>";
}
Which worked just fine in all browsers, including IE.
You could do this part with JQuery:
$("#"+ id).mouseover(function() {
mOver('"+ id +"', '" + pic + "');
});
You can even take this a lot further:
https://stackoverflow.com/a/4158203/190596

Undo function not firing after keyup on textual input

I have a simple script showing the character count for a text input element or a textarea element.
$("input[type=text],textarea").keyup(function(){
var currentLength = ($(this).val().length);
var maximum = 100;
var spanLimit = $("span[name=Limit]");
spanLimit.html("("+ currentLength + " of " + maximum + ")");
});
While the script performs its function, I noticed that the user loses the ability to undo his/her typing with either Ctrl+Z or the right click menu option. If I comment out the following line, the undo function is not lost:
spanLimit.html("("+ currentLength + " of " + maximum + ")");
Is there any way to not lose the undo stack after performing DOM manipulation?
P.S. This behavior is visible when using IE8
You forgot a quote in var spanLimit = $("span[name=Limit]);.
It should be var spanLimit = $("span[name=Limit]");

Categories