I'm currently developping a mobile app with Ionic framework and AngularJS.
In my login page, the user's account name is loaded on his second connection (and is considered as a password field). However, this user can have multiple accounts. What I've been asked is to show the last three characters of this login.
I would have wanted to use something like a filter, but it doesn't seem to work on inputs ...
Then I've been looking into angularJS directives, and I've been struggling for a few days now, trying many things.
The main problem i'm encountering when doing something like
app.directive("editor", function(){
return {
require: "?ngModel",
scope: true,
template: "<input ng-model='value' ng-change='onChange()'>",
link: function(scope, element, attrs, ngModel){
if (!ngModel) return;
scope.onChange = function(){
/* process coded value here */
ngModel.$setViewValue(scope.value);
};
ngModel.$render = function(){
/* Or process coded value here */
scope.value = ngModel.$modelValue;
};
}
};
});
With this directive, I manage to have my controller value changed, but I would like only to have my view value changed.
I would really appreciate your help, AND your explanations !
I tried to do what you want. And it looks like I got.
Perhaps this is not a complete solution, but it works.
And I have not tested it in mobile browser and Safari.
You may need to modify it a bit.
Live example on jsfiddle.
angular.module('ExampleApp', [])
.controller('firstCtrl', function($scope) {
$scope.sampleItem = {
sampleName: "1234"
};
$scope.change = function(val) {
console.log(val);
}
})
.directive("useModel", ["SelectManager",
function(SelectManager) {
return {
restrict: "A",
scope: {
useModel: "=",
useModelReplacment: "#",
useModelCharacterShow: "=",
useChange: "&"
},
link: function(scope, elem) {
if (!angular.isDefined(scope.useModelCharacterShow))
scope.useModelCharacterShow = 0;
if (scope.useModelReplacment == undefined)
scope.useModelReplacment = "*";
if (scope.useModel == undefined)
scope.useModel = "";
else
elem.val(getMaskValue(scope.useModel));
scope.$watch('useModel', function(val) {
elem.val(getMaskValue(val));
if (scope.useChange)
scope.useChange();
})
function getMaskValue(val) {
var maskVal = "";
for (var i = 0; i < val.length; i++) {
if (scope.useModelCharacterShow > 0) {
if (i >= scope.useModelCharacterShow)
maskVal += scope.useModelReplacment;
else
maskVal += val[i];
}
if (scope.useModelCharacterShow < 0) {
if (i < val.length + scope.useModelCharacterShow)
maskVal += scope.useModelReplacment;
else
maskVal += val[i];
}
if (scope.useModelCharacterShow == 0) {
maskVal += scope.useModelReplacment;
}
}
return maskVal;
}
function onKeyPressed(event) {
if (event.ctrlKey && (event.charCode == 99 || event.charCode == 118 || event.charCode == 97 || event.charCode == 120))
return true;
var key_code = event.charCode;
var input = event.srcElement || event.target;
var ch = String.fromCharCode(key_code);
var start = SelectManager._getSelectionStart(input);
var end = SelectManager._getSelectionEnd(input);
// console.log('start end', start,end);
scope.useModel = scope.useModel.substr(0, start) + ch + scope.useModel.substr(end);
// console.log('inner value onKeyPressed', scope.useModel);
scope.$apply();
//console.log('show value onKeyPressed', maskVal);
//input.value = getMaskValue(scope.useModel);
event.returnValue = false;
SelectManager._setSelection(input, start + 1, start + 1);
return false;
}
function onKeyUp(event) {
if (event.ctrlKey && (event.charCode == 99 || event.charCode == 118 || event.charCode == 97 || event.charCode == 120))
return true;
var key_code = event.keyCode;
if (!(key_code == 13 || key_code == 27 || key_code == 8 || key_code == 46))
return true;
var input = event.srcElement || event.target;
var start = SelectManager._getSelectionStart(input);
var end = SelectManager._getSelectionEnd(input);
// console.log('start end', start,end);
if (key_code == 8 && start == end) {
start--;
}
if (key_code == 46 && start == end) {
//start++;
end++;
}
//console.log('inner value keyup', scope.useModel);
scope.useModel = scope.useModel.substr(0, start) + scope.useModel.substr(end);
//console.log('inner value keyup', scope.useModel);
scope.$apply();
//input.value = getMaskValue(scope.useModel);;
event.returnValue = false;
SelectManager._setSelection(input, start, start);
return event.returnValue;
}
function onKeyDown() {
var key_code = event.keyCode;
if (!(key_code == 13 || key_code == 27 || key_code == 8 || key_code == 46))
return true;
event.returnValue = false;
return event.returnValue;
}
function onPaste(event) {
var input = event.srcElement || event.target;
var ch = "";
if (event.type == "drop") {
event.returnValue = false;
return false
}
if (event.type == "paste")
ch = event.clipboardData.getData("text");
var start = SelectManager._getSelectionStart(input);
var end = SelectManager._getSelectionEnd(input);
// console.log('start end', start,end);
scope.useModel = scope.useModel.substr(0, start) + ch + scope.useModel.substr(end);
// console.log('inner value onKeyPressed', scope.useModel);
scope.$apply();
//input.value = getMaskValue(scope.useModel);
event.returnValue = false;
SelectManager._setSelection(input, start + ch.length, start + ch.length);
return false;
}
elem.on('keypress', onKeyPressed);
elem.on('keyup', onKeyUp);
elem.on('keydown', onKeyDown);
elem.on('paste drop', onPaste);
},
};
}
])
.service('SelectManager', function() {
return {
_getSelectionStart: function(obj) {
var p = 0;
if (obj.selectionStart) {
if (typeof(obj.selectionStart) == "number") p = obj.selectionStart;
} else if (document.selection) {
var r = document.selection.createRange().duplicate();
r.moveEnd("character", obj.value.length);
p = obj.value.lastIndexOf(r.text);
if (r.text == "") p = obj.value.length;
}
return p;
},
_getSelectionEnd: function(obj) {
var p = 0;
if (obj.selectionEnd) {
if (typeof(obj.selectionEnd) == "number") {
p = obj.selectionEnd;
}
} else if (document.selection) {
var r = document.selection.createRange().duplicate();
r.moveStart("character", -obj.value.length);
p = r.text.length;
}
return p;
},
GetXY: function(obj) {
var x = 0;
var y = 0;
while (obj.offsetParent) {
x += obj.offsetLeft;
y += obj.offsetTop;
obj = obj.offsetParent;
}
return {
X: x,
Y: y
};
},
_setSelection: function(obj, a, b) {
if (obj.setSelectionRange) {
obj.focus();
obj.setSelectionRange(a, b);
} else if (obj.createTextRange) {
var r = obj.createTextRange();
r.collapse();
r.moveStart("character", a);
r.moveEnd("character", (b - a));
r.select();
}
},
_Collapse: function(obj) {
var r = obj.createTextRange();
r.collapse();
}
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
<div ng-app="ExampleApp">
<div ng-controller="firstCtrl">
use-model(first three) <input use-model="sampleItem.sampleName" use-change="change(sampleItem.sampleName)" use-Model-Character-Show="3">
<br> use-model(last three) <input use-model="sampleItem.sampleName" use-change="change(sampleItem.sampleName)" use-Model-Character-Show="-3">
<br> ng-model <input ng-model="sampleItem.sampleName">
<pre> {{sampleItem.sampleName}}</pre>
<button ng-click="sampleItem.sampleName='AAAAA'">
set AAAAA
</button>
</div>
</div>
Related
I have a problem with html/javascript code, the code should format numbers taken from keyboard (1 -> 0.01, 2-> 0.12, 3->1.23 ... 6->1,234.56).
It seems that the result of substring and substr is appended twice. In debug it works fine but without debug it doesn't. (1 -> 0.011, 2->1.122, 3->112.233)
It works the same for delete or backspace.
Here is the code:
formatElementAmount = function(f, d) {
d = d.replace(/\./g, '');
d = d.replace(/\,/g, '');
d = parseFloat(d);
d = d + '';
var c = document.getElementById((f.target || f.srcElement).id);
var b = '0123456789';
var a = f.which || f.keyCode;
if (a == 13) { // keycode 13 = enter >
return false;
}
if (a == 9) { // keycode 9 == tab
return true;
}
if (a == 8 || a == 46) { // keyCode 8 == backspace, 46 == delete
if (d.length > 0) {
d = d.substring(0, d.length - 1);
c.value = '';
}
c.value = format(d);
return false;
}
if (c.value.length > 12) {
c.value = '';
c.value = format(d);
return false;
}
if (a >= 96 && a <= 105) { // 96 = numbpad 0, 105 = numpad 9
a = a - 48;
}
key = String.fromCharCode(a);
if (b.indexOf(key) == -1) {
return false;
}
if ((d.length == 0) && (key == '0')) {} else {
d = d + key;
}
c.value = '';
c.value = format(d);
return false;
};
format = function(f) {
if (f.length == 0) {
return '0.00';
}
if (f.length == 1) {
return '0.0' + f;
}
if (f.length == 2) {
return '0.' + f;
}
var a, b, c, d, e;
if (f.length > 2) {
a = '';
for (c = 0, d = f.length - 3; d >= 0; d--) {
if (c == 3) {
a += ',';
c = 0;
}
a += f.charAt(d);
c++;
}
b = '';
len2 = a.length;
for (d = len2 - 1; d >= 0; d--) {
b += a.charAt(d);
}
e = f.substr(f.length - 2);
b += '.' + e;
}
return b;
};
<input id="paymentForm" name="paymentForm" type="text" value="0.00" onkeydown="if(this.value =='') this.value ='0.00';
if (!formatElementAmount(event, this.value)) {
event.stopPropagation();
}"></input>
The problem with your current code is it doesn't prevent the default action of the keyDown event:
if (!formatElementAmount(event, this.value)) {
event.stopPropagation();
event.preventDefault();
}
First of all your should stop using event.stopPropagation() - it doesn't stop default event. Also don't use event.preventDefault() which is not recommended. Instead use return false which disable default event effect and stop insert chars from keyboard.
Also use keypress event instead of keydown (I can't explain why it works because I don't know).
<input id="paymentForm" name="paymentForm" type="text" value="0.00" onkeypress="if(this.value =='') this.value ='0.00';
if (!formatElementAmount(event, this.value)) {
return false;
}"></input>
I tested this fix in Firefox, IE10 & Edge which i actually have on my computer.
I'm trying to implement a customised input that can use left or right arrow key to select the digit and use up/down arrow key to increment/decrement the digit. Here's the code in jsfiddle: http://jsfiddle.net/uk5t3z4d/48/. However, I have two problems:
I cannot add digit using the number pad, the input always stays at X.XX
When I use another function I wrote (parseLocalFloat which is commented out), the output stops displaying anything, and I cannot use the left and right key to select the digit etc.
How can I overcome these two issues? Please shed a light on me, thanks!
HTML
<div class="display" id="out"></div>
<div class="form-group">
<label for="comment">value:</label>
<input class="form-control" type="text" value="0.00" id="in"></input>
</div>
JavaScript
function createSelection(field, start, end) {
if( field.createTextRange ) {
var selRange = field.createTextRange();
selRange.collapse(true);
selRange.moveStart('character', start);
selRange.moveEnd('character', end);
selRange.select();
} else if( field.setSelectionRange ) {
field.setSelectionRange(start, end);
} else if( field.selectionStart ) {
field.selectionStart = start;
field.selectionEnd = end;
}
}
function getLocalDecimalSeparator() {
var n = 1.1;
return n.toLocaleString().substring(1,2);
}
function parseLocalFloat(num) {
return +(num.replace(getLocalDecimalSeparator(), '.'));
}
var inputBox = document.getElementById('in');
//var inputBox = parseLocalFloat(document.getElementByID('in').value);
inputBox.onkeyup = function(){
document.getElementById('out').innerHTML = inputBox.value;
}
$('#in').on("keydown", function(e){
var gotCode = false;
var curPos = this.selectionStart;
var endPos = this.selectionEnd;
if(curPos !== endPos) {
createSelection(this, curPos, curPos+1);
}
// get the position
if(e.keyCode == 37){
curPos--;
gotCode=true;
}
if(e.keyCode == 39){
curPos++;
gotCode=true;
}
var before = $(this).val().substring(0,curPos);
var after = $(this).val().substring(curPos+1);
var cur = Number($(this).val().substring(curPos, curPos+1));
// avoid adding extra stuff
if(curPos < $(this).val().length) {
if(e.keyCode == 38) {
cur++;
if(cur > 9) cur = 0;
$(this).val(before + '' + cur + '' + after);
gotCode=true;
}
if(e.keyCode == 40) {
cur--;
if(cur < 0) cur = 9;
$(this).val(before + '' + cur + '' + after);
gotCode=true;
}
}
if(!gotCode) {
e.preventDefault();
return false;
}
var field = this;
window.setTimeout(function(){
createSelection(field, curPos, curPos+1);
}, 10);
});
as for the "get number keys to work":
as stated you need to add the keys you want to support:
if(e.keyCode >= 48 && e.keyCode <= 57) {
var num = e.keyCode - 48; // 0=48; 9=59
$(this).val(before + '' + num + '' + after);
gotCode = true;
e.preventDefault(); // otherwise a new number is added as well
}
(this needs to come before the if (!gotCode) ... )
as for the customFloat: the the response from Moishe
For #1:
if(!gotCode) {
e.preventDefault();
return false;
}
ensures that if gotCode is false the default event (which in this case is the default keydown event) will not occur.
gotCode only seems to be true if keyCode is equal to 37, 38, 39, or 40 (the arrow keys). You are essentially preventing the other keys (like number keys) from having any effect on the textBox.
You probably would like to enable the number keys (when shift or caps aren't on) and number pad keys.
Additionally, you may want to check that the cur is a number (and not .) before attempting to increment or decrement its value.
You could do:
var isNumberKey = (
( e.keyCode >= 48 //is more than or equal to 0 key
&& e.keyCode <= 57 //is less than or equal to 9 key
&& !e.shiftKey) //shift key or cap key not on
|| ( e.keyCode >= 96 //more than or equal to 0 key in number pad
&& e.keyCode <= 105)); //less than or equal to 9 key in number pad
if(!gotCode && !isNumberKey) { //not arrow key or number key
console.log(e);
e.preventDefault();
return false;
}
For #2:
var inputBox = parseLocalFloat(document.getElementByID('in').value);
is setting inputBox to whatever parseLocalFloat returns which happens to be a number.
This is problematic because you then attempt to attach a keyUp event to that number instead of the inputBox:
inputBox.onkeyup = function(){
document.getElementById('out').innerHTML = inputBox.value;
}
You may want to instead call parseLocalFloat on the number and set the out textBox's value to that:
var inputBox = document.getElementById('in');
inputBox.onkeyup = function(){
document.getElementById('out').innerHTML = parseLocalFloat(inputBox.value);
}
function createSelection(field, start, end) {
if( field.createTextRange ) {
var selRange = field.createTextRange();
selRange.collapse(true);
selRange.moveStart('character', start);
selRange.moveEnd('character', end);
selRange.select();
} else if( field.setSelectionRange ) {
field.setSelectionRange(start, end);
} else if( field.selectionStart ) {
field.selectionStart = start;
field.selectionEnd = end;
}
}
function getLocalDecimalSeparator() {
var n = 1.1;
return n.toLocaleString().substring(1,2);
}
function parseLocalFloat(num) {
return +(num.replace(getLocalDecimalSeparator(), '.'));
}
var inputBox = document.getElementById('in');
// var inputBox = parseLocalFloat(document.getElementByID('in').value);
inputBox.onkeyup = function(){
document.getElementById('out').innerHTML = parseLocalFloat(inputBox.value);
}
$('#in').on("keydown", function(e){
var gotCode = false;
var curPos = this.selectionStart;
var endPos = this.selectionEnd;
if(curPos !== endPos) {
createSelection(this, curPos, curPos+1);
}
// get the position
if(e.keyCode == 37){
curPos--;
gotCode=true;
}
if(e.keyCode == 39){
curPos++;
gotCode=true;
}
var $thisVal = $(this).val();
var before = $thisVal.substring(0,curPos);
var after = $thisVal.substring(curPos+1);
var cur = Number($thisVal.substring(curPos, curPos+1));
// avoid adding extra stuff
if(curPos < $thisVal.length && !isNaN(cur)) {
if(e.keyCode == 38) {
cur++;
if(cur > 9) cur = 0;
$(this).val(before + '' + cur + '' + after);
gotCode=true;
}
if(e.keyCode == 40) {
cur--;
if(cur < 0) cur = 9;
$(this).val(before + '' + cur + '' + after);
gotCode=true;
}
}
var isNumberKey = ((e.keyCode >= 48 && e.keyCode <= 57 && [16, 20].indexOf(e.keyCode) == -1 && !e.shiftKey) || (e.keyCode >= 96 && e.keyCode <= 105));
if(!gotCode && !isNumberKey) {
console.log(e);
e.preventDefault();
return false;
}
var field = this;
window.setTimeout(function(){
createSelection(field, curPos, curPos+1);
}, 10);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="display" id="out"></div>
<div class="form-group">
<label for="comment">value:</label>
<input class="form-control" type="text" value="0.00" id="in"></input>
</div>
I'd like to have the phone number field on this website only accept numbers or digits. I do not have access to edit the HTML code, so can this be done with jQuery by targeting the field's ID? If so, how can it be done?
I've already tried a few suggestions on this site and none have worked so far.
Thanks in advance for any assistance!
Similar to Jeroen's solution, here's one that is a little cleaner because rather than replacing the invalid input, it completely prevents it.
$('#nbr').on('keypress', function(ev) {
var keyCode = window.event ? ev.keyCode : ev.which;
//codes for 0-9
if (keyCode < 48 || keyCode > 57) {
//codes for backspace, delete, enter
if (keyCode != 0 && keyCode != 8 && keyCode != 13 && !ev.ctrlKey) {
ev.preventDefault();
}
}
});
http://jsfiddle.net/PUQGQ/
Use jQuery to hook into the textfield's keypress event. In the handler, read the textfield's value and filter out everything that you don't want using a regex replace.
Update: untested example to illustrate:
jQuery("#myPhonefield").keypress(function(){
var value = jQuery(this).val();
value = value.replace(/[^0-9]+/g, '');
jQuery(this).val(value);
});
You can use jquery's keypress as recommended by Jeroen; however, I would recommend doing it without using a regex. Something along these lines should work for you:
$('#test').on('keypress', function(evt) {
var charCode = (evt.which) ? evt.which : event.keyCode;
return !(charCode != 46 && charCode > 31 && (charCode < 48 || charCode > 57));
});
Live DEMO
To handle pasting, you can perform a regular expression check on blur or focusout:
$('#test').on('focusout', function() {
var value = $(this).val();
$(this).val(value.replace(/[^0-9]/g, ''));
});
Live Demo
http://jsfiddle.net/charlescarver/hTMdF/
$("input[type=submit]").click(function() {
var regex = /\d/g;
var text = $("input[type=text]").val();
if (regex(text)) {
alert("yes");
}
});
This will alert you if a number is found.
Here is my solution (It also validates data/values copy&pasted):
function InputValidator(input, validationType, validChars) {
if (input === null || input.nodeType !== 1 || input.type !== 'text' && input.type !== 'number')
throw ('Please specify a valid input');
if (!(InputValidator.ValidationType.hasOwnProperty(validationType) || validationType))
throw 'Please specify a valid Validation type';
input.InputValidator = this;
input.InputValidator.ValidCodes = [];
input.InputValidator.ValidCodes.Add = function (item) {
this[this.length] = item;
};
input.InputValidator.ValidCodes.hasValue = function (value, target) {
var i;
for (i = 0; i < this.length; i++) {
if (typeof (target) === 'undefined') {
if (this[i] === value)
return true;
}
else {
if (this[i][target] === value)
return true;
}
}
return false;
};
var commandKeys = {
'backspace': 8,
'tab': 9,
'enter': 13,
'shift': 16,
'ctrl': 17,
'alt': 18,
'pause/break': 19,
'caps lock': 20,
'escape': 27,
'page up': 33,
'page down': 34,
'end': 35,
'home': 36,
'left arrow': 37,
'up arrow': 38,
'right arrow': 39,
'down arrow': 40,
'insert': 45,
'delete': 46,
'left window key': 91,
'right window key': 92,
'select key': 93,
/*creates Confusion in IE */
//'f1': 112,
//'f2': 113,
//'f3': 114,
//'f4': 115,
//'f5': 116,
//'f6': 117,
//'f7': 118,
//'f8': 119,
//'f9': 120,
//'f10': 121,
//'f11': 122,
//'f12': 123,
'num lock': 144,
'scroll lock': 145,
};
commandKeys.hasValue = function (value) {
for (var a in this) {
if (this[a] === value)
return true;
}
return false;
};
function getCharCodes(arrTarget, chars) {
for (var i = 0; i < chars.length; i++) {
arrTarget.Add(chars[i].charCodeAt(0));
}
}
function triggerEvent(name, element) {
if (document.createEventObject) {
// dispatch for IE
var evt = document.createEventObject();
return element.fireEvent('on' + name, evt)
}
else {
// dispatch for firefox + others
var evt = document.createEvent("HTMLEvents");
evt.initEvent(name, true, true); // event type,bubbling,cancelable
return !element.dispatchEvent(evt);
}
}
if (validationType == InputValidator.ValidationType.Custom) {
if (typeof (validChars) === 'undefined')
throw 'Please add valid characters';
getCharCodes(input.InputValidator.ValidCodes, validChars);
}
else if (validationType == InputValidator.ValidationType.Decimal) {
getCharCodes(input.InputValidator.ValidCodes, '0123456789.');
}
else if (validationType == InputValidator.ValidationType.Numeric) {
getCharCodes(input.InputValidator.ValidCodes, '0123456789');
}
input.InputValidator.ValidateChar = function (c) {
return this.ValidCodes.hasValue(c.charCodeAt(0));
}
input.InputValidator.ValidateString = function (s) {
var arr = s.split('');
for (var i = 0; i < arr.length; i++) {
if (!this.ValidateChar(arr[i])) {
arr[i] = '';
}
}
return arr.join('');
}
function bindEvent(el, eventName, eventHandler) {
if (el.addEventListener) {
el.addEventListener(eventName, eventHandler, false);
} else if (el.attachEvent) {
el.attachEvent('on' + eventName, eventHandler);
}
}
function getCaretPosition(i) {
if (!i) return;
if ('selectionStart' in i) {
return i.selectionStart;
}
else {
if (document.selection) {
var sel = document.selection.createRange();
var selLen = document.selection.createRange().text.length;
sel.moveStart('character', -i.value.length);
return sel.text.length - selLen;
}
}
}
function setCursor(node, pos) {
var node = (typeof (node) === "string" || node instanceof String) ? document.getElementById(node) : node;
if (!node) {
return false;
}
else if (node.createTextRange) {
var textRange = node.createTextRange();
textRange.collapse(true);
textRange.moveEnd(pos);
textRange.moveStart(pos);
textRange.select();
return true;
} else if (node.setSelectionRange) {
node.setSelectionRange(pos, pos);
return true;
}
return false;
}
function validateActive() {
if (input.isActive) {
var pos = getCaretPosition(input);
var arr = input.value.split('');
for (var i = 0; i < arr.length; i++) {
if (!this.ValidateChar(arr[i])) {
arr[i] = '';
if (pos > i)
pos--;
}
}
console.log('before : ' + input.value);
input.value = arr.join('');
console.log('after : ' + input.value, input);
setCursor(input, pos);
setTimeout(validateActive, 10);
}
}
bindEvent(input, 'keypress', function (e) {
var evt = e || window.event;
var charCode = evt.which || evt.keyCode;
if (!input.InputValidator.ValidCodes.hasValue(charCode) && !commandKeys.hasValue(charCode)) {
if (evt.preventDefault) {
evt.preventDefault();
evt.stopPropagation();
}
return false;
}
});
bindEvent(input, 'keyup', function (e) {
var evt = e || window.event;
var charCode = evt.which || evt.keyCode;
if (!input.InputValidator.ValidCodes.hasValue(charCode) && !commandKeys.hasValue(charCode)) {
if (evt.preventDefault) {
evt.preventDefault();
evt.stopPropagation();
}
return false;
}
});
bindEvent(input, 'change', function (e) {
var dt = input.value;
input.value = input.InputValidator.ValidateString(input.value);
if (input.value !== dt)
triggerEvent('change', input);
});
bindEvent(input, 'blur', function (e) {
var dt = input.value;
input.value = input.InputValidator.ValidateString(input.value);
input.isActive = false;
if (input.value !== dt)
triggerEvent('blur', input);
});
bindEvent(input, 'paste', function (e) {
var evt = e || window.event;
var svt = input.value;
if (evt && evt.clipboardData && evt.clipboardData.getData) {// Webkit - get data from clipboard, put into editdiv, cleanup, then cancel event
if (/text\/html/.test(evt.clipboardData.types)) {
var dt = evt.clipboardData.getData('text/html');
input.value = input.InputValidator.ValidateString(dt);
if (input.value !== dt)
triggerEvent('change', input);
}
else if (/text\/plain/.test(e.clipboardData.types)) {
var dt = evt.clipboardData.getData('text/plain');
input.value = input.InputValidator.ValidateString(dt);
if (input.value !== dt)
triggerEvent('change', input);
}
else {
input.value = '';
}
waitforpastedata(input, svt);
if (e.preventDefault) {
e.stopPropagation();
e.preventDefault();
}
return false;
}
else {// Everything else - empty editdiv and allow browser to paste content into it, then cleanup
input.value = '';
waitforpastedata(input, svt);
return true;
}
});
bindEvent(input, 'select', function (e) {
var evt = e || window.event;
if (evt.preventDefault) {
evt.preventDefault();
evt.stopPropagation();
}
return false;
});
bindEvent(input, 'selectstart', function (e) {
var evt = e || window.event;
if (evt.preventDefault) {
evt.preventDefault();
evt.stopPropagation();
}
return false;
});
/* no need to validate wile active,
removing F keys fixed IE compatability*/
//bindEvent(input, 'fucus', function (e) {
// input.isActive = true;
// validateActive();
//});
//validate current value of the textbox
{
var dt = input.value;
input.value = input.InputValidator.ValidateString(input.value);
//trigger event to indicate value has changed
if (input.value !== dt)
triggerEvent('change', input);
}
function waitforpastedata(elem, savedcontent) {
if (elem.value !== '') {
var dt = input.value;
elem.value = elem.InputValidator.ValidateString(elem.value);
if (input.value !== dt)
triggerEvent('change', input);
}
else {
var that = {
e: elem,
s: savedcontent
}
that.callself = function () {
waitforpastedata(that.e, that.s)
}
setTimeout(that.callself, 10);
}
}
}
InputValidator.ValidationType = new (function (types) {
for (var i = 0; i < types.length; i++) {
this[types[i]] = types[i];
}
})(['Numeric', 'Custom', 'Decimal']);
To apply it to an input, do the following :
new InputValidator(document.getElementById('txtValidate'), InputValidator.ValidationType.Decimal);/* Numeric or Custom */
If you specify Custom as the validation type you have to specify the valid characters.
eg :
new InputValidator(document.getElementById('txtValidate'), InputValidator.ValidationType.Custom,'1234abc');
Something really odd going on here, and I have gone round in circles trying to figure out what is going on...I have a couple of input boxes, with onchange events firing for them, the event being loaded with a JS function that takes the value ( name of another item ) and actions the function accordingly. Only thing is, when the value of the string arrives at the other function, it has somehow been assigned a numeric value, specifically that of the input box.
My php that helps build the form:
$filterfield = '"p_delweek"';
print "<span class='filter'>Del Week<input class='menulink spin-button' id='weekno' type='text' value='".$weekno."' onKeyUp='doFilter($filterfield)' onChange='doFilter($filterfield)' data-filtered='0'/><input type='button' value='Clear' onClick='doUnfilter()'></span>";
$filterfield = '"p_seedweek"';
print "<span class='filter'>Sow Week<input class='menulink spin-button' id='sowweekno' type='text' value='".$weekno."' onKeyUp='doFilter($filterfield)' onChange='doFilter($filterfield)' data-filtered='0'/><input type='button' value='Clear' onClick='doUnfilter()'></span>";
Resulting HTML in source:
<span class="filter">Del Week<input style="width: 50px; height: 22px;" class="menulink spin-button smartspinner" id="weekno" value="26" onkeyup='doFilter("p_delweek")' onchange='doFilter("p_delweek")' data-filtered="0" type="text"><input value="Clear" onclick="doUnfilter()" type="button"></span><span class="filter">Sow Week<input style="width: 50px; height: 22px;" class="menulink spin-button smartspinner" id="sowweekno" value="26" onkeyup='doFilter("p_seedweek")' onchange='doFilter("p_seedweek")' data-filtered="0" type="text"><input value="Clear" onclick="doUnfilter()" type="button"></span>
Javascript function that is called:
function doFilter(filterfield) {
console.log("DoFilter:"+filterfield);
var filterInfo=[
{
fieldName : filterfield,
logic : "equal",
value : Sigma.Util.getValue("weekno")
}
]
// the next lines action the filtering
var grid=Sigma.$grid("myGrid1");
console.log("filterinfo="+filterInfo);
var rowNOs=grid.applyFilter(filterInfo);
}
It all goes fine until we get to the console.log("DoFilter:"+filterfield) , which results in DoFilter:25; 25 happens to be the value of the input box.
How is it grabbing that value? How to pass the real one?
TBH — I'm not sure if I got what you're after. However, if you must call a function inline (I recommend that you don’t), you can pass a reference to the input field as parameter and make it available in the methods’s body:
<input onchange="doFilter('p_delweek', this)" type="text">
function doFilter(filterfield, field) {
console.log(filterfield);
// field is a reference to the input field, hence
console.log(field.value);
// will print the current value for this field
}
This is not the answer, this file is the problem:
(function($) {
$.fn.extend({
spinit: function(options) {
var settings = $.extend({ min: 0, max: 100, initValue: 0, callback: doFilter, stepInc: 1, pageInc: 10, width: 50, height: 15, btnWidth: 10, mask: '' }, options);
return this.each(function() {
var UP = 38;
var DOWN = 40;
var PAGEUP = 33;
var PAGEDOWN = 34;
var mouseCaptured = false;
var mouseIn = false;
var interval;
var direction = 'none';
var isPgeInc = false;
var value = Math.max(settings.initValue, settings.min);
var el = $(this).val(value).css('width', (settings.width) + 'px').css('height', settings.height + 'px').addClass('smartspinner');
raiseCallback(value);
if (settings.mask != '') el.val(settings.mask);
$.fn.reset = function(val) {
if (isNaN(val)) val = 0;
value = Math.max(val, settings.min);
$(this).val(value);
raiseCallback(value);
};
function setDirection(dir) {
direction = dir;
isPgeInc = false;
switch (dir) {
case 'up':
setClass('up');
break;
case 'down':
setClass('down');
break;
case 'pup':
isPgeInc = true;
setClass('up');
break;
case 'pdown':
isPgeInc = true;
setClass('down');
break;
case 'none':
setClass('');
break;
}
}
el.focusin(function() {
el.val(value);
});
el.click(function(e) {
mouseCaptured = true;
isPgeInc = false;
clearInterval(interval);
onValueChange();
});
el.mouseenter(function(e) {
el.val(value);
});
el.mousemove(function(e) {
if (e.pageX > (el.offset().left + settings.width) - settings.btnWidth - 4) {
if (e.pageY < el.offset().top + settings.height / 2)
setDirection('up');
else
setDirection('down');
}
else
setDirection('none');
});
el.mousedown(function(e) {
isPgeInc = false;
clearInterval(interval);
interval = setTimeout(onValueChange, 250);
});
el.mouseup(function(e) {
mouseCaptured = false;
isPgeInc = false;
clearInterval(interval);
});
el.mouseleave(function(e) {
setDirection('none');
if (settings.mask != '') el.val(settings.mask);
}); el.keydown(function(e) {
switch (e.which) {
case UP:
setDirection('up');
onValueChange();
break; // Arrow Up
case DOWN:
setDirection('down');
onValueChange();
break; // Arrow Down
case PAGEUP:
setDirection('pup');
onValueChange();
break; // Page Up
case PAGEDOWN:
setDirection('pdown');
onValueChange();
break; // Page Down
default:
setDirection('none');
break;
}
});
el.keyup(function(e) {
setDirection('none');
});
el.keypress(function(e) {
if (el.val() == settings.mask) el.val(value);
var sText = getSelectedText();
if (sText != '') {
sText = el.val().replace(sText, '');
el.val(sText);
}
if (e.which >= 48 && e.which <= 57) {
var temp = parseFloat(el.val() + (e.which - 48));
if (temp >= settings.min && temp <= settings.max) {
value = temp;
raiseCallback(value);
}
else {
e.preventDefault();
}
}
});
el.blur(function() {
if (settings.mask == '') {
if (el.val() == '')
el.val(settings.min);
}
else {
el.val(settings.mask);
}
});
el.bind("mousewheel", function(e) {
if (e.wheelDelta >= 120) {
setDirection('down');
onValueChange();
}
else if (e.wheelDelta <= -120) {
setDirection('up');
onValueChange();
}
e.preventDefault();
});
if (this.addEventListener) {
this.addEventListener('DOMMouseScroll', function(e) {
if (e.detail > 0) {
setDirection('down');
onValueChange();
}
else if (e.detail < 0) {
setDirection('up');
onValueChange();
}
e.preventDefault();
}, false);
}
function raiseCallback(val) {
if (settings.callback != null) settings.callback(val);
}
function getSelectedText() {
var startPos = el.get(0).selectionStart;
var endPos = el.get(0).selectionEnd;
var doc = document.selection;
if (doc && doc.createRange().text.length != 0) {
return doc.createRange().text;
} else if (!doc && el.val().substring(startPos, endPos).length != 0) {
return el.val().substring(startPos, endPos);
}
return '';
}
function setValue(a, b) {
if (a >= settings.min && a <= settings.max) {
value = b;
} el.val(value);
}
function onValueChange() {
if (direction == 'up') {
value += settings.stepInc;
if (value > settings.max) value = settings.max;
setValue(parseFloat(el.val()), value);
}
if (direction == 'down') {
value -= settings.stepInc;
if (value < settings.min) value = settings.min;
setValue(parseFloat(el.val()), value);
}
if (direction == 'pup') {
value += settings.pageInc;
if (value > settings.max) value = settings.max;
setValue(parseFloat(el.val()), value);
}
if (direction == 'pdown') {
value -= settings.pageInc;
if (value < settings.min) value = settings.min;
setValue(parseFloat(el.val()), value);
}
raiseCallback(value);
}
function setClass(name) {
el.removeClass('up').removeClass('down');
if (name != '') el.addClass(name);
}
});
}
});
})(jQuery);
Why and where does this alter the passing value of a function attached to the < INPUT > ?
Are there any good number picker for jquery (or standalone js)?
I would like a number picker where there is a max and min number that the user can choose from. Also, it have other options such as displaying odd number or even number or prime number or a range of number whereby some numbers in between are skipped.
Using a select to do this you can create an array with the numbers to skip and do a for loop to write the options:
int minNumber = 0;
int maxNumber = 10;
int[] skipThese = { 5, 7 };
for (int i = minNumber; i <= maxNumber; i++)
{
if(!skipThese.Contains(i)) Response.Write(String.Concat("<option value=\"", i, "\">", i, "</option>"));
}
You can do this with razor or any other way to output the HTML.
You can also do this with jQuery, dynamicaly, following the same idea:
$(document).ready(function() {
var minNumber = 0;
var maxNumber = 10;
var skipThese = [5, 7];
for (var i = minNumber; i <= maxNumber; i++) {
if ($.inArray(i, skipThese) == -1) $('#selectListID').append("<option value=\"" + i + "\">" + i + "</option>");
}
});
Edit:
Or you can use the C# code above in an aspx page and load it with AJAX from the page:
Create a select box in the page:
<select name="numPicker" id="numPicker">
<option>Loading...</option>
</select>
In a script in this page you could use jQuery's ajax() to fetch the data and populate the <select>:
$(document).ready(function() {
var numPickerSelect = $("#numPicker");
$.ajax({
url: 'url/to/page.aspx',
type: 'post'
success: function(data) {
numPickerSelect.find('option').remove(); // Remove the options in the select field
numPickerSelect.append(data); // Load the content generated by the server into the select field
},
error: function() {
alert('An error has ocurred!');
}
});
//Or use this (not sure if will work)
numPickerSelect.load("url/to/page.aspx");
});
I have used this. You should be able to modify to add extra options such as min and max fairly easily.
// Make a control only accept numeric input
// eg, $("#myedit").numeric()
// $("#myedit").numeric({alow: ' ,.'})
// $("#myedit").numeric({decimals: 2})
(function($) {
$.fn.alphanumeric = function(p) {
if (p == 'destroy') {
$(this).unbind('keypress');
$(this).unbind('blur');
return;
}
p = $.extend({
ichars: "!##$%^&*()+=[]\\\';,/{}|\":<>?~`.- ",
nchars: "",
allow: "",
decimals: null
}, p);
return this.each
(
function() {
if (p.nocaps) p.nchars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (p.allcaps) p.nchars += "abcdefghijklmnopqrstuvwxyz";
s = p.allow.split('');
for (i = 0; i < s.length; i++) if (p.ichars.indexOf(s[i]) != -1) s[i] = "\\" + s[i];
p.allow = s.join('|');
var reg = new RegExp(p.allow, 'gi');
var ch = p.ichars + p.nchars;
ch = ch.replace(reg, '');
var dp = p.decimals;
var isInteger = function(val) {
var objRegExp = /(^-?\d\d*$)/;
return objRegExp.test(val);
};
var isNumeric = function(val) {
// If the last digit is a . then add a 0 before testing so if they type 25. it will be accepted
var lastChar = val.substring(val.length - 1);
if (lastChar == ".") val = val + "0";
var objRegExp = new RegExp("^\\s*-?(\\d+(\\.\\d{1," + dp + "})?|\\.\\d{1," + dp + "})\\s*$", "g");
if (dp == -1)
objRegExp = new RegExp("^\\s*-?(\\d+(\\.\\d{1,25})?|\\.\\d{1,25})\\s*$", "g");
var result = objRegExp.test(val);
return result;
};
$(this).blur(function(e) {
var text = $(this).val();
if (dp != null) {
if (dp == 0) {
if (!isInteger(text)) {
$(this).val('');
e.preventDefault();
}
}
else {
if (!isNumeric(text)) {
$(this).val('');
e.preventDefault();
}
}
} else {
var c = text.split('')
for (i = 0; i < text.length; i++) {
if (ch.indexOf(c[i]) != -1) {
$(this).val('');
e.preventDefault();
};
}
}
});
$(this).keypress
(
function(e) {
switch (e.which) {
//Firefox fix, for ignoring specific presses
case 8: // backspace key
return true;
case 46: // delete key
return true;
};
if (dp != null) {
if (e.which == 32) { e.preventDefault(); return false; }
var range = getRange(this);
var typed = String.fromCharCode(e.which);
var text = $(this).val().substr(0, range.start) + typed + $(this).val().substr(range.start);
if (dp == 0) {
if (!isInteger(text)) e.preventDefault();
}
else {
if (!isNumeric(text)) e.preventDefault();
}
return;
}
if (!e.charCode) k = String.fromCharCode(e.which);
else k = String.fromCharCode(e.charCode);
if (ch.indexOf(k) != -1) e.preventDefault();
if (e.ctrlKey && k == 'v') e.preventDefault();
}
);
$(this).bind('contextmenu', function() { return false });
}
);
};
$.fn.numeric = function(p) {
if (p == 'destroy') {
$(this).unbind('keypress');
$(this).unbind('blur');
return;
}
var az = "abcdefghijklmnopqrstuvwxyz";
az += az.toUpperCase();
var opts = {};
if (!isNaN(p)) {
opts = $.extend({
nchars: az
}, { decimals: p });
} else {
opts = $.extend({
nchars: az
}, p);
}
return this.each(function() {
$(this).alphanumeric(opts);
}
);
};
$.fn.integer = function(p) {
if (p == 'destroy') {
$(this).unbind('keypress');
$(this).unbind('blur');
return;
}
var az = "abcdefghijklmnopqrstuvwxyz";
az += az.toUpperCase();
p = {
nchars: az,
allow: '-',
decimals: 0
};
return this.each(function() {
$(this).alphanumeric(p);
}
);
};
$.fn.alpha = function(p) {
if (p == 'destroy') {
$(this).unbind('keypress');
$(this).unbind('blur');
return;
}
var nm = "1234567890";
p = $.extend({
nchars: nm
}, p);
return this.each(function() {
$(this).alphanumeric(p);
}
);
};
})(jQuery);