ASP.NET Datasource bound to Combo. Include all entries - asp.net

I have 2 combo boxes bound to a data-source, in order to make a search web page in ASP.NET. Both combo boxes are bound to database tables. The data-source determines its SQL SELECT statement based on the values of the combo boxes, so results are filtered. But, I want to include the case where the user doesn't want to set a value in some of the combos and wants to retrieve all database records regarding this combobox. I have included static entries in both combos (e.g. ), but how can I program the datasource, so as when is selected by user, no WHERE statement will be applied?
I found this answer a bit useful, but there are security issues and is not so straightforward.
Changing SqlDataSource.SelectCommand at runtime breaks pagination
Thanks in advance

Assuming that the value in the comboboxes when the user selects nothing is -1 you can modify your sql like this:
SELECT *
FROM TABLE
WHERE ((COLUMN_1 = #PARAM_1) OR #PARAM_1 = -1)
AND ((COLUMN_2 = #PARAM_2) OR #PARAM_2 = -1)
if you pass -1 as value for both parameters the query will return all the records in the table

Related

In App Maker, how do you make dynamic table cell text?

In App Maker, I am displaying a table and want to replace table cell data with different text using a data lookup from another table. Assume two tables, Departments and Employees.
Departments is two fields, DeptID and DeptDescription.
Employees is multiple fields including DeptID.
In the table listing for Employees, I would like to replace the DeptID with the DeptDescription. (The page datasource is Employees. I do not want to set up a relationship between the data models.)
I am guessing I want to do some scripting in the onDataLoad event for the table cell label for DeptID. I have this much so far:
app.datasources.Departments.query.filters.DeptID._equals = widget.datasource.item.DeptID;
app.datasources.Departments.newQuery().run();
widget.text = app.datasources.Departments.item.DeptDescription;
I know this is not correct, but am I close?
This answer is untested, but I wanted to present a possible solution that would not require a lot of DB calls, especially ones that make repeated calls to a server script which might consume a lot of processing time when you do line item calls.
Set up a separate datasource under the Department model. Change the default 'Query Builder' to 'Query Script' and add a parameter of type 'list(number)' or 'list(string)', this should match your Primary Key field type. Uncheck the 'auto load' option.
In your 'Query Script' portion enter the following code:
query.filters.Id._in = query.parameters.YourParameter;
return query.run();
Go to your Employees datasource that is supposed to generate your table and find your 'On Load' client script section. In this section enter the following code:
var departmentsDs = app.datasources.YourDepartmentsDs;
departmentsDs.properties.YourParameter = datasource.items.map(function(deptIds) {return deptIds.DeptID;});
departmentDs.load();
Now go the page that contains your table. If you have not already create a label widget do so now. In this label widget for the text binding enter the following:
#datasources.YourDepartmentsDs.loaded && (#datasources.YourDepartmentsDs.items).map(function(Id){return Id.Id}).indexOf(#widget.datasource.item.DeptID) !== -1 ? #datasources.YourDepartmentDs.items[(#datasources.YourDepartmentsDs.items).map(function(Id){return Id.Id}).indexOf(#widget.datasource.item.DeptID)].DeptDescription : 'Unable to retrieve Dept Description'
As stated this is untested and I wrote the code from memory without App Maker in front of me so it may require some additional tweaking. Going with the first option presented by J.G. would also be a very viable solution though. And I apologize but the code formatter does not seem to be working for me.
1 way) Create an aggregate table that joins your tables if you need to bypass using the relations feature. This way you can use sql to join the two tables in the datasource definition
2) if you don't want to make a new table. Change the text from a value binding to "more options"
=getDescription(#datasource.item.DeptId)
and then the code you wrote in a client side script
function getDescription(id){
google.script.run
.withSuccessHandler(function successHandler(result){ return result;})
.withFailureHandler( function failureHandler(e){ console.log(" Failed" +e);})
.queryValue(id);
}
server side script:
function queryValue(id){
var query = app.models.Departments.newQuery();
query.filters.DeptID._equals = id;
var results = query.run();
return results[0]["DeptDescription"];
}
that last line might be results[0].DeptDescription

Move to record and not filter to record

Currently my dropdownlist returns a value that I use in a SQL WHERE clause to return a result set. I would like to be able to just move to the selected record as oppose to filtering the whole set. When I filter I am no longer able to page through the records (I can only choose another search selection from the dropdownlist because there are no other records to page through - I would like to use both). What is the best way to achieve this?

How to show all items in Listbox that is linked to dropdown

In an Access Userform I have a listbox that is linked to a dropdown field. In the dropdown field the user can choose a country, and the listbox then updates and shows only the records that are relevant to that country.
I have described how I get the listbox to filter based on the selection in the dropdown in this question here.
While I managed to solve one problem there I created another.
Now when I open the form, the listbox is empty instead of showing all records.
My question: How can I show all records in the listbox to begin with and THEN have the user filter the list based on the dropdown?
The SQL Code in the LIstbox is now the following:
SELECT tblFUNDS.MorningsStar_Fund_Name, tblFUNDS.ISIN, tblFUNDS.RDR, tblISIN_Country_Table.Country
FROM tblFUNDS INNER JOIN tblISIN_Country_Table ON tblFUNDS.ISIN = tblISIN_Country_Table.ISIN
GROUP BY tblFUNDS.MorningsStar_Fund_Name, tblFUNDS.ISIN, tblFUNDS.RDR, tblISIN_Country_Table.Country, tblFUNDS.Fund_Selection
HAVING (((tblISIN_Country_Table.Country)=[Forms]![frmMain]![ddnCountry].[Text]) AND ((tblFUNDS.Fund_Selection)=0));
So I ended up solving this one as well... with a bit of help from an online article which I can now no longer find unfortunately (otherwise I would reference it here):
SELECT tblFUNDS.MorningsStar_Fund_Name, tblFUNDS.ISIN, tblFUNDS.RDR, tblISIN_Country_Table.Country
FROM tblFUNDS INNER JOIN tblISIN_Country_Table ON tblFUNDS.ISIN = tblISIN_Country_Table.ISIN
GROUP BY tblFUNDS.MorningsStar_Fund_Name, tblFUNDS.ISIN, tblFUNDS.RDR, tblISIN_Country_Table.Country, tblFUNDS.Fund_Selection
HAVING (((tblISIN_Country_Table.Country) Like Nz([Forms]![frmMain]![ddnCountry].[Text],'*')) AND ((tblFUNDS.Fund_Selection)=0));
The important part is this...
Like Nz([Forms]![frmMain]![ddnCountry].[Text],'*')) AND ((tblFUNDS.Fund_Selection)=0));
Essentially the Nz function lets you return a value when a variant is null. I had it return * which ofcourse is the SQL equivalent of Return All.

ASP.NET DropDownList - How do I handle missing values?

I have a list of values in a SQL Table which are used to popluate a DropDownList, having a unique Integer as the value of each item and a String as the visible text (via SqlDataSource). There is also a third field in the database which is a flag to indicate whether the list item is active or not (inactive items are not shown in the DropDownList)
Selections made in the dropdown are stored in the database as their integer value (as part of a dataset making up the overall record), not the text value.
Over time, the items in the DropDownList may be removed by marking the items as inactive. However, there is still a need to open old records which may have had a now-inactive item as part of it's data...
My question is, what's the best way to ensure that the missing value included in the dropdown for the old record?
The two methods that spring to mind are to either:
Populate DropDownList with only the currently active items and, when loading a record, catch when the app tries to select a value that doesn't exist, go back to the db to see what it should be (the text value) and manually add it into the dropdown.
or...
Populate DropDownList with all list items (both active and inactive), load the record and then programatically remove all the inactive items (execpt for any that are now selected).
Neither of these seem particularly efficient, so I was wondering whether there is a best practice for this kind of thing?
there are so many optimum ways to do that sort of things, i am defining here a couple of them, use any of following if your Drop down list items count is less than 200 , lets say drop down list is of Products
1)
i) Load all Products records in drop down list and hide the inactive ones by setting visible=false
i) When you load a user record than look for its drop down list value if its visible than select it and enjoy, if its not visible than make it visible by setting its property visible=true and select it and also set its index or id in a flag to change its visibility(visible=false) again after your/users required operation performed.
2)
i) load only active Product records in drop down list ii) while loading a user record also load its product details(name, id, inactive_status) using Joins in sql.
iii) check in that user record if item is inactive then add its record in drop down list as you have all its details now with user details record else just select it.
IMPORTANT NOTE: if you drop down list has items in millions than use ADVANCE SEARCH techniques
The first thing I would do is question your business logic - should you be able to make an item inactive if it is being used as a foreign key in an active row elsewhere? If you make it inactive should it not remove all foreign keys as well?
To answer your question though I would go with a variation on the second idea but filtering in the page like that is probably slower than doing directly with SQL so I guess you have something like this at the moment to populate the dropdown
SELECT * FROM Table WHERE Active = 1
You should already have your record and the foreign key value so I would change it to this
SELECT * FROM Table WHERE Active = 1 OR PrimaryKey = [YourForeignKey]
Then you will always have the selected item but should also be fairly efficient.

