1
votes

I have 2 TextFields in a Nativescript-vue application.

<StackLayout col="0" row="1">
  <Label text="Unit Price Excl"></Label>
  <TextField v-model="newItem.unitPriceExcl" @textChange="calcPricing" keyboardType="number" hint="Unit Price Excl"></TextField>
</StackLayout>
<StackLayout col="1" row="1">
  <Label text="Unit Price Incl"></Label>
  <TextField v-model="newItem.unitPriceIncl" @textChange="calcPricing" keyboardType="number" hint="Unit Price Incl"></TextField>
</StackLayout>

From the above, you can see I call the same method whenever the text changes for any of the 2 textboxes.

...
methods: {
  calcPricing(args) {
    // get focus here
  }
}
...

What I want is, in the calcPricing method, to determine which of the 2 textboxes currently has focus.

1
You may use focus / blur events on text field to recognise which one in active. - Manoj
@Manoj - I realise there is a focus event. Are you suggesting I have some kind of arbitrary variable to store which was the last textfield that was focussed, that I can then use in the textchange event? - Carel
Yes, I'm suggesting the same. - Manoj

1 Answers

1
votes

Here is a possible implementation of what you are trying to do

<TextField v-model="newItem.unitPriceExcl" @textChange="calcPricing" keyboardType="number" @focus="focus" @blur="blur" hint="Unit Price Excl"></TextField>
<TextField v-model="newItem.unitPriceIncl" @textChange="calcPricing" keyboardType="number" @focus="focus" @blur="blur" hint="Unit Price Incl"></TextField>
...
data: () => ({ focusedElement: null })
methods: {
  focus({ object }) {
    this.focusedElement = object;
  },

  // You don't have to handle blur depending on your logic, but I find it more consistent
  blur({ object }) {
    if (this.focusedElement !== object) return;
    this.focusedElement = null;
  }
}
...

If you don't really want to know which element has the focus, but rather from which element the modification come from. You can do it this way :

<TextField v-model="newItem.unitPriceExcl" @textChange="calcPricing('unitPriceExl')" keyboardType="number" hint="Unit Price Excl"></TextField>
...
methods: {
  calcPricing(name) {
    return (args) => {
      // Your logic goes here, you have access to name, and to args
    }
  }
}
...

Side note: you can also use some native methods to find which view is currently focused. However note that it's not faster, and also that it's not recommended, the main idea is to used the NS common api.

<TextField v-model="newItem.unitPriceExcl" @textChange="calcPricing" keyboardType="number" hint="Unit Price Excl" ref="unitPriceExcl"></TextField>
...
let UIResponder;
if (isIOS) {
  UIResponder = (UIResponder as any).extend({
      currentFirstResponder() {
         this.currentFirstResponder = null;
         UIApplication.sharedApplication.sendActionToFromForEvent('findFirstResponder', null, null, null);
         return this.currentFirstResponder;
      },
      findFirstResponder(application: UIApplication) {
        this.currentFirstResponder = new WeakRef(self)
      }
    }, {
      exposedMethods: {
        currentFirstResponder: { returns: UIView, params: [ ] }
      }
    })
}
...
methods: {
  getFocusedView() {
    if (isAndroid) {
      const activity = application.android.foregroundActivity;
      if (activity) {
        return activity.getCurrentFocus()
      }
    } else if (isIOS) {
      return UIResponder.currentFirstResponder;
    }

    return null;
  },

  isFocused(object) {
    if (object.nativeView && object.nativeView.nativeView) return false;
    return this.getFocusedView() === object.nativeView.nativeView;
  },

  calcPricing(args) {
    if (this.isFocused(this.$refs.unitPriceExcl)) {
        console.log('unitPriceExcl is selected');
    }
  },
}
...