In Lazarus, how to defocus TCustomControl descendents (cross-platform)? - freepascal

I am using Lazarus 2.3.0, FPC 3.3.1
A control will get focus when you put it on a form, by default. Lets say you have a TMemo (implemented via Widgetset) on a TForm. When the form is active, the memo will get focus. So, how to defocus the memo so the form will be shown with no focused control at all? You may ask "Why?". Just for learning, I am trying to understand why I can't do it (or should not do it).
Right now I tried the following alternatives with no success on Linux:
// Form1 OnActive event
DefocusControl(Memo1, False);
DefocusControl(Memo1, True);
Form1.ActiveControl := nil;
PS.: It is worth noting that right now there is a 7 year issue opened on a related topic here:
https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/25396

Here is the workaround that I use. You can disable TabStop property of every control on your form through Object Inspector or dynamically with:
for i := 0 to Form1.ComponentCount-1 do
if Form1.Components[i] is TWinControl then
(Form1.Components[i] as TWinControl).TabStop := False;
Form1.ActiveControl := nil;
DefocusControl when used in FormActivate doesn't work for me at all, it does nothing. I guess it's just a bug. Removing (second parameter in DefocusControl) is not even implemented in Lazarus.

Related

trigger itemSelect event on Primefaces autocomplete

I have a primefaces autocomplete element which works great except one thig. The problem is that when I enter a valid text (which is mappable to the data behind) but I don't select the element from the propositions, and don't press tab or enter, nothing happens.
So I enter a value and click into another field, the element is not selected and the validation fails. However, I don't want the user to force to explicitly select an item.
My ideas were, that i put an onchange listener to the input element and trigger the primefaces itemSelect event within. But I don't know how to do that, if it's even possible.
Or maybe there are other solutions?
Thanks in advance!
I found a way, although it might not be the most beautiful and easy one.
Maybe it helps somebody...
This is a specific solution for primefaces (5.3), but it should work for other versions too.
$('#form\\:txtAutoComplete_input').val('Foo');
$('#form\\:txtAutoComplete_input').trigger('keydown');
$('#form\\:txtAutoComplete_input').trigger('input');
$('#form\\:txtAutoComplete_panel .ui-autocomplete-item').trigger('click');
For some reason, after the value is entered into the input field, you have to trigger the keydown and the input event in that order. After these events the autocomplete list shows with the matching values. There you have to trigger click on a certain element, so all the backing bean stuff is properly executed.
There is an API for Primefaces widgets.
For instance ;
<p:autoComplete id="gtautoaomplet" value="#{item.soemprop}" completeMethod="#{bean_CrossCheckNew.completeText}" scrollHeight="250"/>
In JS code ;
widget_form_mapingGrid_0_gtautoaomplet.search('foo');
When you write "PrimeFaces.widgets" in your browser console you can see all the widgets available in your page.
For more datail :
https://primefaces.github.io/primefaces/jsdocs/index.html
Good luck.

Access Violation Exception on Textbox Autocomplete

In textchanged event Access Violation Exception occurs frequently.
it's a security level problem may be. try this: Go to the Project Property page, and then go into the Security Section.
"Enable ClickOnce Security Settings" will be seen checked. uncheck it
reference: https://social.msdn.microsoft.com/Forums/windows/en-US/e599b2e2-3cda-43ad-b15f-a69b4fea1a75/dynamic-filling-of-textbox-autocomplete-not-working?forum=winforms
I too wanted to populate a TextBox AutoCompleteCustomSource using the users input from that same textbox as a filter, so I had the TextChanged event grabbing data to fill the dropdown suggestions list.
I tried so many different ways to fill the data, which all resulted in random or constant Access Violation. If I'm not wrong I finally have it nailed down I think.
It seems that it doesn't matter what method you're using to actually add the items to the AutoCompleteCustomSource. The problem arises when you go to replace those items.
Before changing any of the data in TheTextbox.AutoCompleteCustomSource, you need to first set:
TheTextBox.AutoCompleteSource = AutoCompleteSource.None
Then you can use any method you like to clear and/or refill it:
TheTextBox.AutoCompleteCustomSource.Clear()
TheTextBox.AutoCompleteCustomSource.AddRange(AutoSuggestItems)
Set the AutoCompleteSource back to CustomSource when you're done:
TheTextBox.AutoCompleteSource = AutoCompleteSource.CustomSource
' prevent that annoying selection of the whole textbox text
TheTextBox.Select(Me.TheTextBox.Text.Length, 0)
*Note: If you also set TheTextBox.AutoCompleteMode while changing the data like I was originally, it causes the Access Violation error later. (SO FAR) the above method has worked correctly. I hope this is my last update to this solution :)

Why does ddl 'onchange' event not appear in intellisense?

