quasar: Single-tap outside a QDialog or QSelect doesn't work in Cordova iOS app. Have to double-tap.

What happened?

The user has to double-tap outside a QDialog to close it when the app is built for cordova/iOS. Single tap doesn’t do anything.

What did you expect to happen?

For the QDialog to be closed when a single tap is made outside of it.

Reproduction URL

n/a

How to reproduce?

It’s only when it’s running through Cordova on iOS, either via build or dev

When trying via dev I stopped quasar dev -m cordova -T ios and ran quasar dev, then went back to the app on the phone without rebuilding.

It then only needed a single tap outside a QDialog to dismiss it. When I ran quasar dev -m cordova -T ios again and returned to the app I need double tap again.

Flavour

Quasar CLI with Webpack (@quasar/cli | @quasar/app-webpack)

Areas

Components (quasar), Cordova Mode

Platforms/Browsers

iOS

Quasar info output

Operating System - Darwin(21.4.0) - darwin/x64
NodeJs - 16.2.0

Global packages
  NPM - 7.13.0
  yarn - 1.22.18
  @quasar/cli - 1.3.0
  @quasar/icongenie - 2.3.3
  cordova - 11.0.0

Important local packages
  quasar - 2.7.1 -- Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time
  @quasar/app-webpack - 3.5.3 -- Quasar Framework App CLI with Webpack
  @quasar/extras - 1.14.0 -- Quasar Framework fonts, icons and animations
  eslint-plugin-quasar - Not installed
  vue - 3.2.31 -- The progressive JavaScript framework for building modern web UI.
  vue-router - 4.0.14
  pinia - Not installed
  vuex - 4.0.2 -- state management for Vue.js
  electron - 7.3.3 -- Build cross platform desktop apps with JavaScript, HTML, and CSS
  electron-packager - Not installed
  electron-builder - Not installed
  @babel/core - 7.18.2 -- Babel compiler core.
  webpack - 5.73.0 -- Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.
  webpack-dev-server - 4.8.1 -- Serves a webpack app. Updates the browser on changes.
  workbox-webpack-plugin - Not installed
  register-service-worker - 1.7.2 -- Script for registering service worker, with hooks
  typescript - 4.5.5 -- TypeScript is a language for application scale JavaScript development
  @capacitor/core - Not installed
  @capacitor/cli - Not installed
  @capacitor/android - Not installed
  @capacitor/ios - Not installed

Quasar App Extensions
  *None installed*

Relevant log output

No response

Additional context

Single tap works as it should on Android, as does single click in Chrome or Safari when I’m developing on Desktop, or even when I access the dev server over the network on iOS Safari.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 1
  • Comments: 32 (5 by maintainers)

Commits related to this issue

Most upvoted comments

Fix will be available in Quasar v2.10.3 and v1.22.3

My app, which is a PWA, suffers from this exact issue on iOS so I don’t think it’s a Cordova-issue; it seems to manifest itself only when running in a dedicated webview; my PWA has to be added to the home-screen and accesses from there in order for the problem to appear. The problem is clear as day, as you can add https://quasar.dev to the home-screen, access it from there and see the problem in action:

https://user-images.githubusercontent.com/351744/202194893-0d339fad-74be-4765-84e5-3874f6af1731.mov

I’ve gotten an earful from my end-users because of this 👎 I don’t know if it’s related, but I also have a @dblclick-handler on a q-tab which ends up requiring three taps in order to trigger. That’s just crazy. Can we please have someone from the Quasar-team look at this?

I also encounter this breaking issue and this needs a fix ASAP. For the meantime I’ve created this work around hope this helps @skmbr

openDialog() { this.show_dialog = true;

  this.$nextTick(() => {
    $(".q-dialog__backdrop").on('click', function(event){
      this.show_dialog = false;
      event.stopPropagation();
      event.stopImmediatePropagation();
    }.bind(this));
  });

},

@skmbr I have a bit of a workaround for this, it’s not ideal but seems to work (sorry I still use options API).

<template>
<q-dialog
    v-model="_modelValue"
    transition-show="slide-up"
    transition-hide="slide-down"
    :position="position || 'bottom'"
  >
    <slot/>
  </q-dialog>
</template>

<script>
export default {
  props: ["modelValue", "position"],
  emits: ["update:model-value"],
  computed: {
    _modelValue: {
      get () { return this.modelValue },
      set (value) { this.$emit('update:model-value', value) },
    },
  },
  watch: {
    async _modelValue(newVal) {
      if (newVal) {
        await this.$nextTick();
      }
      const background = document.querySelector('.q-dialog__backdrop');
      if (newVal) {
        background.addEventListener('click', () => this.clicked());
      } else {
        background.removeEventListener('click', () => this.clicked());
      }
    }
  },
  methods: {
    clicked() {
      this._modelValue = false;
    }
  }
}
</script>