Adding event to a WatchKit item of a table - button

I have created a table in which the items contains some groups and some labels. I would like that when the user tap on the item, I receive an action. How can I do it? Is it possible to add an invisible button covering all the area of an item of the table?

You will need to connect the table row to another Interface Controller by control dragging from the row, and selecting push or modal.
Give the Storyboard Segue an identifier (string).
Then, to pass data to the Interface Controller, override contextForSegueWithIdentifier:inTable:rowIndex:
Swift:
override func contextForSegueWithIdentifier(segueIdentifier: String, inTable table: WKInterfaceTable, rowIndex: Int) -> AnyObject? {
if segueIdentifier == "identifier" {
return "banana"
}
return nil
}
Objective-C:
- (nullable id)contextForSegueWithIdentifier:(nonnull NSString *)segueIdentifier inTable:(nonnull WKInterfaceTable *)table rowIndex:(NSInteger)rowIndex {
if ([segueIdentifier isEqualToString:#"identifier"]) {
return #"banana";
}
return nil;
}

Button can contain groups (you have to choose this option in the editor) so the problem is solved! I don't understand why this answer is rated negatively. It works!

Related

Display Infolog when selecting record in dropdown menu

Is there a way to display an info log when selecting a certain record in a dropdown menu/based on a field value?
For example:
When creating a new Quotation, if I select a customer which is bankrupt (so the value on the field bankrupt is true for that customer.) I want to show a info dialog: "Bankrupt!" I want to show this before the record is being created, at the moment it is being selected.
In your form find the field you want (form layout, no datasource), override Modified method an put your code before super();
To get the value use: this.text(); Here you can get the select value before insert.
Code example:
public boolean modified()
{
boolean ret;
CustTable custTable = CustTable::find(this.text());
if (custTable.Bankrupt == NoYes::Yes)
info("Bankrupt!");
ret = super();
return ret;
}

How to delete a row in the 1st Interface Controller by pressing a button in the 2nd Interface Controller ( Modal View )

I have a table in the 1st interface controller , when a press on a row , a modal interface controller opens up , it contains a button.
I want the button to delete the row in the first interface controller.
Here is my code :
In the first interface controller
Blockquote
// It opens up a modal view ( with the context of the tapped row )
override func contextForSegueWithIdentifier(segueIdentifier: String, inTable table: WKInterfaceTable, rowIndex: Int) -> AnyObject? {
var timelineRow = timeline.reverse()
return timelineRow[rowIndex]
}
Blockquote
And here is my code in the second interface controller
Blockquote
override func awakeWithContext(context: AnyObject?) {
super.awakeWithContext(context)
sentContext = (context as? Dictionary)!
sentRow = sentContext
//sentRow contains the context
}
#IBAction func deleteRow() {
var sentRow : [String:String] = ["action":"delete"]
NSNotificationCenter.defaultCenter().postNotificationName("notification_DeleteRow", object: nil, userInfo: sentRow)
dismissController()
}
Blockquote
I've sent the index of the row through the contextForSegueWithIdentifier.
In the 2nd Interface Controller I've extracted the Context and put it in variable
I then send back the userInfo throught the NSNotificationCenter
My Problem :
How can I use the userInfo sent back from the modal controller in order to delete the tapped row.
How would I manage to delete the tapped row (1st IC) by pressing on the delete button situated in the (2nd IC)
There are a few options in this situation:
You could use NSUserDefaults, and while it would work, this isn't how that class is intended to be used.
You can create your own custom NSNotification and broadcast it from the modal controller. Your first interface controller would listen for this event and delete the appropriate record.
You can pass a reference to your first interface controller to the modal controller and retrieve it in awakeWithContext:. This allows you to set the first interface controller as a delegate. Once this happens, you can define whatever protocol you'd like to inform the first controller of important events.
I have a blog post that goes into more detail on the second two topics: Advanced WatchKit Interface Controller Techniques
This can be achieved with custom delegate easily,
#protocol MyCustomDelegate <NSObject>
- (void)deleteButtonTapped:(id)sender;
#end
- (IBAction)deleteButtonTapped:(id)sender {
if ([self.delegate respondsToSelector:#selector(deleteButtonTapped:)]) {
[self.delegate deleteButtonTapped:sender];
};
}
More detailed answer is here.

Passing parameters of dynamics ax

On Dynamics AX 2012,Passing between two step form a parameter that I would use to change the data source of the second form;
how you pass a parameter from the init form to init the data source?
I hope I have understood the question
If you wanto to pass a parameter between forms, you have multiway.
One solution.
In Form - A override a method clicked() control Button
void clicked()
{
Args args;
FormRun formRun;
;
args = new Args();
args.name(formstr(nameyourFormB));
args.record(nameTableSourceRecords);
args.caller(element);
formRun=new FormRun(args);
formRun.run();
formRun.wait();
}
So , in the SecondForm - Form - B
override method init()
public void init()
{
super();
if(element.args() && element.args().record() &&element.args().record().TableId == tableNum(nameSourceRecords))
{
nameTableSourceRecords = element.args().record() ;
stringEdit.text(nameTableSourceRecords.nameFieldTableSourceRecords);
}
}
You have to insert in Designs node Form-B a one StringEdite (set AutoDeclaration YES) in Properties.
Now, you open Form-A select a record, click on control Button -> will Open Form-B and you have set a value in your StringEdit control.
I hope to help you.
Greetings!
Get the parameter in the form.init(), save it to a variable in your form's classdeclaration, then override the datasource's init() method and manually create a FormDataSource object using the passed in parameter to determine the datasource.
Although I'm not sure how you're going to show this on form controls...the controls will expect the datasource to be what it is set up as. There's probably a better way to achieve whatever you're trying to do.
One solution of this is to use EnumTypeParameter and EnumParameter property on menuitem of child form. Set these parameter value on parent form and on child form init you just need an if clause then. like:
if (args.parmEnumType() == yourEnum && args.parmEnum() == 'yourEnumValue')
{
//set the desired datasource
}
these links may help you:
opening a form on basis of menuitem
and
xArgs.parmEnumType

How to trigger an action from a NSTableCellView in view based NSTableView when using bindings

I'm facing a problem with a view-based NSTableView running on 10.8 (target is 10.7, but I think this is not relevant).
I'm using an NSTableView, and I get content values for my custom NSTableCellView through bindings. I use the obejctValue of the NSTableCellView to get my data.
I added a button to my cell, and I'd like it to trigger some action when clicked. So far I have only been able to trigger an action within the custom NSTableCellView's subclass.
I can get the row that was clicked like this, using the chain:
NSButton *myButton = (NSButton*)sender;
NSTableView *myView = (NSTableView*)myButton.superview.superview.superview;
NSInteger rowClicked = [myView rowForView:myButton.superview];
From there I don't know how to reach my App Delegate or controller where the action is defined.
As I am using cocoa bindings, I do not have a delegate on the NSTableView that I could use to trigger my action.
Do you have any idea how I could talked back to controller ?
Many thanks in advance!
Although you are using bindings you can still set your controller as the delegate for your tableview in the interface builder.
I see that you already are able to access the table view from inside your cell. The next task must be simple, just set the table view delegate as the target for your button's action.
Thanks for your question, I also will be triggering an action from a button on a NSTableView. Your question helped to put me on the correct path.
First to address the your solution to finding which row number my NSTableView is on. I was able to find it without knowing the button, in my custom NSTableView I installed the following as a first attempt:
- (NSInteger)myRowNumber
{
return [(NSTableView*)self.superview.superview rowForView:self];
}
this works fine, however it is less than robust. It only works if you already know specifically how deep you are in the view hierarchy. A more robust and universal solution is:
- (NSInteger)myRowNumber
{
NSTableView* tableView = nil;
NSView* mySuperview = self;
do
{
NSView* nextSuper = mySuperview.superview;
if (nextSuper == nil)
{
NSException *exception =
[NSException exceptionWithName:#"NSTableView not found."
reason:[NSString stringWithFormat:#"%# search went too deep.",
NSStringFromSelector(_cmd)] userInfo:nil];
#throw exception;
}
if ([nextSuper isKindOfClass:[NSTableView class]])
tableView = (NSTableView*)nextSuper;
else
mySuperview = mySuperview.superview;
} while (tableView == nil);
return [tableView rowForView:self];
}
this not only works at the NSTableView level, but works with anything installed at any level above it, no matter how complex the view hierarchy.
As to the unanswered part of your question, I established an IBOutlet in my class and using interface builder tied if to my files owner (in my case my document class). Once I had a reference to the class I was sending my message to, and the row number, I call the function. In my case the call required that I pass the row number it originates from.
[self.myDoc doSomethingToRow:self.myRowNumber];
I tested this and it works at various levels of the view hierarchy above NSTableView. And it functions without having to have the row selected first (which appears to be assumed in Apples documentation).
Regards, George Lawrence Storm, Maltby, Washington, USA
Use rowForView: and the responder chain
To respond to a control's action embedded within an NSTableCellView, the control should issue the action to the First Responder. Alternatively, File Owner is possible but this is more tightly coupled.
Use rowForView: within the action method to determine which row's control issued the action:
- (IBAction)revealInFinder:(id)sender {
NSInteger row = [self.tableView rowForView:sender];
...
}
The action is implemented within any of the responder chain classes. Most likely, this will be your subclassed NSWindowController instance. The responder could also be the application delegate; assuming the delegate has a means to talk to the NSTableView.
See Apple's example TableViewPlayground: Using View-Based NSTableView and NSOutlineView to see this in action.
Suhas answer helped me.
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
if let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "EDIT_CELL_VIEW"), owner: self) as? SymbolManagerCell {
if let editButton = cell.subviews[0] as? NSButton {
editButton.target = cell // this is required to trigger action
}
return cell
}
return nil
}

