Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android issue #127

Open
egeriis opened this issue Feb 18, 2015 · 20 comments
Open

Android issue #127

egeriis opened this issue Feb 18, 2015 · 20 comments

Comments

@egeriis
Copy link
Contributor

egeriis commented Feb 18, 2015

MentionsInput doesn't work at all in Android (4.4.2) at least, since keyPress is never triggered.

So my question is why the inputBuffer is filled from the keyPress listener rather than the bottom of the keyDown listener?

@egeriis
Copy link
Contributor Author

egeriis commented Mar 23, 2015

@djhvscf Any input?

@djhvscf
Copy link
Contributor

djhvscf commented Mar 26, 2015

Working on it

@egeriis
Copy link
Contributor Author

egeriis commented Mar 27, 2015

@djhvscf I would love to do a pull request. I'm simply a bit lost in the source code :)

@djhvscf
Copy link
Contributor

djhvscf commented Mar 27, 2015

Yes.. but always you have to try! :)

@egeriis
Copy link
Contributor Author

egeriis commented May 22, 2015

@djhvscf Any progress?

@fmpwizard
Copy link

@egeriis @djhvscf I run into this issue too running android 4.4.4 inside a webview. I went ahead and just commented out the code inside onInputBoxKeyPress and put it at the top of onInputBoxInput

code snippet:

//Takes the input event when users write or delete something
    function onInputBoxInput(e) {
      //certain versions of android mobile browser don't trigger the keypress event.
      if(e.keyCode !== KEY.BACKSPACE) {
        var typedValue = String.fromCharCode(e.which || e.keyCode); //Takes the string that represent this CharCode
        inputBuffer.push(typedValue); //Push the value pressed into inputBuffer
      }
      updateValues();
      updateMentionsCollection();

      var triggerCharIndex = _.lastIndexOf(inputBuffer, settings.triggerChar); //Returns the last match of the triggerChar in the inputBuffer
      if (triggerCharIndex > -1) { //If the triggerChar is present in the inputBuffer array
        currentDataQuery = inputBuffer.slice(triggerCharIndex + 1).join(''); //Gets the currentDataQuery
        currentDataQuery = utils.rtrim(currentDataQuery); //Deletes the whitespaces

        _.defer(_.bind(doSearch, this, currentDataQuery)); //Invoking the function doSearch ( Bind the function to this)
      }
    }

    //Takes the keypress event
    function onInputBoxKeyPress(e) {
      /*if(e.keyCode !== KEY.BACKSPACE) { //If the key pressed is not the backspace
        var typedValue = String.fromCharCode(e.which || e.keyCode); //Takes the string that represent this CharCode
        inputBuffer.push(typedValue); //Push the value pressed into inputBuffer
      }*/
    }

Now my android app that uses webview has this plugin working again, and it still works on Firefox and Chrome on the desktop. as well as chrome and firefox on android.

@djhvscf would you accept a PR for this fix?

UPDATE
Turns out that to make it work I'm also catching the input event on my js code and if I see a keyCode === 0, I read the text area text and then override the value, which is then passed to mentions and then it all works

@djhvscf
Copy link
Contributor

djhvscf commented Jun 17, 2015

Sure please open a PR

@egeriis
Copy link
Contributor Author

egeriis commented Aug 10, 2015

@fmpwizard Did you ever open a PR for this?

@kenneymyers
Copy link