I was working out a problem with a ddl trying to get a message box to popup when the item changed. You can read about that here >>>
How to Popup Alert() from asp:DropDownList OnSelectedIndexChanged?
The working answer shows me to use the onchange event but then I'm working in VS2010 this event does not appear in the intellisense dropdown. However if I type it in anyway it works fine.
For this, you need to understand how the thing works....when you change the value of a input element, onchange event gets triggered on the browser, so the browser looks for a way to handle it. So when you put the onchange event specified for the element it gets called.
Now, ASP.NET OnSelectedIndexChanged uses the same functionality(logically saying) to POST the page to the server. From there, the ASP.NET runtime triggers the function you wrote in the codebehind file and returns you the result. Now, if you really don't require any operation that can only happen on the server, you don't need to use the server functionality, instead you can do it in javascript.
On the other hand, if you want something that happens on server: like some database get, you are supposed to use the OnSelectedIndexChanged event.
And if you use the OnSelectedIndexChanged event, you can still call some javascript functions from there.
Page.ClientScript.RegisterClientScriptBlock(typeof(string),"myScript","alert('HI')",true);
To answer your question about intellisense, onchange is a event of input types, and in aspx pages, i guess you are using <asp:..> tags, which does not have the same event - thus visual studio does not show it in the intellisense. But when you put it, it gets assigned to the HTML markups, which is interpreted correctly by the browser.
PROS and CONS
onchange works on your browser, so it is lot faster than the server-side code. On the other hand, we had an issue once that the browsers has the capability to restrict pop-ups. So if you want some really important message to be shown, it is better to use the Server-Side event and the RegisterClientScriptBlock function.
Hope it helps.

How to get text from textbox in GAS?

I run my GAS as an Apps-script-gadget on my web-page and use the GUI-builder. I have two questions:
1.
I know how to set text in a textbox:
app.getElementById("TextBox1").setText("BigSister");
But how do i get text from a textbox?
I tried:
app.getElementById("TextBox1").getText();
...getValue();
...value;
etc.
Nothing works...
2.
Is it possible to print a message window from the code to the screen f.Ex. for debugging purposes?
Any advice would be appreciated.
Within your handler code, you can access the value of the text box as
var value = e.parameter.TextBox1 ;
Before doing this you must have run the setName() method on your text box.
var tetxbox1 = app.createTextBox().setName('TextBox1');
I suggest you run through some of the tutorials at https://developers.google.com/apps-script/articles where you can find answers to many of your questions.
You can retrieve the value of your ListBox when it is passed back through a handler. It's passed in the parameter class under the Id of the ListBox. The following is a fool-proof method of retrieving that value:
function changeHandler(e)
{
var source = e.parameter['source']; //source is your Id of the element
var value = e.parameter[source]; //value is the selected item as ['a' | 'a,b,c']
//More code here
}
I'm still waiting for a solution to retrieve that value without a handler.
EDIT here is a workin example for you to test
online test
and the script + GUI is here
=======================
Srik answer is absolutely right - as usual ;-) - but to make things a bit more clear to you since you are using GUI builder here is a small screen capture that shows the relevant parameters.
As for your second question, the simplest thing to do to get a momentary showing window to 'print' some data to screen is to use a texBox or a textAreal (or anything else that allows to show text...) and play with the setVisible(true) & setVisible(false) to show/hide the widget. In the GUI builder you can put it anywhere in your UI, even over other elements that you normally use since it will be invisible most of the time (the visibility parameter is available in the GUI builder environment as well). It will behave exactly as a 'popup' in other environments...

Multiselect select element - capturing current option set before adding / removing new items

Hello and thank you for reading.
I have an aspx form hosted in SharePoint 2010 that has some multiple select elements within a form. There are buttons to add and remove options from these select elements.
My problem is that I need to run a query based on the options within these multi select elements each time new options are added / removed from them. SharePoint is executing some server side code I don't have access to but here's my underlying problem.
If I hook into the buttons' onclick event, when my function is called the options have already been added to or removed from the select element. I need to capture the current option set of these elements, before the onclick function executes.
Is there another event I can tie into? Something like onbeforeclick on the buttons or optionsChanged on the multi select element? It doesn't look like any event will satisfy what I need to do here, but I'm hoping someone has faced a similar issue before.
Thanks,
Zachary Carter
The only solution I could come up with is to capture the present set of options each time an option is added or removed.
This solution is going to involve alot of array manipulation however, and if I can avoid that and simply tie into an event, before the onclick event of the button is called, that would be my ideal solution.
This might not be a great answer to your question, and if not, I apologize. However, I just ran into a very similar problem, albeit using Visual Basic. The solution wasn't elegant in my eyes, but I used VB's MouseUp event, which fires when the mouse button is released. On release (i.e., at the end of the previous action), I save all the information in the elements into an array, and then on the next click, before anything else happens, I can check against that array.
Edit: Gah, looks like you posted essentially that solution while I was typing. Sorry I didn't notice.