I am using Flex3.0. in this i am craeting a custom component for an Alert.and for that alert i am applying styles. but when i opening the alert through the application i want to set focus on Alert button.means when i press enter button there are two buttons in alert YES and NO.i need to focus on YES button. any one help me if any reffer url also please provide me
Thanks,
Praveen
you need to set the defaultButtonFlag: (its the last parameter)
Alert.show('alert', 'alert', Alert.NO|Alert.YES, this, null, null, Alert.NO);
From the APIDocs:
show(text:String = "", title:String = "", flags:uint = 0x4, parent:Sprite = null, closeHandler:Function = null, iconClass:Class = null, defaultButtonFlag:uint = 0x4):Alert
[static] Static method that pops up the Alert control.
In a regular Alert.show call this means you can specify the last argument as Alert.YES to make it the default selection. With a custom component, you can call setFocus() on the particular element within your custom Alert component that you want to select (i.e.: in call setFocus() within the custom Alert component's creationComplete event).
So a sample implementation of a YES/NO Alert box would be (split code over two lines to avoid scroll bars):
Alert.show("sample text","sample title",
Alert.YES|Alert.NO,null,null,null,Alert.YES);
Hope this helps.
Related
I am creating a custom confirmation dialog in Google App Maker and would like the Confirm button to call a passed-in function. I don't see an "onclick" event in the button widget. Any suggestions on how to do this?
function confirmationDialog(msg, confirmFunction)
{
var desc = app.pageFragments.ConfirmationDialog.descendants;
var label = desc.Label;
var confirmButton = desc.Confirm;
label.text = msg;
confirmButton.onClick = confirmFunction; // does not work
app.showDialog(app.pageFragments.ConfirmationDialog);
}
Thanks
It'd be great if this was a bit easier, but the best bet is to use Custom Properties (https://developers.google.com/appmaker/ui/viewfragments).
You can set up a custom property of type "Dynamic" and call it anything, take "onConfirmCallback", for example. Then you can set the function on that custom property:
Code to invoke dialog:
app.pageFragments.ConfirmationDialog.properties.onConfirmCallback = function(param) {
alert(param);
};
app.showDialog(app.pageFragments.ConfirmationDialog);
And then in the onClick for the close button:
app.pageFragments.ConfirmationDialog.properties.onConfirmCallback("hi");
app.closeDialog();
Also note that there are slightly better ways to set up labels than in your example, also using custom properties.
Create custom properties for any widget properties you want to customize, and then bind those custom properties (#properties.propertyName) to the widget property. For example you might have a confirmText property, with the confirm buttons text property boudn to #properties.confirmText.
Then when you invoke your dialog, you can just set those custom properties. Quick modification of your example code using properties for everything:
function confirmationDialog(msg, confirmFunction)
{
var properties = app.pageFragments.ConfirmationDialog.properties;
properties.text = msg;
properties.confirmCallback = confirmFunction;
app.showDialog(app.pageFragments.ConfirmationDialog);
}
For my confirmation dialogs, I just set the onclick of the OK button before I show the dialog (everything is in one place, which is easier for the dummy (me) who will have to maintain it in six months:
var dialog=app.pages.ConfirmationDialog;
dialog.descendants.message.text='Are you sure...?'
dialog.descendants.btnOk.getElement().onclick=function(){
//do something here
app.closeDialog();
});
};
app.showDialog(dialog);
}
I would like to use the standard JavaFX Alert class for a confirmation dialog that includes a check box for "Do not ask again". Is this possible, or do I have to create a custom Dialog from scratch?
I tried using the DialogPane.setExpandableContent() method, but that's not really what I want - this adds a Hide/Show button in the button bar, and the check box appears in the main body of the dialog, whereas I want the check box to appear in the button bar.
Yes, it is possible, with a little bit of work. You can override DialogPane.createDetailsButton() to return any node you want in place of the Hide/Show button. The trick is that you need to reconstruct the Alert after that, because you will have got rid of the standard contents created by the Alert. You also need to fool the DialogPane into thinking there is expanded content so that it shows your checkbox. Here's an example of a factory method to create an Alert with an opt-out check box. The text and action of the check box are customizable.
public static Alert createAlertWithOptOut(AlertType type, String title, String headerText,
String message, String optOutMessage, Consumer<Boolean> optOutAction,
ButtonType... buttonTypes) {
Alert alert = new Alert(type);
// Need to force the alert to layout in order to grab the graphic,
// as we are replacing the dialog pane with a custom pane
alert.getDialogPane().applyCss();
Node graphic = alert.getDialogPane().getGraphic();
// Create a new dialog pane that has a checkbox instead of the hide/show details button
// Use the supplied callback for the action of the checkbox
alert.setDialogPane(new DialogPane() {
#Override
protected Node createDetailsButton() {
CheckBox optOut = new CheckBox();
optOut.setText(optOutMessage);
optOut.setOnAction(e -> optOutAction.accept(optOut.isSelected()));
return optOut;
}
});
alert.getDialogPane().getButtonTypes().addAll(buttonTypes);
alert.getDialogPane().setContentText(message);
// Fool the dialog into thinking there is some expandable content
// a Group won't take up any space if it has no children
alert.getDialogPane().setExpandableContent(new Group());
alert.getDialogPane().setExpanded(true);
// Reset the dialog graphic using the default style
alert.getDialogPane().setGraphic(graphic);
alert.setTitle(title);
alert.setHeaderText(headerText);
return alert;
}
And here is an example of the factory method being used, where prefs is some preference store that saves the user's choice
Alert alert = createAlertWithOptOut(AlertType.CONFIRMATION, "Exit", null,
"Are you sure you wish to exit?", "Do not ask again",
param -> prefs.put(KEY_AUTO_EXIT, param ? "Always" : "Never"), ButtonType.YES, ButtonType.NO);
if (alert.showAndWait().filter(t -> t == ButtonType.YES).isPresent()) {
System.exit();
}
And here's what the dialog looks like:
I have a modal popup that appears whenever an editor tries to save a component with some values (a date field in the past in this case).
In this popup I show the editor a few options (very similar to the default "Open Shared Item" dialog) and an OK/Cancel button combo. On Cancel I fire the "cancel" event and the editor goes back to the editing screen, all good here. On "OK" I want to change the value of the field to match whatever the editor selected, then save.
I tried to use an approach with FieldBuilder and the sample Boris mentioned on this other topic but I can't get to the field from my popup dialog.
Any suggestions on how I can go and modify the xml of the item (could be also a page) from a modal popup?
EDIT: Code used in getControlForFieldName
function getControlForFieldName(name) {
var fieldBuilder = $display.getView().properties.controls.fieldBuilder;
var fieldsContainer = fieldBuilder.properties.input;
var fieldsNode = fieldsContainer.getElement();
var fieldContainer = $dom.getFirstElementChild(fieldsNode);
while (fieldContainer) {
var labelNode = $dom.getFirstElementChild(fieldContainer);
var fieldNode = $dom.getNextElementSibling(labelNode);
var control = fieldNode.control;
if (control.getFieldName() == name) {
return control;
}
fieldContainer = $dom.getNextElementSibling(fieldContainer);
}
}
EDIT #2
After Frank's advice, and some help from Jaime & Frank offline, I got it to work as follows:
The popup is called from a Command Extension (Save & Close in my case)
The command.js specifies an event handler that gets called on "submit" (== OK was pressed)
$evt.addEventHandler(p.dialogPopup, "submit",
this.getDelegate(this._onPopupSubmit));
In my popup I am passing the selected item (it's a keyword ID) to the event handler:
this.fireEvent("submit", { id: select.options[select.selectedIndex].value });
and now back in the event handler _onPopupSubmit(e) I just read e.data.id, load this keyword, get properties like ID & Title, and update the metadata of the item using item.setMetadata("new metadata with updated values").
Simple :)
Your code runs in a popup, so any references you make to global variables will be taken from the popup window.
So when you get the fieldBuilder:
var fieldBuilder = $display.getView().properties.controls.fieldBuilder;
$display is a reference to a global variable. So this actually looks for the FieldBuilder in the popup window (which doesn't have one).
To get the FieldBuilder of the Component window, you can get it from the opener:
var fieldBuilder = opener.$display.getView().properties.controls.fieldBuilder;
You might want to consider actually passing the updated value to either a callback function or with a (custom) event though, since that makes your popup less dependent on opener. trick.
I am building a custom button and I have this so far:
{!REQUIRESCRIPT("/soap/ajax/8.0/connection.js")}
var lead = new sforce.SObject("Lead");
lead.id = "{!Lead.Id}";
lead.OwnerId = "ID";
lead.Status = "STATUS";
var result = sforce.connection.update([lead]);
if (result[0].getBoolean("success"))
{
// Refresh window
window.location.reload();
}
else
{
alert("Error saving lead");
}
This all works perfectly and makes the changes I desire, but what I also want to happen is when the button is clicked, and before anything is saved, I want the:
lead.Reason__c
Text field to pop up, like it would if you double clicked it, so that the user can fill in a reason for clicking the button
I have tried code like:
lead.Reason__c.open
lead.Reason__c.edit
But have had no luck and am pretty much just stabbing in the dark with this.
I hope someone can help,
Thanks all
Since you only have one field, you do not need a form, I would recommend you use javascript's prompt box and if it returns something other than null (null -> user clicked cancel) do your magic
{!REQUIRESCRIPT("/soap/ajax/8.0/connection.js")}
var reason = prompt("Enter reason", "");
if (reason != null) {
var lead = new sforce.SObject("Lead");
lead.id = "{!Lead.Id}";
lead.OwnerId = "ID";
lead.Status = "STATUS";
lead.Reason__c = reason;
...
}
PS: I would also recommend using a "fresher" ajax toolkit than 8.0 :) we are at 24.0 now. I doubt they'll obsolete the old ones but you never know.
The correct way to truly simulate a double-click is by dispatching a double-click event to the element; this page has an excellent reference on how to do that. I can confirm that you can create a custom button that dispatches a double-click to an SFDC edit field and it acts as if the user double-clicked the field themselves. Quick and dirty example:
var evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent( 'dblclick', true, true, window, 1, 12, 345, 7, 220, false, false, true, false, 0, null );
document.getElementById('lea13_ilecell').dispatchEvent(evObj);
However, that's not going to be a sound approach for you because once you double-click a field, as you know, the "Save" and "Cancel" buttons are rendered to the user with no ability to override their behavior in the manner you need to. You could hack around this with some jQuery magic, but I'd recomment mmix's approach, it's much more sound. If your requirements expand to something beyond a single text field, you may need to incorporate some fancy dynamic HTML/CSS dialog boxes, or VisualForce, but based on what you need, the prompt approach is the simplest answer.
No matter what I try, I can't seem to fire the click event on the "default" button in an Alert control in a Flex 3.4 application.
Alert.show(
'Are you sure you want to delete the selected link?',
'Confirm Delete',
Alert.YES | Alert.CANCEL,
null,
confirmDelete,
null,
Alert.YES
);
In the above code sample, the final argument: Alert.YES is specifying that the "default" option (from the bitwise list in the 3rd argument) is the "Yes" button. In theory, and based on my experience designing Windows applications, "default button" means that hitting the enter key (or sometimes the space bar) fires the click event for that button.
If it matters, the Alert in question is modal.
I can see that the button is styled as the default: it gets a bit of a halo or extra border when compared to the Cancel button or when compared to itself when passing null as the last argument.
However, hitting the enter and space keys seem to have no affect. Am I doing something wrong, or missing some crucial step in getting this functionality to work?
Update 2010-02-17:
Based on my 2nd comment on #rhtx's answer:
Ok, finally got around to trying this. Since the Alert class uses lots of static methods, I essentially just copied the Alert and AlertForm classes into my project (and fixed some relative paths for includes), and what I ended up with was an uglier alert box that works (or doesn't, depending on your perspective) the same way as the vanilla Alert class. I did realize, however, that if you hit TAB it will focus the alert buttons, at which point hitting Escape/Enter will have the desired effect... So how do I eliminate the need to hit TAB?
I tried a few more things and didn't get anywhere.
I tried faking a TAB keypress after opening the alert (with both KEY_DOWN and KEY_UP event types):
var a:Alert = Alert.show(msg, title, Alert.YES | Alert.CANCEL, null, fnCb);
var tabEvent:KeyboardEvent = new KeyboardEvent(
KeyboardEvent.KEY_DOWN,
true,
false,
0,
Keyboard.TAB
);
a.dispatchEvent(tabEvent);
I also found this blog post and tried doing this to focus the alertForm:
var a:Alert = Alert.show(msg, title, Alert.YES | Alert.CANCEL, null, fnCb);
a.mx_internal::alertForm.setFocus();
Neither of these threw errors, but neither produced the desired result, either.
I would approach this by extending the Alert class to include functionality that listens for keyUp events from the Enter and Space keys.
In the createChildren method of your subclass:
override public function createChildren():void
{
super.createChildren();
this.addEventListener(KeyboardEvent.KEY_UP, keyUpListener);
this.stage.addEventListener(KeyboardEvent.KEY_UP, keyUpListener);
}
private function keyUpListener(e:KeyboardEvent):void
{
if(e.keyCode == Keyboard.ENTER || e.keyCode == Keyboard.SPACE)
{
//Trigger the Alert.YES functionality...
}
}
I'm having some issues with my set up this morning and can't get into the Alert class to provide info on how to "Trigger the Alert.YES functionality", but I'll try to post some more on this later on. Hope this little bit helps.
Also - I'm not 100% on this - but I think you will need to manually remove the event listeners when the Alert popup is removed.
Aaand... you may not need both of those listeners. Can't test right now to make sure.
UPDATE: -----------------
After a little more looking, maybe the best way to go about this is to extend the AlertForm class (which manages the Alert's buttons), and then extend the Alert class to use your extended AlertForm class.
The AlertForm class has a keyDownHandler method, which it defines like this:
override protected function keyDownHandler(event:KeyboardEvent):void
{
var buttonFlags:uint = Alert(parent).buttonFlags;
if (event.keyCode == Keyboard.ESCAPE)
{
if ((buttonFlags & Alert.CANCEL) || !(buttonFlags & Alert.NO))
removeAlert("CANCEL");
else if (buttonFlags & Alert.NO)
removeAlert("NO");
}
}
You can see that it is setting up the 'close' behavior in response to pressing the Escape key. You add a little logic, based on the code in the above 'keyUpListener' function to make a call to the AlertForm's removeAlert method, passing in the appropriate String value for the Yes button.
For reference, the removeAlert method looks like this:
private function removeAlert(buttonPressed:String):void
{
var alert:Alert = Alert(parent);
alert.visible = false;
var closeEvent:CloseEvent = new CloseEvent(CloseEvent.CLOSE);
if (buttonPressed == "YES")
closeEvent.detail = Alert.YES;
else if (buttonPressed == "NO")
closeEvent.detail = Alert.NO;
else if (buttonPressed == "OK")
closeEvent.detail = Alert.OK;
else if (buttonPressed == "CANCEL")
closeEvent.detail = Alert.CANCEL;
alert.dispatchEvent(closeEvent);
mx.managers.PopUpManager.removePopUp(alert);
}
I ran into a similar situation. What got me out of it was:
(1) defining the default button in Alert.show(), (2) using a callLater(), and (3) setting the focus manually on the default button.
For example, using Alert.CANCEL as the intended default button (can change to Alert.YES if needed):
var a:Alert = Alert.show(msg, title, Alert.YES | Alert.CANCEL, null, fnCb, null, Alert.CANCEL);
callLater(setAlertButtonFocus,[a]);
...
private function setAlertButtonFocus(a:Alert):void {
a.mx_internal::alertForm.mx_internal::defaultButton.setFocus();
}
This enables the Escape and Enter keys to act as if the user clicked the default button with the mouse.