i am using HTML.TEXTAREA in my MVC2.0 application but i cant restrict the textarea to allow user to input only 255 characters.
I have also provided <% html.textarea("Name",new {#maxlength = "255"}) %> but still i couldnt achieve the target.
Please provide me any solutions.
Thanks
Verify your HTML version
In Html 4.0,
maxlength is not a valid property for TextArea.
maxLength attribute is added in HTML 5.0.(But unfortunately HTML 5.0 is quite new and not much browser support it)
For more information,
http://www.w3schools.com/html5/att_textarea_maxlength.asp
You can write java script and restrict text area size.
<script type="text/javascript">
$(function () {
$("#id").keypress(function () {
var maxlen = 100;
if ($(this).val().length > maxlen) {
return false;
}
})
});
</script>
A very easy way is to use SubString. Its not something that you need to bang your head for and you can write it yourself.
For Example:
var textAreaObject = document.getElementById("TextAreaId");
if (textAreaObject != null) {
var maxlength = 60; //Give the desired value for your Maxlength
if (textAreaObject .value.length > maxlength) {
//Substring from the entered text. Easy-peezy
textAreaObject .value = textAreaObject .value.substring(0, maxlength);
}
}
Works everywhere and anywhere. And use this for on paste and on keypress events. Happy coding.
Related
I am trying to create a plugin that works similar to the tagging feature here on Stack Overflow. The plugin adds an onchange event to the editor and than checks the data to see if the user entered a tag and replaces any tags found with a div.
CKEDITOR.plugins.add('tagit', {
icons: '',
init: function (editor) {
var tags = ['MyTag'],
tokens = [];
editor.on('change', function (event) {
var tokenUpdated = false;
tokens = tokenize(event.editor.getData());
for (var tokenIndex = 0; tokenIndex < tokens.length; tokenIndex++) {
var token = String(tokens[tokenIndex]);
if (!token.match(/tagit/gmi) && tags.some(function (tag) { return token.indexOf(tag) >= 0; })) {
tokens[tokenIndex] = '<div class="tagit">' + tokens[tokenIndex] + '</div>';
tokenUpdated = true;
}
}
if (tokenUpdated) {
event.editor.setData(tokens.join(''));
}
});
var tokenize = function (data) {
var match = '(<div class="tagit">.*?<\/div>)';
for (var i = 0; i < tags.length; i++) {
match += '|(' + tags[i] + ')';
}
var re = new RegExp(match, "gmi");
return data.split(re);
}
}
});
The problem is when I call setData the change event is fired again and event.editor.getData() returns the html before I called setData. Is the change event fired before the data has actually been set? There's an option internal that I tried setting to true but than the data doesn't appear to be updated.
You are changing editors content so it's natural that change event will be called with editor.setData function. TBO I think that your implementation has a much important problem than circular call - you are comparing HTML content by regex. It's bad practice and you will encounter more problems during this implementation.
This feature is not obvious and requires working with document selection, not simply querying its content (also for performance reasons).
But I have a good information. With CKEditor 4.10 we are shipping new plugins which can easily be used to create feature you are talking about - especially textmatch and textwatcher. Mentioned plugins will be shipped alongside with autocomplete and mentions plugins. You can read more about our progress on GH:
Mentions: https://github.com/ckeditor/ckeditor-dev/issues/1703
Autocomplete: https://github.com/ckeditor/ckeditor-dev/issues/1751
4.10 release is set on 26 June but it could change, check GH milestones for updates.
After release, I can provide some example implementation for your feature - but I'm sure that with new plugins it will be easy as pie.
On my current project, users can type text in English and Hebrew languages.
Would be great to define direction automatically, according to the current text. For example, if the text contains Hebrew symbols, the direction should be RTL. But if the text doesn't contain Hebrew, then the direction is LTR.
Text can be changed at any moment, and I think that the best solution is to switch the direction dynamically like it works in the Google Translate service.
I didn't find already done solution and I want to propose my own.
It works pretty simply. Each time, when text has been changed, I'm checking it for Hebrew symbols and I change the text direction if need. To apply changes in config (in my case it's direction of the text), I should destroy and init CKEditor with updated config.
How you can test it:
Try to type something in English
Try to type something in Hebrew, for example, "שם"
Try to remove Hebrew symbols
You will see how the direction in editor will be changed according to current text
Here is the code:
var CKEditorConfig = {
contentsLangDirection: 'ltr',
forcePasteAsPlainText: true
},
editorInstance;
(function () {
// Initialise editor.
function initEditor() {
editorInstance = CKEDITOR.replace('editor', CKEditorConfig);
editorInstance.on('contentDom', function () {
var body = this.document.getBody();
// These listeners will be deactivated once editor dies.
// Input event to track any changes of the content
this.editable().attachListener(body, 'input', function () {
editorOnChange();
});
});
}
// On change callback.
function editorOnChange() {
var text = CKEDITOR.instances['editor'].getData(),
direction = isHebrew(text) ? 'rtl' : 'ltr',
currentDirection = CKEditorConfig.contentsLangDirection;
// Direction was changed -> reinit CKEditor.
if (currentDirection && currentDirection != direction) {
CKEditorConfig.contentsLangDirection = direction;
CKEDITOR.instances['editor'].destroy();
editorInstance = initEditor();
}
}
// Checks is current text uses hebrew language or not.
function isHebrew (text) {
const HebrewChars = new RegExp("[\u05D0-\u05FF]+");
if (!HebrewChars.test(text)) {
return false;
}
return true;
}
// Init editor.
initEditor();
})();
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdn.ckeditor.com/4.7.1/basic/ckeditor.js"></script>
<body>
<textarea id="editor" cols="50" rows="20"></textarea>
</body>
Seems CKEditor cannot be launched here. I see some error.
You can try to launch it right on JSFiddle
One problem: strange but event "input" is not launched for operations like copy-paste in this example, but work in my current application. Seems versions of libraries are the same. But it's not very important for this example.
I hope it will be useful for somebody.
Sometimes it is useful to have the HTML editor in CRM interface. It is possible to implement the editor directly to CRM 2013. As editor we will use ckeditor which allows to use it without installation on the server.
Identify the field where you would like to use the rich text editor.
Create html-webresource which will define ckeditor. Go to Settings-Customizations-Customize the System-Web Resources.
In html editor of web resource, select the Source tab and insert the following code:
<html>
<head>
<title></title>
<script src="//cdn.ckeditor.com/4.4.7/standard/ckeditor.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
function getTextFieldName()
{
var vals = new Array();
if (location.search != "")
{
vals = location.search.substr(1).split("&");
for (var i in vals)
{
vals[i] = vals[i].replace(/\+/g, " ").split("=");
}
//look for the parameter named 'data'
for (var i in vals)
{
if (vals[i][0].toLowerCase() == "data")
{
var datavalue = vals[i][2];
var vals2 = new Array();
var textFieldName = "";
vals2 = decodeURIComponent(datavalue).split("&");
for (var i in vals2)
{
var queryParam = vals2[i].replace(/\+/g, " ").split("=");
if (queryParam[0] != null && queryParam[0].toLowerCase() == "datafieldname")
{
textFieldName = queryParam[1];
}
}
if (textFieldName == "")
{
alert('No "dataFieldName" parameter has been passed to Rich Text Box Editor.');
return null;
}
else
{
return textFieldName;
}
}
else
{
alert('No data parameter has been passed to Rich Text Box Editor.');
}
}
}
else
{
alert('No data parameter has been passed to Rich Text Box Editor.');
}
return null;
}
CKEDITOR.timestamp = null;
// Maximize the editor window, i.e. it will be stretched to target field
CKEDITOR.on('instanceReady',
function( evt )
{
var editor = evt.editor;
editor.execCommand('maximize');
});
var Xrm;
$(document).ready(function ()
{
// Get the target field name from query string
var fieldName = getTextFieldName();
var Xrm = parent.Xrm;
var data = Xrm.Page.getAttribute(fieldName).getValue();
document.getElementById('editor1').value = data;
/*
// Uncomment only if you would like to update original field on lost focus instead of property change in editor
//Update textbox on lost focus
CKEDITOR.instances.editor1.on('blur', function ()
{
var value = CKEDITOR.instances.editor1.getData();
Xrm.Page.getAttribute(fieldName).setValue(value);
});
*/
// Update textbox on change in editor
CKEDITOR.instances.editor1.on('change', function ()
{
var value = CKEDITOR.instances.editor1.getData();
Xrm.Page.getAttribute(fieldName).setValue(value);
});
// Following settings define that the editor allows whole HTML content without removing tags like head, style etc.
CKEDITOR.config.allowedContent = true;
CKEDITOR.config.fullPage = true;
});
</script>
<meta>
</head>
<body style="word-wrap: break-word;">
<textarea class="ckeditor" cols="80" id="editor1" name="editor1" rows="10"></textarea>
</body>
</html>
Note:
As you can see, there are a few important sections
a) The following code loads the ckeditor and jquery from web so that they don't have to be installed on server.
<script src="//cdn.ckeditor.com/4.4.7/standard/ckeditor.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
b) Function getTextFieldName() which gets the name of target field where should be rich text editor placed. This information is obtained from query string. This will allow to use this web resource on multiple forms.
c) Initialization of ckeditor itself - setting the target field and properties of ckeditor. Also binding the editor with predefined textarea on the page.
Open the form designer on the form where you would like to use WYSIWYG editor. Create a text field with sufficient length (e.g. 100 000 chars) which will hold the html source code.
Insert the iframe on the form. As a webresource use the resource created in previous steps. Also define Custom Parameter(data) where you should define the name of the text field defined in step 4. In our situation we created new_bodyhtml text field so the parameter holds this value. This value is returned by the getTextFieldName() of the web resource.
Do not forget to save and publish all changes in CRM customization otherwise added webresources and updated form are not available.
That's all, here is example how it looks like:
Yes, you can use CKEditor, but when I implemented the CKEditor on a form, it turns out it is quite limited in the functionality in provides. Also, the HTML it generates leaves much to be desired. So, I tried a similar idea to Pavel's but using a backing field to store the actual HTML using TinyMCE. You can find the code here:
Javascript
HTML
Documentation
I have package my solution as a managed and unmanaged CRM solution that can be imported and utilised on any form. Moreover, it works on both CRM 2013 and CRM 2015
I don't think this is a Drupal-specific question, but more of a general jquery/ajax issue:
Basically, I'm trying to use javascript to add up form fields and display the result in a "subtotal" field within the same form. Everything is working fine until i click the option to add another field (via ajax), which then changes my "subtotal" field to zero, and won't work again until I remove the field.
Here is the function that adds up the fields:
function calculateInvoiceFields(){
var total = 0;
var rate = 0;
var quantity = 0;
var i = 0;
var $ = jQuery;
$("#field-aminvoice-data-values tr").each(function(){
// quantity field number
quantity = $("#edit-field-aminvoice-data-und-"+i+"-field-aminvoice-quantity-und-0-value").val();
// rate field as number
rate = $("#edit-field-aminvoice-data-und-"+i+"-field-aminvoice-rate-und-0-value").val();
if(!isNaN(quantity) && !isNaN(rate)){
total += quantity*rate;
}
i++;
});
return total;
}
And here are the functions that get fired for .ready and .live:
jQuery(document).ready(function(){
var $ = jQuery;
$(".field-type-commerce-price input").val(calculateInvoiceFields());
});
jQuery(function(){
var $ = jQuery;
$(".form-text").live('change', function(){
$(".field-type-commerce-price input").val(calculateInvoiceFields());
});
});
Any ideas would be a big help. Thanks in advance!
I recommend using 'on' for any binding statement. and 'off' for unbinding.
The reason it doesn't work after an AJAX call, is because you need to be watching for that element to be added to the DOM, and an event attached to it after it gets loaded. If you load a new element in, and there is nothing watching for it, it won't add the event watch to that new DOM element.
As below:
function calculateInvoiceFields(){
/*..*/
return total;
}
$(document).ready(function(){
$(".field-type-commerce-price input").val(calculateInvoiceFields());
$("body").on('change', ".form-text", function(){
$(".field-type-commerce-price input").val(calculateInvoiceFields());
});
});
usually it stops working when an error has been thrown. did you check out your javascript console (firefox firebug, or built in for chrome) for any indication of an error?
I've successfully implemented a bit of code that strips all HTML from a pasted string using stripTags(). My next goal is to mark a few tags with white flags so they get ignored on 'paste' event using .wrap() to augment the function.
I'm using prototype.js as a framework and have slowly been working through the growing pains of learning both the framework and javascript, but this issue has presented a bit of a roadblock.
I've googled around a bit and found what looks like two great solutions, but I don't seem to be implementing them correctly.
Found solutions:
http://perfectionkills.com/wrap-it-up/ (function to indicate tags to remove)
and
http://pastebin.com/xbymCFi9 (function to allow tags to keep)
I pretty much copied and pasted from the latter.
If I pull the 'br' from the code, then the regex is ignored and all html is stripped. If I leave it, nothing gets pasted.
Here is what I've pieced together (and I feel silly for not being able to figure this out!).
String.prototype.stripTags = String.prototype.stripTags.wrap(
function(proceed, allowTags) {
if (allowTags) {
if (Object.isString(allowTags)) allowTags = $w(allowTags)
this.gsub(/(<\/?\s*)([^\s>]+)(\s[^>]*)?>/, function(match) {
if (allowTags.include(match[2].toLowerCase()))
return match[1] + match[2] + match[3] + '>'
})
} else {
// proceed using the original function
return proceed();
}
});
WysiHat.Commands.promptLinkSelection = function() {
if (this.linkSelected()) {
if (confirm("Remove link?"))
this.unlinkSelection();
} else {
var value = prompt("Enter a URL", "http://www.alltrips.com/");
if (value)
this.linkSelection(value);
}
}
document.on("dom:loaded", function() {
var editor = WysiHat.Editor.attach('event_desc');
var toolbar = new WysiHat.Toolbar(editor);
editor.observe("paste", function(event) {
var el = $(this);
setTimeout(function() {
var pText = el.innerHTML.stripTags('br');
//alert(pText);
$('event_desc_editor').update(pText);
$('event_desc').setValue(pText);
}, 0);
});
(You may recognize the WysiHat code from 37Signals text editor)
note: you can see the alert commented out. If I do alert the ptext, I get 'undefined' returned.
So I've given up on and moved to a regex solution:
el.innerHTML.replace(/<(?!\s*\/?\s*p\b)[^>]*>/gi,'')