View Issue Details

IDProjectCategoryView StatusLast Update
04652User patchesSurvey designpublic2010-12-14 13:02
Reporteruser9586 
Assigned Toc_schmitz 
PrioritynormalSeverityminor 
Status closedResolutionfixed 
Product Version1.90 
Target VersionFixed in Version1.91 
Summary04652: Keyboard-less operation through JS keypad
DescriptionAs described before in http://sourceforge.net/mailarchive/message.php?msg_name=20100908124843.af9a493a.yuri.delia%40eurac.edu , we're using limesurvey on tablet-pcs in a setting similar to paper questionnaires.

These tablet PCs don't have a keyboard or numeric keypad. We designed our questionnaires so that there's mostly no need to enter text or numbers (we used sliders, options, etc).

There are still rare cases where entering an arbitrary number or a very short text is desiderable though, and should be possible without having a keyboard.

This patch adds a new per-survey setting called 'Keyboard-less operation', which adds a virtual keypad, or virtual keyboard to 'Numerical/Multiple numerical/Short text/Multiple short text' question types (we don't use short text ourselves, but it was easy enough to implement to include it anyway). By differentiating the keypad, based on the question type, the UI is superior than using a system-wide virtual keypad.

The patch itself uses a jquery plugin called 'Keypad', by Keith Wood (http://keith-wood.name/keypad.html), which is dual-licensed MIT/GPL and supports multiple language translations and layouts.
Additional InformationNotably, the 'token' can also be entered with a virtual keyboard.
TagsNo tags attached.
Complete LimeSurvey version number (& build)9114

Relationships

Activities

c_schmitz

2010-10-11 23:55

administrator   ~13089

Can you please provide the patch as a subversion patch (svn diff) against our 1.91 development version at the subversion branch at :
https://limesurvey.svn.sourceforge.net/svnroot/limesurvey/source/limesurvey_dev

Thank you!

DenisChenu

2010-11-07 16:11

developer   ~13450

Maybe it's a good idea to add this in a template version ?

I think it can be add in default-kbless template. some js/css file and template.js modification.

c_schmitz

2010-11-07 20:00

administrator   ~13451

rather not. I want don't want to maintain another template. Also having this feature configurable from the UI is superior than having it in the template.

user9586

2010-11-29 11:52

  ~13661

Patch updated.

user9586

2010-11-29 11:54

 

svn-patch-2.diff (46,430 bytes)
Index: scripts/jquery/jquery.keypad.min.js
===================================================================
--- scripts/jquery/jquery.keypad.min.js	(revision 0)
+++ scripts/jquery/jquery.keypad.min.js	(revision 0)
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/keypad.html
+   Keypad field entry extension for jQuery v1.3.0.
+   Written by Keith Wood (kbwood{at}iinet.com.au) August 2008.
+   Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and 
+   MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. 
+   Please attribute the author if you use it. */
+(function($){var t='keypad';function Keypad(){this.BS='\x08';this.DEL='\x7F';this.EN='\x0D';this._curInst=null;this._disabledFields=[];this._keypadShowing=false;this.regional=[];this.regional['']={buttonText:'...',buttonStatus:'Open the keypad',closeText:'Close',closeStatus:'Close the keypad',clearText:'Clear',clearStatus:'Erase all the text',backText:'Back',backStatus:'Erase the previous character',enterText:'Enter',enterStatus:'Carriage return',shiftText:'Shift',shiftStatus:'Toggle upper/lower case characters',alphabeticLayout:this.qwertyAlphabetic,fullLayout:this.qwertyLayout,isAlphabetic:this.isAlphabetic,isNumeric:this.isNumeric,isRTL:false};this._defaults={showOn:'focus',buttonImage:'',buttonImageOnly:false,showAnim:'show',showOptions:{},duration:'normal',appendText:'',useThemeRoller:false,keypadClass:'',prompt:'',layout:['123'+this.CLOSE,'456'+this.CLEAR,'789'+this.BACK,this.SPACE+'0'],separator:'',target:null,keypadOnly:true,randomiseAlphabetic:false,randomiseNumeric:false,randomiseOther:false,randomiseAll:false,beforeShow:null,onKeypress:null,onClose:null};$.extend(this._defaults,this.regional['']);this.mainDiv=$('<div class="'+this._mainDivClass+'" style="display: none;"></div>')}var u='\x00';var v='\x01';var w='\x02';var x='\x03';var y='\x04';var z='\x05';var A='\x06';var B='\x07';$.extend(Keypad.prototype,{CLOSE:u,CLEAR:v,BACK:w,SHIFT:x,SPACE_BAR:y,SPACE:z,HALF_SPACE:A,ENTER:B,qwertyAlphabetic:['qwertyuiop','asdfghjkl','zxcvbnm'],qwertyLayout:['!@#$%^&*()_='+A+z+u,A+'`~[]{}<>\\|/'+z+'789','qwertyuiop\'"'+A+'456',A+'asdfghjkl;:'+z+'123',z+'zxcvbnm,.?'+z+A+'-0+',z+x+y+B+A+w+v],markerClassName:'hasKeypad',_mainDivClass:'keypad-popup',_inlineClass:'keypad-inline',_appendClass:'keypad-append',_triggerClass:'keypad-trigger',_disableClass:'keypad-disabled',_inlineEntryClass:'keypad-keyentry',_coverClass:'keypad-cover',setDefaults:function(a){extendRemove(this._defaults,a||{});return this},_attachKeypad:function(a,b){var c=(a.nodeName.toLowerCase()!='input'&&a.nodeName.toLowerCase()!='textarea');var d={_inline:c,_mainDiv:(c?$('<div class="'+this._inlineClass+'"></div>'):$.keypad.mainDiv),ucase:false};d.settings=$.extend({},b||{});this._setInput(a,d);this._connectKeypad(a,d);if(c){$(a).append(d._mainDiv).bind('click.keypad',function(){d._input.focus()});this._updateKeypad(d)}else if($(a).is(':disabled')){this._disableKeypad(a)}},_setInput:function(a,b){b._input=$(!b._inline?a:this._get(b,'target')||'<input type="text" class="'+this._inlineEntryClass+'" disabled="disabled"/>');if(b._inline){a=$(a);a.find('input').remove();if(!this._get(b,'target')){a.append(b._input)}}},_connectKeypad:function(d,e){var f=$(d);if(f.hasClass(this.markerClassName)){return}var g=this._get(e,'appendText');var h=this._get(e,'isRTL');if(g){f[h?'before':'after']('<span class="'+this._appendClass+'">'+g+'</span>')}if(!e._inline){var i=this._get(e,'showOn');if(i=='focus'||i=='both'){f.focus(this._showKeypad).keydown(this._doKeyDown)}if(i=='button'||i=='both'){var j=this._get(e,'buttonText');var k=this._get(e,'buttonStatus');var l=this._get(e,'buttonImage');var m=$(this._get(e,'buttonImageOnly')?$('<img src="'+l+'" alt="'+k+'" title="'+k+'"/>'):$('<button type="button" title="'+k+'"></button>').html(l==''?j:$('<img src="'+l+'" alt="'+k+'" title="'+k+'"/>')));f[h?'before':'after'](m);m.addClass(this._triggerClass).click(function(){if($.keypad._keypadShowing&&$.keypad._lastField==d){$.keypad._hideKeypad()}else{$.keypad._showKeypad(d)}return false})}}e.saveReadonly=f.attr('readonly');f.addClass(this.markerClassName).attr('readonly',(this._get(e,'keypadOnly')?'readonly':'')).bind('setData.keypad',function(a,b,c){e.settings[b]=c}).bind('getData.keypad',function(a,b){return this._get(e,b)});$.data(d,t,e)},_destroyKeypad:function(a){var b=$(a);if(!b.hasClass(this.markerClassName)){return}var c=$.data(a,t);if(this._curInst==c){this._hideKeypad()}b.siblings('.'+this._appendClass).remove().end().siblings('.'+this._triggerClass).remove().end().prev('.'+this._inlineEntryClass).remove();b.empty().unbind('focus',this._showKeypad).removeClass(this.markerClassName).attr('readonly',c.saveReadonly);$.removeData(c._input[0],t);$.removeData(a,t)},_enableKeypad:function(b){var c=$(b);if(!c.hasClass(this.markerClassName)){return}var d=b.nodeName.toLowerCase();if(d=='input'||d=='textarea'){b.disabled=false;c.siblings('button.'+this._triggerClass).each(function(){this.disabled=false}).end().siblings('img.'+this._triggerClass).css({opacity:'1.0',cursor:''})}else if(d=='div'||d=='span'){c.children('.'+this._disableClass).remove();var e=$.data(b,t);e._mainDiv.find('button').attr('disabled','')}this._disabledFields=$.map(this._disabledFields,function(a){return(a==b?null:a)})},_disableKeypad:function(b){var c=$(b);if(!c.hasClass(this.markerClassName)){return}var d=b.nodeName.toLowerCase();if(d=='input'||d=='textarea'){b.disabled=true;c.siblings('button.'+this._triggerClass).each(function(){this.disabled=true}).end().siblings('img.'+this._triggerClass).css({opacity:'0.5',cursor:'default'})}else if(d=='div'||d=='span'){var e=c.children('.'+this._inlineClass);var f=e.offset();var g={left:0,top:0};e.parents().each(function(){if($(this).css('position')=='relative'){g=$(this).offset();return false}});c.prepend('<div class="'+this._disableClass+'" style="width: '+e.outerWidth()+'px; height: '+e.outerHeight()+'px; left: '+(f.left-g.left)+'px; top: '+(f.top-g.top)+'px;"></div>');var h=$.data(b,t);h._mainDiv.find('button').attr('disabled','disabled')}this._disabledFields=$.map(this._disabledFields,function(a){return(a==b?null:a)});this._disabledFields[this._disabledFields.length]=b},_isDisabledKeypad:function(a){return(a&&$.inArray(a,this._disabledFields)>-1)},_changeKeypad:function(a,b,c){var d=b||{};if(typeof b=='string'){d={};d[b]=c}var e=$.data(a,t);if(e){if(this._curInst==e){this._hideKeypad()}extendRemove(e.settings,d);this._setInput($(a),e);this._updateKeypad(e)}},_showKeypad:function(b){b=b.target||b;if($.keypad._isDisabledKeypad(b)||$.keypad._lastField==b){return}var c=$.data(b,t);$.keypad._hideKeypad(null,'');$.keypad._lastField=b;$.keypad._pos=$.keypad._findPos(b);$.keypad._pos[1]+=b.offsetHeight;var d=false;$(b).parents().each(function(){d|=$(this).css('position')=='fixed';return!d});if(d&&$.browser.opera){$.keypad._pos[0]-=document.documentElement.scrollLeft;$.keypad._pos[1]-=document.documentElement.scrollTop}var e={left:$.keypad._pos[0],top:$.keypad._pos[1]};$.keypad._pos=null;c._mainDiv.css({position:'absolute',display:'block',top:'-1000px',width:($.browser.opera?'1000px':'auto')});$.keypad._updateKeypad(c);e=$.keypad._checkOffset(c,e,d);c._mainDiv.css({position:(d?'fixed':'absolute'),display:'none',left:e.left+'px',top:e.top+'px'});var f=$.keypad._get(c,'showAnim');var g=$.keypad._get(c,'duration');g=(g=='normal'&&$.ui&&$.ui.version>='1.8'?'_default':g);var h=function(){$.keypad._keypadShowing=true;var a=$.keypad._getBorders(c._mainDiv);c._mainDiv.find('iframe.'+$.keypad._coverClass).css({left:-a[0],top:-a[1],width:c._mainDiv.outerWidth(),height:c._mainDiv.outerHeight()})};if($.effects&&$.effects[f]){c._mainDiv.show(f,$.keypad._get(c,'showOptions'),g,h)}else{c._mainDiv[f||'show']((f?g:''),h)}if(!f){h()}if(c._input[0].type!='hidden'){c._input[0].focus()}$.keypad._curInst=c},_updateKeypad:function(a){var b=this._getBorders(a._mainDiv);a._mainDiv.empty().append(this._generateHTML(a)).find('iframe.'+this._coverClass).css({left:-b[0],top:-b[1],width:a._mainDiv.outerWidth(),height:a._mainDiv.outerHeight()});a._mainDiv.removeClass().addClass(this._get(a,'keypadClass')+(this._get(a,'useThemeRoller')?' ui-widget ui-widget-content':'')+(this._get(a,'isRTL')?' keypad-rtl':'')+' '+(a._inline?this._inlineClass:this._mainDivClass));var c=this._get(a,'beforeShow');if(c){c.apply((a._input?a._input[0]:null),[a._mainDiv,a])}},_getBorders:function(c){var d=function(a){var b=($.browser.msie?1:0);return{thin:1+b,medium:3+b,thick:5+b}[a]||a};return[parseFloat(d(c.css('border-left-width'))),parseFloat(d(c.css('border-top-width')))]},_checkOffset:function(a,b,c){var d=a._input?this._findPos(a._input[0]):null;var e=window.innerWidth||document.documentElement.clientWidth;var f=window.innerHeight||document.documentElement.clientHeight;var g=document.documentElement.scrollLeft||document.body.scrollLeft;var h=document.documentElement.scrollTop||document.body.scrollTop;if(($.browser.msie&&parseInt($.browser.version,10)<7)||$.browser.opera){var i=0;a._mainDiv.find(':not(div,iframe)').each(function(){i=Math.max(i,this.offsetLeft+$(this).outerWidth()+parseInt($(this).css('margin-right'),10))});a._mainDiv.css('width',i)}if(this._get(a,'isRTL')||(b.left+a._mainDiv.outerWidth()-g)>e){b.left=Math.max((c?0:g),d[0]+(a._input?a._input.outerWidth():0)-(c?g:0)-a._mainDiv.outerWidth()-(c&&$.browser.opera?document.documentElement.scrollLeft:0))}else{b.left-=(c?g:0)}if((b.top+a._mainDiv.outerHeight()-h)>f){b.top=Math.max((c?0:h),d[1]-(c?h:0)-a._mainDiv.outerHeight()-(c&&$.browser.opera?document.documentElement.scrollTop:0))}else{b.top-=(c?h:0)}return b},_findPos:function(a){while(a&&(a.type=='hidden'||a.nodeType!=1)){a=a.nextSibling}var b=$(a).offset();return[b.left,b.top]},_hideKeypad:function(a,b){var c=this._curInst;if(!c||(a&&c!=$.data(a,t))){return}if(this._keypadShowing){b=(b!=null?b:this._get(c,'duration'));b=(b=='normal'&&$.ui&&$.ui.version>='1.8'?'_default':b);var d=this._get(c,'showAnim');if($.effects&&$.effects[d]){c._mainDiv.hide(d,this._get(c,'showOptions'),b)}else{c._mainDiv[(d=='slideDown'?'slideUp':(d=='fadeIn'?'fadeOut':'hide'))](d?b:'')}}var e=this._get(c,'onClose');if(e){e.apply((c._input?c._input[0]:null),[c._input.val(),c])}if(this._keypadShowing){this._keypadShowing=false;this._lastField=null}if(c._inline){c._input.val('')}this._curInst=null},_doKeyDown:function(e){if(e.keyCode==9){$.keypad.mainDiv.stop(true,true);$.keypad._hideKeypad()}},_checkExternalClick:function(a){if(!$.keypad._curInst){return}var b=$(a.target);if(!b.parents().andSelf().is('.'+$.keypad._mainDivClass)&&!b.hasClass($.keypad.markerClassName)&&!b.parents().andSelf().hasClass($.keypad._triggerClass)&&$.keypad._keypadShowing){$.keypad._hideKeypad()}},_shiftKeypad:function(a){a.ucase=!a.ucase;this._updateKeypad(a);a._input.focus()},_clearValue:function(a){this._setValue(a,'',0);this._notifyKeypress(a,$.keypad.DEL)},_backValue:function(a){var b=a._input[0];var c=a._input.val();var d=[c.length,c.length];if(b.setSelectionRange){d=(a._input.attr('readonly')||a._input.attr('disabled')?d:[b.selectionStart,b.selectionEnd])}else if(b.createTextRange){d=(a._input.attr('readonly')||a._input.attr('disabled')?d:this._getIERange(b))}this._setValue(a,(c.length==0?'':c.substr(0,d[0]-1)+c.substr(d[1])),d[0]-1);this._notifyKeypress(a,$.keypad.BS)},_selectValue:function(a,b){this.insertValue(a._input[0],b);this._setValue(a,a._input.val());this._notifyKeypress(a,b)},insertValue:function(a,b){a=(a.jquery?a:$(a));var c=a[0];var d=a.val();var e=[d.length,d.length];if(c.setSelectionRange){e=(a.attr('readonly')||a.attr('disabled')?e:[c.selectionStart,c.selectionEnd])}else if(c.createTextRange){e=(a.attr('readonly')||a.attr('disabled')?e:this._getIERange(c))}a.val(d.substr(0,e[0])+b+d.substr(e[1]));pos=e[0]+b.length;if(a.css('display')!='none'){a.focus()}if(c.setSelectionRange){if(a.css('display')!='none'){c.setSelectionRange(pos,pos)}}else if(c.createTextRange){var e=c.createTextRange();e.move('character',pos);e.select()}},_getIERange:function(e){e.focus();var f=document.selection.createRange().duplicate();var g=this._getIETextRange(e);g.setEndPoint('EndToStart',f);var h=function(a){var b=a.text;var c=b;var d=false;while(true){if(a.compareEndPoints('StartToEnd',a)==0){break}else{a.moveEnd('character',-1);if(a.text==b){c+='\r\n'}else{break}}}return c};var i=h(g);var j=h(f);return[i.length,i.length+j.length]},_getIETextRange:function(a){var b=(a.nodeName.toLowerCase()=='input');var c=(b?a.createTextRange():document.body.createTextRange());if(!b){c.moveToElementText(a)}return c},_setValue:function(a,b){var c=a._input.attr('maxlength');if(c>-1){b=b.substr(0,c)}a._input.val(b);if(!this._get(a,'onKeypress')){a._input.trigger('change')}},_notifyKeypress:function(a,b){var c=this._get(a,'onKeypress');if(c){c.apply((a._input?a._input[0]:null),[b,a._input.val(),a])}},_get:function(a,b){return a.settings[b]!==undefined?a.settings[b]:this._defaults[b]},_generateHTML:function(a){var b=this._get(a,'useThemeRoller');var c=this._get(a,'isRTL');var d=this._get(a,'prompt');var e=this._get(a,'separator');var f=(!d?'':'<div class="keypad-prompt'+(b?' ui-widget-header ui-corner-all':'')+'">'+d+'</div>');var g=this._randomiseLayout(a);for(var i=0;i<g.length;i++){f+='<div class="keypad-row">';var h=g[i].split(e);for(var j=0;j<h.length;j++){if(a.ucase){h[j]=h[j].toUpperCase()}f+=(h[j]==this.SPACE?'<div class="keypad-space"></div>':(h[j]==this.HALF_SPACE?'<div class="keypad-half-space"></div>':'<button type="button" class="keypad-key'+(b?' ui-state-default':'')+(h[j]==this.CLEAR?' keypad-clear'+(b?' ui-state-highlight':''):(h[j]==this.BACK?' keypad-back'+(b?' ui-state-highlight':''):(h[j]==this.CLOSE?' keypad-close'+(b?' ui-state-highlight':''):(h[j]==this.SHIFT?' keypad-shift'+(b?' ui-state-highlight':''):(h[j]==this.ENTER?' keypad-enter'+(b?' ui-state-highlight':''):(h[j]==this.SPACE_BAR?' keypad-spacebar':''))))))+'" '+'title="'+(h[j]==this.CLEAR?this._get(a,'clearStatus'):(h[j]==this.BACK?this._get(a,'backStatus'):(h[j]==this.ENTER?this._get(a,'enterStatus'):(h[j]==this.CLOSE?this._get(a,'closeStatus'):(h[j]==this.SHIFT?this._get(a,'shiftStatus'):'')))))+'">'+(h[j]==this.CLEAR?this._get(a,'clearText'):(h[j]==this.BACK?this._get(a,'backText'):(h[j]==this.CLOSE?this._get(a,'closeText'):(h[j]==this.SHIFT?this._get(a,'shiftText'):(h[j]==this.ENTER?this._get(a,'enterText'):(h[j]==this.SPACE_BAR?'&nbsp;':(h[j]==' '?'&nbsp;':h[j])))))))+'</button>'))}f+='</div>'}f+='<div style="clear: both;"></div>'+(!a._inline&&$.browser.msie&&parseInt($.browser.version,10)<7?'<iframe src="javascript:false;" class="'+$.keypad._coverClass+'"></iframe>':'');f=$(f);var k=a;var l='keypad-key-down'+(b?' ui-state-active':'');f.find('button').mousedown(function(){$(this).addClass(l)}).mouseup(function(){$(this).removeClass(l)}).mouseout(function(){$(this).removeClass(l)}).filter('.keypad-clear').click(function(){$.keypad._clearValue(k)}).end().filter('.keypad-back').click(function(){$.keypad._backValue(k)}).end().filter('.keypad-close').click(function(){$.keypad._curInst=(k._inline?k:$.keypad._curInst);$.keypad._hideKeypad()}).end().filter('.keypad-shift').click(function(){$.keypad._shiftKeypad(k)}).end().filter('.keypad-enter').click(function(){$.keypad._selectValue(k,$.keypad.EN)}).end().not('.keypad-clear').not('.keypad-back').not('.keypad-close').not('.keypad-shift').not('.keypad-enter').click(function(){$.keypad._selectValue(k,$(this).text())});return f},_randomiseLayout:function(b){var c=this._get(b,'randomiseNumeric');var d=this._get(b,'randomiseAlphabetic');var e=this._get(b,'randomiseOther');var f=this._get(b,'randomiseAll');var g=this._get(b,'layout');if(!c&&!d&&!e&&!f){return g}var h=this._get(b,'isNumeric');var k=this._get(b,'isAlphabetic');var l=this._get(b,'separator');var m=[];var p=[];var q=[];var r=[];for(var i=0;i<g.length;i++){r[i]='';var s=g[i].split(l);for(var j=0;j<s.length;j++){if(this._isControl(s[j])){continue}if(f){q.push(s[j])}else if(h(s[j])){m.push(s[j])}else if(k(s[j])){p.push(s[j])}else{q.push(s[j])}}}if(c){this._shuffle(m)}if(d){this._shuffle(p)}if(e||f){this._shuffle(q)}var n=0;var a=0;var o=0;for(var i=0;i<g.length;i++){var s=g[i].split(l);for(var j=0;j<s.length;j++){r[i]+=(this._isControl(s[j])?s[j]:(f?q[o++]:(h(s[j])?m[n++]:(k(s[j])?p[a++]:q[o++]))))+l}}return r},_isControl:function(a){return a<' '},isAlphabetic:function(a){return(a>='A'&&a<='Z')||(a>='a'&&a<='z')},isNumeric:function(a){return(a>='0'&&a<='9')},_shuffle:function(a){for(var i=a.length-1;i>0;i--){var j=Math.floor(Math.random()*a.length);var b=a[i];a[i]=a[j];a[j]=b}}});function extendRemove(a,b){$.extend(a,b);for(var c in b){if(b[c]==null||b[c]==undefined){a[c]=b[c]}}return a};$.fn.keypad=function(a){var b=Array.prototype.slice.call(arguments,1);if(a=='isDisabled'){return $.keypad['_'+a+'Keypad'].apply($.keypad,[this[0]].concat(b))}return this.each(function(){typeof a=='string'?$.keypad['_'+a+'Keypad'].apply($.keypad,[this].concat(b)):$.keypad._attachKeypad(this,a)})};$.keypad=new Keypad();$(function(){$(document.body).append($.keypad.mainDiv).mousedown($.keypad._checkExternalClick)})})(jQuery);
\ No newline at end of file
Index: scripts/jquery/css/jquery.keypad.alt.css
===================================================================
--- scripts/jquery/css/jquery.keypad.alt.css	(revision 0)
+++ scripts/jquery/css/jquery.keypad.alt.css	(revision 0)
@@ -0,0 +1,102 @@
+/* Alternate style sheet for jQuery Keypad v1.3.0 */
+button.keypad-trigger {
+	width: 25px;
+	padding: 0px;
+}
+img.keypad-trigger {
+	margin: 2px;
+	vertical-align: middle;
+}
+.keypad-popup {
+	display: none;
+	z-index: 10;
+	margin: 0;
+	padding: 0;
+	background-color: #fff;
+	color: #000;
+	border: 1px solid #888;
+	border-radius: 4px;
+	-moz-border-radius: 4px;
+	-webkit-border-radius: 4px;
+	font-family: Arial,Helvetica,sans-serif;
+	font-size: 14px;
+}
+.keypad-keyentry {
+	display: none;
+}
+.keypad-inline {
+	background-color: #f4f4f4;
+	border: 1px solid #888;
+	border-radius: 4px;
+	-moz-border-radius: 4px;
+	-webkit-border-radius: 4px;
+}
+.keypad-disabled {
+	position: absolute;
+	z-index: 100;
+	background-color: white;
+	opacity: 0.25;
+	filter: alpha(opacity=25);
+}
+.keypad-rtl {
+	direction: rtl;
+}
+.keypad-prompt {
+	clear: both;
+	text-align: center;
+}
+.keypad-prompt.ui-widget-header {
+	margin: 2px;
+}
+.keypad-row {
+	clear: both;
+	float: left;
+	width: 100%;
+}
+.keypad-space {
+	float: left;
+	margin: 2px;
+	width: 24px;
+}
+* html .keypad-space { /* IE6 */
+	margin: 0px;
+	width: 28px;
+}
+.keypad-half-space {
+	float: left;
+	margin: 1px;
+	width: 12px;
+}
+* html .keypad-half-space { /* IE6 */
+	margin: 0px;
+	width: 14px;
+}
+.keypad-key {
+	float: left;
+	margin: 2px;
+	padding: 0px;
+	width: 24px;
+	text-align: center;
+	cursor: pointer;
+}
+.keypad-spacebar {
+	width: 164px;
+}
+.keypad-enter {
+	width: 52px;
+}
+.keypad-clear, .keypad-back, .keypad-close, .keypad-shift {
+	width: 108px;
+	font-weight: bold;
+}
+.keypad-cover {
+	display: none;
+	display/**/: block;
+	position: absolute;
+	z-index: -1;
+	filter: mask();
+	top: -4px;
+	left: -4px;
+	width: 125px;
+	height: 200px;
+}
Index: scripts/jquery/css/jquery.keypad.css
===================================================================
--- scripts/jquery/css/jquery.keypad.css	(revision 0)
+++ scripts/jquery/css/jquery.keypad.css	(revision 0)
@@ -0,0 +1,124 @@
+/* Main style sheet for jQuery Keypad v1.3.0 */
+button.keypad-trigger {
+	width: 25px;
+	padding: 0px;
+}
+img.keypad-trigger {
+	margin: 2px;
+	vertical-align: middle;
+}
+.keypad-popup {
+	display: none;
+	z-index: 10;
+	margin: 0;
+	padding: 0;
+	background-color: #fff;
+	color: #000;
+	border: 1px solid #888;
+	border-radius: 4px;
+	-moz-border-radius: 4px;
+	-webkit-border-radius: 4px;
+	font-family: Arial,Helvetica,sans-serif;
+	font-size: 14px;
+}
+.keypad-keyentry {
+	display: none;
+}
+.keypad-inline {
+	background-color: #f4f4f4;
+	border: 1px solid #888;
+	border-radius: 4px;
+	-moz-border-radius: 4px;
+	-webkit-border-radius: 4px;
+}
+.keypad-disabled {
+	position: absolute;
+	z-index: 100;
+	background-color: white;
+	opacity: 0.5;
+	filter: alpha(opacity=50);
+}
+.keypad-rtl {
+	direction: rtl;
+}
+.keypad-prompt {
+	clear: both;
+	text-align: center;
+}
+.keypad-prompt.ui-widget-header {
+	margin: 2px;
+}
+.keypad-row {
+	clear: both;
+	float: left;
+	width: 100%;
+}
+.keypad-space {
+	float: left;
+	margin: 2px;
+	width: 24px;
+}
+* html .keypad-space { /* IE6 */
+	margin: 0px;
+	width: 28px;
+}
+.keypad-half-space {
+	float: left;
+	margin: 1px;
+	width: 12px;
+}
+* html .keypad-half-space { /* IE6 */
+	margin: 0px;
+	width: 14px;
+}
+.keypad-key {
+	float: left;
+	margin: 2px;
+	padding: 0px;
+	width: 24px;
+	background-color: #f4f4f4;
+	border-radius: 4px;
+	-moz-border-radius: 4px;
+	-webkit-border-radius: 4px;
+	text-align: center;
+	cursor: pointer;
+}
+.keypad-key[disabled] {
+	border: 2px outset;
+}
+.keypad-key-down {
+}
+.keypad-spacebar {
+	width: 164px;
+}
+.keypad-enter {
+	width: 52px;
+}
+.keypad-clear, .keypad-back, .keypad-close, .keypad-shift {
+	width: 52px;
+	color: #fff;
+	font-weight: bold;
+}
+.keypad-clear {
+	background-color: #a00;
+}
+.keypad-back {
+	background-color: #00a;
+}
+.keypad-close {
+	background-color: #0a0;
+}
+.keypad-shift {
+	background-color: #0aa;
+}
+.keypad-cover {
+	display: none;
+	display/**/: block;
+	position: absolute;
+	z-index: -1;
+	filter: mask();
+	top: -4px;
+	left: -4px;
+	width: 125px;
+	height: 200px;
+}
Index: scripts/jquery/locale/ui.keypad-pt-BR.js
===================================================================
--- scripts/jquery/locale/ui.keypad-pt-BR.js	(revision 0)
+++ scripts/jquery/locale/ui.keypad-pt-BR.js	(revision 0)
@@ -0,0 +1,18 @@
+/* http://keith-wood.name/keypad.html
+   brazilian portuguese initialisation for the jQuery keypad extension
+   Written by Israel Rodriguez (yzraeu{at}gmail.com) July 2009. */
+(function($) { // hide the namespace
+    $.keypad.regional['pt-BR'] = {
+        buttonText: '...', buttonStatus: 'Abrir o teclado',
+        closeText: 'Fechar', closeStatus: 'Fechar o teclado',
+        clearText: 'Limpar', clearStatus: 'Limpar todo o texto',
+        backText: 'Apagar', backStatus: 'Apagar o caractere anterior',
+        shiftText: 'Shift', shiftStatus: 'Ativar maiúsculas/minusculas',
+        alphabeticLayout: $.keypad.qwertyAlphabetic,
+        fullLayout: $.keypad.qwertyLayout,
+        isAlphabetic: $.keypad.isAlphabetic,
+        isNumeric: $.keypad.isNumeric,
+        isRTL: false
+    };
+    $.keypad.setDefaults($.keypad.regional['pt-BR']);
+})(jQuery);
Index: scripts/jquery/locale/ui.keypad-de.js
===================================================================
--- scripts/jquery/locale/ui.keypad-de.js	(revision 0)
+++ scripts/jquery/locale/ui.keypad-de.js	(revision 0)
@@ -0,0 +1,32 @@
+/* http://keith-wood.name/keypad.html
+   German localisation for the jQuery keypad extension
+   Written by Uwe Jakobs(u.jakobs{at}imageco.de) September 2009. */
+(function($) { // hide the namespace
+
+$.keypad.qwertzAlphabetic = ['qwertzuiopüß', 'asdfghjklöä', 'yxcvbnm'];
+$.keypad.qwertzLayout = 
+	['!"§$%&/()=?`' + $.keypad.BACK + $.keypad.HALF_SPACE + '$£€/',
+	'<>°^@{[]}\\~´;:' + $.keypad.HALF_SPACE + '789*',
+	$.keypad.qwertzAlphabetic[0] + '+*' +
+	$.keypad.HALF_SPACE + '456-',
+	$.keypad.HALF_SPACE + $.keypad.qwertzAlphabetic[1] +
+	'#\'' + $.keypad.SPACE + '123+',
+	'|' + $.keypad.qwertzAlphabetic[2] + 'µ,.-_' +
+	$.keypad.SPACE + $.keypad.HALF_SPACE +'.0,=', 
+	$.keypad.SHIFT + $.keypad.SPACE + $.keypad.SPACE_BAR +
+	$.keypad.SPACE + $.keypad.SPACE + $.keypad.SPACE + $.keypad.CLEAR +
+	$.keypad.SPACE + $.keypad.SPACE + $.keypad.HALF_SPACE + $.keypad.CLOSE];
+$.keypad.regional['de'] = {
+	buttonText: '...', buttonStatus: 'Öffnen',
+	closeText: 'schließen', closeStatus: 'schließen',
+	clearText: 'löschen', clearStatus: 'Gesamten Inhalt löschen',
+	backText: 'zurück', backStatus: 'Letzte Eingabe löschen',
+	shiftText: 'umschalten', shiftStatus: 'Zwischen Groß- und Kleinschreibung wechseln',
+	alphabeticLayout: $.keypad.qwertzAlphabetic,
+	fullLayout: $.keypad.qwertzLayout,
+	isAlphabetic: $.keypad.isAlphabetic,
+	isNumeric: $.keypad.isNumeric,
+	isRTL: false};
+$.keypad.setDefaults($.keypad.regional['de']);
+
+})(jQuery);
Index: scripts/jquery/locale/ui.keypad-nl.js
===================================================================
--- scripts/jquery/locale/ui.keypad-nl.js	(revision 0)
+++ scripts/jquery/locale/ui.keypad-nl.js	(revision 0)
@@ -0,0 +1,17 @@
+/* http://keith-wood.name/keypad.html
+   dutch initialisation for the jQuery keypad extension
+   Written by Michiel Mussies (mail{at}webcrafts.nl) November 2009. */
+(function($) { // hide the namespace
+    $.keypad.regional['nl'] = {
+        buttonText: '...', buttonStatus: 'Open',
+        closeText: 'Sluit', closeStatus: 'Sluit',
+        clearText: 'Wissen', clearStatus: 'Wis alle tekens',
+        backText: 'Terug', backStatus: 'Wis laatste teken',
+        shiftText: 'Shift', shiftStatus: 'Activeer hoofd-/kleine letters',
+        alphabeticLayout: $.keypad.qwertyAlphabetic,
+        fullLayout: $.keypad.qwertyLayout,
+        isAlphabetic: $.keypad.isAlphabetic,
+        isNumeric: $.keypad.isNumeric,
+        isRTL: false};
+    $.keypad.setDefaults($.keypad.regional['nl']);
+})(jQuery);
Index: scripts/jquery/locale/ui.keypad-es.js
===================================================================
--- scripts/jquery/locale/ui.keypad-es.js	(revision 0)
+++ scripts/jquery/locale/ui.keypad-es.js	(revision 0)
@@ -0,0 +1,17 @@
+/* http://keith-wood.name/keypad.html
+   Spanish initialisation for the jQuery keypad extension
+   Written by Cristhian Benitez (cbenitez@gmail.com). */
+(function($) { // hide the namespace
+$.keypad.regional['es'] = {
+	buttonText: '...', buttonStatus: 'Abrir el teclado',
+	closeText: 'Cerrar', closeStatus: 'Cerrar el teclado',
+	clearText: 'Limpiar', clearStatus: 'Eliminar todo el texto',
+	backText: 'Volver', backStatus: 'Borrar el caracter anterior',
+	shiftText: 'Shift', shiftStatus: 'Cambiar mayusculas/minusculas',
+	alphabeticLayout: $.keypad.qwertyAlphabetic,
+	fullLayout: $.keypad.qwertyLayout,
+	isAlphabetic: $.keypad.isAlphabetic,
+	isNumeric: $.keypad.isNumeric,
+	isRTL: false};
+$.keypad.setDefaults($.keypad.regional['es']);
+})(jQuery);
Index: scripts/jquery/locale/ui.keypad-fr.js
===================================================================
--- scripts/jquery/locale/ui.keypad-fr.js	(revision 0)
+++ scripts/jquery/locale/ui.keypad-fr.js	(revision 0)
@@ -0,0 +1,33 @@
+/* http://keith-wood.name/keypad.html
+   French initialisation for the jQuery keypad extension
+   Written by Keith Wood (kbwood{at}iinet.com.au) August 2008. */
+(function($) { // hide the namespace
+
+$.keypad.azertyAlphabetic = ['àâçéèêîôùû', 'azertyuiop', 'qsdfghjklm', 'wxcvbn'];
+$.keypad.azertyLayout = ['&~#{([_@])}' + $.keypad.HALF_SPACE + '£$€',
+	'<>|`°^!?\'"\\' + $.keypad.HALF_SPACE + '/*=',
+	$.keypad.HALF_SPACE + $.keypad.azertyAlphabetic[0] + $.keypad.SPACE + '789',
+	$.keypad.azertyAlphabetic[1] + '%' + $.keypad.HALF_SPACE + '456',
+	$.keypad.HALF_SPACE + $.keypad.azertyAlphabetic[2] + $.keypad.SPACE + '123',
+	'§' + $.keypad.azertyAlphabetic[3] + ',.;:' + $.keypad.HALF_SPACE + '-0+',
+	$.keypad.SHIFT + $.keypad.SPACE_BAR + $.keypad.HALF_SPACE +
+	$.keypad.BACK + $.keypad.CLEAR + $.keypad.CLOSE];
+$.keypad.regional['fr'] = {
+	buttonText: '...', buttonStatus: 'Ouvrir',
+	closeText: 'Fermer', closeStatus: 'Fermer le pavé numérique',
+	clearText: 'Effacer', clearStatus: 'Effacer la valeur',
+	backText: 'Défaire', backStatus: 'Effacer la dernière touche',
+	shiftText: 'Maj', shiftStatus: '',
+	alphabeticLayout: $.keypad.azertyAlphabetic,
+	fullLayout: $.keypad.azertyLayout,
+	isAlphabetic: isAlphabetic,
+	isNumeric: $.keypad.isNumeric,
+	isRTL: false};
+$.keypad.setDefaults($.keypad.regional['fr']);
+
+function isAlphabetic(ch) {
+	return ($.keypad.isAlphabetic(ch) ||
+		'áàäãâçéèëêíìïîóòöõôúùüû'.indexOf(ch) > -1);
+}
+
+})(jQuery);
Index: scripts/survey_runtime.js
===================================================================
--- scripts/survey_runtime.js	(revision 9552)
+++ scripts/survey_runtime.js	(working copy)
@@ -12,6 +12,25 @@
     $(".question").find("select").each(function () {
         hookEvent($(this).attr('id'),'mousewheel',noScroll);
     });
+        var kp = $("input.num-keypad");
+        if(kp.length) kp.keypad({showAnim: 'fadeIn', keypadOnly: false});
+        kp = $("input.text-keypad");
+        if(kp.length)
+        {
+                var spacer = $.keypad.HALF_SPACE;
+                for(var i = 0; i != 8; ++i) spacer += $.keypad.SPACE;
+		kp.keypad({
+			showAnim: 'fadeIn',
+			keypadOnly: false,
+			layout: [
+                                spacer + $.keypad.CLEAR + $.keypad.CLOSE, $.keypad.SPACE,
+			        '!@#$%^&*()_=' + $.keypad.HALF_SPACE + $.keypad.BACK,
+			        $.keypad.HALF_SPACE + '`~[]{}<>\\|/' + $.keypad.SPACE + $.keypad.SPACE + '789',
+			        'qwertyuiop\'"' + $.keypad.HALF_SPACE + $.keypad.SPACE + '456',
+			        $.keypad.HALF_SPACE + 'asdfghjkl;:' + $.keypad.SPACE + $.keypad.SPACE + '123',
+			        $.keypad.SPACE + 'zxcvbnm,.?' + $.keypad.SPACE + $.keypad.SPACE + $.keypad.HALF_SPACE + '-0+',
+			        $.keypad.SHIFT + $.keypad.SPACE_BAR + $.keypad.ENTER]});
+        }
 });
 
 Array.prototype.push = function()
