I was reading this blog: http://andrejusb.blogspot.ca/2015/06/select-one-choice-with-select-items-tag.html
He creates a custom selectItems which has the list of values in a bean. The other fields are bound to a view which corresponds to a table in the database. When the user clicks save all these fields will be saved, but I do not understand how this new custom selectItems will be saved. It isn't binding to any table in the database. How would this work? How can we save this custom list of values to the database?
He was just demonstrating how to create bean-based selectItems. When user selects, you need to capture the index of selection in your backing code:
<af:selectOneChoice label="Select Search" id="socSrch" autoSubmit="true" valueChangeListener="#pageFlowScope.wci.handleSelectSearch}" contentStyle="width:250px">
<f:selectItems id="si1" value="#{pageFlowScope.wci.searchNames}"/>
</af:selectOneChoice>
public void handleSelectSearch(ValueChangeEvent valueChangeEvent) {
if (valueChangeEvent.getNewValue() == null) {
return;
}
int selSearch = (Integer) valueChangeEvent.getNewValue();
//...now write this to DB via code handle to view and field if desired
}
At this point you can decide if you want to write out the index (the value) of the selected item to database via your backing bean code handle to the view, or you can get the label of the select item from your backing ArrayList of select items with some further coding, and populate that into the view, then commit. The view would have a field to receive what you wanted to put into it.
Related
How do get this simple task done in ADF -
Based on some parameter I want a row to be retrieved from a view object programmatically. I have no idea how this could be done. IF I am not using ADF my business method would have a query like below and then return whatever details i want in the form on object.
*select * from abcTable where abccolumn = param1;*
param1 is an input from a jsf page. I capture that input and based on that input i need to query another database table (which will be in the form of View object in the ADF) to retrieve additional details and fill up some other components in the jsf page. How do I get this task done. I am trying to get instance of the view object but i do not seem to find any method using which I could retrieve only limited rows i want based on a where clause. The executeQuery method does not return anything (weird case).
You can filter viewObject programmatically and can get rows-
you can filter viewObject using 2 methods
1. where clause
2. filterdRows
see- Get Filtered Rows From View Object in Oracle ADF
The VO has a setWhereClause method that you can use to add/modify a where clause to the query.
You can also pre-define a VO with a bind parameter query.
Some more info on the UI side :
ADF Query with Parameters and List of Values and
ADF Query with Parameters and List of Values - Part II
Bind that parameter to a variable in your bean. Let's say you want
to search the value from and input text:
On page:
<af:inputText id="it8" binding="#{pageFlowScope.<YOURBEAN>.inputSearchBox}"/>
In your bean:
private RichInputText inputSearchBox;
public void setInputSearchBox(RichInputText inputSearchBox) {
this.inputSearchBox= inputSearchBox;
}
public RichInputText getInputSearchBox() {
return inputSearchBox;
}
Make a method in the bean that would do the search:
On page:
<af:commandButton text="search" id="cb6" actionListener="#{pageFlowScope.<YOURBEAN>.search}"/>
In bean:
public void search(ActionEvent actionEvent) {
}
In this method you will need to get the ViewObject from AppModuleImpl:
BindingContext bindingContext = BindingContext.getCurrent();
DCDataControl dc =bindingContext.findDataControl("YOURAPPMODULEDATACONTROL");
AppModuleImpl appM = (AppModuleImpl )dc.getDataProvider();
ViewObjectImpl vo = appM.getYourVO();
Create and apply a view criteria on that viewObject with the text that you entered in the input:
String searchValue = null;
//get the value from the search field
if (inputSearchBox.getValue() != null) {
searchValue = inputSearchBox.getValue().toString();
}
ViewCriteria vc = vo.createViewCriteria();
ViewCriteriaRow vcRow = vc.createViewCriteriaRow();
vcRow.setAttribute("Field you want to search by", searchValue);
vc.addRow(vcRow);
vo.applyViewCriteria(vc);
vo.executeQuery();
Now the ViewObject is filtered by your search value.
If you want to go through the result and save some VO values from that line you found you would need to make a row iterator, iterate through it and store the values you need in some variables:
RowSetIterator rsi = vo.getRowSetIterator();
String valueToGet = null;
while (rsi.hasNext()){
Row r = rsi.next();
valueToGet = (String)r.getAttribute("<WHAT ATTRIBUTE YOU WANT TO GET>");
}
Am using a DataSet and a TableAdapter to populate a Datagridview. The Datagridview allows inserting new records at the bottom. Now when I enter values for the new record in the Datagridview, the record is not automatically saved back to the database. Which event do U need to handle or what code do I need to write to get the new record saved back to the databse.
am using C#.
you can put somewhere a Save button and when user click that button you call a method like this:
private void UpdateDataSet(DataSet dataSet)
{
// Check for changes with the HasChanges method first.
if(!dataSet.HasChanges(DataRowState.Modified)) return;
// Create temporary DataSet variable and
// GetChanges for modified rows only.
DataSet tempDataSet =
dataSet.GetChanges(DataRowState.Modified);
// Check the DataSet for errors.
if(tempDataSet.HasErrors)
{
// Insert code to resolve errors.
}
// After fixing errors, update the data source with
// the DataAdapter used to create the DataSet.
adapter.Update(tempDataSet);
}
Are you calling the Update() method on the TableAdapter? The following code comes from MSDN's discussion on the TableAdapter:
try
{
this.Validate();
this.customersBindingSource.EndEdit();
this.customersTableAdapter.Update(this.northwindDataSet.Customers);
MessageBox.Show("Update successful");
}
catch (System.Exception ex)
{
MessageBox.Show("Update failed");
}
There are various places where you can put this sort of logic - as Davide Piras suggests you could have a Save button on your form or if you want data to be saves as each row is entered you can have your save logic with the RowValidated event handler.
I have a problem which should be easy but I have trouble with finding the solution. I have a database that I want to present in a datatable. However I need additional columns that get more information about the current row. For example - the database has a set of people with id numbers. What I need is to display the Name, Last Name, ID (all columns of database), but then I want to display the address which is in a different REST webservice and to get it I need to send the ID (from database). I hope I have described it clearly but just in case I will point out:
-my database has 3 columns: name, las name, id number
-I need to add a 4th column to my datatable with address
-to get the address I need to send the id number to a rest webservice
The only solution I was able to find so far i to add all database elements to a list or some container and then use it inside a bean. But that is unacceptable since the database is very big. There must be a simpler way but it seems that I can't form an adequate question for google to get the proper results :> Can any one give some advice?
So what you basically want is to do a join between the result of a query to a database and the webservice.
Of course you don't need to load the entire DB in some bean to do this "join", just load the data you would like to display on screen in a backing bean, load the addresses for each row, and bind the result to the datatable.
Something like this:
#ManagedBean
#ViewScoped
public class MyBean {
#EJB
private someDataService;
#EJB
private someWebService;
List<Person> persons;
Map<Long, String> addresses;
#PostConstruct
public void retrieveData() {
persons = someDataService.getByID(someID);
for (Person person : persons) {
addresses.put(person.getID(), someWebService.getByID(person.getID));
}
}
// getters here
}
And the Facelet:
<h:dataTable value="#{myBean.persons}" var="person">
<h:column>
#{person.name}
</h:column>
<h:column>
#{person.lastName}
</h:column>
<h:column>
#{myBean.addresses[person.ID]}
</h:column>
</h:dataTable>
There are some choices to be made. You could also do the joining inside a single service and have it return some type that includes the address. You could also make a wrapper or a decorator.
It would also be more efficient if the web service could handle a list of IDs instead of requiring a separate call for each address fetched. You might also wanna do some local caching, etc, but those details are up to you ;)
I have a DataGridView that is bound - via a binding source - to a list of entities:
VehicleRepository:
private IObjectSet<Vehicles> _objectSet;
public VehicleRepository(VPEntities context)
{
_context = context;
_objectSet = context.Vehicles;
}
List<Vehicle> IVehicleRepository.GetVehicles(Model model)
{
return _objectSet
.Where(e => e.ModelId == model.ModelId)
.ToList();
}
In my presenter
private List<Vehicle> _vehicles;
...
_vehicles = _vehicleRepository.GetVehicles(_model);
_screen.BindTo(_vehicles);
in my view
public void BindTo(List<Vehicle> vehicles)
{
_vehicles = vehicles;
if (_vehicles != null)
{
VehicleBindingSource.DataSource = _vehicles;
}
}
This works fine - my grid displays the data as it should. However, in the grid I am wanting to replace the ModelId column with a description field from the Model table. I've tried changing the binding for the column from ModelId to Model.ModelDescription but the column just appears blank.
I'm pretty sure that the data is being loaded, as I can see it when I debug, and when the same list is passed to a details screen I can successfully bind the related data to text fields and see the data.
Am I doing something obviously wrong?
It's a bit manual, but it 'works on my machine'.
Add a column to your DataGridView for the description field and then after you set your DataSource iterate through like so.
Dim row As Integer = 0
foreach (entity In (List<Entity>)MyBindingSource.DataSource)
{
string description = entity.Description;
MyDataGridView.Rows[row].Cells["MyDescriptionCell"].Value = description;
row ++;
}
You get a readonly view of your lookup. I make the new column readonly, but you could write something to handle the user changing the field if you wanted updates to run back to the server. Might be messy though.
The answer involves adding unbound read only columns and setting their value in the DataGridView's DataBindingComplete event
as described here
You can just add a column to your DataGridView, and in the DataPropertyName you must set the [entity].[Field name you need] in your case you could do: VehiclesType.Description
then you must add another binding source for the VehiclesTypes to the form, fill it using your context, and your good to go ;)
I have a problem with Linq and ObservableCollections in my WPF application.
Context of the problem:
I've created a very simple SQL database with two tables: User and BankAccounts.
The User Table has an one-to-many relationship with the BankAccounts Table. Next I've created Linq-to-SQL dataclasses, which worked fine ==> the assosiation between the two tables was detected as well.
Next I've created a function to retreive all Users which works fine:
DataClassesDataContext dc = new DataClassesDataContext
var query = from u in dc.Users
select u;
Now suppose I want to add a new BankAccount to each user (not very likely but still).
I could add the following code
for each(User u in query)
{
u.BankAccounts.Add(New BankAccount());
}
The above works all fine. The BankAccounts property is automaticly part of the User class, due to the assosiation in the database and Linq DataClasses.
However, in my application I first add the query results to an ObservableCollection. Hereby I could use all sorts off databinding and changenotification. This is accomplished by the following code;
ObservableCollection<User> oUsers = new ObservableCollection<User>(query);
Problem: Within the ObservableCollection I can't do anyting with the users BankAccounts property because it is now of type EntitySet<>. So I can't do the following statement anymore.
for each(User u in oUsers)
{
u.BankAccounts.Add(New BankAccount());
}
Somehow, when queryresults are added to an observablecollection It is not possible to acces the user.BankAccounts properties anymore. However, it is possible to bind the BankAccounts Property to any control, like a listbox, and it contains the correct data.
Does someone now how I can create an observableCollction (or similar collection) from wich I can access these "assosiated" properties? I'm realy looking forward for to a solution.
Thanks in advance!
Best regards,
Bas Zweeris
E: Bas.Zweeris#Capgemini.com
Keep track of the original query which will implement IQueryable, you can run any further queries you need against that.
The ObservableCollection should just be for WPF to have something to bind to - its very useful if you want to add a new collection item but not have it pushed to the database before the user has had chance to edit it.
eg.
// Create a new blank client type
var ct = new ClientType()
{
IsArchived = false,
Description = "<new client type>",
Code = "CT000",
CanLoginOnline = true
};
// Tell the data source to keep track of this object
db.ClientTypes.InsertOnSubmit(ct);
// Also add the object to the observable collection so that it can immediately be shown in the UI and editted without hitting the db
clienttypes.Add(ct);