mirror of
https://github.com/cwinfo/powerdns-admin.git
synced 2025-06-15 04:26:05 +00:00
Initial commit
This commit is contained in:
22
app/static/global/plugins/bootstrap-maxlength/LICENSE
Normal file
22
app/static/global/plugins/bootstrap-maxlength/LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2013 Maurizio Napoleoni;
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
134
app/static/global/plugins/bootstrap-maxlength/README.md
Normal file
134
app/static/global/plugins/bootstrap-maxlength/README.md
Normal file
@ -0,0 +1,134 @@
|
||||
# [Bootstrap MaxLength](http://mimo84.github.com/bootstrap-maxlength/) [](https://travis-ci.org/mimo84/bootstrap-maxlength) [](https://sourcegraph.com/github.com/mimo84/bootstrap-maxlength)
|
||||
|
||||
|
||||
This plugin integrates by default with Twitter bootstrap using badges to display the maximum length of the field where the user is inserting text.
|
||||
This plugin uses the HTML5 attribute "maxlength" to work.
|
||||
|
||||
|
||||
The indicator badge show up on focusing on the element, and disappear when the focus is lost.
|
||||
|
||||
## Configurable options
|
||||
|
||||
* **alwaysShow**: if true the threshold will be ignored and the remaining length indication will be always showing up while typing or on focus on the input. Default: false.
|
||||
* **threshold**: this is a number indicating how many chars are left to start displaying the indications. Default: 10.
|
||||
* **warningClass**: it's the class of the element with the indicator. By default is the bootstrap "label label-success" but can be changed to anything you'd like.
|
||||
* **limitReachedClass**: it's the class the element gets when the limit is reached. Default is "label label-important label-danger" (to support Bootstrap 2 and 3).
|
||||
* **separator**: represents the separator between the number of typed chars and total number of available chars. Default is "/".
|
||||
* **preText**: is a string of text that can be outputted in front of the indicator. preText is empty by default.
|
||||
* **postText**: is a string outputted after the indicator. postText is empty by default.
|
||||
* **showMaxLength**: if false, will display just the number of typed characters, e.g. will not display the max length. Default: true.
|
||||
* **showCharsTyped**: if false, will display just the remaining length, e.g. will display remaining lenght instead of number of typed characters. Default: true.
|
||||
* **placement**: is a string, define where to output the counter. Possible values are: **bottom** ( *default option* ), **left**, **top**, **right**, **bottom-right**, **top-right**, **top-left**, **bottom-left** and **centered-right**.
|
||||
* **message**: an alternative way to provide the message text, i.e. 'You have typed %charsTyped% chars, %charsRemaining% of %charsTotal% remaining'. %charsTyped%, %charsRemaining% and %charsTotal% will be replaced by the actual values. This overrides the options separator, preText, postText and showMaxLength.
|
||||
* **utf8**: if true the input will count using utf8 bytesize/encoding. For example: the '£' character is counted as two characters.
|
||||
* **twoCharLinebreak**: count linebreak as 2 characters to match IE/Chrome textarea validation.
|
||||
* **customMaxAttribute**: allows a custom maxlength attribute to allow exceeding maxlength. 'overmax' class gets added when exceeded to allow user to implement form validation.
|
||||
|
||||
## Examples
|
||||
|
||||
Basic implementation:
|
||||
|
||||
$('input[maxlength]').maxlength();
|
||||
|
||||
Change the threshold value:
|
||||
|
||||
$('input.className').maxlength({
|
||||
threshold: 20
|
||||
});
|
||||
|
||||
An example with some of the configurable options:
|
||||
|
||||
$('input.className').maxlength({
|
||||
alwaysShow: true,
|
||||
threshold: 10,
|
||||
warningClass: "label label-info",
|
||||
limitReachedClass: "label label-warning",
|
||||
placement: 'top',
|
||||
preText: 'used ',
|
||||
separator: ' of ',
|
||||
postText: ' chars.'
|
||||
});
|
||||
|
||||
The same example using the message option:
|
||||
|
||||
$('input.className').maxlength({
|
||||
alwaysShow: true,
|
||||
threshold: 10,
|
||||
warningClass: "label label-info",
|
||||
limitReachedClass: "label label-warning",
|
||||
placement: 'top',
|
||||
message: 'used %charsTyped% of %charsTotal% chars.'
|
||||
});
|
||||
|
||||
An example allowing user to enter over max characters.
|
||||
Sample HTML element:
|
||||
```html
|
||||
<textarea class="form-control" id="xyz" name="xyz" maxlength="10"></textarea>
|
||||
```
|
||||
|
||||
// Setup maxlength
|
||||
$('.form-control').maxlength({
|
||||
alwaysShow: true,
|
||||
validate: false,
|
||||
allowOverMax: true
|
||||
});
|
||||
|
||||
// validate form before submit
|
||||
$('form').on('submit', function (e) {
|
||||
$('.form-control').each(
|
||||
function () {
|
||||
if ($(this).hasClass('overmax')) {
|
||||
alert('prevent submit here');
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
## Changelog
|
||||
|
||||
### 1.5.7
|
||||
* Fixed issue with bower
|
||||
|
||||
### 1.5.6
|
||||
* Added over maxlength functionality with customMaxAttribute
|
||||
* Added twoCharLinebreak option
|
||||
|
||||
### 1.5.5
|
||||
* Implemented input event rather than keydown to improve usability
|
||||
* Fixed jshint, jscs errors
|
||||
|
||||
### 1.5.4
|
||||
|
||||
* When an input with associated maxlength element is removed, maxlength is also removed.
|
||||
|
||||
### 1.5.3
|
||||
|
||||
* Fixed #40, error on resize event.
|
||||
|
||||
### 1.5.2
|
||||
|
||||
* Fixed #44 (pasted text in can cause it to go over the max length)
|
||||
|
||||
### 1.5.1
|
||||
|
||||
* Added self protection of multiple focus events
|
||||
* Added back detection of window resizing
|
||||
|
||||
### 1.5.0
|
||||
|
||||
* Removed window.resize event
|
||||
* Maxlength is created and destroyed each time
|
||||
* Fixed Doesn't update the limit after input's maxlength attribute was changed [#31](https://github.com/mimo84/bootstrap-maxlength/issues/31)
|
||||
* Added Gruntfile
|
||||
* Added qunit unit tests
|
||||
|
||||
### 1.4.2
|
||||
|
||||
* Fixed issue with counting when the user moves with shift+tab keyboard shortcut.
|
||||
* Replaced the warningClass limitReachedClass options to use labels rather than badges for Bootstrap 3.0 better compatibility.
|
||||
|
||||
### 1.4.1
|
||||
|
||||
* Added support for TAB key when the maxlength is reached.
|
@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "bootstrap-maxlength",
|
||||
"title": "BootStrap Maxlength",
|
||||
"description": "jQuery and Bootstrap plugin for character count on inputs",
|
||||
"keywords": [
|
||||
"count",
|
||||
"input",
|
||||
"maxlength",
|
||||
"length",
|
||||
"textarea",
|
||||
"form"
|
||||
],
|
||||
"version": "1.5.7",
|
||||
"author": {
|
||||
"name": "Maurizio Napoleoni",
|
||||
"url": "http://zoomingin.net"
|
||||
},
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT License",
|
||||
"url" : "https://github.com/mimo84/bootstrap-maxlength/blob/master/LICENSE"
|
||||
}
|
||||
],
|
||||
"bugs": "https://github.com/mimo84/bootstrap-maxlength/issues",
|
||||
"homepage": "http://mimo84.github.com/bootstrap-maxlength/",
|
||||
"docs": "http://mimo84.github.com/bootstrap-maxlength/",
|
||||
"download": "https://github.com/mimo84/bootstrap-maxlength/zipball/master",
|
||||
"dependencies": {
|
||||
"jquery": ">=1.9"
|
||||
}
|
||||
}
|
438
app/static/global/plugins/bootstrap-maxlength/bootstrap-maxlength.js
vendored
Normal file
438
app/static/global/plugins/bootstrap-maxlength/bootstrap-maxlength.js
vendored
Normal file
@ -0,0 +1,438 @@
|
||||
(function ($) {
|
||||
'use strict';
|
||||
/**
|
||||
* We need an event when the elements are destroyed
|
||||
* because if an input is remvoed, we have to remove the
|
||||
* maxlength object associated (if any).
|
||||
* From:
|
||||
* http://stackoverflow.com/questions/2200494/jquery-trigger-event-when-an-element-is-removed-from-the-dom
|
||||
*/
|
||||
if (!$.event.special.destroyed) {
|
||||
$.event.special.destroyed = {
|
||||
remove: function (o) {
|
||||
if (o.handler) {
|
||||
o.handler();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
$.fn.extend({
|
||||
maxlength: function (options, callback) {
|
||||
var documentBody = $('body'),
|
||||
defaults = {
|
||||
showOnReady: false, // true to always show when indicator is ready
|
||||
alwaysShow: false, // if true the indicator it's always shown.
|
||||
threshold: 10, // Represents how many chars left are needed to show up the counter
|
||||
warningClass: 'label label-success',
|
||||
limitReachedClass: 'label label-important label-danger',
|
||||
separator: ' / ',
|
||||
preText: '',
|
||||
postText: '',
|
||||
showMaxLength: true,
|
||||
placement: 'bottom',
|
||||
showCharsTyped: true, // show the number of characters typed and not the number of characters remaining
|
||||
validate: false, // if the browser doesn't support the maxlength attribute, attempt to type more than
|
||||
// the indicated chars, will be prevented.
|
||||
utf8: false, // counts using bytesize rather than length. eg: '£' is counted as 2 characters.
|
||||
appendToParent: false, // append the indicator to the input field's parent instead of body
|
||||
twoCharLinebreak: true, // count linebreak as 2 characters to match IE/Chrome textarea validation. As well as DB storage.
|
||||
allowOverMax: false // false = use maxlength attribute and browswer functionality.
|
||||
// true = removes maxlength attribute and replaces with 'data-bs-mxl'.
|
||||
// Form submit validation is handled on your own. when maxlength has been exceeded 'overmax' class added to element
|
||||
};
|
||||
|
||||
if ($.isFunction(options) && !callback) {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
options = $.extend(defaults, options);
|
||||
|
||||
/**
|
||||
* Return the length of the specified input.
|
||||
*
|
||||
* @param input
|
||||
* @return {number}
|
||||
*/
|
||||
function inputLength(input) {
|
||||
var text = input.val();
|
||||
|
||||
if (options.twoCharLinebreak) {
|
||||
// Count all line breaks as 2 characters
|
||||
text = text.replace(/\r(?!\n)|\n(?!\r)/g, '\r\n');
|
||||
} else {
|
||||
// Remove all double-character (\r\n) linebreaks, so they're counted only once.
|
||||
text = text.replace(new RegExp('\r?\n', 'g'), '\n');
|
||||
}
|
||||
|
||||
var currentLength = 0;
|
||||
|
||||
if (options.utf8) {
|
||||
currentLength = utf8Length(text);
|
||||
} else {
|
||||
currentLength = text.length;
|
||||
}
|
||||
return currentLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate the text of the specified input.
|
||||
*
|
||||
* @param input
|
||||
* @param limit
|
||||
*/
|
||||
function truncateChars(input, maxlength) {
|
||||
var text = input.val();
|
||||
var newlines = 0;
|
||||
|
||||
if (options.twoCharLinebreak) {
|
||||
text = text.replace(/\r(?!\n)|\n(?!\r)/g, '\r\n');
|
||||
|
||||
if (text.substr(text.length - 1) === '\n' && text.length % 2 === 1) {
|
||||
newlines = 1;
|
||||
}
|
||||
}
|
||||
|
||||
input.val(text.substr(0, maxlength - newlines));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the length of the specified input in UTF8 encoding.
|
||||
*
|
||||
* @param input
|
||||
* @return {number}
|
||||
*/
|
||||
function utf8Length(string) {
|
||||
var utf8length = 0;
|
||||
for (var n = 0; n < string.length; n++) {
|
||||
var c = string.charCodeAt(n);
|
||||
if (c < 128) {
|
||||
utf8length++;
|
||||
}
|
||||
else if ((c > 127) && (c < 2048)) {
|
||||
utf8length = utf8length + 2;
|
||||
}
|
||||
else {
|
||||
utf8length = utf8length + 3;
|
||||
}
|
||||
}
|
||||
return utf8length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the indicator should be showing up.
|
||||
*
|
||||
* @param input
|
||||
* @param thereshold
|
||||
* @param maxlength
|
||||
* @return {number}
|
||||
*/
|
||||
function charsLeftThreshold(input, thereshold, maxlength) {
|
||||
var output = true;
|
||||
if (!options.alwaysShow && (maxlength - inputLength(input) > thereshold)) {
|
||||
output = false;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how many chars are left to complete the fill up of the form.
|
||||
*
|
||||
* @param input
|
||||
* @param maxlength
|
||||
* @return {number}
|
||||
*/
|
||||
function remainingChars(input, maxlength) {
|
||||
var length = maxlength - inputLength(input);
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* When called displays the indicator.
|
||||
*
|
||||
* @param indicator
|
||||
*/
|
||||
function showRemaining(indicator) {
|
||||
indicator.css({
|
||||
display: 'block'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* When called shows the indicator.
|
||||
*
|
||||
* @param indicator
|
||||
*/
|
||||
function hideRemaining(indicator) {
|
||||
indicator.css({
|
||||
display: 'none'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This function updates the value in the indicator
|
||||
*
|
||||
* @param maxLengthThisInput
|
||||
* @param typedChars
|
||||
* @return String
|
||||
*/
|
||||
function updateMaxLengthHTML(maxLengthThisInput, typedChars) {
|
||||
var output = '';
|
||||
if (options.message) {
|
||||
output = options.message.replace('%charsTyped%', typedChars)
|
||||
.replace('%charsRemaining%', maxLengthThisInput - typedChars)
|
||||
.replace('%charsTotal%', maxLengthThisInput);
|
||||
} else {
|
||||
if (options.preText) {
|
||||
output += options.preText;
|
||||
}
|
||||
if (!options.showCharsTyped) {
|
||||
output += maxLengthThisInput - typedChars;
|
||||
}
|
||||
else {
|
||||
output += typedChars;
|
||||
}
|
||||
if (options.showMaxLength) {
|
||||
output += options.separator + maxLengthThisInput;
|
||||
}
|
||||
if (options.postText) {
|
||||
output += options.postText;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function updates the value of the counter in the indicator.
|
||||
* Wants as parameters: the number of remaining chars, the element currently managed,
|
||||
* the maxLength for the current input and the indicator generated for it.
|
||||
*
|
||||
* @param remaining
|
||||
* @param currentInput
|
||||
* @param maxLengthCurrentInput
|
||||
* @param maxLengthIndicator
|
||||
*/
|
||||
function manageRemainingVisibility(remaining, currentInput, maxLengthCurrentInput, maxLengthIndicator) {
|
||||
maxLengthIndicator.html(updateMaxLengthHTML(maxLengthCurrentInput, (maxLengthCurrentInput - remaining)));
|
||||
|
||||
if (remaining > 0) {
|
||||
if (charsLeftThreshold(currentInput, options.threshold, maxLengthCurrentInput)) {
|
||||
showRemaining(maxLengthIndicator.removeClass(options.limitReachedClass).addClass(options.warningClass));
|
||||
} else {
|
||||
hideRemaining(maxLengthIndicator);
|
||||
}
|
||||
} else {
|
||||
showRemaining(maxLengthIndicator.removeClass(options.warningClass).addClass(options.limitReachedClass));
|
||||
}
|
||||
|
||||
if (options.allowOverMax) {
|
||||
// class to use for form validation on custom maxlength attribute
|
||||
if (remaining < 0) {
|
||||
currentInput.addClass('overmax');
|
||||
} else {
|
||||
currentInput.removeClass('overmax');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns an object containing all the
|
||||
* informations about the position of the current input
|
||||
*
|
||||
* @param currentInput
|
||||
* @return object {bottom height left right top width}
|
||||
*
|
||||
*/
|
||||
function getPosition(currentInput) {
|
||||
var el = currentInput[0];
|
||||
return $.extend({}, (typeof el.getBoundingClientRect === 'function') ? el.getBoundingClientRect() : {
|
||||
width: el.offsetWidth,
|
||||
height: el.offsetHeight
|
||||
}, currentInput.offset());
|
||||
}
|
||||
|
||||
/**
|
||||
* This function places the maxLengthIndicator at the
|
||||
* top / bottom / left / right of the currentInput
|
||||
*
|
||||
* @param currentInput
|
||||
* @param maxLengthIndicator
|
||||
* @return null
|
||||
*
|
||||
*/
|
||||
function place(currentInput, maxLengthIndicator) {
|
||||
var pos = getPosition(currentInput),
|
||||
inputOuter = currentInput.outerWidth(),
|
||||
outerWidth = maxLengthIndicator.outerWidth(),
|
||||
actualWidth = maxLengthIndicator.width(),
|
||||
actualHeight = maxLengthIndicator.height();
|
||||
|
||||
// get the right position if the indicator is appended to the input's parent
|
||||
if (options.appendToParent) {
|
||||
pos.top -= currentInput.parent().offset().top;
|
||||
pos.left -= currentInput.parent().offset().left;
|
||||
}
|
||||
|
||||
switch (options.placement) {
|
||||
case 'bottom':
|
||||
maxLengthIndicator.css({ top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 });
|
||||
break;
|
||||
case 'top':
|
||||
maxLengthIndicator.css({ top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 });
|
||||
break;
|
||||
case 'left':
|
||||
maxLengthIndicator.css({ top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth });
|
||||
break;
|
||||
case 'right':
|
||||
maxLengthIndicator.css({ top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width });
|
||||
break;
|
||||
case 'bottom-right':
|
||||
maxLengthIndicator.css({ top: pos.top + pos.height, left: pos.left + pos.width });
|
||||
break;
|
||||
case 'top-right':
|
||||
maxLengthIndicator.css({ top: pos.top - actualHeight, left: pos.left + inputOuter });
|
||||
break;
|
||||
case 'top-left':
|
||||
maxLengthIndicator.css({ top: pos.top - actualHeight, left: pos.left - outerWidth });
|
||||
break;
|
||||
case 'bottom-left':
|
||||
maxLengthIndicator.css({ top: pos.top + currentInput.outerHeight(), left: pos.left - outerWidth });
|
||||
break;
|
||||
case 'centered-right':
|
||||
maxLengthIndicator.css({ top: pos.top + (actualHeight / 2), left: pos.left + inputOuter - outerWidth - 3 });
|
||||
break;
|
||||
|
||||
// Some more options for placements
|
||||
case 'bottom-right-inside':
|
||||
maxLengthIndicator.css({ top: pos.top + pos.height, left: pos.left + pos.width - outerWidth });
|
||||
break;
|
||||
case 'top-right-inside':
|
||||
maxLengthIndicator.css({ top: pos.top - actualHeight, left: pos.left + inputOuter - outerWidth });
|
||||
break;
|
||||
case 'top-left-inside':
|
||||
maxLengthIndicator.css({ top: pos.top - actualHeight, left: pos.left });
|
||||
break;
|
||||
case 'bottom-left-inside':
|
||||
maxLengthIndicator.css({ top: pos.top + currentInput.outerHeight(), left: pos.left });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function retrieves the maximum length of currentInput
|
||||
*
|
||||
* @param currentInput
|
||||
* @return {number}
|
||||
*
|
||||
*/
|
||||
function getMaxLength(currentInput) {
|
||||
var attr = 'maxlength';
|
||||
if (options.allowOverMax) {
|
||||
attr = 'data-bs-mxl';
|
||||
}
|
||||
return currentInput.attr(attr) || currentInput.attr('size');
|
||||
}
|
||||
|
||||
return this.each(function () {
|
||||
|
||||
var currentInput = $(this),
|
||||
maxLengthCurrentInput,
|
||||
maxLengthIndicator;
|
||||
|
||||
$(window).resize(function () {
|
||||
if (maxLengthIndicator) {
|
||||
place(currentInput, maxLengthIndicator);
|
||||
}
|
||||
});
|
||||
|
||||
if (options.allowOverMax) {
|
||||
$(this).attr('data-bs-mxl', $(this).attr('maxlength'));
|
||||
$(this).removeAttr('maxlength');
|
||||
}
|
||||
|
||||
function firstInit() {
|
||||
var maxlengthContent = updateMaxLengthHTML(maxLengthCurrentInput, '0');
|
||||
maxLengthCurrentInput = getMaxLength(currentInput);
|
||||
|
||||
if (!maxLengthIndicator) {
|
||||
maxLengthIndicator = $('<span class="bootstrap-maxlength"></span>').css({
|
||||
display: 'none',
|
||||
position: 'absolute',
|
||||
whiteSpace: 'nowrap',
|
||||
zIndex: 1099
|
||||
}).html(maxlengthContent);
|
||||
}
|
||||
|
||||
// We need to detect resizes if we are dealing with a textarea:
|
||||
if (currentInput.is('textarea')) {
|
||||
currentInput.data('maxlenghtsizex', currentInput.outerWidth());
|
||||
currentInput.data('maxlenghtsizey', currentInput.outerHeight());
|
||||
|
||||
currentInput.mouseup(function () {
|
||||
if (currentInput.outerWidth() !== currentInput.data('maxlenghtsizex') || currentInput.outerHeight() !== currentInput.data('maxlenghtsizey')) {
|
||||
place(currentInput, maxLengthIndicator);
|
||||
}
|
||||
|
||||
currentInput.data('maxlenghtsizex', currentInput.outerWidth());
|
||||
currentInput.data('maxlenghtsizey', currentInput.outerHeight());
|
||||
});
|
||||
}
|
||||
|
||||
if (options.appendToParent) {
|
||||
currentInput.parent().append(maxLengthIndicator);
|
||||
currentInput.parent().css('position', 'relative');
|
||||
} else {
|
||||
documentBody.append(maxLengthIndicator);
|
||||
}
|
||||
|
||||
var remaining = remainingChars(currentInput, getMaxLength(currentInput));
|
||||
manageRemainingVisibility(remaining, currentInput, maxLengthCurrentInput, maxLengthIndicator);
|
||||
place(currentInput, maxLengthIndicator);
|
||||
}
|
||||
|
||||
if (options.showOnReady) {
|
||||
currentInput.ready(function () {
|
||||
firstInit();
|
||||
});
|
||||
} else {
|
||||
currentInput.focus(function () {
|
||||
firstInit();
|
||||
});
|
||||
}
|
||||
|
||||
currentInput.on('destroyed', function () {
|
||||
if (maxLengthIndicator) {
|
||||
maxLengthIndicator.remove();
|
||||
}
|
||||
});
|
||||
|
||||
currentInput.on('blur', function () {
|
||||
if (maxLengthIndicator && !options.showOnReady) {
|
||||
maxLengthIndicator.remove();
|
||||
}
|
||||
});
|
||||
|
||||
currentInput.on('input', function () {
|
||||
var maxlength = getMaxLength(currentInput),
|
||||
remaining = remainingChars(currentInput, maxlength),
|
||||
output = true;
|
||||
|
||||
if (options.validate && remaining < 0) {
|
||||
truncateChars(currentInput, maxlength);
|
||||
output = false;
|
||||
} else {
|
||||
manageRemainingVisibility(remaining, currentInput, maxLengthCurrentInput, maxLengthIndicator);
|
||||
}
|
||||
|
||||
//reposition the indicator if placement "bottom-right-inside" & "top-right-inside" is used
|
||||
if (options.placement === 'bottom-right-inside' || options.placement === 'top-right-inside') {
|
||||
place(currentInput, maxLengthIndicator);
|
||||
}
|
||||
|
||||
return output;
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}(jQuery));
|
10
app/static/global/plugins/bootstrap-maxlength/bootstrap-maxlength.min.js
vendored
Normal file
10
app/static/global/plugins/bootstrap-maxlength/bootstrap-maxlength.min.js
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/* ==========================================================
|
||||
*
|
||||
* bootstrap-maxlength.js v 1.5.7
|
||||
* Copyright 2014 Maurizio Napoleoni @mimonap
|
||||
* Licensed under MIT License
|
||||
* URL: https://github.com/mimo84/bootstrap-maxlength/blob/master/LICENSE
|
||||
*
|
||||
* ========================================================== */
|
||||
|
||||
!function(a){"use strict";a.event.special.destroyed||(a.event.special.destroyed={remove:function(a){a.handler&&a.handler()}}),a.fn.extend({maxlength:function(b,c){function d(a){var c=a.val();c=b.twoCharLinebreak?c.replace(/\r(?!\n)|\n(?!\r)/g,"\r\n"):c.replace(new RegExp("\r?\n","g"),"\n");var d=0;return d=b.utf8?f(c):c.length}function e(a,c){var d=a.val(),e=0;b.twoCharLinebreak&&(d=d.replace(/\r(?!\n)|\n(?!\r)/g,"\r\n"),"\n"===d.substr(d.length-1)&&d.length%2===1&&(e=1)),a.val(d.substr(0,c-e))}function f(a){for(var b=0,c=0;c<a.length;c++){var d=a.charCodeAt(c);128>d?b++:b+=d>127&&2048>d?2:3}return b}function g(a,c,e){var f=!0;return!b.alwaysShow&&e-d(a)>c&&(f=!1),f}function h(a,b){var c=b-d(a);return c}function i(a){a.css({display:"block"})}function j(a){a.css({display:"none"})}function k(a,c){var d="";return b.message?d=b.message.replace("%charsTyped%",c).replace("%charsRemaining%",a-c).replace("%charsTotal%",a):(b.preText&&(d+=b.preText),d+=b.showCharsTyped?c:a-c,b.showMaxLength&&(d+=b.separator+a),b.postText&&(d+=b.postText)),d}function l(a,c,d,e){e.html(k(d,d-a)),a>0?g(c,b.threshold,d)?i(e.removeClass(b.limitReachedClass).addClass(b.warningClass)):j(e):i(e.removeClass(b.warningClass).addClass(b.limitReachedClass)),b.allowOverMax&&(0>a?c.addClass("overmax"):c.removeClass("overmax"))}function m(b){var c=b[0];return a.extend({},"function"==typeof c.getBoundingClientRect?c.getBoundingClientRect():{width:c.offsetWidth,height:c.offsetHeight},b.offset())}function n(a,c){var d=m(a),e=a.outerWidth(),f=c.outerWidth(),g=c.width(),h=c.height();switch(b.appendToParent&&(d.top-=a.parent().offset().top,d.left-=a.parent().offset().left),b.placement){case"bottom":c.css({top:d.top+d.height,left:d.left+d.width/2-g/2});break;case"top":c.css({top:d.top-h,left:d.left+d.width/2-g/2});break;case"left":c.css({top:d.top+d.height/2-h/2,left:d.left-g});break;case"right":c.css({top:d.top+d.height/2-h/2,left:d.left+d.width});break;case"bottom-right":c.css({top:d.top+d.height,left:d.left+d.width});break;case"top-right":c.css({top:d.top-h,left:d.left+e});break;case"top-left":c.css({top:d.top-h,left:d.left-f});break;case"bottom-left":c.css({top:d.top+a.outerHeight(),left:d.left-f});break;case"centered-right":c.css({top:d.top+h/2,left:d.left+e-f-3});break;case"bottom-right-inside":c.css({top:d.top+d.height,left:d.left+d.width-f});break;case"top-right-inside":c.css({top:d.top-h,left:d.left+e-f});break;case"top-left-inside":c.css({top:d.top-h,left:d.left});break;case"bottom-left-inside":c.css({top:d.top+a.outerHeight(),left:d.left})}}function o(a){var c="maxlength";return b.allowOverMax&&(c="data-bs-mxl"),a.attr(c)||a.attr("size")}var p=a("body"),q={showOnReady:!1,alwaysShow:!1,threshold:10,warningClass:"label label-success",limitReachedClass:"label label-important label-danger",separator:" / ",preText:"",postText:"",showMaxLength:!0,placement:"bottom",showCharsTyped:!0,validate:!1,utf8:!1,appendToParent:!1,twoCharLinebreak:!0,allowOverMax:!1};return a.isFunction(b)&&!c&&(c=b,b={}),b=a.extend(q,b),this.each(function(){function c(){var c=k(d,"0");d=o(g),f||(f=a('<span class="bootstrap-maxlength"></span>').css({display:"none",position:"absolute",whiteSpace:"nowrap",zIndex:1099}).html(c)),g.is("textarea")&&(g.data("maxlenghtsizex",g.outerWidth()),g.data("maxlenghtsizey",g.outerHeight()),g.mouseup(function(){(g.outerWidth()!==g.data("maxlenghtsizex")||g.outerHeight()!==g.data("maxlenghtsizey"))&&n(g,f),g.data("maxlenghtsizex",g.outerWidth()),g.data("maxlenghtsizey",g.outerHeight())})),b.appendToParent?(g.parent().append(f),g.parent().css("position","relative")):p.append(f);var e=h(g,o(g));l(e,g,d,f),n(g,f)}var d,f,g=a(this);a(window).resize(function(){f&&n(g,f)}),b.allowOverMax&&(a(this).attr("data-bs-mxl",a(this).attr("maxlength")),a(this).removeAttr("maxlength")),b.showOnReady?g.ready(function(){c()}):g.focus(function(){c()}),g.on("destroyed",function(){f&&f.remove()}),g.on("blur",function(){f&&!b.showOnReady&&f.remove()}),g.on("input",function(){var a=o(g),c=h(g,a),i=!0;return b.validate&&0>c?(e(g,a),i=!1):l(c,g,d,f),("bottom-right-inside"===b.placement||"top-right-inside"===b.placement)&&n(g,f),i})})}})}(jQuery);
|
Reference in New Issue
Block a user