4

I have a bit of code on my website to turn users text input into all uppercase letters. I thought it was working fine until someone pointed out that on their mobile phone a strange glitch occurs. As the user types into the textbox, it inserts extra letters as the user types, so for example, if they are trying to type 'BOB' it changes to 'BOBOB' or if they type 'DAD' it becomes 'DADAD'.

I've replicated this issue on two different Android phones and on an Amazon Fire tablet. It doesn't happen on a desktop PC.

Edit: I can't just use CSS to change the text to uppercase as it reverts back to however the user typed it once the form (that the textbox is on) is submitted. I need the form to submit with the text actually converted to uppercase.

$('.surname input[type=text]').keyup(function() {
  var newVal = $(this).val().toUpperCase();
  console.log('newVal', newVal);
  $(this).val(newVal);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="surname">
  <input type="text">
</div>
David M
  • 43
  • 6
  • Perhaps use both `input` and `keyup` events as suggested here: https://stackoverflow.com/questions/38989559/jquery-keyup-event-for-mobile-device/39031921 – Nick Parsons Sep 22 '19 at 01:15
  • 1
    I can confirm the issue on my Android too. – CertainPerformance Sep 22 '19 at 01:16
  • 2
    Messing with text input consistently is really hard – is an alternative approach maybe possible? For example, uppercasing when focus leaves the textbox, `text-transform: uppercase`, a separate label, … – Ry- Sep 22 '19 at 01:23
  • 2
    It's not a jQuery issue, using vanilla event handlers produces the bug as well – CertainPerformance Sep 22 '19 at 01:23
  • 1
    What happens if you want to edit the text in the middle? – Lee Taylor Sep 22 '19 at 01:28
  • Why not move your code to `keydown` listener function and add `e.preventDefault()` . Example: `input.value = input.value + e.key.toUpperCase(); e.preventDefault();` – Cocest Sep 22 '19 at 11:31
  • 1
    The solution you're trying to implement has a lot of issues; what if user changes the caret position, drag the text, or even past the input. The best approach is to convert the input to uppercase before submitting to the server. – Cocest Sep 22 '19 at 11:38
  • @Cocest ok, how do i go about doing that please? what is the full script I need to make it work? – David M Sep 22 '19 at 19:10
  • Sorry for replying late. I will paste the code as soon as possible. – Cocest Sep 22 '19 at 20:25

2 Answers2

5

Formatting text as it’s created while maintaining the right selection across browsers is notoriously difficult. I would do this by styling the text to look uppercase instead:

.surname input {
  text-transform: uppercase;
}
<div class="surname">
  <input type="text">
</div>

Whatever reads the text can then convert it to uppercase. Or, if you really need the value to change on the frontend, convert it to uppercase on blur.

Ry-
  • 218,210
  • 55
  • 464
  • 476
  • (@David M) Note: Keeping a separate copy of the value around may lead to hard to find bugs if the two copies get out of sync, so make sure that if the value is updated in code, the input element value is also updated. – Jochem Kuijpers Sep 22 '19 at 01:28
  • Unfortunately, I can't use CSS to change it to uppercase as it reverts back to however the user typed it once the form (that the textbox is on) is submitted. Does using 'blur' fix the issue, and if so, what is the code needed? – David M Sep 22 '19 at 02:22
  • 1
    @DavidM: Relying on JavaScript to preprocess user input is a little awkward. Are you sure you can’t get the backend to change it? Anyway, `$('#the-form').submit(function () { $('.surname input').val(function (i, val) { return val.toUpperCase(); }); });` should be about right (using the form’s `submit` event rather than the input’s `blur`). – Ry- Sep 22 '19 at 04:05
  • @Ry: Thanks for your help so far. The form submits a user's customization on a product page to a 'Your Shopping Cart' page. I can't alter the code of the Cart page to change all text to uppercase as it's only selected products that need the customized text to be uppercase. I tried adding your code to the bottom of form on the product page but it's not working so I've obviously done something wrong. The actual code I added was: `` – David M Sep 22 '19 at 10:14
  • @DavidM: Is `#product` the form? Can you show its HTML? – Ry- Sep 22 '19 at 21:42
  • @Ry- I think you're solution is correct. @DavidM remove this `$(this).val(newVal);` (if you haven't already) and let the CSS handle it. If it must be upper cased do it on form submit – Drew Delano Sep 22 '19 at 23:13
  • @Ry: yes, as far as I can tell the form is named 'product'. The code is in the Liquid language as it's a Shopify store. The code at the start of the form is: {% form 'product', product, class:productform_class %} – David M Sep 23 '19 at 10:43
  • @DavidM: Names and ids are different. Can you show its HTML, as rendered? (i.e. look at it with View Source in your browser.) Logging `$('#product').length` and `$('.surname input').length` at the beginning of the script will also help. – Ry- Sep 23 '19 at 16:33
  • @DavidM: I checked your link – the form doesn’t have the id `product` *and* the input doesn’t have a parent with the class `surname`. If you can’t figure out how to change the relevant HTML, replace `$('#product')` with `$('#surname').closest('form')` and `$('.surname input')` with `$('#surname')`. – Ry- Sep 23 '19 at 16:37
  • @Ry: So I need the script to be as follows?: `` Is that correct? – David M Sep 23 '19 at 23:58
  • @Ry: It is now converting the text to uppercase when the button is clicked, thanks. I just need to test it on mobile devices to see if the original issue has gone away. – David M Sep 24 '19 at 10:34
  • @Ry: it seems to work fine when tested on my samsung galaxy phone. do you think this code will work fine across all browsers and devices? – David M Sep 25 '19 at 10:06
  • @DavidM: Yes – ones that support your version of jQuery, anyway, when it loads successfully. (JavaScript can fail to load, which is why this should be done on the server side regardless of how portable it is, but…) – Ry- Sep 25 '19 at 20:15
  • @Ry: Thanks very much for your help. If the javascript failed to load for a user, would it simply mean the text doesn't get converted to uppercase but the user's input form can still be submitted (which is fine), or would it prevent the form actually being submitted (and therefore prevent the user adding the product to the shopping cart)? – David M Sep 25 '19 at 23:40
  • @DavidM: The former. – Ry- Sep 26 '19 at 00:00
  • @Ry: Excllent. Thanks again – David M Sep 26 '19 at 11:54
0

This code convert the user's input to uppercase before submit.

STYLE:

input#surname {
   text-transform: uppercase;
}

