How to fire onChange event on ZK Textbox? - textbox

In ZK, say I have a Textbox
<textbox id="tb"/>
And then in java I do
private Textbox tb;
tb.setValue("some new value");
I want that when I set this value, to trigger the onChange (or onOK) method of the textbox, as if the user has inputed the new text himself and pressed enter.

In the java you just have to do:
private Textbox tb;
tb.setValue("some new value");
Events.postEvent("onChange", tb, null);
Check this to more information.

Related

Vaadin flow select component prevent click event propagation to grid header

In Vaadin Flow 23.1.x we have a grid with different filter fields in the header.
In the screen below the "Vendorstatus" is a ComboBox and the ValudateCode is a Select component.
What we now see:
If we click in the Vedonrstatus field, the dropdown opens and nothing else happens, which is ok
If we click in the ValutaCode field, the dropdown opens too, but also the "Sort" of the grid is triggered.
So it looks like the select component does not consume/block the ClickEvent from propagating down to the parent components.
Is there a way to prevent the click to trigger the sort of the column grid?
Workarround would be to re-implement my Select based header filter with ComboBox type ones.
The code to generate the filter header:
headerRow.getCell(col).setComponent(createSelectFilter(...));
And the createSelectFilter method:
private static Component createSelectFilter(...) {
VerticalLayout vl= new VerticalLayout();
Label l= new Label("Headername");
vl.add(l);
Select<MyobjClass> select= new Select<>();
select.setItems(...);
select.getElement().addEventListener("click",
event -> {})
.addEventData("event.stopPropagation()");
select.addValueChangeListener( e --> updateDataFilter());
vl add(select);
return vl;
}
This does not stop propagation of the click to open the dropdown and select a value to also trigger a sort "command" on that column
You must use this method to add the listener them you can
select.getElement().addEventListener("click",
event -> ...)
.addEventData("event.stopPropagation()");

Getting multiple button captions into an edit field with one fuction

I want to create a function which takes the Caption of a pressed button and put it into an Edit field. I have multiple buttons, and I don't want to have multiple OnClick events with almost the same code in each of them.
I've searched and tried out stuff for hours, but can't seem to find anything like that (but I think I am not the only one with this problem).
I am not really new to programming but neither am I good at it.
Edit: I remember that there is a parameter in the click functions in .NET which is EventArgs e, which is missing while working with Embarcadero.
private void button_Click(object sender, EventArgs e)
{
edit.Text = e.Caption; //I don't really remember the exact syntax but I hope you get what I meant
}
Most VCL/FMX event handlers have a Sender parameter, which is a pointer to the object that is firing the event. For example:
void __fastcall TMyForm::ButtonClick(TObject *Sender)
{
Edit1->Text = static_cast<TButton*>(Sender)->Caption;
}
Just assign this single event handler to the OnClick event of all of your TButton objects. The Sender will be the current button being pressed.
Note to the above answer by Remy - for VCL the property name is "Caption" but for FMX the property name for a button is "Text"

ZK Binding NotifyChange not work on onChanging Event?