Index: images/keypad.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: images/keypad.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: common_functions.php
===================================================================
--- common_functions.php	(revision 9552)
+++ common_functions.php	(working copy)
@@ -7956,4 +7956,19 @@
     return $bAnsw;
 }
 
+/**
+ * Include Keypad headers
+ */
+function vIncludeKeypad()
+{
+    global $js_header_includes, $css_header_includes, $clang;
+
+    $js_header_includes[] = '/scripts/jquery/jquery.keypad.min.js';
+    if ($clang->langcode !== 'en')
+    {
+        $js_header_includes[] = '/scripts/jquery/locale/ui.keypad-'.$clang->langcode.'.js';
+    }
+    $css_header_includes[] = '/scripts/jquery/css/jquery.keypad.alt.css';
+}
+
 // Closing PHP tag intentionally left out - yes, it is okay
Index: qanda.php
===================================================================
--- qanda.php	(revision 9552)
+++ qanda.php	(working copy)
@@ -3926,7 +3926,7 @@
 // ---------------------------------------------------------------
 function do_multipleshorttext($ia)
 {
-    global $dbprefix, $clang;
+    global $dbprefix, $clang, $thissurvey;
 
     if ($ia[8] == 'Y')
     {
@@ -3980,6 +3980,16 @@
         $suffix = '';
     }
 
+    if ($thissurvey['nokeyboard']=='Y')
+    {
+        vIncludeKeypad();
+        $kpclass = "text-keypad";
+    }
+    else
+    {
+        $kpclass = "";
+    }
+
     if ($qidattributes['random_order']==1) {
         $ansquery = "SELECT * FROM {$dbprefix}questions WHERE parent_qid=$ia[0]  AND language='".$_SESSION['s_lang']."' ORDER BY ".db_random();
     }
@@ -4039,7 +4049,7 @@
                 $answer_main .= "\t<li>\n"
                 . "<label for=\"answer$myfname\">{$ansrow['question']}</label>\n"
                 . "\t<span>\n".$prefix."\n".'
-				<textarea class="textarea" name="'.$myfname.'" id="answer'.$myfname.'" 
+				<textarea class="textarea '.$kpclass.'" name="'.$myfname.'" id="answer'.$myfname.'" 
 				rows="'.$drows.'" cols="'.$tiwidth.'" onkeyup="textLimit(\'answer'.$ia[1].'\', '.$maxsize.'); '.$checkconditionFunction.'(this.value, this.name, this.type);" '.$numbersonly.'>';
 
                 if($label_width < strlen(trim(strip_tags($ansrow['question']))))
@@ -4068,7 +4078,7 @@
                 if ($ansrow['question'] == "") {$ansrow['question'] = "&nbsp;";}
                 $answer_main .= "\t<li>\n"
                 . "<label for=\"answer$myfname\">{$ansrow['question']}</label>\n"
-                . "\t<span>\n".$prefix."\n".'<input class="text" type="text" size="'.$tiwidth.'" name="'.$myfname.'" id="answer'.$myfname.'" value="';
+                . "\t<span>\n".$prefix."\n".'<input class="text '.$kpclass.'" type="text" size="'.$tiwidth.'" name="'.$myfname.'" id="answer'.$myfname.'" value="';
 
                 if($label_width < strlen(trim(strip_tags($ansrow['question']))))
                 {
@@ -4102,7 +4112,7 @@
 // ---------------------------------------------------------------
 function do_multiplenumeric($ia)
 {
-    global $dbprefix, $clang, $js_header_includes, $css_header_includes;
+    global $dbprefix, $clang, $js_header_includes, $css_header_includes, $thissurvey;
 
     if ($ia[8] == 'Y')
     {
@@ -4190,6 +4200,16 @@
         $suffix = '';
     }
 
+    if ($thissurvey['nokeyboard']=='Y')
+    {
+        vIncludeKeypad();
+        $kpclass = "num-keypad";
+    }
+    else
+    {
+        $kpclass = "";
+    }
+
     if(!empty($numbersonlyonblur))
     {
         $numbersonly .= ' onblur="'.implode(';', $numbersonlyonblur).'"';
@@ -4356,7 +4376,7 @@
 
             if ($slider_layout === false)
             {
-                $answer_main .= "<span class=\"input\">\n\t".$prefix."\n\t<input class=\"text\" type=\"text\" size=\"".$tiwidth.'" name="'.$myfname.'" id="answer'.$myfname.'" value="';
+                $answer_main .= "<span class=\"input\">\n\t".$prefix."\n\t<input class=\"text $kpclass\" type=\"text\" size=\"".$tiwidth.'" name="'.$myfname.'" id="answer'.$myfname.'" value="';
                 if (isset($_SESSION[$myfname]))
                 {
                     $answer_main .= $_SESSION[$myfname];
@@ -4587,7 +4607,7 @@
 // ---------------------------------------------------------------
 function do_numerical($ia)
 {
-    global $clang;
+    global $clang, $thissurvey;
 
     if ($ia[8] == 'Y')
     {
@@ -4642,8 +4662,18 @@
         $acomma=".,";
     }
 
+    if ($thissurvey['nokeyboard']=='Y')
+    {
+        vIncludeKeypad();
+        $kpclass = "num-keypad";
+    }
+    else
+    {
+        $kpclass = "";
+    }
+
     // --> START NEW FEATURE - SAVE
-    $answer = "<p class=\"question\">\n\t$prefix\n\t<input class=\"text\" type=\"text\" size=\"$tiwidth\" name=\"$ia[1]\" "
+    $answer = "<p class=\"question\">\n\t$prefix\n\t<input class=\"text $kpclass\" type=\"text\" size=\"$tiwidth\" name=\"$ia[1]\" "
     . "id=\"answer{$ia[1]}\" value=\"{$_SESSION[$ia[1]]}\" alt=\"".$clang->gT('Answer')."\" onkeypress=\"return goodchars(event,'-0123456789{$acomma}')\" onchange='$checkconditionFunction(this.value, this.name, this.type)'"
     . "maxlength=\"{$maxsize}\" />\n\t{$suffix}\n</p>\n";
     if ($qidattributes['hide_tip']==0)
@@ -4664,7 +4694,7 @@
 // ---------------------------------------------------------------
 function do_shortfreetext($ia)
 {
-    global $clang, $js_header_includes;
+    global $clang, $js_header_includes, $thissurvey;
 
     if ($ia[8] == 'Y')
     {
@@ -4715,6 +4745,15 @@
     {
         $suffix = '';
     }
+    if ($thissurvey['nokeyboard']=='Y')
+    {
+        vIncludeKeypad();
+        $kpclass = "text-keypad";
+    }
+    else
+    {
+        $kpclass = "";
+    }
     if (trim($qidattributes['display_rows'])!='')
     {
         //question attribute "display_rows" is set -> we need a textarea to be able to show several rows
@@ -4747,7 +4786,7 @@
         //NEW: textarea instead of input=text field
 
         // --> START NEW FEATURE - SAVE
-        $answer .= '<textarea class="textarea" name="'.$ia[1].'" id="answer'.$ia[1].'" '
+        $answer .= '<textarea class="textarea '.$kpclass.'" name="'.$ia[1].'" id="answer'.$ia[1].'" '
         .'rows="'.$drows.'" cols="'.$tiwidth.'" onkeyup="textLimit(\'answer'.$ia[1].'\', '.$maxsize.'); '.$checkconditionFunction.'(this.value, this.name, this.type);" '.$numbersonly.'>';
         // --> END NEW FEATURE - SAVE
 
@@ -4758,7 +4797,7 @@
     else
     {
         //no question attribute set, use common input text field
-        $answer = "<p class=\"question\">\n\t$prefix\n\t<input class=\"text\" type=\"text\" size=\"$tiwidth\" name=\"$ia[1]\" id=\"answer$ia[1]\" value=\""
+        $answer = "<p class=\"question\">\n\t$prefix\n\t<input class=\"text $kpclass\" type=\"text\" size=\"$tiwidth\" name=\"$ia[1]\" id=\"answer$ia[1]\" value=\""
         .htmlspecialchars($_SESSION[$ia[1]],ENT_QUOTES,'UTF-8')
         ."\" maxlength=\"$maxsize\" onkeyup=\"$checkconditionFunction(this.value, this.name, this.type)\" $numbersonly />\n\t$suffix\n</p>\n";
     }
Index: admin/database.php
===================================================================
--- admin/database.php	(revision 9552)
+++ admin/database.php	(working copy)
@@ -1075,6 +1075,7 @@
                             'showwelcome'=>$_POST['showwelcome'],
                             'allowprev'=>$_POST['allowprev'],
                             'allowjumps'=>$_POST['allowjumps'],
+                            'nokeyboard'=>$_POST['nokeyboard'],
                             'showprogress'=>$_POST['showprogress'],
                             'listpublic'=>$_POST['public'],
                             'htmlemail'=>$_POST['htmlemail'],
@@ -1366,6 +1367,7 @@
                             'showwelcome'=>$_POST['showwelcome'],
                             'allowprev'=>$_POST['allowprev'],
                             'allowjumps'=>$_POST['allowjumps'],
+                            'nokeyboard'=>$_POST['nokeyboard'],
                             'showprogress'=>$_POST['showprogress'],
                             'printanswers'=>$_POST['printanswers'],
         //                            'usetokens'=>$_POST['usetokens'],
Index: admin/install/create-mysql.sql
===================================================================
--- admin/install/create-mysql.sql	(revision 9552)
+++ admin/install/create-mysql.sql	(working copy)
@@ -280,6 +280,7 @@
   `showprogress` char(1) default 'Y',
   `allowjumps` char(1) default 'N',
   `navigationdelay` tinyint(2) default '0',
+  `nokeyboard` char(1) default 'N',
    PRIMARY KEY(`sid`)
 ) ENGINE=$databasetabletype CHARACTER SET utf8 COLLATE utf8_unicode_ci;
 
Index: admin/install/create-mssqlnative.sql
===================================================================
--- admin/install/create-mssqlnative.sql	(revision 9552)
+++ admin/install/create-mssqlnative.sql	(working copy)
@@ -300,6 +300,7 @@
   [showprogress] char(1) default 'N',
   [allowjumps] char(1) default 'N',
   [navigationdelay] tinyint default '0',
+  [nokeyboard] char(1) default 'N',
   
   PRIMARY KEY  ([sid])
 ) 
Index: admin/install/create-postgres.sql
===================================================================
--- admin/install/create-postgres.sql	(revision 9552)
+++ admin/install/create-postgres.sql	(working copy)
@@ -304,7 +304,8 @@
 	tokenlength smallint DEFAULT '15',
     showprogress character(1) DEFAULT 'N'::bpchar,
     allowjumps character(1) DEFAULT 'N'::bpchar,
-    navigationdelay smallint DEFAULT '0'
+    navigationdelay smallint DEFAULT '0',
+    nokeyboard character(1) DEFAULT 'N'::bpchar
 );
 
 ALTER TABLE ONLY prefix_surveys ADD CONSTRAINT prefix_surveys_pkey PRIMARY KEY (sid);
Index: admin/install/create-mssql.sql
===================================================================
--- admin/install/create-mssql.sql	(revision 9552)
+++ admin/install/create-mssql.sql	(working copy)
@@ -291,6 +291,7 @@
   [showprogress] char(1) default 'N',
   [allowjumps] char(1) default 'N',
   [navigationdelay] tinyint default '0',
+  [nokeyboard] char(1) default 'N',
   
   PRIMARY KEY  ([sid])
 ) 
Index: admin/editsurveysettings.php
===================================================================
--- admin/editsurveysettings.php	(revision 9552)
+++ admin/editsurveysettings.php	(working copy)
@@ -332,6 +332,17 @@
         $editsurvey .= ">".$clang->gT("No")."</option>\n"
                 . "</select></li>\n";
 
+        //No Keyboard
+        $editsurvey .= "<li><label for='nokeyboard'>".$clang->gT("Keyboard-less operation")."</label>\n"
+                . "<select id='nokeyboard' name='nokeyboard'>\n"
+                . "<option value='Y'";
+        if (!isset($esrow['nokeyboard']) || !$esrow['nokeyboard'] || $esrow['nokeyboard'] == "Y") {$editsurvey .= " selected='selected'";}
+        $editsurvey .= ">".$clang->gT("Yes")."</option>\n"
+                . "<option value='N'";
+        if (isset($esrow['nokeyboard']) && $esrow['nokeyboard'] == "N") {$editsurvey .= " selected='selected'";}
+        $editsurvey .= ">".$clang->gT("No")."</option>\n"
+                . "</select></li>\n";
+
 	//Show Progress
 	$editsurvey .= "<li><label for='showprogress'>".$clang->gT("Show progress bar")."</label>\n"
                 . "<select id='showprogress' name='showprogress'>\n"
Index: admin/update/upgrade-mysql.php
===================================================================
--- admin/update/upgrade-mysql.php	(revision 9552)
+++ admin/update/upgrade-mysql.php	(working copy)
@@ -407,6 +407,7 @@
         modify_database("", "ALTER TABLE `prefix_surveys` ADD `showprogress` char(1) default 'Y'"); echo $modifyoutput; flush();
         modify_database("", "ALTER TABLE `prefix_surveys` ADD `allowjumps` char(1) default 'N'"); echo $modifyoutput; flush();
         modify_database("", "ALTER TABLE `prefix_surveys` ADD `navigationdelay` tinyint(2) default '0'"); echo $modifyoutput; flush();
+        modify_database("", "ALTER TABLE `prefix_surveys` ADD `nokeyboard` char(1) default 'N'"); echo $modifyoutput; flush();
         modify_database("", "CREATE TABLE `prefix_survey_permissions` (
                                 `sid` int(10) unsigned NOT NULL,
                                 `uid` int(10) unsigned NOT NULL,
Index: admin/update/upgrade-mssqlnative.php
===================================================================
--- admin/update/upgrade-mssqlnative.php	(revision 9552)
+++ admin/update/upgrade-mssqlnative.php	(working copy)
@@ -422,6 +422,7 @@
         modify_database("", "ALTER TABLE [prefix_surveys] ADD showprogress CHAR(1) NULL default 'Y'"); echo $modifyoutput; flush();
         modify_database("", "ALTER TABLE [prefix_surveys] ADD allowjumps CHAR(1) NULL default 'N'"); echo $modifyoutput; flush();
         modify_database("", "ALTER TABLE [prefix_surveys] ADD navigationdelay tinyint NOT NULL default '0'"); echo $modifyoutput; flush();
+        modify_database("", "ALTER TABLE [prefix_surveys] ADD nokeyboard CHAR(1) NULL default 'N'"); echo $modifyoutput; flush();
         modify_database("", "CREATE TABLE [prefix_survey_permissions] (
                             [sid] INT NOT NULL,         
                             [uid] INT NOT NULL,         
Index: admin/update/upgrade-postgres.php
===================================================================
--- admin/update/upgrade-postgres.php	(revision 9552)
+++ admin/update/upgrade-postgres.php	(working copy)
@@ -249,6 +249,7 @@
         modify_database("", "ALTER TABLE prefix_surveys ADD showprogress CHAR(1) NULL default 'Y'"); echo $modifyoutput; flush();
         modify_database("", "ALTER TABLE prefix_surveys ADD allowjumps CHAR(1) NULL default 'N'"); echo $modifyoutput; flush();
         modify_database("", "ALTER TABLE prefix_surveys ADD navigationdelay smallint NOT NULL default '0'"); echo $modifyoutput; flush();
+        modify_database("", "ALTER TABLE prefix_surveys ADD nokeyboard char(1) default 'N'"); echo $modifyoutput; flush();
         modify_database("", "CREATE TABLE prefix_survey_permissions (
                             sid integer DEFAULT 0 NOT NULL,
                             uid integer DEFAULT 0 NOT NULL,
Index: admin/update/upgrade-mssql.php
===================================================================
--- admin/update/upgrade-mssql.php	(revision 9552)
+++ admin/update/upgrade-mssql.php	(working copy)
@@ -425,6 +425,7 @@
         modify_database("", "ALTER TABLE [prefix_surveys] ADD showprogress CHAR(1) NULL default 'Y'"); echo $modifyoutput; flush();
         modify_database("", "ALTER TABLE [prefix_surveys] ADD allowjumps CHAR(1) NULL default 'N'"); echo $modifyoutput; flush();
         modify_database("", "ALTER TABLE [prefix_surveys] ADD navigationdelay tinyint default '0'"); echo $modifyoutput; flush();
+        modify_database("", "ALTER TABLE [prefix_surveys] ADD nokeyboard CHAR(1) NULL default 'N'"); echo $modifyoutput; flush();
         modify_database("", "CREATE TABLE [prefix_survey_permissions] (
                             [sid] INT NOT NULL,         
                             [uid] INT NOT NULL,         
Index: index.php
===================================================================
--- index.php	(revision 9552)
+++ index.php	(working copy)
@@ -2298,6 +2298,16 @@
     // TOKEN REQUIRED BUT NO TOKEN PROVIDED
     if ($tokensexist == 1 && !returnglobal('token'))
     {
+        if ($thissurvey['nokeyboard']=='Y')
+        {
+            vIncludeKeypad();
+            $kpclass = "text-keypad";
+        }
+        else
+        {
+            $kpclass = "";
+        }
+
         // DISPLAY REGISTER-PAGE if needed
         // DISPLAY CAPTCHA if needed
         sendcacheheaders();
@@ -2319,7 +2329,7 @@
 	        <form id='tokenform' method='get' action='{$publicurl}/index.php'>
                 <ul>
                 <li>
-            <label for='token'>".$clang->gT("Token")."</label><input class='text' id='token' type='text' name='token' />";
+            <label for='token'>".$clang->gT("Token")."</label><input class='text $kpclass' id='token' type='text' name='token' />";
             
             echo "<input type='hidden' name='sid' value='".$surveyid."' id='sid' />
 				<input type='hidden' name='lang' value='".$templang."' id='lang' />";
svn-patch-2.diff (46,430 bytes)

user9586

2010-11-29 11:55

  ~13662

Sorry for the double-post, the last patch was missing new files.

c_schmitz

2010-11-30 15:24

administrator   ~13670

Great patch - thank you very much!

user9586

2010-11-30 16:00

  ~13672

svn is missing the new files contained in the patch in the scripts directory.

c_schmitz

2010-11-30 16:05

administrator   ~13673

Last edited: 2010-11-30 16:06

View 2 revisions

I committed everything I got. Can you add another patch file with the missing files? Which files you think are missing?

user9586

2010-11-30 16:08

  ~13674

It's in the patch already (see the first file: scripts/jquery/jquery.keypad.min.js). Maybe you forgot to add them before the commit?

c_schmitz

2010-11-30 16:28

administrator   ~13675

Yes, and I added them to SVN for sure. Update your local subversion again.

user9586

2010-11-30 16:40

  ~13676

You were right. I don't know why, but 'svn up' and 'svn status' both reported that the repository was updated, but those files were still missing.

I removed 'scripts' and forced an updated to get the files...

Anyway, sorry for the noise.

c_schmitz

2010-11-30 18:06

administrator   ~13677

np ;)

Issue History

Date Modified Username Field Change
2010-10-05 20:02 user9586 New Issue
2010-10-05 20:02 user9586 File Added: patch.diff
2010-10-11 23:55 c_schmitz Status new => feedback
2010-10-11 23:55 c_schmitz Note Added: 13089
2010-11-07 16:11 DenisChenu Note Added: 13450
2010-11-07 20:00 c_schmitz Note Added: 13451
2010-11-07 20:05 c_schmitz Assigned To => c_schmitz
2010-11-07 20:05 c_schmitz Status feedback => assigned
2010-11-29 11:52 user9586 File Added: svn-patch.diff
2010-11-29 11:52 user9586 Note Added: 13661
2010-11-29 11:54 user9586 File Added: svn-patch-2.diff
2010-11-29 11:55 user9586 Note Added: 13662
2010-11-30 15:06 c_schmitz File Deleted: patch.diff
2010-11-30 15:06 c_schmitz File Deleted: svn-patch.diff
2010-11-30 15:24 c_schmitz Note Added: 13670
2010-11-30 15:24 c_schmitz Status assigned => resolved
2010-11-30 15:24 c_schmitz Fixed in Version => 1.91
2010-11-30 15:24 c_schmitz Resolution open => fixed
2010-11-30 16:00 user9586 Note Added: 13672
2010-11-30 16:00 user9586 Status resolved => feedback
2010-11-30 16:00 user9586 Resolution fixed => reopened
2010-11-30 16:05 c_schmitz Note Added: 13673
2010-11-30 16:06 c_schmitz Note Edited: 13673 View Revisions
2010-11-30 16:08 user9586 Note Added: 13674
2010-11-30 16:08 user9586 Status feedback => assigned
2010-11-30 16:28 c_schmitz Note Added: 13675
2010-11-30 16:40 user9586 Note Added: 13676
2010-11-30 18:06 c_schmitz Note Added: 13677
2010-11-30 18:06 c_schmitz Status assigned => resolved
2010-11-30 18:06 c_schmitz Resolution reopened => fixed
2010-12-14 13:02 c_schmitz Status resolved => closed