/*add this to your css section or css file linked to the page*/

HTML:

<form name="reg-form" onsubmit="return processForm(event)" action="/cart/add" id="product_form_4118292955170" accept-charset="UTF-8" class="product-form--wide" enctype="multipart/form-data" method="post">
    <input type="hidden" name="form_type" value="product">
    <input type="hidden" name="utf8" value="✓">
    <!--add other input from the current or original form-->
    <div class="surname">
        <input required class="required" id="surname" type="text" name="properties[SURNAME]">
    </div>
    <!--put submit button here-->
</form>

JavaScript Code:

<script>
    function processForm(e) {
        var username_input = document.getElementById("surname");
        username_input.value = username_input.value.toUpperCase();

        return true;

        // You can submit the user's input here using Ajax, but
        // don't forget to remove action attribute in the form, 
        // set "e.pereventDefault()" and return false
    }
</script>
Cocest
  • 147
  • 1
  • 2
  • 15
  • 1
    @David M Combine my solution with Ry-♦ solution that will solve your problem, Thank you. – Cocest Sep 22 '19 at 21:04
  • I can see the script working (it is turning the text to uppercase). I can't figure out how to get it working with the original form on the page (that actually adds the product to the shopping cart). The page is at [link](https://glamorous-gifts.co.uk/products/test-product-mug-with-surname?usersurname) – David M Sep 23 '19 at 11:09
  • @David M: I have edited my answer, check it out. Don't forget to add other input to the new form from the current form. – Cocest Sep 23 '19 at 14:18
  • Thanks for trying to help. I've added the code to my page but I can't put the 'onsubmit' into the form tag as it's not HTML (it's "Liquid" code) so it won't accept it. The Liquid code at the start of the form is as follows: `{% form 'product', product, class:productform_class; %} – David M Sep 23 '19 at 23:49
  • @DavidM Try to re-create the solution using Liquid Code. Liquid Code is beyond my scope, maybe this tutorial might help: https://www.shopify.com.ng/partners/blog/building-a-clickable-call-to-action-button-for-your-shopify-theme – Cocest Sep 24 '19 at 08:23
  • It's ok, thanks very much for trying. I can't find anything on how to do call an onsubmit function in Liquid code. I tried to add the onsubmit to the 'add to cart' button (which is HTML) but that didn't work. – David M Sep 24 '19 at 10:33