How can I force entry to complete in a NSTextField from a NSButton - objective-c

I just noticed a problem when my user-interface is in a certain state. I have a table view with two columns both of which the user can enter data that is to be used later. There's also a button which acts upon the contents of the table view.
The problem is if the user has entered new data in the column but has not yet exited the field by using the tab key or return key (i.e. the cursor is still in the field and in editing mode) and the button is pressed the old value is used not the current value sitting in the field.
What is the best way to handle this this? I want to use whatever the user has entered thus far.
Basically, The button code needs to tell the text field to finish completion or exit the editing mode. But I can't seem to find a method that will do that.

Use bindings. In Interface Builder, select the table column and in the Inspector go to Table Column Bindings and set the Value content binding appropriately and ensure the "Continuously Updates Values" option is checked. Then changes to the table cell content will propagate immediately.

Found the answer, At least for me.
Find out if a row is selected and if so deselect it. This causes the current entry to be completed.
- (void) completeTableEntry
{
// If a column is selected ensure it is completed
NSInteger sr = [keyValueTable selectedRow];
if (sr != -1) {
[keyValueTable deselectRow:sr];
}
}

How about:
[theTargetWindowWhateverThatIs endEditingFor:nil];
theTargetWindowWhateverThatIs may be, for example, self.window if you are inside a NSWindowController.

Related

Editing SWT Table cell. Changed value jumps back immediately to old value as soon as I leave cell. Why?

I have a Dialog and there is a Table (Tableviewer) inside it.
tableViewer = new TableViewer(composite, SWT.BORDER | SWT.MULTI);
Certain columns of my table are editable. I click on the cell, I edit the value, I leave the cell and the edited value immediately reverts back to the old one.
What should I configure/set in table/tablehelper to make the edited values last longer than the time I spend in the cell?
EDIT!-----------------------------
We have a Helper class that is responsible for creating CellEditingSupport like this:
`
if ("w".equalsIgnoreCase(hd_bean_mode)) {
CellEditingSupport editingSupport = new CellEditingSupport(viewer,pds[i]);
col.setEditingSupport(editingSupport);
}`
This class itself is quite complex and does a lot of magic through reflexion, etc... The funny thing however is that other tables use this very same Helper class, seemingly with the same configuration and they work!
One more thing: I am conviced that the columns in my table get the Editingsupport. I know it because of the debugger and because the cells are editable. The only problem is that those edits do not last long.

Programmatically set dgrid row as active

I'm trying to programmatically set a dgrid row as active, not just selected. I have a dojo dgrid OnDemandList which is using the Selection and Keyboard Mixins.
Using the select(row) method I can programmatically select a given row, but that row is not active. When a row is active, I can use the Up and Down arrow keys to navigate to the rows above and below it. When a row is just selected, the row is highlighted but the arrows keys do not work.
Clicking the row with the mouse will make it active and selected, but I'm trying to build my interface to be 100% usable with just the keyboard.
Ok, took me awhile but got it figured out. What I was really trying to do was add focus to a row. The code for doing that was in dgrid/Keyboard.js under the _focusOnNode method.
The actual code to change focus from row currentFocusedNode to row focusedNode is:
if(currentFocusedNode){
// Clean up previously-focused element
// Remove the class name and the tabIndex attribute
put(currentFocusedNode, "!dgrid-focus[!tabIndex]");
if(has("ie") < 8){
// Clean up after workaround below (for non-input cases)
currentFocusedNode.style.position = "";
}
}
if(has("ie") < 8){
// setting the position to relative magically makes the outline
// work properly for focusing later on with old IE.
// (can't be done a priori with CSS or screws up the entire table)
focusedNode.style.position = "relative";
}
focusedNode.tabIndex = grid.tabIndex;
focusedNode.focus();
put(focusedNode, ".dgrid-focus");
The code above is really just a code fragment, for it to work you will have to declare "dojo/has" and "put-selector/put" first as well as define the currentFocusedNode and focusedNode. But I'm leaving that as an exercise for the reader ;-)
Also note that this only changes the "focus", it will not select the focusedNode but that can easily be done using grid.select(focusedNode);

key Equiv. for nsbutton is not working properly for multiple nsbuttons