How to implement the same story text to different page objects in Jbehave

I am just starting out with Jbehave Web with WebDriver and wondered whether it was possible to have the same textual step apply to different step methods.
Say for example you have the following two scenarios
Scenario 1
Given I am on the properties to buy page
When I click Search
Then I should see the results page containing all properties to buy
Scenario 2
Given I am on the properties to rent page
When I click Search
Then I should see the results page containing all properties to rent
If I implemented this using the page object pattern I would have a page object called for example buyProperties and likewise for rental properties a page object called something along the lines of rentProperties (as well as result page objects).
In both scenarios a search button/link is clicked so the step text is the same. However, in reality they are on different pages (and page objects).
How could I implement Jbehave so that for the rental scenario it knows to call the step method implementing clicking the search button on the rentProperties page and for the buy scenario it knows to call the step method implementing clicking the search button on the buyProperties page?
Your steps class will have two methods - one annotated with #Given("...rent") and one annotated #Given("...buy"). Each method does it's own thing. If "rent" and "buy" is a variable passed in then do different things based on the value of that variable. I'm not sure I get the question...sorry.
Try
#Given ("I am on the properties to $action page")
public void given_i_am_on_the_properties_action_page(#Named("action") String action) {
if (action.equalsIgnoreCase("Buy") {
do something;
}
if (action.equalsIgnoreCase("Rent") {
do something;
}
}
The 'do something' could be setting up the page object for the next steps.
Similarly you can use the same method and a variable for your #Then step.
I have used something similar to select menu items and to wait for the page to load before going on to the next step
#When ("I select menu item $menuItem")
public static void when_i_select_menu_item(#Named("menuItem") String menuItem) {
String item = "";
String waitFor = "";
if (menuItem.equalsIgnoreCase("admin")) {
item = "Admin";
waitFor = "admin_page";
}
if (menuItem.equalsIgnoreCase("home")) {
item = "Home";
waitFor = "home_page";
}
if (menuItem.equalsIgnoreCase("search")) {
item = "Search";
waitFor = "search_page";
}
driver.findElement(By.id(item)).click();
(new WebDriverWait(driver, timeout)).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
return element.findElement(By.id(waitFor)).isDisplayed() || d.findElement(By.id(waitFor)).isEnabled();
}
});
}

Resources