Keyboard icon indicating copy to clipboard operation
Keyboard copied to clipboard

Mathquill for input area

Open zagannath opened this issue 8 years ago • 14 comments

Hi Rob thank you for awesome keyboard , really appreciate you work,Im wondering is it possible to input laTex expression in your text field by enabling mathquill(https://github.com/mathquill/mathquill) and is it possible to separate keyboard and text box as I'm developing for iPad it will allow more control over UX.

I tried to add class on UI component like .addClass( 'mathquill-editable') but its not working can you please tell me another workaround.

zagannath avatar Jan 11 '16 07:01 zagannath

Hi @zagannath!

You can set the usePreview option to false to not include a textarea in the keyboard popup.

I created this demo showing how to use virtual keyboard events to update mathquill renders. I hope that is what you had in mind!

HTML

<textarea id="keyboard"></textarea>
<br>
<div id="mathquill"></div>

CSS

/* position keyboard at bottom of the screen - jQuery UI isn't even loaded! */
.ui-keyboard {
  border-radius: 0;
  left: 0;
  top: auto;
  bottom: 0;
  position: fixed;
  width: 100%;
}

Script

$(function() {

  var mathquill = $('#mathquill').mathquill();

  $('#keyboard')
    .on('visible keyboardChange hidden', function(e, keyboard, el) {
      mathquill.mathquill('latex', keyboard.$preview.val());
    })
    .keyboard({
      usePreview: false
    })
    // activate the typing extension
    .addTyping({
      showTyping: true,
      delay: 250
    });

});

I actually think it would be really cool to make a custom layout which has predefined LaTeX keys like \frac and \sqrt, etc; but I don't have time to set up a demo like that :wink:

Mottie avatar Jan 11 '16 17:01 Mottie

Thank you very much Rob for quick reply. one more question though, is it possible to add image on keyboard buttons as I need fraction and othersymbol which is not in unicode charmap. e.g. screen shot 2016-01-12 at 2 22 57 pm

zagannath avatar Jan 12 '16 08:01 zagannath

To add images, set a background image on the span inside the button. You'll also need to hide the text and set a width to maintain the span's width (demo):

.ui-keyboard-frac span {
  background-image: url('https://cloud.githubusercontent.com/assets/2561440/12258775/26781542-b937-11e5-88b9-4a0b926dc8c0.png');
  background-position: -10px -5px;
  text-indent: -99em;
  width: 1.2em;
}
.ui-keyboard-sqrt span {
  background-image: url('https://cloud.githubusercontent.com/assets/2561440/12258775/26781542-b937-11e5-88b9-4a0b926dc8c0.png');
  background-position: -203px -5px;
  text-indent: -99em;
  width: 1.2em;
}

Script with 2 basic action keys

$(function() {

  $.extend($.keyboard.keyaction, {
    'frac': function(kb) {
      kb.insertText('\\frac{}{}');
      var caret = $.keyboard.caret(kb.$el);
      kb.saveCaret(caret.start - 3, caret.start - 3);
    },
    'sqrt': function(kb) {
      kb.insertText('\\sqrt{}');
      var caret = $.keyboard.caret(kb.$el);
      kb.saveCaret(caret.start - 1, caret.start - 1);
    },
  });

  var mathquill = $('#mathquill').mathquill();

  $('#keyboard')
    .on('visible keyboardChange hidden', function(e, keyboard, el) {
      mathquill.mathquill('latex', keyboard.$preview.val());
    })
    .keyboard({
      usePreview: false,
      layout: 'custom',
      customLayout: {
        'default': [
          'sin cos tan \u03c0 {b}',
          '7 8 9 + -',
          '4 5 6 * frac',
          '1 2 3 ^ sqrt',
          '0 . , {left} {right}',
          '< > = {clear} {a}'
        ]
      },
      useCombos: false
    })
    // activate the typing extension
    .addTyping({
      showTyping: true,
      delay: 250
    });

});

Mottie avatar Jan 12 '16 10:01 Mottie

You are amazing, Thank you very much. is it not possible to render input characters in box() rather then separate div, this last thing will complete my implementation . Again thank you very much Rob and I'm sorry for bothering you :(

zagannath avatar Jan 13 '16 05:01 zagannath

Do you mean have the keyboard work directly inside the mathquill box like Desmos? It might be possible, but I'd have to dig into the code since worrying about caret position and how to deal with backspace and delete are important. Honestly, I don't really have the free time right now.

Mottie avatar Jan 13 '16 12:01 Mottie

Yes thats what I wanted.. no problem you already helped me alot.. Thanks

zagannath avatar Jan 13 '16 22:01 zagannath

Hey!

I'm reopening this discussion because I'm trying to achieve exactly the same thing.

I've started to play around I've managed to improve your jsfiddle, you can see the result here: http://jsfiddle.net/yLo3nf83/3/

On the things I've made:

  • it was broken since mathquill isn't a jquery librairie anymore
  • instead of using .latex I've used .cmd that allows to send a command to mathquill instead of filling it with latex formulas
  • and when the keys aren't text to write (left/right arrow keys, backspace) I'm using .keystroke to stimulate keyboard input

Both those last 2 points allows to handle the caret position as mathquill expects it to be in its input (like you were wondering).

The problem is that I end up with a useless (and desynchronized) text-input while mathquill-input is as expected. I haven't had the time to hide this text-input or see how to directly send input to the mathquill-input but that will be my next step.

I was wondering, would you like to see this kind of work included into virtual-keyboard? Do you have any pointers on how to do my next steps?

Fyi, I'm not going to work on it in the next days because I have an urgency but I'm going back on it just after.

Thanks for this lib :)