I have two nsbuttons in my interface builder.For all of these three nsbuttons I have set Key Equilant to "Return" key.And also I set nextkey view to all of these buttons.
I have 3 different actions for all of these three buttons and connections has made properly.
If I use mouse click appropriate actions are getting executed.
After running the Application,initially my first button has focus,presses return key, 1st button's action is executed.Next I pressed tab key,focussed has changed to 2nd button,pressed return key but 1st button's action is executed.Again I pressed tab key,focussed has changed to 3rd button,pressed return key still 1st button's action is executed.
What I am missing here.Why the appropiate action is not happenning on pressing Return key over nsbutton even focus is highlighted.
It sounds like you're using keyboard navigation to switch between buttons and activate the selected one. In that case, the Return key would normally correspond to pressing the selected button. However, since you've assigned Return as a shortcut for one or more of the buttons, the responder chain searches for and finds a button with a matching key equivalent, so that button's message is sent instead.
Try clearing the key equivalent for all three of your buttons. I think that'll give the behavior you're looking for.
If you're not using keyboard navigation, it's not clear why the tab button has any effect. Nevertheless, if you're trying to do something like make the default button cycle from one button to the next, you'll need to change the keyboard equivalent each time a button is pressed. I wouldn't recommend that generally -- I don't think users would like to have the default button change from one moment to the next. If you must though, here's some code:
- (IBAction)nextButton:(NSButton*)sender
{
int tag = [sender tag];
NSView *superview = [sender superview];
if ([sender.keyEquivalent isEqualToString:#"\r"]) {
NSButton *nextButton = [superview viewWithTag:(tag % 3) + 1];
nextButton.keyEquivalent = #"\r";
sender.keyEquivalent = #"";
}
}
This assumes that you've got three buttons, and each is configured with the nextButton: method as its action. Also, the buttons have tags 1, 2, and 3 respectively. The idea here is that when the default button (i.e. the one with the return key as its equivalent) is selected, it sets the next button's key equivalent to Return and sets its own equivalent to nothing.
You can obviously change the way the code works -- you may want each button to call a different action, for example. In that case, just have each action call a common method that does the same job as the code above.
The lesson here is that if you set the same key equivalent for several buttons, the first one to be found will be "pressed". If you want the key equivalent to change, you need to change the equivalent set for your various buttons.
I'm not sure what you mean about the focus changing when you press the tab key -- I don't see this behavior (I've set up the initial first responder and next key connections). All three buttons are blue, but only the first one pulsates, no matter what keys I press. After experimenting a bit, I found that the button that is at the top of the list (in the window's object list) is the one whose action is performed on clicking return.
I can't find any documentation on this, but I don't think you can set the same key equivalent for multiple buttons in the same window.

How to show button cell (check box) title in table view, using bindings

I am trying a simple application where I have a mutable array of mutable dictionaries, such as -
NSMutableDictionary *sample6 = [[NSMutableDictionary alloc] initWithObjectsAndKeys:#"title6",#"title",[NSNumber numberWithBool:NO],#"state", nil];
In IB I created a table view with NSButtonCell (check box).
I was able to show checkboxes state (checked or unchecked), using following table column bindings:
Value - ArrayController.arrangedObjects.state
In this case it shows an array of checkboxes with title - "Check" as shown in below screen-shot:
Now my aim is to show checkboxes title using bindings, such that it
gets value from same mutable dictionary from which it is getting its
state.
I tried following binding for button cell but it did not work:
title -> ArrayController.selection.title
I also tried this binding for button cell :
title -> ArrayController.arrangedObjects.title
but it didn't work, it appeared like this after using above binding:
Can any one suggest me which controller key to use and if this is not the correct way to show titles then what is the correct way to do so?
Unfortunately you'll need to write a little code if you want to do it this way. When binding table column values to an array, the table column is handling taking the prototype data cell, setting its values, and "stamping" it in place for each row. The button cell's bindings aren't exposed "through" the table column, so a simple binding won't do it for you.
To Answer Your Question
So. Since only the value binding is exposed, the title must be set manually if you really want the checkbox's title to reflect the value (ie, you really want the checkbox to handle both the check state and displaying the title). To do this, you have to mix bindings with < NSTableDelegateProtocol > . Use the -tableView:willDisplayCell:forTableColumn:row: method to set the cell's -title property to that of the proper object in your array controller's -arrangedObjects array each time you're asked. Mixing bindings and data source / delegate methods is actually quite common for more than the most basic applications, so don't worry that you're doing something dirty. Note: you won't be able to support editing the title by doing this since it's a checkbox.
An Alternative Design
Personally, I'd avoid all that and just add a separate table column for the title. Bind the new column's value to the array controller's arrangedObjects.title and turn off the checkbox button cell's title so only the checkbox itself is displayed. That simplifies the whole thing greatly and allows editing the title.

Gray out a form row's (detail's) button conditionally with VBA code

I have a standard form in MS-Access which lists a bunch of orders, and each row contains order no, customer, etc fields + a button to view notes and attached document files.
On request from our customer we should gray out the button btnAnm (or check or uncheck a checkbox) depending on a calculation from two queries to two other tables (a SELECT COUNT WHERE and a check if a text field is empty).
I've tried btnAnm_BeforeUpdate(...) and btnAnm_BeforeRender(...) and put breakpoints in the subs, but none of them trigger. The same if I use the control Ordernr instead of btnAnm.
I'd like a function in the Detail VBA code to be triggered for each "Me." (row) so to speak, and set the row's control's properties in that sub.
What do I do? I've looked at the help file and searched here.
*Edit: So I want to do something that "isn't made to work that way"? Ie. events are not triggered in Details.
As an alternative, could I base the value of a checkbox on each line on a query based on the 'Ordernr' field of the current row and the result of a SELECT COUNT from another table and empty field check?
Do I do this in the query the list is based on, or can I bind the extra checkbox field to a query?
A description of how to do this (combine a COUNT and a WHERE "not empty" to yes/no checkbox value) would be perfectly acceptable, I think! :)*
You cannot do much with an unbound control in a continuous form, anything you do will only apply to the current record. You can use a bound control with a click event so that it acts like a button.
Presumably the related documents have a reference to the order number that appears on your form, which means that you can create a control, let us call it CountOrders, with a ControlSource like so:
=DCount("OrderID","QueryName","OrderID=" & [OrderID])
The control can be hidden, or you can set it up to return true or False for use with a textbox, you can also use it for Conditional Formatting, but sadly, not for command buttons.
Expression Is [CountOrders]>0
You can also hide the contents and add a click event so that is acts in place of the command button. Conditional Formatting will allow you to enable or disable a textbox.
As I understand your question, you have a continuous form with as command button that appears on each row - and you'd like to enable/disable the button conditionally depending on the contents of the row.
Unfortunately you can't do that. It seems that you can't reference the individual command buttons separately.
Having wanted to do something similar in the past I came up with two alternate ways of setting up my interface.
Put a trap into the onClick code for the Button. Which is icky, because it is counter intuitive to the user. But it gets you that functionality now.
Move the command button (and editable fields) up into the form header, and make the rows read only. Your users then interact with the record only in the header, and select the record they want work with in the list below. As I recall this is known a Master-Detail interface.