Get cursor position in Ionic 4? - ionic4

I cannot find selectionStart in Ionic 4 when I am referencing ion-textarea. In Ionic v3 I did something like this to get cursor position:
for iOS textArea._native.nativeElement.selectionStart
and for Android event.target.selectionStart
but it seems like I cannot find selectionStart on elementRef.
I tried to access element using
#ViewChild('txArea', { read: ElementRef }) textArea: ElementRef;
and
<ion-textarea
#txArea
[(ngModel)]="description"
(keyup)="onKeyUp($event, txArea)"
rows="4"
autocorrect="on" autocomplete="on"
placeholder="Enter description (i.e. #JoeDoe, #forehand)">
</ion-textarea>
Can somebody help with this?
Thanks

I think you're looking for this:
https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent
MouseEvent.clientX
MouseEvent.clientY

You can use querySelector() on the nativeElement.
Assume that you are trying to access the view child reference using an instance variable as follows:
#ViewChild('txArea', {static: false, read: ElementRef})
txArea: ElementRef;
You can get selectionStart from an event handler (class method) as follows:
onClick () {
console.log(
this
.txArea
.nativeElement
.querySelector('textarea')
.selectionStart
)
}

I found a way to get the real input in Ionic
onKeyUp($event, txArea){
const realInput = $event.target.querySelector('input')
const start = realInput.selectionStart;
const end = realInput.selectionEnd;
}
this way you can get selectionStart and selectionEnd

Related

Stuck with $ref pointing to Proxy object with vue-router

