I've created some elements of my GUI with GWT framework. I've just one button with an simple onCLick method. And when the button gets the focus (setfocus(true)) the triogger fires a click event automatically. But I just want the button holds the focus without fire any events .
How to make it in a simple way ?
my code :
public void onModuleLoad(){
..............
textBoxTx = new TextBox();
textBoxTx.addKeyDownHandler(new KeyDownHandler() {
public void onKeyDown(KeyDownEvent event) {
switch(event.getNativeKeyCode()){
case KeyCodes.KEY_ENTER: addTx();
}
}
});
....
protected void addTx()
final String tx = textBoxTx.getText().toUpperCase().trim();
textBoxTx.setFocus(true);
if (!tx.matches("^[0-9\\.]{1,10}$")) {
Window.alert("'" + tx + "' n'est pas valide .");
textBoxTx.selectAll();
return;
}
textBoxTx.setText("");
param_Tx=Double.parseDouble(tx);
if (param_An==0)
rateFlexTable.setText(1, 2, tx);
else
{
for (int i=1;i<=param_An;i++)
rateFlexTable.setText(i, 2,tx);
rateFlexTable.setText(param_An, 4,"");
}
**// fire the click event of my button when I give the focus**
**btnCalcul.setFocus(true)**
}
If you have a standard com.google.gwt.user.client.ui.Button, calling setFocus(true) on it will not activate the ClickHandlers for that button. It may be good if you could share some code because what you describe should not happen unless you are explicitly calling Button.click() or the user is actually click on the button.
Related
I found an article online that said to setup the toolbar button to be a type that stays pressed you just set a style TBBS_CHECKBOX on the button but it doesn't work for me (it still acts like a normal button). I confirmed the style is set, just after created and the SetWindowText() MFC wizard setup of CMainFrame::OnCreate(). What am I doing wrong?
for (int i=0; ; i++) {
int id=m_wndToolBar.GetItemID(i);
if (id==0) {
break;
}
if (id == ID_THE_ID) {
m_wndToolBar.SetButtonStyle(i, TBBS_CHECKBOX);
}
}
Using Command Handlers is the recommended implementation here. A command ID may be used in multiple UI items, eg a menu item and a toolbar button. A handler affects all items with the same ID, so you don't need a separate one for each item. The CCmdUI Class provides methods that can cause UI items like menus or toolbar buttons to behave as push-buttons, check-boxes or radio-buttons, in addition to enabling/disabling.
In your example, suppose that the option whether to filter is instantiated on a per document basis, ie all views of the document would be filtered or non-filtered, all at the same time. You should define a boolean variable in your document class:
BOOL m_bFilterData = FALSE;
Then the ON_COMMAND and ON_UPDATE_COMMAND_UI handlers for the toolbar button with the Filter pic (and possibly a menu item as well):
BEGIN_MESSAGE_MAP(CMyDoc, CDocument)
.
.
ON_COMMAND(ID_VIEW_FILTERDATA, OnViewFilterData)
ON_UPDATE_COMMAND_UI(ID_VIEW_FILTERDATA, OnUpdateViewFilterData)
.
.
END_MESSAGE_MAP()
void CMyDoc::OnViewFilterData()
{
// Toggle filtered state
m_bFilterData = !m_bFilterData;
// Tell all views to refresh - You can limit this using the lHint/pHint params
UpdateAllViews(NULL, 0L, NULL);
}
void CMyDoc::OnUpdateViewFilterData(CCmdUI* pCmdUI)
{
// Enable/Disable as needed
pCmdUI->Enable(m_nTotalItems>0);
// Show pressed/checked if data filtered
pCmdUI->SetCheck(m_bFilterData);
}
Now, if the filter option is instantiated per view, ie each view can indpendently be filtered or non-filtered, the above must go to your view class(-es):
void CMyView::OnViewFilterData()
{
// Toggle filtered state
m_bFilterData = !m_bFilterData;
// Refresh this view only
.
.
}
void CMyView::OnUpdateViewFilterData(CCmdUI* pCmdUI)
{
// Enable/Disable as needed
pCmdUI->Enable(GetDocument()->m_nTotalItems > 0);
// Show pressed/checked if data filtered
pCmdUI->SetCheck(m_bFilterData);
}
My initial view has this code
if (CLLocationManager.Status == CLAuthorizationStatus.Denied ||
CLLocationManager.Status == CLAuthorizationStatus.Restricted ||
CLLocationManager.Status == CLAuthorizationStatus.NotDetermined)
{
Core.FirstLaunch = true;
NavigationController.PushViewController(new LocationServicesVerifyViewController(), false);
}
else
{
NavigationController.PushViewController(new JobListViewController(), false);
}
If the location is not enabled, the location services verify controller is shown, however, the menu has a back button which is taking the user to license activation screen.
How can I change the back button to Job list and clicking it will take the user to job list controller instead?
e.g.,
Solution 1: You need to replace the backbutton and associate an action handler. You could either use text or an image for the Back Button. To do this, in your ViewDidLoad override, add this:
var _backButton = new UIBarButtonItem()
{
Title = "Back",
// Image = UIImage.FromBundle("back_navbar").OriginalRendering(), Need to add the image in Resources for this to work
TintColor = UIColor.FromRGB(0, 70, 113) // Change this to your app colours
};
_backButton.Clicked += _backButton_Clicked;
NavigationItem.SetLeftBarButtonItem(_backButton, animated: true);
And then handle the button press as shown:
void _backButton_Clicked(object sender, System.EventArgs e)
{
var controller = new JobListViewController();
this.PresentViewController(controller, true, null);
}
Solution 2: You could also just remove the unwanted LicenseActivation view controller from the navigation stack so going back won't go to that page. So when you are leaving the LicenseActivation page, in the ViewWillDisappear override, add this code:
var oldControllers = this.NavigationController.ViewControllers;
var newControllers = new UIViewController[oldControllers - 1];
int index = 0;
foreach (var item in oldControllers) {
if (item != this)
{
newControllers [index] = item;
index++;
}
}
this.NavigationController.ViewControllers = newControllers;
Solution 3:
Just use a modal for the LicenseActivation page, so that as soon as you Accept the LicenseActivation, it closes the modal and goes to the next page.
So you are pushing views on to the navigation stack, e.g.,
NavigationController.PushViewController(new LocationServicesVerifyViewController(), false);
so when you press back you are popping the stack and going to the last view. If you don't want this type of navigation you could do this:
Don't push the LocationServicesVerifyViewController to the navigation controller. Rather present it modally like this:
PresentModalViewController(new LocationServicesVerifyViewController(), false);
You will need a close button on LocationServicesVerifyViewController to dismiss.
I would present the JobListViewController by pushing to the navigation controller first then check for the location inside JobListViewController then present the modal LocationServicesVerifyViewController if needed.
OR
Do you need a whole view controller for this? You could just present a popup:
var locationServiceAlertController = UIAlertController.Create("Location Services are off", "Your company... Bla", UIAlertControllerStyle.Alert);
locationServiceAlertController.AddAction(UIAlertAction.Create("Enable", UIAlertActionStyle.Default, alert => Console.WriteLine ("Do your enable stuff")));
locationServiceAlertController.AddAction(UIAlertAction.Create("Cancel", UIAlertActionStyle.Cancel, alert => Console.WriteLine ("Cancel was clicked")));
PresentViewController(locationServiceAlertController, true, null);
I want to add some functionality to the right arrow button, the one that puts the user selection into the selected elements panel. Specifically, when the user selects an element from the avaliable choices, I don't want the element to be taken to the selected elements panel if there are elements at the right panel of another palette. So basically, what I need is to execute custom java code when the button is pressed, and alter the default behavior of the palette when a condition occurs.
I found the solution somewhere else. Just in case someone needs it, here is what you have to do.
myPalette = new Palette<MyClass>(...) {
#Override
protected Recorder newRecorderComponent() {
Recorder<MyClass> recorder = super.newRecorderComponent();
recorder.add(new AjaxFormComponentUpdatingBehavior("onchange") {
protected void onUpdate(AjaxRequestTarget target) {
// Custom code
...
if (target != null)
// Update another component
target.add(anotherComponent);
}
}
);
return recorder;
}
};
I have a form and I want to display a confirmation dialogBox when the user presses the back button. Let say that I have one Texbonx that listens to a ChangeValueHandler
addValueChangeHandler(new ValueChangeHandler<String>() {
#Override
public void onValueChange(ValueChangeEvent<String> event) {
setChanged(true);
}
});
This is the short scenario
1) I enter text in the TextBox
2) I hit the back button
3) The ValueChangeEvent is not called
I tried the fire the BlurEvent programmatically on the TextBox with textBox.fireEvent(new BlurEvent() { }); but still no result.
Any suggestions ?
When the page is closed (by pressing the back button, or closing the page) no events will be fired by the controls. What will fire first is window.onbeforeunload to give you a chance to warn the user about data loss and offer to stay on the page. If the user chooses to stay on the page, then all the events that were supposed to be fired, will fire (so your change event will fire).
You can attach a handler to the native onbeforeunload event by using Window.addClosingHandler.
Window.addWindowClosingHandler(new ClosingHandler() {
#Override
public void onWindowClosing( ClosingEvent event )
{
event.setMessage("If you leave the page now all data will be lost.");
}
});
It's worth noting that the ClosingEvent and it's underlying onbeforeunload event, cannot, under any circumstances, be cancelled programmatically. The only way to prevent the user from leaving the page is if the user itself chooses "Stay On This Page" in the popup that results from the code above.
What I did is to set the focus of the TextBox to False and then check if it's changed, that forces the TextBox to unfocus when hiting the back button.
This is the code that check if a form is changed
public boolean isChanged(){
if(formPanel == null) return false;
for (int i = 0; i < formPanel.getWidgetCount(); i++) {
if(formPanel.getWidget(i) instanceof BaseWidget){
BaseWidget w= (BaseWidget) formPanel.getWidget(i);
w.setFocus(false);
if(w.isChanged()){
return true;
}
}
}
return false;
}
When I create a checkbox column (through use of formatters/editors) in Slickgrid, I've noticed that it takes two clicks to interact with it (one to focus the cell, and one to interact with the checkbox). (Which makes perfect sense)
However, I've noticed that I am able to interact with the checkbox selectors plugin (for selecting multiple rows) with one click. Is there any way I can make ALL of my checkboxes behave this way?
For futher readers I solved this problem by modifing the grid data itself on click event. Setting boolean value to opposite and then the formatter will display clicked or unclicked checkbox.
grid.onClick.subscribe (function (e, args)
{
if ($(e.target).is(':checkbox') && options['editable'])
{
var column = args.grid.getColumns()[args.cell];
if (column['editable'] == false || column['autoEdit'] == false)
return;
data[args.row][column.field] = !data[args.row][column.field];
}
});
function CheckboxFormatter (row, cell, value, columnDef, dataContext)
{
if (value)
return '<input type="checkbox" name="" value="'+ value +'" checked />';
else
return '<input type="checkbox" name="" value="' + value + '" />';
}
Hope it helps.
The way I have done it is pretty straight forward.
First step is you have to disable the editor handler for your checkbox.
In my project it looks something like this. I have a slickgridhelper.js to register plugins and work with them.
function attachPluginsToColumns(columns) {
$.each(columns, function (index, column) {
if (column.mandatory) {
column.validator = requiredFieldValidator;
}
if (column.editable) {
if (column.type == "text" && column.autocomplete) {
column.editor = Slick.Editors.Auto;
}
else if (column.type == "checkbox") {
//Editor has been diasbled.
//column.editor = Slick.Editors.Checkbox;
column.formatter = Slick.Formatters.Checkmark;
}
}
});
Next step is to register an onClick event handler in your custom js page which you are developing.
grid.onClick.subscribe(function (e, args) {
var row = args.grid.getData().getItems()[args.row];
var column = args.grid.getColumns()[args.cell];
if (column.editable && column.type == "checkbox") {
row[column.field] = !row[column.field];
refreshGrid(grid);
}
});
Now a single click is suffice to change the value of your checkbox and persist it.
Register a handler for the "onClick" event and make the changes to the data there.
See http://mleibman.github.com/SlickGrid/examples/example7-events.html
grid.onClick.subscribe(function(e, args) {
var checkbox = $(e.target);
// do stuff
});
The only way I found solving it is by editing the slick.checkboxselectcolumn.js plugin. I liked the subscribe method, but it haven't attached to me any listener to the radio buttons.
So what I did is to edit the functions handleClick(e, args) & handleHeaderClick(e, args).
I added function calls, and in my js file I just did what I wanted with it.
function handleClick(e, args) {
if (_grid.getColumns()[args.cell].id === _options.columnId && $(e.target).is(":checkbox")) {
......
//my custom line
callCustonCheckboxListener();
......
}
}
function handleHeaderClick(e, args) {
if (args.column.id == _options.columnId && $(e.target).is(":checkbox")) {
...
var isETargetChecked = $(e.target).is(":checked");
if (isETargetChecked) {
...
callCustonHeaderToggler(isETargetChecked);
} else {
...
callCustonHeaderToggler(isETargetChecked);
}
...
}
}
Code
pastebin.com/22snHdrw
Search for my username in the comments
I used the onBeforeEditCell event to achieve this for my boolean field 'can_transmit'
Basically capture an edit cell click on the column you want, make the change yourself, then return false to stop the cell edit event.
grid.onBeforeEditCell.subscribe(function(row, cell) {
if (grid.getColumns()[cell.cell].id == 'can_transmit') {
if (data[cell.row].can_transmit) {
data[cell.row].can_transmit = false;
}
else {
data[cell.row].can_transmit = true;
}
grid.updateRow(cell.row);
grid.invalidate();
return false;
}
This works for me. However, if you're using the DataView feature (e.g. filtering), there's additional work to update the dataview with this change. I haven't figured out how to do that yet...
I managed to get a single click editor working rather hackishly with DataView by calling
setTimeout(function(){ $("theCheckBox").click(); },0);
in my CheckBoxCellEditor function, and calling Slick.GlobalEditorLock.commitCurrentEdit(); when the CheckBoxCellEditor created checkbox is clicked (by that setTimeout).
The problem is that the CheckBoxCellFormatter checkbox is clicked, then that event spawns the CheckBoxCellEditor code, which replaces the checkbox with a new one. If you simply call jquery's .click() on that selector, you'll fire the CheckBoxCellEditor event again due because slickgrid hasn't unbound the handler that got you there in the first place. The setTimeout fires the click after that handler is removed (I was worried about timing issues, but I was unable to produce any in any browser).
Sorry I couldn't provide any example code, the code I have is to implementation specific to be useful as a general solution.