Is it possible to configure a key binding that's active only in a given view? From a plugin? It should be inactive in all other views except the selected one.
This is possible via a context in a key binding that makes the binding active only in very specific situations, and depending on your needs you don't even need a special plugin to do so (though it sounds like for your case you do).
As a brief overview, key bindings can optionally contain 1 or more contexts that determine if the binding should be active or not. If multiple contexts are applied to the same key, then all of them must be satisfied before the binding is made active. It's possible to have the same key sequence bound to multiple commands (or variations on the same command) so long as they have context that disambiguates them.
If there are multiple keys bound to the same key, they're considered in order (starting at the last defined binding and moving upward) until one with a context that applies it seen, or one with no context is seen. Hence, ordering of bindings can be important; put the most specific ones later in the file and the least specific sooner.
For example, given this key binding:
{ "keys": ["ctrl+shift+h"],
"command": "echo",
"args": {"msg": "Key binding triggered"},
"context": [
{ "key": "setting._my_setting", "operator": "equal", "operand": true },
],
},
This binding is only active in places where the setting _my_setting has a boolean value of true; if the value is false or the setting is not set, the binding is not active.
So initially, the binding will not be active, and pressing that key will trigger whatever other command happens to be bound to this key sequence.
However, if you were to open the console and run:
view.settings().set("_my_setting", True)
Now the binding is active in whatever file was focused when you did it, but disabled everywhere else.
There's nothing magic about the name of the setting or how it interacts except that this context (which is built into Sublime) can only be used for Boolean settings. So in particular it follows the hierarchy of settings and you can add the setting in one or more the following places:
Preferences.sublime-settings to make the binding active/inactive everywhere
Project specific setting to make the binding active/inactive in files contained in a particular window
Syntax specific settings to make the binding active/inactive in files of a specific type
In the view settings (as in the example above in a plugin) to make the binding active/inactive in specific views.
Items further down the list override items sooner (so view settings trump everything, syntax settings trump project and defaults, etc).
For more fine grained control or to use other settings than just boolean ones, you need to implement an EventListener or ViewEventListener in a plugin and handle the on_query_context event, which allows you to create a custom context for use in bindings.
More information on that is available in the API documentation; you can also check out this video on defining custom contexts as well (disclaimer: I'm the author of the video)
Related
THe documentation for accumB says:
Note: As with stepper, the value of the behavior changes "slightly
after" the events occur. This allows for recursive definitions.
In my case there is no recursion, but i want to get updates "right now", not "slightly after". Why there is no special version of accumB? I guess, i'm missing something obvious?
EDIT: In my application I have data Config, which holds various configuration values and a bunch of Event (Config -> Config), which are fired when user changes some value in GUI. Now, i want other parts of my program to access Config whenever they want, that's why i used Behavior Config there. The problem is that when changing event is fired, the behavior still has old value of Config, so i can't observe this change immediately.
If you have a Behavior Conf, then you can make other Behaviors from it via the Applicative class combinators. For instance, it may be that you turn it into a Behavior String which is then displayed in a text field. Once you feed a Behavior to such an UI widget, the widget code makes sure that the new value of the Behavior is displayed.
If you need an explicit indication of when the configuration has changed, then an Event Conf may be more appropriate. You can use the accumE function for that, it will contain the new value.
To hand over values from an XPage to a custom control, which approach should be used ?
a) Define properties in the custom control at design time. Fill in the properties at the XPage with computed values. Use the value via 'compositeData' in the custom control at runtime.
or
b) Put the value in a session scope variable at the XPage in BeforePageLoad event. Bind the session scope variable to the field in the custom control.
The session scope is primarily intended for ensuring that values persist as the user navigates between pages. I like to call it the "shopping cart" scope: if you built an e-commerce site in Domino, you wouldn't want the site to forget that a user had added a product to their cart just because they clicked back to the home page. So this scope is also useful for features like remembering search / sort / filter options as the user navigates the app so each time they navigate somewhere else and come back, it remembers their prior behavior without having to store this information permanently in the NSF.
For passing in-page information to a Custom Control from a container, however, compositeData is definitely the way to go. This is because that variable is populated with the passed parameters only for the duration of the processing of the relevant control. Once that control has been dealt with, all pointers to the passed parameters are cleaned up automatically, which provides incremental scalability improvement for each instance compared to storing the same information for the duration of each user's session.
There will be cases where there is overlap: a given Custom Control might reference information that is appropriate to store in the session scope. In this scenario I like to mix the two techniques... for example:
<xp:inputText value="#{sessionScope[compositeData.scopeKey]}" />
The above syntax allows a Custom Control to be passed by its container the identifier for where in the session scope the relevant information is stored. This provides some serious flexibility, because I can drop the same control into multiple contexts, with each telling the control which information it should retrieve / store in scope.
I assumed that for an Update plugin, it specified a list of attributes, that if are changed, cause the plugin to fire.
So if I register a plugin against Foo, with only one filtering attribute specified against Bar, every time a Foo entity is updated, CRM performs a check to see if Bar has been updated, if it has, it runs my plugin. So with the code below, I would expect my plugin to execute once.
Foo foo = new Foo();
foo.Bar = 0;
foo.Id = service.Create(foo);
foo.Bar = 1;
service.Update(foo.Bar); // My plugin would execute
service.Update(foo.Bar); // Bar hasn't changed, I would assume the plugin will not execute
Am I right in this assumption?
While your initial analysis is loosely correct (i.e. filtering attributes cause the plugin to fire only if one or more filtering attributes have changed) this is not fully accurate.
When an entity is changed, e.g. the email address on a contact, the platform (and therefore your plugin) only receives the delta. In my example there would be an Entity in the Target InputParameter which only contains a single attribute (email). This is the case even if the contact record contains much more data - only that which is changed is sent to the platform. (as an aside, this is where Pre and Post entity Images come in as they allow you to access values on the entity that weren't changed, without having to issue a Retrieve).
So with this in mind it is instead correct to say that filtering attributes mean that the plugin will only fire if one or more of the filtering attributes are present in the request. The CRM ui doesn't usually send a value unless it has changed (forcesubmit overrides this behaviour). In your example Daryl the plugin will fire twice as the filtering attribute is present in both requests.
This is to narrow down the execution of the plugin.
The plugin fires only if one or more of the registered attributes changed.
Say I have a custom field type called MyCoolField that I have deployed in a solution. This solution also contains a SPEventReceivers that has overridden ItemAdded, ItemUpdated, and ItemDeleting. All the specifics of this particular field type are probably not super relevant, but one thing to note is that inside of the OnAdded method it attempts to add a series of event receivers to its ParentList.
After this solution has been deployed, I activate a site-scoped feature that does nothing except add a new site content type - MyContentType. Now, I would not expect any event receivers registered anywhere, since ParentList is supposed to be null for site content types.
So in yet another feature, I go add this MyContentType to a list. The question I have is whether I should expect the OnAdded method to get called now (when adding a content type to the list) or does it only get called when adding the field to list/content type? It seems like it is not getting added (the event receivers are not getting registered), but I wanted to make sure that is truly expected behavior and not something else odd going on in this environment.
I'm not a Notes programmer, however, for my sins, have been working on some Notes features for an in-house project recently. I need to enable/disable editing of a field depending on circumstances. It seems to me to be a fairly standard feature, I need, but I can't find any information on how to do this anywhere.
In form setup (and other field's onchange) code, something like the following:
if some requirement = true then
textField.enable = true
else
textField.enable = false
end if
I've seen other places where there's a workaround of conditionally hiding paragraphs based on some code, having 2 paragraphs with opposite hiding conditions, one with an editable field, the other with a computed field. However, I don't know enough about Notes to see how this is implemented (I can see it done on other forms, but there seem to be some 'magic' steps within Notes which I either can't see or don't get).
[EDIT]
The reply from Kerr seems to be what I'm looking for, but I still can't find out where the InputEnabled property is located. Should have said in the initial question, I'm using Notes 7.0.3.
In fairness, it doesn't matter what the circumstances are for when to enable/disable the field, it's just some boolean condition that is set, in my case only on form loading so I don't even have to worry about this changing dynamically while the form is displayed.
I've got a few issues with Notes, my largest bugbear being that it's so tied so tightly to the Designer UI, which is utter shite. I can do this sort of thing programmatically in most GUI languages (C#, Java, Delphi, even VB), but I need to open property boxes in Notes and set them correctly.
This would be OK as an optional method, but forcing you to go this way means you can only work as well as the IDE lets you in this case, and the IDE here seems to actively work against you. You can't open multiple functions/scripts, you can't swap from one script to another without going back to the menus on the left, you can't easily search the codebase for occurrences of variables/fields (and believe me, this is a major failing for me because either Notes or the internal codebase in my case seems to make a lot of use of global variables!), you can only work with fields through the property boxes that get displayed, you can't edit code in Designer while debugging through the main Notes client.
While the Java side of the coding is better than LotusScript, it's still fairly crappy (why can't you debug INTO Java code?? Why do you need to re-import JAR files for each Java class, does each class have a different CLASSPATH???). Possibly this was improved in Notes 8, I hear it's based on Eclipse. Does anyone know whether this is true or not?
It would help to hear more specifics about the 'circumstances', but the most common way to handle this is to use a hide when formula on the field you want to enable/disable.
Technically you are not enabling or disabling the field, just hiding it, but usually that works just as well.
Since there are few events to work with in Notes, developers commonly use the document refresh as the 'event' to cause the field to hide or show.
Let's assume you have two fields called TriggerField and Subject. Say also you want to disable the Subject based on a value in the TriggerField. The easiest way to do so is to set the TriggerField as a Dialog List type and check the "Refresh fields on keyword change" option. This means when the value of the dialog list changes, the entire document will get refreshed.
Then in your hide when formula for the Subject field, you specify your criteria for when to show or hide that field. Anytime field values change, followed by a refresh of the document (i.e. form), that hide when formula will be re-evaluated.
There are other ways, depending on your circumstances, to solve this problem. If you want to let the user refresh the form themselves, put a button on the form that calls the #Command([ViewRefreshFields]) command. You can add any other formulas to that button before the refresh command if you want to make other changes to the form at the same time.
Another option is to make a certain field display-only. Then create a button that runs LotusScript to allow users to change that display-only field. In the script you can propmt the user for a value, set the display-only field, and then call for a document refresh.
In ND7 and up if you want to just disable the field for input, write an appropriate formula in the InputEnabled section of the field you want to disable.
So I have two fields one called Trigger, a checkbox with the value "On" and another Subject that is a text field. When Trigger is checked I want the value Subject to be enabled.
I simply put the following formula in the Input Enabled element of the field Subject:
Trigger = "On"
I also want this to be recalculated whenever the value of Trigger changes so I select the "Refresh fields on keyword change" option on the Trigger field.
If you're stuck in an older version you need to to hide paragraphs appropriately.