Can you tell us what the fix was here (show us the example code for testing the keyCode as this still seems to be a problem for Android?

@fmpwizard
Copy link

sorry for the delay, what I ended up doing on my project may qualify as a hack, instead of a clean fix.

I first bind the input event of the text area field like this:

        //Android >= 4.4.2 doesn't send the keyCode on some events, so we detect that here
        //and send the last char of the message box.
        sendBoxElem.bind("input", function(e) {
          var char = this.value.charCodeAt(this.value.length - 1);
          scope.data = char;
          if(e.keyCode === undefined){
            e.keyCode = char;
          }
          return true;
        });

Note that this means that to trigger the drop down auto complete, the @ sign has to be the last character in the text area, in other words, if you type a message on your cell, then click in the middle of the field, and type @, the plugin will not know about it, because I just look at the last char, for my site this was good enough.

And then I made the changes I listed a few messages earlier on this ticket.

Hope this helps, it has been working well for us since I implemented several months ago.

@NikunjDoshi
Copy link

Thanks @fmpwizard , Here`s my iteration to your fix, inorder to make it work cross browser/device(android / ios / desktop)

  1. var sendBoxElem = $('textarea.mention'); sendBoxElem.bind("input", function(e) { var ua = navigator.userAgent.toLowerCase(); var isAndroid = ua.indexOf("android") > -1; //&& ua.indexOf("mobile"); if(isAndroid) { var char = this.value.charCodeAt(this.value.length - 1); //$scope.data = char; if(e.keyCode === undefined){ e.keyCode = char; } return true; } });

  2. `function onInputBoxInput(e) {
    var ua = navigator.userAgent.toLowerCase();
    var isAndroid = ua.indexOf("android") > -1; //&& ua.indexOf("mobile");
    if(isAndroid) {//certain versions of android mobile browser don't trigger the keypress event.
    if(e.keyCode !== KEY.BACKSPACE) {
    var typedValue = String.fromCharCode(e.which || e.keyCode); //Takes the string that represent this CharCode
    inputBuffer.push(typedValue); //Push the value pressed into inputBuffer
    }
    }
    updateValues();
    updateMentionsCollection();

        var triggerCharIndex = _.lastIndexOf(inputBuffer, settings.triggerChar); //Returns the last match of the triggerChar in the inputBuffer
        if (triggerCharIndex > -1) { //If the triggerChar is present in the inputBuffer array
            currentDataQuery = inputBuffer.slice(triggerCharIndex + 1).join(''); //Gets the currentDataQuery
            currentDataQuery = utils.rtrim(currentDataQuery); //Deletes the whitespaces
            _.defer(_.bind(doSearch, this, currentDataQuery)); //Invoking the function doSearch ( Bind the function to this)
        }
    }
    
    //Takes the keypress event
    function onInputBoxKeyPress(e) {
        var ua = navigator.userAgent.toLowerCase();
        var isAndroid = ua.indexOf("android") > -1; //&& ua.indexOf("mobile");
        if(!isAndroid) {
            if(e.keyCode !== KEY.BACKSPACE) { //If the key pressed is not the backspace
                var typedValue = String.fromCharCode(e.which || e.keyCode); //Takes the string that represent this CharCode
                inputBuffer.push(typedValue); //Push the value pressed into inputBuffer
            }
        }
    }`
    

Hope it helps someone

Regards,
Nikunj

@kapilkumar1983
Copy link

kapilkumar1983 commented Dec 20, 2016

Dear Sir,

i am facing mobile (android) chrome problem mention list not showing, Please help me, keypress function is not working on mobile, please help me
thanks

richjeffery added a commit to richjeffery/jquery-mentions-input that referenced this issue Aug 7, 2017
* Adjusts code to remove deprecated jQuery calls
* Adds functionality that autocompletes inputs if there's only one result and you press space
* Improves support for autocomplete on mobile devices (podio#127)
@arijit-das
Copy link

arijit-das commented Dec 6, 2017

Hello,
I am still having this issue although i took the commited js of @richjeffery .

I am getting undefined although i am setting the e.keyCode ... in android

Did you guys made it work? I am using the code same as @NikunjDoshi mentioned

@richjeffery
Copy link

Hi @arijit-das - the current release (0.1.4) of my fork is tested working on Android 8 and Android 6 using the built-in keyboard, as part of a website's textbox.

  1. are you using it in-browser, or as part of an app?
  2. are you on the current release? https://github.com/richjeffery/jquery-mentions-input/releases/latest

@arijit-das
Copy link

Hello @richjeffery ... thanks for answering ...

  1. I was using Android 7 and google Keyboard ...
  2. I am using it as a website textarea from browser
  3. Looks like i am using 1.0.3 ... Let me take the code fro the current 1.0.4 and check ...
    Thank you

@arijit-das
Copy link

arijit-das commented Dec 6, 2017

@richjeffery ... No its not working for me ...
I am using this in my page

setTimeout(function(){
$('textarea.mention').bind("input", function(e) {
var ua = navigator.userAgent.toLowerCase();
var isAndroid = ua.indexOf("android") > -1; //&& ua.indexOf("mobile");
if(isAndroid) {
var char = this.value.charCodeAt(this.value.length - 1);
//$scope.data = char;
if(e.keyCode === undefined){

e.keyCode = char;
//alert('ab' + e.keyCode + ' ' + char);
}
return true;
}
});
}, 4000);

to catch the keypress because i have several textarea with mention

In android block in onInputBoxInput function, typedValue is always empty. it seems this function is getting called before setting the character.

@richjeffery
Copy link

@arijit-das - I too use multiple mention inputs on some pages, but my code is slightly different to catch Android keypresses (for example, it's not wrapped in a setTimeout, just within a script block):

// On mobile, bind typing so mentions behave as expected
                $('textarea.mention').bind('input', function(e) { 
                    var ua = navigator.userAgent.toLowerCase(); 
                    var isAndroid = ua.indexOf('android') > -1;
                    //&& ua.indexOf(\'mobile\'); 
                    if(isAndroid) { 
                        var char = this.value.charCodeAt(this.value.length - 1); //$scope.data = char; 
                        if(e.keyCode === undefined){ 
                            e.keyCode = char; 
                        } 
                    return true; 
                    } 
                });

I'm actually not sure wrapping it in a setTimeout block would work as expected. In addition, what is the typedValue in onInputBoxKeyPress, as you are right that onInputBoxInput is called beforehand.

@arijit-das
Copy link

Hi, @richjeffery ,
Problem was indeed with settimeout ... When i removed it it worked for the 1st textarea ... but for the other textareas it didn't work ...

@arijit-das
Copy link

Ok it worked for me ... Problem was my code block was getting added before all the textareas in the DOM ... So i made sure the code block is added in the last of those text areas. Wrapping the code block in document.ready doesnot work also

@gregoiremotot
Copy link

I added this in my html

 jQuery('textarea.mention').bind('input', function(e) { 
      var ua = navigator.userAgent.toLowerCase(); 
      var isAndroid = ua.indexOf('android') > -1;
      //&& ua.indexOf(\'mobile\'); 
      if(isAndroid) { 
          var char = this.value.charCodeAt(this.value.length - 1); //$scope.data = char; 
          if(e.keyCode === undefined){ 
              e.keyCode = char; 
          } 
      return true; 
      } 
  });

and in jquery.mentionsInput.js line 112
I changed

lmInputBox.bind('keypress', onInputBoxKeyPress); //Bind the keypress event to the text area

to

 // On mobile, bind typing so mentions behave as expected
var ua = navigator.userAgent.toLowerCase();
var isAndroid = ua.indexOf("android") > -1; //&& ua.indexOf("mobile");
if (isAndroid) {
    elmInputBox.bind('input', onInputBoxKeyPress); //Bind the input event to the text area
} else {
   elmInputBox.bind('keypress', onInputBoxKeyPress); //Bind the keypress event to the text area
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants