I had create an example like Editor Example, while the difference is that my demo can hide column. While when I hidden some column, I can not the collect selected column index, I changed my mind, I want to get the selected column's header name. How to get it?
Following is the handler to handle the selected column
But I don't know how to get the column name
public void handleLayerEvent(ILayerEvent event) {
if (event instanceof CellSelectionEvent) {
CellSelectionEvent cellEvent = (CellSelectionEvent) event;
int columnIndex = natTable.getColumnIndexByPosition(cellEvent.getColumnPosition());
SelectionLayer selectionLayer = cellEvent.getSelectionLayer();
........
}
You need the reference to the ColumnHeaderLayer and get the data value. E.g. ColumnHeaderLayer#getDataValueByPosition(int, int)
Related
In my Form, I have Two TabPages, with the same DataSource for each.
In TabPageA I have all records from my DataSource. I select records in TabPageA and I want to only show, in TabPageB, those records I selected previously in TabPageA.
If I don't select anything in TabPageA I don't see anything in TabPageB
For example if in my GridA I selected Record#4 , in GridB I see only Record#4.
I don't think you'll be able to filter TabPageB differently from TabPageA easily due to the fact they share the same DataSource.
There are two quick ways to modify this.
Keep it as one DataSource:
Create a global QueryBuildRange to easily update the range on selected records.
public class FormRun extends ObjectRun
{
QueryBuildRange qbr;
}
Override the init of your datasource. Here you will set the qbr:
public void init()
{
super();
qbr = this.queryBuildDataSource().addRange(fieldNum(SalesTable, RecId));
}
Then override the pageActivated TabPage method for each to set the range and re-execute the query to your liking:
TabPageA:
public void pageActivated()
{
super();
qbr.value('');
SalesTable_ds.executeQuery();
}
TabPageB
public void pageActivated()
{
super();
element.createRange();
SalesTable_ds.executeQuery();
}
Method to update range:
public void createRange()
{
MultiSelectionHelper multiSelectionHelper = MultiSelectionHelper::createFromCaller(this);
common common;
Set set = new Set(Types::Int64);
// Necessary if the datasource you want is not the header datasource.
multiSelectionHelper.parmDatasource(SalesTable_ds);
common = multiSelectionHelper.getFirst();
while (common)
{
// Use of set not necessary, but a little cleaner.
set.add(common.RecId);
common = MultiSelectionHelper.getNext();
}
qbr.value(strRem(set.toString(), '"{}'));
}
This is somewhat dirty, but you get the idea and could clean it up as needed.
Two Datasources:
Update the range on the second datasource (used by TabPageB) based on the multi-selection of the first datasource. But I'm assuming you only want one datasource for some reason.
I want to add a table in database and want to add a column and save information and retrieve it on another button clicked, if table already exists it would just insert information following is the code that is used by me but giving error.
Button insert_info=(Button)findViewById(R.id.button1);
insert_info.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
SQLiteDatabase db;
try
{
final EditText txt_field1=(EditText)findViewById(R.id.editText1);
String Per_Name=txt_field1.getText().toString();
db=openOrCreateDatabase("sez.db",SQLiteDatabase.CREATE_IF_NECESSARY,null);
String Query_createTable="CREATE TABLE sezInformation(Name VARCHAR(100))";
String Query_insert="insert into sezInformation(Name) values("+Per_Name+")";
db.execSQL(Query_insert);
}
catch(Exception e)
{
Toast.makeText(WelomePerson.this, "ERROR"+e.toString(), Toast.LENGTH_LONG).show();
}
}
});
Whenever I enter the value means khan or any other in layout Edittext field and click on button it shows
No such column :khan while insert into sezInformation (Name) values(khan)
Please also tell me how to retrieve the same saved data in a textview.
Use CREATE TABLE IF NOT EXISTS instead of CREATE TABLE.
Also be sure to use 2 distinct execSQL() commands (one to create the table and one to insert), or it won't work, since you can't execute multiple commands at once.
In SQL, string literals should be in 'single quotes'. Otherwise they are taken as identifiers such as column names.
Even better, use parameters:
db.execSQL("insert into sezInformation(Name) values(?)",
new Object[] { Per_Name });
I have a rather complex form in the way that the number of form fields is flexibel. In short, the model object is a TLabel (TranslationLabel) that contains a Map of values (translations). Language here is an enum so the idea is that the number of fields (text areas) for which a translation is given depends on the values in this enum.
This is my form (simplified):
public class TranslationEditForm extends Form {
private final static List<Language> LANGUAGES = newArrayList(Language.values());
public TranslationEditForm(String id, final TranslationLabelView label) {
super(id, new CompoundPropertyModel<TranslationLabelView>(label));
ListView<Language> textAreas = new ListView<Language>("translationRepeater", LANGUAGES) {
#Override
protected void populateItem(final ListItem<Language> itemLang) {
//loop through the languages and create 1 textarea per language
itemLang.add(new Label("language", itemLang.getModelObject().toString()));
Model<String> textModel = new Model<String>() {
#Override
public String getObject() {
//return the value for current language
return label.getValue(itemLang.getModelObject());
}
#Override
public void setObject(String object) {
//set the value for current language
label.getTranslations().put(itemLang.getModelObject(), object);
}
};
itemLang.add(new TextArea<String>("value", textModel).setRequired(true));
}
};
//add the repeater containing a textarea per language to the form
this.add(textAreas);
}
}
Now, it works fine, 1 text area is created per language and its value is also set nicely; even more when changed the model gets updated as intended.
If you submit the form after emptying a text area (so originally there was a value) then of course there is a validation error (required). Normal (wicket) behaviour would be that the invalid field is still empty but for some reason the original value is reset and I don't understand why.
If I override onError like this:
#Override
protected void onError() {
this.updateFormComponentModels();
}
then it is fine, the value of the field is set to the submitted value (empty) instead of the original value.
Any idea what is causing this? What is wicket failing to do because the way I've set up the form (because with a simple form/model this is working fine as are the wicket examples)?
Posted as answer, so the question can be marked as solved:
ListView does recreate all its items at render time. This means that the validation will be broken. Have a look at API doc of the ListView
Calling setReuseItems() on the ListView solves this.
Regards,
Bert
Does anyone know for an example of GWT's CellTable using RequestFactory and that table is being edited? I would like to list objects in a table (each row is one object and each column is one property), be able to easily add new objects and edit. I know for Google's DynaTableRf example, but that one doesn't edit.
I searched Google and stackoverflow but wasn't able to find one. I got a bit confused with RF's context and than people also mentioned some "driver".
To demonstrate where I currently arrived, I attach code for one column:
// Create name column.
Column<PersonProxy, String> nameColumn = new Column<PersonProxy, String>(
new EditTextCell()) {
#Override
public String getValue(PersonProxy person) {
String ret = person.getName();
return ret != null ? ret : "";
}
};
nameColumn.setFieldUpdater(new FieldUpdater<PersonProxy, String>() {
#Override
public void update(int index, PersonProxy object, String value) {
PersonRequest req = FaceOrgFactory.getInstance().requestFactory().personRequest();
PersonProxy eObject = req.edit(object);
eObject.setName(value);
req.persist().using(eObject).fire();
}
});
and my code for data provider:
AsyncDataProvider<PersonProxy> personDataProvider = new AsyncDataProvider<PersonProxy>() {
#Override
protected void onRangeChanged(HasData<PersonProxy> display) {
final Range range = display.getVisibleRange();
fetch(range.getStart());
}
};
personDataProvider.addDataDisplay(personTable);
...
private void fetch(final int start) {
lastFetch = start;
requestFactory.personRequest().getPeople(start, numRows).fire(new Receiver<List<PersonProxy>>() {
#Override
public void onSuccess(List<PersonProxy> response) {
if (lastFetch != start){
return;
}
int responses = response.size();
if (start >= (personTable.getRowCount()-numRows)){
PersonProxy newP = requestFactory.personRequest().create(PersonProxy.class);
response.add(newP);
responses++;
}
personTable.setRowData(start, response);
personPager.setPageStart(start);
}
});
requestFactory.personRequest().countPersons().fire(new Receiver<Integer>() {
#Override
public void onSuccess(Integer response) {
personTable.setRowCount(response+1, true);
}
});
}
I try to insert last object a new empty object. And when user would fill it, I'd insert new one after it. But the code is not working. I says that user is "attempting" to edit a object previously edited by another RequestContext.
Dilemmas:
* am I creating too many context'es?
* how to properly insert new object into celltable, created on the client side?
* on fieldUpdater when I get an editable object - should I insert it back to table or forget about it?
Thanks for any help.
am I creating too many context'es?
Yes.
You should have one context per HTTP request (per fire()), and a context that is not fire()d is useless (only do that if you/the user change your/his mind and don't want to, e.g., save your/his changes).
You actually have only one context to remove here (see below).
Note that your approach of saving on each field change can lead to "race conditions", because a proxy can be edit()ed by at most one context at a time, and it remains attached to a context until the server responds (and once a context is fired, the proxy is frozen –read-only– also until the server responds).
(this is not true in all cases: when onConstraintViolation is called, the context and its proxies are unfrozen so you can "fix" the constraint violations and fire the context again; this should be safe because validation is done on the server-side before any service method is called).
how to properly insert new object into celltable, created on the client side?
Your code looks OK, except that you should create your proxy in the same context as the one you'll use to persist it.
on fieldUpdater when I get an editable object - should I insert it back to table or forget about it?
I'm not 100% certain but I think you should refresh the table (something like setRowData(index, Collections.singletonList(object)))
BTW, the driver people mention is probably the RequestFactoryEditorDriver from the Editor framework. It won't help you here (quite the contrary actually).
I have a celltable in GWT and want to implement sorting functionality on it , from database(Criteria)
for that i just want to know how to get the value of the column which has been clicked for sorting
here is my code
ctJobs.addColumnSortHandler(new ColumnSortEvent.Handler() {
public void onColumnSort(ColumnSortEvent event) {
event.getColumn();
event.getColumn().getValue("what do we need to write here ???");
from event.getColumn() , i am getting column in the form of object
com.google.gwt.cell.client.ClickableTextCell#188a12e
I want to know the the column's name / value
for that i am trying event.getcolumn().getvalue("??");
but what is the parameter for that, or is there any other way of getting column's name which has been clicked.
Thanks
Are you using a ListDataProvider or an AsyncDataProvider for your cell table?
In case of an AsyncDataProvider the sorting must be done on the server side, so there is no need to add a ColumnSortHandler.
Please see the GWT docs.
To get the name of the column clicked for sorting see this question.
When creating the table columns, set the dataStoreName of the column.
column.setDataStoreName("columnX");
Next, when in the AsyncDataProvider get the sort history of the clicked headers like the following
final AsyncDataProvider<SQLRow> dataProvider = new AsyncDataProvider<SQLRow>(){
#Override
protected void onRangeChanged(HasData<SQLRow> display) {
for (int i=0;i<sortList.size();i++) {
sortList.get(i).getColumn().getDataStoreName();
}
}
}