Cascading dropdowns and control state (no AJAX, Jquery or Updated Panels) - cascadingdropdown

I am having a weird post back problem. I have two dropdowns, project and charge codes. Projects selection populates the charge code drop down. I noticed that when I select a charge code, the value appears in the dropdown for a split second and then changes to the first choice in the dropdown. The Index change of that dropdown triggers and the value is the first option in the dropdown, not the one selected. I am not sure why it's doing this, but it must have something to do with postback. If it is a postback problem, is there a way to store the dropdown selection and restore the selection after re-load? Please don't suggest using AJAX or update panels, as we aren't allowed. Here is my asp code:
<p>
<asp:DropDownList ID="ddlProjects" runat="server"
onselectedindexchanged="ddlProjects_SelectedIndexChanged"
AutoPostBack="True" Visible="false" >
</asp:DropDownList>
</p>
<asp:DropDownList ID="ddlChargeCodes" runat="server" AutoPostBack="true"
onselectedindexchanged="ddlChargeCodes_SelectedIndexChanged" Visible="false">
</asp:DropDownList>
<p>
and the C# code behind:
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (!IsPostBack)
{
LoadProjectsDropDown();
}
//Rest of Pageload Omitted....
// Initial Population of Project Dropdown
protected void LoadProjectsDropDown()
{
try
{ // Populate the Projects Drop Down from Table
ddlProjects.Items.Clear();
ddlProjects.DataSource = Time_Tracker.BLL.ProjectsManager.GetItems();
ddlProjects.DataTextField = "Project_Name";
ddlProjects.DataValueField = "Project_ID";
ddlProjects.DataBind();
ddlProjects.Items.Insert(0, new ListItem("PLEASE SELECT A PROJECT",
"PLEASE SELECT A PROJECT"));
}
catch (Exception ex)
{
Utilities.ErrorLog(ex.Message, ex.GetType().ToString(), ex.StackTrace,
#"Time_Tracker.txt");
}
}
// The Index Change portion of the Project Dropdown, which builds the Charge Code dropdown
protected void ddlProjects_SelectedIndexChanged(object sender, EventArgs e)
{
try
{ // When user selects the Project, Populate Charge Codes for the selected Project
ddlChargeCodes.Visible = true;
if (!string.IsNullOrEmpty(ddlProjects.SelectedValue))
{
ddlChargeCodes.Items.Clear();
ddlChargeCodes.DataSource = Time_Tracker.BLL.TasksManager.GetChargeCodes
(ddlProjects.SelectedValue);
ddlChargeCodes.DataTextField = "Description";
ddlChargeCodes.DataValueField = "Project_ID";
ddlChargeCodes.DataBind();
ddlChargeCodes.Items.Insert(0, new ListItem("PLEASE SELECT A CHARGE
CODE", "PLEASE SELECT A CHARGE CODE"));
Utilities.Project = Convert.ToInt16(ddlProjects.SelectedValue);
}
}
catch (Exception ex)
{
Utilities.ErrorLog(ex.Message, ex.GetType().ToString(), ex.StackTrace, #"Time_Tracker.txt");
}
}
// The Index Change of the Charge Codes Dropdown
protected void ddlChargeCodes_SelectedIndexChanged(object sender, EventArgs e)
{
try
{ // When user selects the Charge Code, it shows a summary and asks for the number of hours
Utilities.Description = Convert.ToString(ddlChargeCodes.SelectedItem);
Utilities.Chargecode = Convert.ToString(ddlChargeCodes.SelectedItem);
lblHoursLabel.Visible = true;
txtHours.Visible = true;
lblConfirmation.Visible = true;
btnStarOver.Visible = true;
btnOK.Visible = true;
lblConfirmation.Text = "Hours on " + Utilities.SelectedDate + " For Charge Code " + Utilities.Description;
}
catch (Exception ex)
{
Utilities.ErrorLog(ex.Message, ex.GetType().ToString(), ex.StackTrace, #"Time_Tracker.txt");
}
}

Did a lot of troubleshooting today. found that upon selecting the chargecode, it would do a pageload without triggering the "change index" event handler. Upon completion of pageload, it would trigger the index change event with the first selection (index 1) selected. Everyone I talked to said it should work the way it is. I finally wrote out the query/databind part of it to populate the dropdown instead of using the stored procedure and it now works. I have included the code change if it will help people in the future.
protected void ddlProjects_SelectedIndexChanged(object sender, EventArgs e)
{
try
{ // When user selects the Project, Populate Charge Codes for the selected Project
ddlChargeCodes.Visible = true;
if (!string.IsNullOrEmpty(ddlProjects.SelectedValue))
{
ddlChargeCodes.Items.Clear();
string strConn = Time_Tracker.DAL.DBUtils.SqlConnectionString;
SqlConnection con = new SqlConnection(strConn);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT Charge_Code, Charge_Code + ' - ' + Description AS Description FROM [Time_Tracker].[dbo].[Tasks] WHERE Inactive = 0 AND Project_ID = " + ddlProjects.SelectedValue;
DataSet objDs = new DataSet();
SqlDataAdapter dAdapter = new SqlDataAdapter();
dAdapter.SelectCommand = cmd;
con.Open();
dAdapter.Fill(objDs);
con.Close();
if (objDs.Tables[0].Rows.Count > 0)
{
ddlChargeCodes.DataSource = objDs.Tables[0];
ddlChargeCodes.DataTextField = "Description";
ddlChargeCodes.DataValueField = "Charge_Code";
ddlChargeCodes.DataBind();
ddlChargeCodes.Items.Insert(0, "PLEASE SELECT A CHARGE CODE");
}
Utilities.Project = Convert.ToInt16(ddlProjects.SelectedValue);
}
}
catch (Exception ex)
{
Utilities.ErrorLog(ex.Message, ex.GetType().ToString(), ex.StackTrace, #"Time_Tracker.txt");
}
}

Related

How to dynamically and correctly change a query in Command Table for Crystal Reports file?

I have many rpt files. I want to change the query for each report using C#. There are several ways to do this changes.
First way:
private void button_Test_Click(object sender, EventArgs e)
{
ReportDocument rptDoc = new ReportDocument();
rptDoc.Load("D:\\Temp_01\\Report1_Test.rpt");
rptDoc.SetDatabaseLogon("User", "Password", "ServName", "DBName");
CrystalDecisions.Shared.ConnectionInfo ConnInf;
ConnInf = rptDoc.Database.Tables[0].LogOnInfo.ConnectionInfo;
String strSQLQuery = "SELECT TOP(123) * FROM sys.all_objects";
String strTableName = rptDoc.Database.Tables[0].Name;
try
{
rptDoc.SetSQLCommandTable(ConnInf, strTableName, strSQLQuery);
rptDoc.VerifyDatabase();
}
catch (Exception ex) { rptDoc.Close(); }
rptDoc.SaveAs("D:\\Temp_02\\Report2_Test.rpt");
rptDoc.Close();
}
It is not the best way. The method SetSQLCommand does not work when the query has any parameters. Even if you set value for each parameter, SetSQLCommand does not work. The example with a parameter which does not work:
private void button_Test_Click(object sender, EventArgs e)
{
ReportDocument rptDoc = new ReportDocument();
rptDoc.Load("D:\\Temp_01\\Report1_Test.rpt");
rptDoc.SetDatabaseLogon("User", "Password", "ServName", "DBName");
CrystalDecisions.Shared.ConnectionInfo ConnInf;
ConnInf = rptDoc.Database.Tables[0].LogOnInfo.ConnectionInfo;
String strSQLQuery = "SELECT TOP(1) * FROM sys.all_objects WHERE name = {?strName}";
String strTableName = rptDoc.Database.Tables[0].Name;
try
{
rptDoc.SetParameterValue("strName", "Text");
rptDoc.SetSQLCommandTable(ConnInf, strTableName, strSQLQuery);
rptDoc.VerifyDatabase();
}
catch (Exception ex) { rptDoc.Close(); }
rptDoc.SaveAs("D:\\Temp_02\\Report2_Test.rpt");
rptDoc.Close();
}
It returns an error. This method does not work with parameters!
Second way:
private void button_Test_Click(object sender, EventArgs e)
{
ReportDocument rptDoc = new ReportDocument();
rptDoc.Load("D:\\Temp_01\\Report1_Test.rpt");
rptDoc.SetDatabaseLogon("User", "Password", "ServName", "DBName");
ISCDReportClientDocument rcd = null;
rcd = rptDoc.ReportClientDocument as ISCDReportClientDocument;
CommandTable rTblOld;
CommandTable rTblNew;
rTblOld = rcd.Database.Tables[0] as CommandTable;
rTblNew = rcd.Database.Tables[0].Clone(true) as CommandTable;
rTblNew.CommandText = "SELECT TOP(1) * FROM sys.all_objects";
try
{
rcd.DatabaseController.SetTableLocationEx(rTblOld, rTblNew);
rcd.VerifyDatabase();
}
catch (Exception ex) { rcd.Close(); }
rcd.SaveAs(rcd.DisplayName, "D:\\Temp_02\\", 1);
rcd.Close();
}
This is also not the best way. The method SetLocalTableEx does a struct of the report is bad. After run SetLocalTableEx, attribute ConnectionInf.UserId have value NULL also the Name of connection
After SetTableLocationEx:
rcd.DatabaseController.SetTableLocationEx(rTblOld, rTblNew);
String UserID;
UserID = rptDoc.Database.Tables[0].LogOnInfo.ConnectionInfo.UserID;
if (UserID == null) MessageBox.Show("UserID has NULL");
UserId has value NULL
Also, before run SetTableLocationEx, Connection Name is MSODBCSQL11
enter image description here
After run SetTableLocationEx, Connection Name is Command
enter image description here
So,
how do dynamic and correctly to change the query in CommandTable for Crystal Reports file?
Thanks,
Artem
You are using command in Crystal Report which is the best way when doing and displaying a data from database to crystal report but unfortunately you do it in Code Behind.
My Question is:
Why don't you do it in Command of Crystal Report itself?
see this link for more info.

how to get drop down list by type respective alphabet in ComboBoxViewerCellEditor

In ComboBoxViewerCellEditor I want to write something and as a result I will get the matching dropdown value.
Can you suggest how to get this? Please find the code below:
public TCOperationColumnEditable(TableViewer viewer) {
super(viewer);
try
{
this.viewer = viewer;
//this.editor = new TextCellEditor(this.viewer.getTable());
OperationGSON[] allOperations = OperationAPIHandler.getInstance().getAllOperations();
ArrayList<String> opnName = new ArrayList<String>();
for(OperationGSON opn : allOperations)
{
opnName.add(opn.opnName);
}
this.editor = new ComboBoxViewerCellEditor(this.viewer.getTable(), SWT.FULL_SELECTION );
this.editor.setLabelProvider(new LabelProvider());
this.editor.setContentProvider(new ArrayContentProvide());
this.editor.setInput(opnName);
String[] stockArr = new String[opnName.size()];
stockArr = opnName.toArray(stockArr);
new AutoCompleteField(this.viewer.getControl(), new CComboContentAdapter(), stockArr);
}
catch(Exception e)
{
System.out.println("[" + getClass().getName() + " : TCOperationColumnEditable()] - Exception : " + e.getMessage());
e.printStackTrace();
}
}
enter image description here
Subclass TextCellEditor.
For a content proposal, use field assist API of JFace
(org.eclipse.jface.fieldassist). Content assist is enabled
when the cell editor is activated for the first time:
if (contentProposalAdapter == null) {
....
// enable content assist on the cell editor's text widget
contentProposalAdapter = new ContentProposalAdapter(text, new TextContentAdapter(), proposalProvider, activationKeyStroke, null);
} else {
contentProposalAdapter.setEnabled(true);
}
super.activate();
....
Make sure to also override method
TextCellEditor#dependsOnExternalFocusListener() to return false always.
Otherwise, you'll face some serious problems concerning focus.

Launching Dialog Box with Data from TableView Row

I'm attempting to launch an Edit Customer Window with text fields filled with reference from the rows of a table. The Table and Dialog both have different controller classes.
Here's the code snippet from the table in question that gives us the required customerID when a user double clicks on a row.
Table Controller: CustomersController:
#Override
public void initialize(URL location, ResourceBundle resources) {
populateCustomerTable();
tableListeners(null);
}
void tableListeners(CustomerData customerData){
tblcustomer.setRowFactory(tr -> {
TableRow<CustomerData> row = new TableRow<>();
row.setOnMouseClicked(event -> {
if (event.getClickCount() == 2 && (!row.isEmpty())) {
int selectedCustomerID = row.getItem().getCustomerID();
System.out.println("A certain row: " + selectedCustomerID + " has been clicked!");
Stage stage = new Stage();
FXMLLoader loader = new FXMLLoader();
try {
Parent root = loader.load(getClass().getResource("../view/popups/edit_customer.fxml"));
stage.setScene(new Scene(root));
stage.setTitle("Editing Existing Customer's Details");
stage.initModality(Modality.APPLICATION_MODAL);
stage.initOwner(btnEditCustomer.getScene().getWindow());
stage.showAndWait();
} catch (IOException e) {
e.printStackTrace();
}
}
});
return row;
});
}
I want selectedCustomerID from the above piece of code to be parsed into the EditCustomerController class hence when the dialog launches, it's text fields should be prepoulated with values suppled from the select query that queries the database with the where condition being tht selectedCustomerID from the CustomersController class.
Code snippet from EditCustomerController class:
#Override
public void initialize(URL location, ResourceBundle resources) {
//populateEditCustomerFields(1);
}
void populateEditCustomerFields(int customerID){
this.customer_ID=customerID;
System.out.println(customer_ID);
try {
con = DatabaseConnection.getConnected();
stmt = con.createStatement();
rs = con.createStatement().executeQuery("SELECT * FROM `h_customers` WHERE `customerID`=" + customer_ID);
while (rs.next()) {
title.setText(rs.getString("title"));
firstName.setText(rs.getString("firstName"));
lastName.setText(rs.getString("lastName"));
nationalID.setText(String.valueOf(rs.getInt("nationalID")));
//dob.setText(rs.getString("DOB"));
mobilePhone.setText(rs.getString("mobilePhone"));
workPhone.setText(rs.getString("workPhone"));
email.setText(rs.getString("email"));
}
} catch (SQLException ex) {
Logger.getLogger(NewRoomController.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
The Idea here is to parse selectedCustomerID from CustomersController into the initialize method of EditCustomerController so the Dialog can launch with the customer details that require editing. I've searched for solutions all over the web and here on StackOverflow, some come close to answering me, some are too complex for my newbie mind, but none has helped. Any solution would be highly appreciated. I will provide any further clarification required.
You can get the controller class and invoke its necessary methods. See this answer for getting controller, then do
editCustomerController.populateEditCustomerFields(selectedCustomerID);
on table row double click.
Further to improve performance, you can load the edit_customer.fxml only once and when the user double clicks, refresh its rendered data with editCustomerController.populateEditCustomerFields(selectedCustomerID).

Populate a combobox from an array list populated from an SQL statment

I am trying to populate a ComboBox with a list that is populated by a SQL statement.
I tried this:
public void buildData(){
ObservableList<ComboBox> data = FXCollections.observableArrayList();
Connection conn = db.makeConnection();
try{
String SQL = "Select Feature from FeaturesTable Order By Feature";
ResultSet rs = conn.createStatement().executeQuery(SQL);
while(rs.next()){
ComboBox cb = new ComboBox();
cb.featureCombo.set(rs.getString("Feature"));
featureCombo.add(cb);
}
featureCombo.setItems(data);
}
catch(Exception e){
e.printStackTrace();
System.out.println("Error on Building Data");
}
}
I'm getting an error under cb.featureCombo.set of "featureCombo cannot be resolved or is not a field" but featureCombo exists as:
#FXML
private ObservableList<ComboBox> featureCombo;
and then another error under featureCombo.setItems(data); probably because of the same problem.
I'm not set on this method if someone has a better way to do this.
If you desire a ComboBox named featureCombo, you are going to have to declare it as a ComboBox and not as private ObservableList<ComboBox> featureCombo; which is making an ObservableList
Something like
#FXML
ComboBox<String> featureCombo;
Then in your method, you need to make a list of String to populate the ComboBox (you currently have a list of ComboBox)
public void buildData(){
ObservableList<String> data = FXCollections.observableArrayList(); //List of String
Connection conn = db.makeConnection();
try{
String SQL = "Select Feature from FeaturesTable Order By Feature";
ResultSet rs = conn.createStatement().executeQuery(SQL);
while(rs.next()){
data.add(rs.getString("Feature")); //add the String to the list
}
featureCombo.setItems(data); //Set the list of String as the data for your combo box
}
catch(Exception e){
e.printStackTrace();
System.out.println("Error on Building Data");
}
}

GWT-RPC method returns empty list on success

I am creating a webpage having CellTable.I need to feed this table with data from hbase table.
I have written a method to retrieve data from hbase table and tested it.
But when I call that method as GWT asynchronous RPC method then rpc call succeeds but it returns nothing.In my case it returns empty list.The alert box show list's size as 0.
Following is the related code.
Please help.
greetingService.getDeviceIDData(new AsyncCallback<List<DeviceDriverBean>>(){
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
System.out.println("RPC Call failed");
Window.alert("Data : RPC call failed");
}
public void onSuccess(List<DeviceDriverBean> result) {
//on success do something
Window.alert("Data : RPC call successful");
//deviceDataList.addAll(result);
Window.alert("Result size: " +result.size());
// Add a text column to show the driver name.
TextColumn<DeviceDriverBean> nameColumn = new TextColumn<DeviceDriverBean>() {
#Override
public String getValue(DeviceDriverBean object) {
Window.alert(object.getName());
return object.getName();
}
};
table.addColumn(nameColumn, "Name");
// Add a text column to show the device id
TextColumn<DeviceDriverBean> deviceidColumn = new TextColumn<DeviceDriverBean>() {
#Override
public String getValue(DeviceDriverBean object) {
return object.getDeviceId();
}
};
table.addColumn(deviceidColumn, "Device ID");
table.setRowCount(result.size(), true);
// more code here to add columns in celltable
// Push the data into the widget.
table.setRowData(0, result);
SimplePager pager = new SimplePager();
pager.setDisplay(table);
VerticalPanel vp = new VerticalPanel();
vp.add(table);
vp.add(pager);
// Add it to the root panel.
RootPanel.get("datagridContainer").add(vp);
}
});
Code to retrieve data from hbase (server side code)
public List<DeviceDriverBean> getDeviceIDData()
throws IllegalArgumentException {
List<DeviceDriverBean> deviceidList = new ArrayList<DeviceDriverBean>();
// Escape data from the client to avoid cross-site script
// vulnerabilities.
/*
* input = escapeHtml(input); userAgent = escapeHtml(userAgent);
*
* return "Hello, " + input + "!<br><br>I am running " + serverInfo +
* ".<br><br>It looks like you are using:<br>" + userAgent;
*/
try {
Configuration config = HbaseConnectionSingleton.getInstance()
.HbaseConnect();
HTable testTable = new HTable(config, "driver_details");
byte[] family = Bytes.toBytes("details");
Scan scan = new Scan();
int cnt = 0;
ResultScanner rs = testTable.getScanner(scan);
for (Result r = rs.next(); r != null; r = rs.next()) {
DeviceDriverBean deviceDriverBean = new DeviceDriverBean();
byte[] rowid = r.getRow(); // Category, Date, Sentiment
NavigableMap<byte[], byte[]> map = r.getFamilyMap(family);
Iterator<Entry<byte[], byte[]>> itrt = map.entrySet()
.iterator();
deviceDriverBean.setDeviceId(Bytes.toString(rowid));
while (itrt.hasNext()) {
Entry<byte[], byte[]> entry = itrt.next();
//cnt++;
//System.out.println("Count : " + cnt);
byte[] qual = entry.getKey();
byte[] val = entry.getValue();
if (Bytes.toString(qual).equalsIgnoreCase("account_number")) {
deviceDriverBean.setAccountNo(Bytes.toString(val));
} else if (Bytes.toString(qual).equalsIgnoreCase("make")) {
deviceDriverBean.setMake(Bytes.toString(val));
} else if (Bytes.toString(qual).equalsIgnoreCase("model")) {
deviceDriverBean.setModel(Bytes.toString(val));
} else if (Bytes.toString(qual).equalsIgnoreCase("driver_name")) {
deviceDriverBean.setName(Bytes.toString(val));
} else if (Bytes.toString(qual).equalsIgnoreCase("premium")) {
deviceDriverBean.setPremium(Bytes.toString(val));
} else if (Bytes.toString(qual).equalsIgnoreCase("year")) {
deviceDriverBean.setYear(Bytes.toString(val));
} else {
System.out.println("No match found");
}
/*
* System.out.println(Bytes.toString(rowid) + " " +
* Bytes.toString(qual) + " " + Bytes.toString(val));
*/
}
deviceidList.add(deviceDriverBean);
}
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (Exception e) {
// System.out.println("Message: "+e.getMessage());
e.printStackTrace();
}
return deviceidList;
}
Could this be lazy fetching on the server side by hbase. This means if you return the list hbase won't get a trigger to actually read the list and you will simple get an empty list. I don't know a correct solution, in the past I've seen a similar problem on GAE. This could by solved by simply asking the size of the list just before returning it to the client.
I don't have the exact answer, but I have an advise. In similar situation I put my own trace to check every step in my program.
On the server side before return put : System.out.println("size of table="+deviceidList.size());
You can put this trace in the loop for deviceidList;