The problem is that editable mode is not shown in the table. That table sets container as a data source. Container is filled with the data from the View. If the column is the result of any function (sum and so on) it can’t be edited as I understood. I will explain in more details with a simple example:
Say what my View in the DB has a column “ABC”. If(A = 0, B + C, A) as ABC The result of it is combined from other tables which have columns A, B, C. Say, what values are A = 0, B = 1, C = 2. So the value of column “ABC” will be 3. But I can’t do it editable because it is a result of function. In the case if it is editable, for example, I write 5 in the editable field. Then my function saves that value to the table which has a column A. The value of ABC becomes 5. I refresh table and reload data and see 5 in the table. How to do that? I am still not sure if you understand what I want.
By the way if the column is just a single value of any column (say (SELECT A FROM MyTable) as ABC) it works well I tested.
to get more/faster answers, maybe work on your question a bit. You could start e.g. on which Container are you using for the table? Indexed? SQLContainer? Do you have a generated column in the container?
Also, at least I was not able to follow what is the exact end result you want. I think a little bit of code would help a lot.
FreeformQuery myQuery = new FreeformQuery("SELECT * FROM Summary", connectionPool, "Id");
SummaryDelegate summaryDelegate = new SummaryDelegate();
myQuery.setDelegate(summaryDelegate);
summaryContainer = new SQLContainer(myQuery);
I have one generated column.
summaryTable.addGeneratedColumn("Actions", new ColumnGenerator() {
public Object generateCell(final Table source, final Object itemId, Object columnId) {
final Button button = new Button("");
button.setStyleName(BaseTheme.BUTTON_LINK);
if(clickedItem == itemId)
{
button.setIcon(new ThemeResource("images/Done-icon.png"));
button.setData(itemId);
button.addListener(new ClickListener() {
public void buttonClick(com.vaadin.ui.Button.ClickEvent event) {
clickedItem = null;
summaryTable.setEditable(false);
getDbHelp().changeSummary(Integer.parseInt(summaryTable.getItem(itemId).getItemProperty("ProjectId").getValue().toString()),
Integer.parseInt(summaryTable.getItem(itemId).getItemProperty("PAXNumber").getValue().toString()),
Float.parseFloat(summaryTable.getItem(itemId).getItemProperty("Sell").getValue().toString()));
}
});
}
else
{
button.setIcon(new ThemeResource("images/edit-icon-1.png"));
button.addListener(new ClickListener() {
public void buttonClick(com.vaadin.ui.Button.ClickEvent event) {
clickedItem = itemId;
summaryTable.setTableFieldFactory(new TableFieldFactory()
{
public Field createField(Container container, Object itemId, Object propertyId, Component uiContext)
{
RowId currentTicket = (RowId) itemId;
if(clickedItem == currentTicket)
{
summaryTable.setImmediate(true);
TextField t = new TextField();
t.setImmediate(true);
return t;
}
return null;
}
});
if (summaryTable.isEditable() == false) {
summaryTable.setEditable(true);
summaryTable.setImmediate(true);
}
}
});
}
return button;
}
});
When I click on a generated column “Action”, editable columns become the ones, which are not generated by functions in MySQL Table “Summary”.
For example
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `Summary` AS SELECT
`Id`,
`Amount` * `Price` AS `Value`,
`Price` - `Sell` AS `Margin`
FROM `Calculations`
In this situation just ‘Id’ column will be editable. Of course, in general ‘Id’ column is not shown to the user. ‘Value’ and ‘Margin’ are not editable. If we will change Amount * Price AS Value, to Amount AS Value, then ‘Value’ will become editable.
How to do that all the columns will become editable?
unfortunately I can’t at least straight away think of a way to do this. The columns you give as an example are calculated in the DB and not related to any real column and thus the ResultSetMetaData coming from the DB will tell that they are read-only. This in turn will make them non-editable in the Tables editable mode.
What I did not yet understand is what should happen when you edit such a column? Obviously the result could not go directly into the DB via SQLContainer.
I think the easiest way to achieve editability for the values you want is to include the columns Amount, Price and Sell into the query as is - they should then be editable.
You could of course hack away at the SQLContainer to make the DB-computed columns editable, but the SQLContainer would still not know where and how to put the data since it’s not even aware of the actual DB columns (Amount etc.).
Another option that comes to mind is that you would create an IndexedContainer based on the SQLContainer you get from your DB view. Then all the properties should be editable. The downside is that now you must write all the DB commit code yourself - e.g. some user changes the Margin column of a row with Id 1, then you would get a ValueChangeEvent somewhere and could generate a DB call based on that.
The closer example of the View in the DB is like this:
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `Summary` AS SELECT
ifnull(`M`.`Margin`, `C`.`Price`-`C`.`Sell`) AS `MarginCalc`
FROM `Calculations` `C` JOIN `Margins` `M` ON `C.ItemId`.`` = `M`.`ItemId`
Actually the View is a bit more complicated, but to understand my wishes I think thats enough. So I have column “MarginCalc”. Let’s say that column Margin from table Margins is null. So the value of “MarginCalc” will be “Calculations”.“Price”-“Calculations”.“Sell” Let’s say that my table is editable. So, when I change a value of “MarginCalc” I change the column “Margin” data via SQLContainer in the “Margins” table. Then I refresh the container I should see the new value “Margin” from table “Margins” as “MarginCalc”. If I will delete it and it will become null, then the result will be “Calculations”.“Price”-“Calculations”.“Sell”.
Ok - I now get what you want. Unfortunately I have no idea how that could be done :(
You might explore the ideas I threw in the air in my previous post - although honestly I don’t know if those are feasible or not. Seems to me that changing the read-only status for a column is quite difficult in SQLContainer - the ColumnProperty does not seem to allow it and there’s no easy way to override. If you could do this, then you could just handle storing the row correctly within your FreeformQueryDelegate.
I hope someone else with fresh ideas could pitch in. At least now the issue is clearly laid out for others too.