I currently use ZK for web-development. Here is my case:
I implement instant search, once text change=> perform search.
Zul File
<textbox id="textSearch" sclass="search_text">
<attribute name="onChanging">
lbOnChangingSearch.setValue(event.getValue());
vm.onChangingTextSearch();
</attribute>
</textbox>
<label id="lbOnChangingSearch" visible="false"></label>
<grid id="gridChapter" model="#load(vm.chapterInPage)">
....
</grid>
Controller code
ListModelList<ChapterJoinComic> chapterInPage;
public ListModelList<ChapterJoinComic> getChapterInPage() {
return chapterInPage;
}
#NotifyChange({ "topComics", "chapterInPage"} )
#Command
public void onChangingTextSearch() {
FilterObject fo = getFilterObject();
fo.setSearch_str(lbOnChangingSearch.getValue());
//
doSearch(fo); // Change chapterInPage
// Manually post Not
BindUtils.postNotifyChange(null,null,this.chapterInPage,"chapterInPage");
}
Problem
After call onChangingText search, Grid dont update databinding.
But if I continue change text (more call onChangingTextSearch ). The Grid will update, but the updated value is the previous value.
It seems the Grid is a-step slower than my latest Model object.
Note If I use onOK instead of onChanging event, the databinding works well.
Anyone can help me. Thanks in advance!
In addition of Malte his answer.
Textbox only sends data to the server with the onChange event to avoid needless network traffic.
If you want to send data to the server with the onChanging event, you need to do :
<textbox instant="true" />
In this case the client will update almost instantly to the server (if you type fast, it will be when you stop typing)
You should remove the BindUtils.postnotifyChange when you use #NotifyChange already, and you use it wrong anyway: the third parameter should be this instead of this.chapterInPage. The JavaDoc explains that you need to specify the bean whose property is changing and the name of the property.
Furthermore, replace your onChanging attribute with the proper way to call a command:
<textbox id="textSearch" sclass="search_text"
onChanging="#command('onChangingTextSearch')" />
Consult the documentation for more information on how to use commands. I think because you do not use the command as a command, the #NotifyChange is not triggered. And your postNotifyChange is wrong, as I said.
Let me know if that works or if there are other problems remaining.
EDIT
I just re-created an example on my own, and it seems to work. Try it like this:
ViewModel --------------------------------
private String searchText = "";
#NotifyChange({"chapterInPage", "searchText"})
#Command
public void onChangingTextSearch(#BindingParam("text") String searchText)
{
this.searchText = searchText;
}
public String getSearchText()
{
return searchText;
}
public ListModelList<String> getChapterInPage()
{
return new ListModelList<>(searchText.split(""));
}
zul --------------------------------------
<textbox onChanging="#command('onChangingTextSearch', text=event.value)" />
<label id="lbl" value="#load(model.searchText)" />
<listbox model="#load(model.chapterInPage)" />
Note that I use command binding to call the search method in the model instead of calling it "manually" in an onChanging listener. This way, I actually execute it as a command, which triggers the notifyChange. When you call it like vm.onChangingTextSearch() in a listener, the #NotifyChange is ignored.
This way, it works as expected, and with every character typed (well, after a couple of millisenconds delay), the list updates. Another advantage is that you do not have to bind your label into the view model, something that zk's documentation discourages.
Can you try to link your zul and model like this and tell me if it works. If it doesn't, you might want to try to create an example on zkFiddle that re-produces your code's behavior.

Passing events back from Angular.dart view to Controller/Component code

I'm trying to figure out how to pass event parameters from a component back to my class handling the event.
In my case, I'm trying to register a "KeyPressed" event in a component, like so:
<textarea ng-keypress="cmp.KeyPressed(event)" rows="1" cols="100"></textarea>
And the code handling the event looks like this:
void KeyPressed(event) {
print("keypressed!");
}
Whenever a key is pressed, the KeyPressed() function fires. However, the "event" being passed in is null. How do I pass in event parameters correctly, and what is the event type?
You need to use $event
<textarea ng-keypress="cmp.KeyPressed($event)" rows="1" cols="100"></textarea>

knockoutJS checkbox and textbox working together

I have a checkbox and a textbox (both are enabled and the checkbox starts unchecked [false]).
What I need is the following:
When I write something in the textbox and leave it (loses focus) the
checkbox is checked automatically.
When I write something in the
textbox, remove it and leave it the checkbox should remain
unchecked.
When I write something in the textbox and click the
checkbox, the checkbox is checked now and the data in the textbox is
not cleared.
When I write something in the textbox and click the
checkbox twice, first happens step 3 and then the checkbox is
unchecked and the data in the textbox is cleared.
When I click in the checkbox the checkbox is checked, then I write in the textbox
and uncheck the checkbox, then the data in the textbox is cleared.
What I tried so far is the following code:
//The checked property in the checkbox is binded to
that.BuildingCriteria.IncludeLoadingDocks
that.BuildingCriteria.IncludeLoadingDocks.subscribe(function (newValue) {
if (!that.updatingTextBox && !newValue) {
that.BuildingCriteria.LoadingDocksMin(null);
}
});
//The textbox value is binded to that.BuildingCriteria.LoadingDocksMin
that.BuildingCriteria.LoadingDocksMin.subscribe(function (newValue) {
that.updatingTextBox = true;
that.BuildingCriteria.IncludeLoadingDocks(true);
that.updatingTextBox = false;
});
This works if you try all the steps above, for all of them but then, when you try some of them again stops working for some... specially if you write something in the textbox with the checkbox unchecked and then leave the textbox, it doesn't check the checkbox automatically anymore.
I tried using flags as you can see but I couldn't make it to work on ALL the cases ALWAYS.
I've been working on this for days so if you can help me out soon I'd appreciate it a lot!
Thanks in advance!!
It's near impossible to gave a straight up answer to your question, but from it I feel the closest thing may be to note a few KO features that you may yet need to consider.
The value binding supports a valueUpdate = 'afterkeydown' version, which would allow you to keep your textbox and checkbox in synch real time. This may well remove the need for requirement 3.
The computed observable supports specializing read and write operations, which at times may be clearer than using subscriptions.
You may need to introduce a "grace" period for the checkbox, if you must stick with requirement 3. Just don't allow updating the checkbox too shortly after leaving the textbox. The throttle extender and hasfocus binding can help you with that.
There's a great blogpost on when to use which feature.
In any case, your requirements are a bit hard to understand without the business case, and it might even be that you're experiencing an XY-problem. From your implementation requirements I'd assume functional (not implementation) requirements like this:
There's a textbox to hold the actual order/criterium/name/whatever.
There's a checkbox to indicate such an order/etc is wanted.
This checkbox should be in synch (checked) with whether the user typed some text.
This checkbox should be in synch (unchecked) if the user empties the textbox.
If the user checks the checkbox then
If there was text for the order/etc it should be cleared.
If there was no text a default order/etc should be suggested.
Here's a jsfiddle with a demo of how you could approach these functional requirements. For completeness, here's the relevant code, starting with the View:
<input type="checkbox" data-bind="checked: isChecked" />
<input type="textbox" data-bind="value: someText, valueUpdate: 'afterkeydown', selectSuggestion: someText" />
The custom binding for selecting the "default suggestion text":
var suggestion = "<enter something>";
ko.bindingHandlers.selectSuggestion = {
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var currentText = ko.utils.unwrapObservable(valueAccessor());
if (currentText === suggestion) element.select();
}
};
And the ViewModel:
var ViewModel = function() {
var self = this;
var privateIsChecked = ko.observable(false);
var privateText = ko.observable("");
self.isChecked = ko.computed({
read: privateIsChecked,
write: function(value) {
if (!privateIsChecked() && value && privateText() === "") {
privateText(suggestion);
}
if (privateIsChecked() && !value) {
privateText("");
}
privateIsChecked(value);
}
});
self.someText = ko.computed({
read: privateText,
write: function(value) {
privateIsChecked(value !== "");
privateText(value);
}
});
}
I'm aware that this doesn't directly answer your question, but like I said that's pretty hard to do for us on Stack Overflow, without knowledge of your business case.

Resources