I was using VueJS in browser mode and am now trying to switch my code to a VueJS SPA and vue-router. I've been stuck for hours with a $refs not working anymore.
To interact with my Google Charts, I was using an absolute reference to the graph (this.$refs.villesChart) to get selected data like that:
computed: {
eventsprox() {
let eventsprox = {
select: () => {
var selection = "";
if (this.$refs.villesChart) selection = this.$refs.villesChart1.chartObject.getSelection();
if (selection.length) {
var row = selection0[0].row + 1;
this.code_commune = this.dataprox[row][4];
this.changerville(this.code_commune, this.dataprox[row][0]);
}
return false;
},
};
return eventsprox;
}
HTML code for graph:
<GChart type="BarChart" id="villesChart" ref="villesChart" :data="dataprox" :options="optionsprox" :events="eventsprox"/>
I don't know why, but in browser mode, this.$refs.villesChart is a component:
[1]: https://i.stack.imgur.com/xJ8pV.png
but now it is a proxy object, and lost its chartObject attribute:
[2]: https://i.stack.imgur.com/JyXrL.png
I'm really confused. Do you have an idea why?
And if I use the proxy object, then I get a Vue warning "Avoid app logic that relies on enumerating keys on a component instance" and it is not working in production environment.
Thanks a lot for your help!!
After hours of testing different solutions, I finally found a solution working with Vue3 and Vue-google-chart 1.1.0.
I got rid of "refs" and put the events definition and code in the data section of my Vue 3 app (instead of computed) and accessed the chart data through a component variable I used to populate it.
Here is my event code where this.dataprox is my data table for the chart:
eventsprox: {
'click': (e) => {
const barselect = parseInt(e.targetID.split('#')[2]) + 1;
this.code_commune = this.dataprox[barselect][4];
this.nom_commune = this.dataprox[barselect][0];
this.changerville(this.code_commune, this.nom_commune);
}
},
My Gchart html code:
<GChart type="AreaChart" :data="datag" :options="optionsg" :events="eventsprox"/>
I hope it can help!

dueChange event for duet picker not working with Ionic 5 / Vue 3

I am using Duet Date Picker in the Ionic 5/ Vue 3 application. The event listener for the duetChange is not working for me.
Here is my code snippet:
<duet-date-picker #duetChange="handleInput($event)"identifier="date" :localization.prop="localisation" direction="left"></duet-date-picker>
handleInput(e: any) {
console.log("e", e);
this.$emit("input", this.content);
}
I have even tried following listners:
v-on:duetChange="handleInput($event)"
v-on:change="handleInput($event)"
#change="handleInput($event)"
Is this the right way to add an event listener or am I missing something?
Here is the code sandbox link:
https://codesandbox.io/s/old-silence-1f0nx?file=/src/App.vue
TIA
I tried to use the duetDatePicker in a Vue CodeSandbox, the following works:
<duet-date-picker
#duetChange="handleInput"
identifier="date"
:localization.prop="localisation_uk"
>
Along with the above, my methods object contained the handleInput function declaration.
Check the App.vue file in the codesandbox for details.
I was able to get it to work the old fashion way...
onMounted(() => {
// Select the date picker component
const date = document.getElementById("date-picker");
// Listen for when date is selected
date.addEventListener("duetChange", function (e) {
console.log("selected date", e.detail.valueAsDate);
});
});
<duet-date-picker id="date-picker"
#duetChange="handleInput"
identifier="date"
:localization.prop="localisation_uk"
>

Fluent/Fabric - Is it possible to clear the input of the NormalPeoplePicker programmatically?

Is it possible to clear the input text (e.g. "qweqweqweqwe" in the example below) of the (Fluent/Fabric) NormalPeoplePicker programmatically?
I have tried accessing the input element (via the onBlur event) and attempted to change it's value and innerHtml but that doesn't work. Also, that doesn't seem to be a good way of doing it.
https://developer.microsoft.com/en-us/fluentui#/controls/web/peoplepicker
NormalPeoplePicker Component keep input value inside state and its not possible to change it directly:
const picker = React.useRef(null)
...
<NormalPeoplePicker
...
onBlur={() => {
if(picker.current) {
picker.current.input.current.value = ""; // Uncaught TypeError: Cannot set property value of #<Autofill> which has only a getter
}
}}
/>
From Official Documentation inside implementation section there is useful method updateValue which allows to change the input value.
const picker = React.useRef(null)
...
<NormalPeoplePicker
...
onBlur={() => {
if(picker.current) {
picker.current.input.current._updateValue("");
}
}}
/>
Codepen working example ln: 104.
Note:
This is a temporary solution, test every use case before production.
let orgSelected: ITag[] = [];
orgSelected.push({key:0 name:''});
const [selectedOrg,setselectedOrg] = useState(orgSelected);
On TagPicker Property just assign the statevalue like this.
selectedItems={selectedOrg}
This way the tagpicker property will always be selected with an empty item.

How can I use clear() method of Select component in UI-kitten?

In a react app I am using ui-kitten components, specifically a Select component:
<Select
placeholder="Selecciona el departamento"
data={departmentOptions}
selectedOption={props.dept}
onSelect={(newDepartment) => {
props.setDepartment(newDepartment);
props.setDepartmentValidation(validationSuccess);
setDept(null);
// props.department = newDepartment;
}}
textStyle={textStyle.label}
controlStyle={styles.input}
style={{ marginBottom: 16 }}
labelStyle={textStyle.label}
icon={renderIcon}
/>
I would like to reset the Select component on the placeholder after every re-render, not the previous selected option.
I know that that method clear() is available as is described in the official documentation: ui-kitten docs but I don't know how to use those methods.
Any idea on how to use these methods (e.g clear(), blur(), show(), hide(), etc.).
I was wondering the exact same question too, and the docs weren't really clear about using methods. However, I found that the section on the Icons component has an example of how to use methods to animate the icons on the press of a button.
You need this at the start of your function body:
const select = React.useRef()
Then in your select component, have something like this:
<Select ref={select}>{...}</Select>
Finally, just do select.clear() when needed to clear the select component.
Let me know if this helps.
This one helped me const select = React.useRef(). I've shared a small snippet of code that you can refer to and the GitHub link that helped me.
const [clear, setClear] = useState(false);
// Create a ref
const select = React.useRef();
//useEffect to check when the clear value has changed
useEffect(() => {
//clear the ref when the clear value has changed
select.current.clear();
}, [clear]);
// Here is your select component
<Select
ref = {select} // ref we created before
selectedIndex = {selectedIndex}
onSelect = {(index) => setSelectedIndex(index)} >
<SelectItem title = "Option 1" / >
<SelectItem title = "Option 2" / >
<SelectItem title = "Option 3" / >
</Select>
Check out this issue on the UI-Kitten GitHub repo.
Here is the link to the comment that helped me. https://github.com/akveo/react-native-ui-kitten/issues/1001#issuecomment-612070876

cy.clear() not clearing input field properly - Cypress

When I perform
cy.get('#fsp-name').clear().type('random text');
If the text already has value lets say 'assd asd adsdsd' and I perform above command I get something similar to 'random textassd'
I also tried using
cy.get('#fsp-name').clear().should('have.value', '').type('random text');
It works some time and in other times it complains it does not equal to ' '.
And I am trying to do this in a each loop like below
const data = [
{selector:'#name', newValue: 'John'},
{selector:'#phone', newValue: '1234567'}
];
cy.wrap(data).each(field => {
cy.get(field.selector).clear().should('have.value', '').type(field.newValue);
cy.contains('Save').click();
cy.visit('/abc/sdd');
cy.get(field.selector).invoke('val').should('equal', field.newValue);
});
Tried the solutions provided above, but all did not help.
I've ended up using this:
cy.get('#my-input-element').focus().clear();
If that doesn't work, the not so happy workaround is:
cy.get('#my-input-element').invoke('val', '');
When .type somehow did not finish the given string (rare cases):
cy.get('#my-input-element').invoke('val', 'Some text here');
I had a similar problem and It was related to focused and click related. I can suggest trying the following two option. I DON'T know it is right or wrong.
cy.get('#fsp-name').click().clear().type('random text');
OR
cy.get('#fsp-name').click().focused().clear().type('random text');
I was talking to the developer and according to him we are using MaterialUI and have some default component using focused and click event differently. After having both options resolved my problem
.clear() is an alias of .type('{selectall}{backspace}') however depending upon the input field set up this would not work in all cases.
I solved this by using .type('{selectall}{backspace}{selectall}{backspace}') instead of the .clear()
I'm using Cypress version 3.8.3 and I noticed that I have to invoke clear() sometimes two times in a row:
cy.get('#fsp-name').clear();
cy.get('#fsp-name').clear();
Seems like the cypress test runner is getting ahead of app initialization and some helpful article links below
https://www.cypress.io/blog/2018/02/05/when-can-the-test-start/
https://www.cypress.io/blog/2019/01/22/when-can-the-test-click/
As of now adding wait before clearing makes the test pass. Let me know if anyone has better solutions
I've had the same problem using Mui React with Cypress and when I called clear an ";" was added.
I've applied the same #Steven Vachon solution calling clear() function of cypress first.
Here my solution:
const clearInputElement = (input) => {
const input2Search = input;
cy.get(input2Search).clear();
cy.get(input2Search).then(($elm) => {
const event = new Event(input2Search, { bubbles: true, cancelable: true });
const input = $elm.get(0); // `as HTMLInputElement` for TypeScript
input.value = "";
input.dispatchEvent(event);
});
};
I ended up having to do clear manually via the DOM:
cy.get('input').then($elm => {
const event = new Event('input', { bubbles: true, cancelable: true });
const input = $elm.get(0); // `as HTMLInputElement` for TypeScript
input.value = '';
input.dispatchEvent(event);
});
I, too, faced a similar issue while using with react-ace editor. I wind up with
function typeContentOnSelectingExistingContent(elementId, content) {
return cy.get(`#${elementId}`).type(`{selectAll}{selectAll}${content}`)
}
Try this, it worked for me:
cy.get('#fsp-name').clear({ force: true }).then(() => {
cy.wait(3000)
cy.get('#fsp-name').invoke('val', '').type(`${valueToBeTyped}{enter}`)
})
Official docs states that:
It is unsafe to chain further commands that rely on the subject after .clear().
That's probably why the code in the original question didn't work, it was chaining clear and type commands:
cy.get('#fsp-name').clear().type('random text');
So, a simple alternative would be something like:
cy.get('#fsp-name').clear()
cy.get('#fsp-name').type('some text')
More about the clear command:
https://docs.cypress.io/api/commands/clear