I am using a ion-datetime picker in ionic 4. This is how I implement it:
in the home.page.html
<ion-item color="dark">
<ion-label>Rest Duration</ion-label>
<ion-datetime
display-format="mm:ss"
placeholder="Tap here"
[(ngModel)]="fullTime"
></ion-datetime>
</ion-item>
in the home.page.ts
export class HomePage {
percent = 0;
radius = 0;
fullTime: any = '00:01:30';
constructor() {}
}
Why is it that when I change my date picker it gives me this error?
[Intervention] Ignored attempt to cancel a touchmove event with
cancelable=false, for example because scrolling is in progress and
cannot be interrupted.
Related
I have question related to touch event with Vuejs.
I want to join some number with mouse event (for PC) and touch event (for Mobile Devices) like this:
<div
#mousedown="startMove(item)"
#mouseup="endMove(item)"
#mousemove="doMove(item)"
#touchstart="startMove(item)"
#touchend="endMove(item)"
#touchmove="doMove(item)"
v-for="item in 9"
:key="item"
>
{{ item }}
</div>
Since mousedown, mouseup, mousemove working well on PC, touch event also fired on mobile devices but it always return item of touchstart.
Example if I move(with touch) from 2 to 5, item always return 2 on touchmove and touchend event.
Here is my data:
data(){
return {
isMoving: false
}
},
methods: {
startMove(e){
this.isMoving= true;
},
endMove(e) {
this.isMoving= false;
},
doMove(e) {
if (this.isMoving) {
console.log(e)
}
}
}
I tested with Chrome develop mode, and tested on Ipad. Can you tell me why and suggest me the solution for this.
Thank for your help.
Touch events work a little differently, try changing your doMove method.
doMove(e) {
if (this.isMoving) {
const clientX = e.clientX || e.changedTouches[0].clientX;
const clientY = e.clientY || e.changedTouches[0].clientY;
console.log(document.elementFromPoint(
clientX,
clientY
).innerHTML);
}
},
Explanation,
In this method, we try to get the position of the current touch or pointer. based on that we are getting the current element.
I am trying to create a button group where a user can choose between multiple options. react-bootstrap 2.0.0-rc.0 provides the combination ToggleButtonGroup + ToggleButton for this purpose. Unfortunately, a radio icon appears next to the button. I want to get rid of it. Below, you can find a minimal example to reproduce the radio icon.
import * as React from "react";
import {
ToggleButton,
ToggleButtonGroup,
} from "react-bootstrap";
interface OwnState {
val: boolean;
}
export default class SomeToggleOptions extends React.Component<OwnProps, OwnState> {
constructor(p: Readonly<OwnProps>) {
super(p);
this.state = { val: true }
}
setVal = (newVal: number) => {
this.setState({
val: newVal == 1
})
}
render() {
return (
<div className="p-1 text-right">
<span className="p-1">Auto Refresh:</span>
<ToggleButtonGroup
name="radio"
size="sm"
onChange={this.setVal}
value={this.state.val ? 1 : 0}
>
{radios.map((radio, idx) => {
return (
<ToggleButton
key={idx}
id={`radio-${idx}`}
variant={
this.state.val === radio.value ? "dark" : "outline-dark"
}
value={idx}
>
{radio.name}
</ToggleButton>
);
})}
</ToggleButtonGroup>
</div>
);
}
}
NOTE: I already found React-Bootstrap Toggle Button is Failing to Hide the Radio Button Circle and this is NOT working for me.
The icon seems to disappear when I use the normal ButtonGroup + Button instead. But this is not primarily an option as you don't have the radio-like "exclusive" behavior there.
I reverted to the earlier react-bootstrap version 1.6.4. This is probably not fixable (without any hacky moves, css-overwriting, or similar) and induced by react-bootstrap 2.0.0 being only a release candidate so far.
In the earlier react-bootstrap version, my code snippet worked flawless.
This appears to be a temporary issue when upgrading react-bootstrap, see my answer here on duplicate question: https://stackoverflow.com/a/72636860/8291415
Also here is the closed issue on github: https://github.com/react-bootstrap/react-bootstrap/issues/5782
I am building a chat messaging app with Ionic4. The expected behavior is to have a sliding item with the picture and name of a friend and upon sliding left, add and remove friend buttons are revealed to add or remove a friend from the chat. Further, if a friend is added to the chat the add button is disabled and the remove button is enabled using the [disabled] tag. Finally if any friends exist that have been added, a button on the bottom appears, to take us to the chat page and initialize a conversation.
The problem is that I initially swipe left on the bottom most friend, and then we see the add and remove buttons with add disabled, So far so good. I then click add and the remove button becomes undisabled, and the add button becomes disabled. I then click remove and it works great!
I then try the same thing on the friend above the bottom and everything fails. The buttons do not enable/disable, but when the remove button still appears disabled.
So far I have tested the custom pipe(s) I created and they have all shown true when a friend appears within chatfriends, so that condition is ok.
//chats.html
<ion-list-header>
Friends
</ion-list-header>
<ion-list>
<ion-item-sliding #slidingitem *ngFor="let key of myfriends" >
<ion-item >
<ion-avatar item-left>
<img src="{{key.photoURL}}">
</ion-avatar>
<h2>{{key.displayName}}</h2>
</ion-item>
<ion-item-options slide="left">
<button ion-button [disabled]="(chatfriends | contains:key)" color="primary" (click)="addfriendtochat(key)" >
Add
</button>
<button ion-button [disabled]="!(chatfriends | contains:key)" color="danger" (click)="removefriendfromchat(key,slidingitem)" >
Remove
</button>
</ion-item-options>
</ion-item-sliding>
</ion-list>
//**************************
//chats.ts
ionViewWillEnter() {
//chats.ts has to listen to chatconnect node as it does with the nodes below
this.requestservice.getmyrequests();
this.requestservice.getmyfriends();
this.requestservice.getmychatconnects();
//this.contains.transform(localfriends, "Eddie");
// this.myfriends = [];
this.events.subscribe('gotrequests', () => {
this.myrequests = [];
this.myrequests = this.requestservice.userdetails;
});
this.events.subscribe('friends', () => {
this.myfriends = [];
this.myfriends = this.requestservice.myfriends;
});
this.events.subscribe('gotchatconnects', () => {
this.mychatconnects = [];
this.mychatconnects = this.requestservice.chatconnects;
});
}
ionViewDidLeave() {
this.events.unsubscribe('gotrequests');
this.events.unsubscribe('friends');
this.events.unsubscribe('gotchatconnects');
}
//this function adds a friend to the chat and a friend to the chatfriend array, and also sets the flag that determines whether or not to show the start chat button
addfriendtochat(friend){
if(this.myfriends.includes(friend)){
this.chatservice.addfriendtochat(friend);
if(this.chatservice.getfriendcount() > 0){
this.friendsinarray = true;
}else{
this.friendsinarray = false;
}
}
this.chatfriends = this.chatservice.getfriends();
}
//this function removes a friend from the chat and removes a friend from the chatfriend array, and also sets the flag that determines whether or not to show the start chat button
removefriendfromchat(friend, slidingitem: ItemSliding){
if(this.myfriends.includes(friend)){
this.chatservice.removefriendfromchat(friend);
if(this.chatservice.getfriendcount() > 0){
this.friendsinarray = true;
}else{
this.friendsinarray = false;
}
}
this.chatfriends = this.chatservice.getfriends();
slidingitem.close();
}
There is no error message, the one notable thing is that upon the steps above when it fails, the items are not reloaded.
I wasn't able to get the exact sliding action I wanted, but the problem was really in the rendering of buttons. After removing the slider the buttons did not hide and unhide or [enable/disable] the add and remove from chat buttons, exactly as previously described. As I posted before, the page did not seem to re-render after objects were updated in the providers. I believe that the problem was just that, subscribing to events from two providers. I switched the tracking of added friends to my requests.ts. This was for two reasons.
1. I pulled my list of friends, called myfriends, from my firebase rest api using that provider, so my object to track whether one of my friends friends was added to the chat, called friendobjs, were there as well. Further I had to use events from both objects to fill in info on my chats.ts page.
2. Everything else on my page that was subscribing to events from that provider so I didn' think conflicts would arise.
Here is the working code, which hides and unhides the add and remove buttons for each friend displayed.
//chats.ts
ionViewWillEnter() {
//chats.ts has to listen to chatconnect node as it does with the nodes below
this.requestservice.getmyfriends();
this.events.subscribe('friends', () => {
this.myfriends = [];
this.friendobjs = [];
this.myfriends = this.requestservice.myfriends;
this.friendobjs = this.requestservice.friendobjs;
this.singleArray = [];
for (var _i = 0; _i < this.myfriends.length; _i++) {
this.singleArray.push({
myfriends: this.myfriends[_i],
friendobjs: this.friendobjs[_i]
});
}
});
this.events.subscribe('addedfriendtochat', () => {
this.friendobjs = [];
this.friendobjs = this.requestservice.friendobjs;
this.singleArray = [];
for (var _i = 0; _i < this.myfriends.length; _i++) {
this.singleArray.push({
myfriends: this.myfriends[_i],
friendobjs: this.friendobjs[_i]
});
}
});
this.events.subscribe('removedfriendfromchat', () => {
this.friendobjs = [];
this.friendobjs = this.requestservice.friendobjs;
this.singleArray = [];
for (var _i = 0; _i < this.myfriends.length; _i++) {
this.singleArray.push({
myfriends: this.myfriends[_i],
friendobjs: this.friendobjs[_i]
});
}
}
removefriendfromchat(friendobj){
if(!friendobj.canbeadded){
this.requestservice.removefriendfromchat(friendobj);
if(!this.requestservice.canchat){
this.friendsinarray = true;
}else{
this.friendsinarray = false;
}
}
addfriendtochat(friendobj){
if(friendobj.canbeadded){
this.requestservice.addfriendtochat(friendobj);
if(!this.requestservice.canchat){
this.friendsinarray = true;
}else{
this.friendsinarray = false;
}
}
}
//chats.html
<ion-item *ngFor="let single of singleArray" >
<ion-avatar item-left>
<img src="{{single.myfriends.photoURL}}">
</ion-avatar>
<h2>{{single.myfriends.displayName}}</h2>
<h2>{{single.friendobjs.canbeadded}}</h2>
<button ion-button round item-right color="primary" [hidden]="!single.friendobjs.canbeadded" (click)="addfriendtochat(single.friendobjs)" >
<ion-icon name="checkmark"></ion-icon>
Add
</button>
<button ion-button round item-right color="danger" [hidden]="single.friendobjs.canbeadded" (click)="removefriendfromchat(single.friendobjs)" >
<ion-icon name="trash"></ion-icon>
Remove
</button>
</ion-item>
I'm developing an app with Ionic 4/Angular 7/Angular Material 7.
In a screen there's a stepper.
Inside each stepper there's complex forms. Given its complexity I put this form inside components.
Inside the second step there's a radio group. When I open the second step I can set focus on a radio with keyboard, but can't select a radio button. The radio button get a grey circle around but not the color of selection.
In the first step there's also a radio group and in the initial state I can select it using keyboard. But if I open the second step and open the first step again the radio buttons are not selectable too.
I've simulated the situation without components inside the steppers and I was not able to reproduce the problem this way. Then I deduce the problem is caused by the component inside a step after this step is open.
How can I be able to correctly select the radio buttons inside a step?
Palliatively solved through a directive:
import { Directive, HostListener } from '#angular/core';
import { MatRadioButton } from '#angular/material';
#Directive({
selector: 'mat-radio-button'
})
export class MatRadioCorrectionDirective {
constructor(private host:MatRadioButton) { }
#HostListener('keyup', ['$event'])
onKeyup(event: KeyboardEvent) {
// console.log(event);
if(
event.keyCode == 38 // arrow up
|| event.keyCode == 40 // arrow down
|| event.keyCode == 37 // arrow left
|| event.keyCode == 39 // arrow right
) {
event.preventDefault();
this.host.checked = true;
// TODO: send event
this.host.change.emit(null);
// setTimeout(() => {
// }, 500);
}
}
}
I am implementing the drag and drop mechanic using react-dnd library, but I find it hard to style my drop targets. I want to show the user which drop target is available to drop on, but using the isOver and canDrop will only style the item that is currently being hovered on.
If I use the !isOver value, all the divs are being styled, without even dragging any of the elements.
How can I style the drop targets only when the dragging of an element happens?
This is my code so far, for a #DropTarget:
import React from 'react';
import {DropTarget} from 'react-dnd';
import {ItemTypes} from './Constants';
const target = {
drop(props, monitor, component){
// console.log("Dropped on", props.id);
},
canDrop(props, monitor, component){
var cardColumn = monitor.getItem().column;
var targetColumn = props.column;
return false; // still testing styling when only an element is being dragged on the page
}
};
#DropTarget(ItemTypes.CARD, target, (connect, monitor) => ({
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver({shallow: true}),
canDrop: monitor.canDrop(),
}))
class CardList extends React.Component{
constructor(props){
super(props);
this.addClass = this.addClass.bind(this);
}
addClass(){
const {isOver, canDrop} = this.props;
if(isOver && canDrop){
return "willDrop"; // green background for .card-list
}
if(isOver && !canDrop){
return "noDrop"; // red background for .card-list
}
if(!isOver && !canDrop){
return ""; // will style all the backgrounds in a color, but not when dragging
}
}
render(){
const {connectDropTarget} = this.props;
return connectDropTarget(
<div class={"card-list col-xl-12 col-lg-12 col-md-12 col-sm-12 col-xs-12 " + this.addClass()} id={this.props.id}>
{this.props.children}
</div>
);
}
}
export default CardList;
Is there a way to get the isDragging value when an element is being dragged on the page, since this is the only possibility to obtain what I want.
Thanks!
Both isOver and canDrop implicitly do the isDragging check, per http://react-dnd.github.io/react-dnd/docs-drop-target-monitor.html - note that they only return true if a drag operation is in progress. Therefore, if you want to style drop targets such that only when something that can be dragged is being dragged, then I think you need another case in your addClass() function to handle that, like this:
addClass(){
const {isOver, canDrop} = this.props;
if(isOver && canDrop){
return "willDrop"; // green background for .card-list
}
if(isOver && !canDrop){
return "noDrop"; // red background for .card-list
}
if(!isOver && canDrop){
return ""; // THIS BLOCK WILL EXECUTE IF SOMETHING IS BEING DRAGGED THAT *COULD* BE DROPPED HERE
}
}
And I don't think you want the !isOver && !canDrop block - this will execute even when nothing is being dragged at all.