I have following requirements:
Obtain action associated with NSButton using : - (SEL)action
Call the obtained action.
Can we perform 2nd pt. Generally we invoke an action like this- [self abc:nil] just thinking if we can invoke the method obtained from 2nd pt. in same way!
Try:
SEL actionSelector = [button action];
[self performSelector: actionSelector withObject:nil];
The action is just a selector—the name of a method. Any number of objects may have a method by that name, and even if only one class implements the method, you may have any number of instances of that class. So, you can't just call the name of a method, because that doesn't express what object will respond to it. You need an object that implements that method, and you need to send that message by that name to that object.
The most likely object you want to send the action message to is the button's target, so get that, the same way you got its action, and send the message to that object. Or, better yet, send the button a performClick: message; if you want to simulate the user clicking the button, that's the way to do that.
Related
How can I disable a CPView? (so that the user can't interact with it while it's still visible)
It's useful for example when the user clicks on something that sends a request to the server and it should get disabled till the result comes back.
CPControls (as abstract subclass of CPView) contains a -setEnabled: method which most UI components inherit from.
http://cappuccino.org/learn/documentation/interface_c_p_control.html#a68d3dc4f2d0a4fad8699fd5982cddc2d
CPViews do not contain such a method, so in your CPView subclass you need to write your own method for enabling and disabling. Then override -mouseDown: and whatever else you need to (look at the docs for CPResponder for a complete list) and implement like so:
- (void)mouseDown:(id)sender
{
if ([self isEnabled])
[super mouseDown:sender];
}
So we all know in an ajax update events must be rebound to new dom elements. Yes delegate is an option, but delegate doesn't work for all scenarios. For instance delegate won't help for something that needs to be done simply on load rather than on a click event.
Rather than split my code into delegate handlers and handlers that need to be rebound on updates, I would rather define a single method with a context parameter that gets called every time the page changes like so:
function onPageUpdate(context) {
$('a', context).click(...); // event handlers
$('.chart', context).addClass(...); // load handlers
}
On dom ready this will be called with the context parameter null. On an ajax update the context will container the new dom elements. This way I'll never have to worry about delegating or ajax updates again.
I'm having trouble getting this to work however. Given the ajax callback:
function onSuccess(data) {
// data contains new dom elements like: <div><a>Click</a><span>chart<span></div>
// replace old elements with new ones
$('a').replaceWith('a', data);
$('span').replaceWith('span', data);
// call pageUpdate with the new context
onPageUpdate(data);
}
Is it possible to make this work like I expect? The replacing works fine, but onPageUpdate isn't binding anything to these new elements, I don't know if thats because the context is just a string object or what. Can anyone think of a way to make this work?
In my mind this is a better solution than delegate, because theres only one method for all handlers and only the elements that need a binding will own it.
From jQuery() - jQuery API
jQuery( selector [, context] )
selector A string containing a selector expression
context A DOM Element, Document, or jQuery to use as context
If the context isn't the correct type - such as passing a string - it's simply going to be ignored. Try wrapping your HTML string in a jQuery object, then use that as the context for your selectors, like so:
var $context = $(data);
$('a').replaceWith('a', $context);
$('span').replaceWith('span', $context);
// call pageUpdate with the new context
onPageUpdate($context);
I won't answer to your question, Anthony Grist's answer is quite right, but there are some things you said that I don't understand. Could you explain them to me ?
For instance delegate won't help for something that needs to be done simply on load rather than on a click event
Sorry but I don't get it, do you have an example ?
In my mind this is a better solution than delegate, because theres
only one method for all handlers and only the elements that need a
binding will own it.
I don't get it too:
only one method: which method are you talking about ?
only the elements ... will own it: it's also the case with delegate, and more, if you have let's say 10 anchor element, only ONE handler would be bound, instead of 10 in your solution
On your method onPageUpdate you're mixing two things: event handling ($("a").click(...)) and DOM modification ($(".char").addClass(...)). Maybe that's why you're confusing about delegate's ability to resolve your problem.
I am trying to call a click event from within another a method from the same Window Form file. It just won't work form me.
For instance:
theClass = partial class(System.Windows.Forms.Form)
method AlarmListBox_Click(sender: System.Object; e: System.EventArgs);
private
protected
public
method DoSomething;
end;
method theClass.DoSomething;
begin
self.AlarmListBox_Click; <<<this is where i want to call the click event
end;
No matter what I do, it keeps raising compiler errors. I tried AlarmListBox.Click, AlarmListBox.performClick, etc.
Some of the errors I got:
There is no overloaded method "AlarmListBox_Click" with 0
parameters.
Cannot access underlying event field
So, how do you fire an event within the same window Form?
It's best to call the Event handler with the default parameters:
AlarmListBox_Click(self, EventArgs.Empty);
By passing self into the method you define that the source of the call was not the AlarmListBox but your form. You could also can pass in custom EventArgs that state that the Event was not raised because of a click on the AlarmListBox but from your code.
You are not passing the parameters of the method AlarmListBox_Click
Try this
AlarmListBox_Click(nil, nil);
When coding with cocoa I've noticed that it's not necessary to have sender parameter when defining IBAction, hence following action:
- (IBAction)showUserInfo:(id)sender;
can be declared as
- (IBAction)showUserInfo;
So I'm wondering if there is any other benefit besides having the button/menu item that sent the action? Only other situation I can think of is having few objects calling same IBAction. Anything else?
Doc says,
The sender parameter usually identifies the control sending the action message (although it can be another object substituted by the actual sender). The idea behind this is similar to a return address on a postcard. The target can query the sender for more information if it needs to.
The sender parameter helps if you want any data from it. For example, on UISegmentControl value change, as in #Mark Adams answer. So if you don't want any information from the sender, you can just omit it, as in your - (IBAction)showUserInfo; example.
It can be handy to use the sender argument when you're connecting the method to UI objects whose values can change and you may need to work with.
For instance if I wired up a method to a UISegmentedControl and set it's control event to UIControlEventValueChanged, I can use the object passed as the sender: argument to obtain it's selected segment index and then, based on the value, make a change in the UI.
-(IBAction)segmentedControlValueChanged:(id)sender
{
UISegmentedControl *control = (UISegmentedControl *)sender;
// Show or hide views depending on the selected index of the segmented control.
if (control.selectedSegmentIndex == 0)
someView.hidden = YES;
else
someView.hidden = NO;
}
Using bindings, how can I make NSButton invoke a method in my AppDelegate class? I tried setting the target sleector to buttonClicked: but in console it gives me:
unrecognized selector sent to instance
0x100105060
Also there's no place in bindings to specify which instance to look for the method in so how can I set it to AppDelegate?
Thanks.
As Simon says, bindings are not appropriate for this situation. Bindings allow you to "bind" UI elements to a data source. In your situation, you need an action - not a binding.
You are getting the error because you haven't actually defined the buttonClicked action. Thus, make sure you declare it with something like in your AppDelegate.m:
- (IBAction) buttonClicked:(id) sender;
Then set the action via interface builder by first setting the "FilesOwner" to the AppDelegate and then connecting the onTouchUpInside event to the action "buttonClicked".
Hope this helps!
Bindings are used to synchronize a variable and an element of the interface.
In your case, I guess an action would be better. Declare your method with IBAction and control-drag from your button to your AppDelegate instance in Interface Builder to be able to select the action.