how to set setEnabled: for NSButton in an NSTableView - nstableview

Hi All
I have an NSTableView which has three columns. The first one is a checkbox and the third one is a button. The button 'is enabled' state depends on whether or not the checkbox is checked.
I am setting the table content in the awakeFromNib method and I am implementing the checkbox state in the - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row method. I need to find a way setEnabled: for the NSButton
Thanks

A good way to set button states in an NSTableView is to use an NSArrayController and bind it to the columns of the NSTableView:
Bind the column that contains the buttons to the NSArrayController (see this example)
Under Enabled
Set the Controller Key to arrangedObjects
Set the Model Key Path to the NSArrayController's button state. For example, let's call it enabled .
Now in the class where you have the NSArrayController and the NSTableView delegate, do something like this after you click a checkbox:
- (void)updateArrayControllerWithButtonState: (BOOL)isEnabled
{
// theTable is the NSTableView instance variable
NSInteger row = [theTable clickedRow];
// Get the array of values that populates the table
NSMutableDictionary *arrayValues = [[theArrayController arrangedObjects] objectAtIndex:row];
// Actually change the NSArrayController's value to match
[arrayValues setObject:[NSNumber numberWithBool:[model isEnabled]] forKey:#"enabled"];
[theTable reloadData];
}
Provided you set up your bindings properly for the NSArrayController & NSTableView, this function should update the current state of the button to match that of the NSArrayController.
This code is untested but should shed some light on the general idea.

Related

tornadofx EventBus expand table row using tableview object

Background:
Suppose I have multiple fragments of a single table in a view, each with a rowExpander.
Expected Behaviour:
If in one table fragment I expand a row, other fragments same indexed row should get expanded. Same for collapse
My Progress:
Sample Fragment:
tableview(dataset) {
column("First Name", Person::firstNameProperty)
column("Last Name", Person::lastNameProperty)
rowExpander(true) {
selectedData.item?.apply {
fire(ExpandDataEvent(dataset.indexOf(this)))
}
column("Mobile Nos.", Person::mobileNumProperty)
column("Email Ids", Person::emailIdProperty)
}
bindSelected(selectedData)
subscribe<ExpandDataEvent> { event ->
selectionModel.select(event.index)
}
}
Event Class:
class ExpandDataEvent(val index: Int) : FXEvent()
What I understand from "subscribe" is that it gets called when an event is fired (currently I am firing the event whenever the user expands the row by either double-click/clicking the plus sign); and since the subscribe is placed inside tableview, it gets called for all the table fragments present (which is what I want). But in the subscribe method I am doing a selectionModel.select(event.index) which only selects the corresponding index row. I want to expand the row (preferably by using the selectionModel)
Question 2:
Is it possible to remove the plus sign column? For rowExpand, if I have set expandOnDoubleClick to true, I dont want the plus sign column in my tableview.
The rowExpander builder returns the actual ExpanderColumn which is basically a normal TableColumn. Save a reference to the expander so that you can operate on it later:
val expander = rowExpander(true) { ... }
Directly below, you can now hide the expander column:
expander.isVisible = false
Now it's easy to toggle the expanded state of a specific row from the event subscriber as well:
subscribe<ExpandDataEvent> { event ->
expander.toggleExpanded(event.index)
selectionModel.select(event.index)
}
You might want to double check that you don't toggle the expander for the tableview that fired the event, so consider including the event source in your event and discriminate on that in the subscriber.
I will investigate if we can add a visible boolean parameter to the rowExpander builder function so you don't need to call isVisible manually :)

Persist checkbox in gridview while custom paging

I have a created a gridview and added a checkbox in item template. This grid has few columns along with DataKey (primary key). Due to performance gain, this grid will fetch the next set of recrods on each page change based on the page number click. So that is done.
Now when user selects a checkbox in page one and then go to page 2 and coming back to page one, then user will not see the checkbox checked as the user did earlier.
So is there a good way to persist the checkbox when user move page to page?
This checkbox be used as a flag to select the rows that can be deleted later by a button outside the grid.
Since you receive a new set each time a paging is selected, I suggest the following approach:
Create an array[] object via javascript that will add to list the datakey whenever a checkbox is selected and in turn remove it if the checkbox is deselected. Something like this:
var selectedDataKeys = [];
$('.checkboxclass').on('change', function() {
// Considering you assign the data key as id for the checkbox otherwise implement a way to retrieve the id.
var dataKey = $(this).prop('id');
// Determine if the dataKey is in the selected data keys array
var isContained = (selectedDataKeys.indexOf(dataKey) > -1 );
if($(this).is(':checked')) {
// If is contained is false - add to the array
if (!isContained)
selectedDataKeys.push(dataKey);
} else {
// If is contained is true - remove to the array
if (isContained){
selectedDataKeys = $.grep(selectedDataKeys, function(value) {
return value != dataKey;
});
}
}
});
From this point on the client user will have an active list of selected items, now its up to you to use that list to manipulate your grid display page. Either modify the display on document ready by comparing all the item on the grid display with the selectedDataKeys array or sending those keys and do the comparison server side.
Hope this helps.

Is there a way to have all radion buttons be unchecked

I have a QGroupBox with a couple of QRadioButtons inside of it and in certain cases I want all radio buttons to be unchecked. Seems that this is not possible when a selection has been made. Do you know of a way I could do this or should I add a hidden radiobutton and check that onen to get the desired result.
You can achieve this effect by temporarily turning off auto exclusivity for all your radio buttons, unchecking them, and then turning them back on:
QRadioButton* rbutton1 = new QRadioButton("Option 1", parent);
// ... other code ...
rbutton1->setAutoExclusive(false);
rbutton1->setChecked(false);
rbutton1->setAutoExclusive(true);
You might want to look at using QButtonGroup to keep things tidier, it'll let you turn exclusivity on and off for an entire group of buttons instead of iterating through them yourself:
// where rbuttons are QRadioButtons with appropriate parent widgets
// (QButtonGroup doesn't draw or layout anything, it's just a container class)
QButtonGroup* group = new QButtonGroup(parent);
group->addButton(rbutton1);
group->addButton(rbutton2);
group->addButton(rbutton3);
// ... other code ...
QAbstractButton* checked = group->checkedButton();
if (checked)
{
group->setExclusive(false);
checked->setChecked(false);
group->setExclusive(true);
}
However, as the other answers have stated, you might want to consider using checkboxes instead, since radio buttons aren't really meant for this sort of thing.
If you're using QGroupBox to group buttons, you can't use the setExclusive(false) function to uncheck the checked RadioButton. You can read about it in QRadioButton section of QT docs. So if you want to reset your buttons, you can try something like this:
QButtonGroup *buttonGroup = new QButtonGroup;
QRadioButton *radioButton1 = new QRadioButton("button1");
QRadioButton *radioButton2 = new QRadioButton("button2");
QRadioButton *radioButton3 = new QRadioButton("button3");
buttonGroup->addButton(radioButton1);
buttonGroup->addButton(radioButton2);
buttonGroup->addButton(radioButton3);
if(buttonGroup->checkedButton() != 0)
{
// Disable the exclusive property of the Button Group
buttonGroup->setExclusive(false);
// Get the checked button and uncheck it
buttonGroup->checkedButton()->setChecked(false);
// Enable the exclusive property of the Button Group
buttonGroup->setExclusive(true);
}
You can disable the exclusive property of the ButtonGroup to reset all the buttons associated with the ButtonGroup, then you can enable the Exclusive property so that multiple button checks won't be possible.

Array Objects and Datagrid with Link Button (Clear Button) in Adobe Flex

I have an an array of objects. I populate the datagrid from the array. The nmber of columns in the datagrid is fix i.e.5 and the first column always shows serial number (0,1,2,3,4).
I have a link button called 'CLEAR' in the last column of the datagrid.
1> How do I make the clear button visible only when the row is particularly clicked ?
2> When the clear button is clicked, how do I make the contents of that particular row cleared. Not deleted, only cleared to insert data again. Also, the serial number (0,1,2,3,4) should not be cleared, nor deleted. How to do this ?
To make your clear button visible something like this would work.
may have to play around with it a bit.
private function onDatagridClick(event:ListEvent):void {
if ( event.rowIndex == -1 ) {
return;
}
clearBTN[event.RowIndex].visible = true;
}
If you don't want to delete your column you need to place some data in there as the datagrid is bound by the data provider you can always add dummy data i.e. blank string, "Enter data" or a custom item renderer for when data is required.

Flex ComboBox, default value and dataproviders

I have a Flex ComboBox that gets populated by a dataprovider all is well...
I would now like to add a default " -- select a item --" option at the 0 index, how can I do this and still use a dataprovider? I have not seen any examples of such, but I can't imagine this being hard...
If you don't need the default item to be selectable you can use the prompt property of ComboBox and set the selectedIndex to -1. That will show the string you set propmt to as the selected value until the user chooses another. It will not appear in the list of options, however.
I came across this problem today and wanted to share my solution.
I have a ComboBox that has an ArrayCollection containing Objects as it's dataprovider. When the application runs, it uses a RemoteObject to go out and get the ArrayCollection/Objects. In my event handler for that call I just have it append another object to the beginning of the ArrayCollection and select it:
var defaultOption:Object = {MyLabelField: "Select One"};
myDataProvider.addItemAt(defaultOption, 0);
myComboBox.selectedIndex = 0;
This is what my ComboBox looks like for reference:
<mx:ComboBox id="myComboBox" dataProvider="{myDataProvider}" labelField="MyLabelField" />
The way I've dealt with this in the past is to create a new collection to serve as the data provider for the combobox, and then I listen for changes to the original source (using an mx.BindingUtils.ChangeWatcher). When I get such a notification, I recreate my custom data provider.
I wish I knew a better way to approach this; I'll monitor this question just in case.
This can be used following code for selected default value of combobox
var index:String = "foo";
for(var objIndex:int = 0; objIndex < comboBox.dataProvider.length; objIndex++) {
if(comboBox.dataProvider[objIndex].label == index)
{
comboBox.selectedIndex = objIndex;
break;
}
}
<mx:ComboBox id="comboBox" dataProvider="{_pageIndexArray}" />

Resources