How to add a click listener to an InputElement in GWT? - gwt

I've created the following checkbox
import com.google.gwt.dom.client.InputElement;
...
final InputElement bulkEditCheckbox = Document.get().createCheckInputElement();
Tried many formulas, but just can't wrap it or add a listener to it. Any suggestions?
PS: getting the following error when trying to wrap with SimpleCheckBox.wrap():
‘A widget that has an existing parent widget may not be added to the detach list’

This fixed my issue:
DOM.sinkEvents(element, Event.ONCLICK);
DOM.setEventListener(element, new EventListener() {
#Override
public void onBrowserEvent(Event event) {
if (Event.ONCLICK == event.getTypeInt()) {
...
}
}
});

Related

Flutter: how to use .addListener of TextEditingController

i'm building a simple app that prints the result of the current TextFormField. Such as when the text changes it prints the new value.
I found out that you can achieve this with TextEditingController.addListener that listens for changes and executes a function.
So i wrapped it all in initState as follows
#override
void initState() {
addressController.addListener(() {
print(addressController.text);
});
The problem I have is that sometimes it records changes even when there aren't any:
This is what happens writing a word and then deleting it.
If you add listener then you should remove it somewhere, otherwise there can be situation when TextEditingController will have 2 or more listeners:
#override
void initState() {
addressController.addListener(_addressControllerListener);
super.initState()
}
void _addressControllerListener() {
print(addressController.text);
}
#override
void dispose() {
addressController.removeListener(_addressControllerListener);
super.dispose()
}

Flutter Firebase stops listening after push and pop operation

I'm saving Firebase data in a list using on child Added listener and on child changed listener, it works good, but when i perform push operation and use pop to back to the screen the listeners stops listening.
Is there any solutions to fix this.
I used this code from Stackoverflow : Code
Sorry for this silly post, i'm new to flutter, I fixed this by using Future method in listeners.
#GrahamD you can find my code here.
My code:
var childAddedListener;
var childChangedListener;
#override
void initState(){
FirebaseDatabase database;
database = FirebaseDatabase.instance;
database.setPersistenceEnabled(true);
database.setPersistenceCacheSizeBytes(10000000);
reference = database.reference().child('Sweets');
childAddedListener = reference.onChildAdded.listen(_onEntryAddedShop);
childChangedListener = reference.onChildChanged.listen(_onEntryChangedShop);
super.initState();
}
On Child Added Listener
Future _onEntryAddedShop(Event event) {
setState(() {
itemsShop.add(Sweets.fromSnapshot(event.snapshot));
});
}
On Child Changed Listener
Future _onEntryChangedShop(Event event) {
print('Child Changed');
var old = itemsShop.singleWhere((entry) {
return entry.id == event.snapshot.key;
});
setState(() {
itemsShop[itemsShop.indexOf(old)] = Sweets.fromSnapshot(event.snapshot);
});
getItemIds();
}
Cancel them in dispose
#override
dispose() {
childAddedListener.cancel();
childChangedListener.cancel();
super.dispose();
}

how to reuse previous state fields in flutter bloc pattern?

have the following. using sliding_up_panel that has body with messages and with a different view in panel content that pops up on click action from bottom bar.
#override
Stream<AppState> mapEventToState(
AppEvent event,
) async* {
if (event is LoadChat) {
List<Msg> msgs = await Api.getMessages();
yield LoadedChat(messages: msgs);
} else if (event is OrderPanelOpen) {
yield OpenedPanelState();
} else if (event is OrderPanelClose) {
yield ClosedPanelState();
}
}
Goal is to hide the appBar when panel is opened. appBar is present in AppLayout which is parent holding the SlidingUpPanel widget itself in a Scaffold.
class _AppLayoutState extends State<AppLayout> {
#override
Widget build(BuildContext context) {
var bloc = BlocProvider.of<AppBloc>(context);
return Container(
child: Scaffold(
appBar: widget.showAppBar
? AppBar(...)
: null,
bottomNavigationBar: BottomAppBar(...),
body: SlidingUpPanel(...),
),
);
}
}
following is the action that adds panel events to bloc
IconButton(
icon: Icon(Icons.description),
onPressed: () {
if (widget.pannelCtrl.isPanelClosed()) {
widget.pannelCtrl.open();
bloc.add(OrderPanelOpen());
} else {
widget.pannelCtrl.close();
bloc.add(OrderPanelClose());
}
})
problem here is SlidingUpPanel has a body that needs to show messages regardless of panel open or close. If panel open and close events are mapped to states with bloc, these open and close events has to be separate states but messages from current state has to be passed to new state by either as constructor params to new state or other ways. is that right approach to achieve this or is there anything else cleaner that I'm missing here.
class ClosedPanelState implements LoadedChat {
final messagesArg;
ClosedPanelState({this.messagesArg});
#override
Widget get currentView => Chat(messages: this.messagesArg);
#override
List<Object> get props => [];
#override
bool get showAppBar => true;
#override
String get title => 'Order Food';
#override
List<Msg> get messages => messages;
}
According to your question's title there's a thing you can do.
For your bloc class you can create a stack-like variable (you can use your own implementation of a LIFO stack or use a List, as you wish). Your bloc class must be Singleton in order to save the Events.
static final List<AppEvent> _events = new List<AppEvent>();
And on your _mapEventToState implementation add the events called to the variable:
#override
Stream<AppState> mapEventToState(
AppEvent event,
) async* {
_events.add(event); // New Line
if (event is LoadChat) {
List<Msg> msgs = await Api.getMessages();
yield LoadedChat(messages: msgs);
} else if (event is OrderPanelOpen) {
yield OpenedPanelState();
} else if (event is OrderPanelClose) {
yield ClosedPanelState();
}
}
Later you write a method for calling the last Event on the Stack/List.
dispatchPreviousState() {
this.add(_events.removeLast());
}
This worked for me to get the latest Event called and dispatching it again.
You can use reversible_bloc to add this behaviour to your bloc / cubit.
Ex.:
class MyReversibleCubit extends Cubit<int> with ReversibleBlocMixin {
MyReversibleCubit(int initialState) : super(initialState);
void changeValue(int newValue) => emit(newValue);
}
Then, when you need to rollback, use revert()
final myReversibleCubit = context.read<MyReversibleCubit>();
myReversibleCubit.changeValue(2);
myReversibleCubit.changeValue(4);
// Current state is 4
myReversibleCubit.revert();
// Current state back to 2

Adding a widget to a listview with .contains

In the init state, I add an if statement to check to see if a custom widget exists on the list that I will pass to the Listview.builder, called an AddItemButtonTile. If it doesn't exist, I want to add it to the list.
#override
void initState() {
if (!displayedList.listContent.contains(AddItemButtonTile)) {
displayedList.listContent.add(AddItemButtonTile(openTextField));
}
super.initState();
}
This code results in a new AddItemButtonTile being added every time I navigate away and return to the page. Why is this If statement returning true?
Try:
#override
void initState() {
if (!displayedList.listContent.any((item) => item is AddItemButtonTile)) {
displayedList.listContent.add(AddItemButtonTile(openTextField));
}
super.initState();
}

gwt add custom widget to panel

I have created some classes in which it create a bunch of widgets (e.g. label, textbox). I want to create the widget on the fly and add it to a panel. How can I do that.
Assuming you use HorizontalPanel, VerticalPanel, FlowPanel or some other panel with an add(Wiget) method, you would simply invoke add(myWidget);
final VerticalPanel panel = new VerticalPanel();
final Button sendButton = new Button("Add widget");
panel.add(sendButton);
sendButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
panel.add(new Label(new Date().toString()));
}
});
RootPanel.get().add(panel);
An alternative may be use the setVisible(boolean) to show and hide widgets instead of adding and removing them.
final VerticalPanel panel = new VerticalPanel();
final Button sendButton = new Button("Toggle visibility");
panel.add(sendButton);
final Label label = new Label(new Date().toString());
panel.add(label);
sendButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
label.setVisible(!label.isVisible());
}
});
RootPanel.get().add(panel);