Store Timestamp in GridView

I have a table with three columns that I need to display on a ASP.NET page. (SQL Server 2005, ASP.NET 2.0)
id int
value varchar(50)
tstamp timestamp
I use the timestamp field to handle concurrency validation so it's for internal use only and will never be displayed to the end user. But I need to store it somewhere in order to do proper updates.
Here's my update sproc.
UPDATE ValueTable SET value = #value
WHERE (id = #id) AND (tstamp = #tstamp)
SELECT #tstamp=tstamp FROM ValueTable
WHERE id=#id
I use a SqlDataSource to connect to my database and the schema has all three columns. My grid view will only display two fields since the timestamp field is hidden (Visible=False)
When I profile my asp page it looks like it doesn't store the timestamp anywhere even though I have a "hidden" field in the table.
How would you store a timestamp value in general on a web page? It should never be displayed, but it is needed for any updates.
After a lot of playing around I think I found a half-decent solution.
The problem seems to be that fields that are "Visible=false" are not included or bound in any update or delete commands.
The HiddenField works fine for Update commands, so if you are not doing any Delete commands you should be fine by including a hidden field which is bound (Bind(TStamp)) to the timestamp column in a templated field.
The problem is that if you are doing Deletes as well it doesn't look at any bound, hidden fields.
What I came up with was to add the timestamp to the data keys of the grid view. That way it will be considered a composite key together with the ID.
So, in short, add the timestamp to the DataKeyNames of the GridView/DetailsView etc, and remove any visible fields. That seemed to do the trick.

Resources