Psycojoker avatar Jan 10 '17 11:01 Psycojoker

Hi @Psycojoker!

Thank you for taking the time to work on the demo!

I'll need to think more on how to get the interaction to work better... so far, I think we might need to save the input values into an array, like I've done in this demo for issue #372. So pressing delete will remove the entire block instead of one letter at a time.

Then we'll probably need to find "key" caret positions for each latex command - like inside the curly brackets for \\frac{}{}} - and reposition the caret when the user presses the right or left arrow.

That's as far as I got without my morning caffeine

Mottie avatar Jan 10 '17 13:01 Mottie

hey @Mottie :)

I've been looking at your demo but something is not clear for me, what would be the benefit (or even the usage) of storing all those input and refinding the caret position for those kind of input?

If you play a bit with my update jsfiddle (like adding a square root, some stuff in it, then playing with the left and right and backspace) you'll see that mathquill handles all this without any problems (but there is a desynchronisation between the content of the textarea and mathquill area). From my point of view, it would be simplier to remove this textarea and directly send the input to mathquill instead of redoing all mathquill work in an intermediate layer. But well, I might be totally wrong since I haven't played yet with virtual-keyboard internal/api to see if this is possible ¯\_(ツ)_/¯

Thanks for your quick answer :)

Psycojoker avatar Jan 12 '17 10:01 Psycojoker

Well I messed around with the demo: http://jsfiddle.net/Mottie/yLo3nf83/4/

I hid the textarea and made the keyboard open when the mathquill box was clicked and it all seems to work pretty well.

I added an up & down arrow key so the layout is a bit messed up, but I don't have time this morning to add any more commands.

See what you can do from here

Mottie avatar Jan 12 '17 13:01 Mottie

Wow, that's really great, thanks a lot! I can now start to build things with that :)

I'll work on that next week.

Do you plan/want to integrate that into virtual-keyboard? Can I help?

Psycojoker avatar Jan 12 '17 16:01 Psycojoker

Sure! We could build a Mathquill extension, or something.

Mottie avatar Jan 12 '17 17:01 Mottie

@Mottie - This was super helpful for me. Quick q - I'm trying to make this work with multiple input fields but having trouble. I've got the keypad opening on click, but not sure if I need to create multiple textareas for the keypad to insert text into.

Here's my markup & code:

<div id="wrap">
    <textarea id="keyboard"></textarea>
     <p class="problem"><span class="mathquill-static-math">-\frac{1}{4}(4-x)=\frac{3}{4}</span> .    </p>
     <div id="mathquill" class="input" tabindex="1" data-disable-touch-keyboard></div>
     <p class="problem"><span class="mathquill-static-math">x^3=x^2 \cdot x</span></p>
    <div id="mathquill" class="input" tabindex="1" data-disable-touch-keyboard></div>
 </div>
		

js:

$(function() {
			var MQ = MathQuill.getInterface(2);
			var mathquill = MQ.MathField(document.getElementById('mathquill'));
			$('.mathquill-static-math').each(function() { MQ.StaticMath(this); });

			var specialKeys = {
					right: "Right",
					left: "Left",
					Down: "Down",
					Up: "Up",
					bksp: "Backspace",
					tab: "Tab",
					clear: "clear",
					s: "shift"
			}
			

			// add special keys, but don't override previous keyaction definitions
			Object.keys(specialKeys).forEach(function(key){
				if (!$.keyboard.keyaction[key]) {
					$.keyboard.keyaction[key] = specialKeys[key];
				}
			});

			$('.input').click(function(){
				$('#keyboard').getkeyboard().reveal();
				$('#arrows').getarrows().reveal();
			})
	
			$('#openKeypad').click(function(){
				$('#keyboard').getkeyboard().reveal();
				$('#arrows').getarrows().reveal();
				$('.input').focus();
			})
			
			 $.keyboard.layouts.arrows = {
					'normal': [
						'{Up}',
						'{left} {right}',
						'{Down}'
					]
				};
			
			$('.reset').click(function(){
				var kb = $('.input').getkeyboard();
				kb.$preview.val('').focus();
			});

			$('#keyboard')
				.on('keyboardChange', function(e, keyboard, el) {
					console.log(e.action);
					if (specialKeys[e.action]) {
							mathquill.keystroke(specialKeys[e.action]);
					} else {
							mathquill.cmd(e.action);      
					}
					// $('.input').focus(); 
				})
				.keyboard({
					usePreview: false,
					lockInput: true,
					noFocus: true,
					alwaysOpen: false,
					userClosed: false,
					layout: 'custom',
					display: {
						"Down": "&darr;",
						"Up": "&uarr;"
					},
					customLayout: {
						'default': [
							'{a} frac x y 1 2 3 \u00F7 {b}',
							'/ ( ) 4 5 6 *',
							'^ < >  7 8 9 -',
							', \u2264 \u2265 . 0  = +'						
							]
						}
							
						
				 }).addExtender({
					layout: 'arrows',
					showing: true	
			
				})
				
				// activate the typing extension
				.addTyping({
					showTyping: true,
					delay: 250
				});
				
		
		// Disable Native Keypad
					
		if (Modernizr.touch) {
					
					// Disable keyboard by adding readonly attribute to field
					 $('[data-disable-touch-keyboard]').attr('readonly', true);
					
			}		
							
							
		}); // End Function

Any help would be much appreciated. Thanks!!

feebala avatar Jan 27 '20 18:01 feebala

I'm not sure, I thought Mathquill created the inputs dynamically.

Mottie avatar Feb 02 '20 16:02 Mottie