I'm trying to implement multiple record selection feature on a grid.
It is very similar to http://www.tek-tips.com/faqs.cfm?fid=3831
It adds an extra column with check boxes. I want those check boxes!!
But it depends on a extra logical field in the underlying table. It need to create a class clscheck which inherits CHECKBOX. I'm not sure why this CLICK procedure is needed for the checkbox.
PROCEDURE CLICK
IF DODEFAULT()
KEYBOARD '{DNARROW}'
ENDIF
ENDPROC
When I removed it, row selection did not work correctly as expected. Why this?
Here is my requirement:
1) I don't want to add an extra logical field in the underlying table.
2) To work with controls in the grid, I think AllowCellSelection must be .T. I want AllowCellSelection = .F. because I don't need to work with any control in the grid except the check boxes. I need to work only with check boxes. The other columns will be read-only.
3) Can I have selected list without the logical field in the underlying table?
4) Can I remove the usage of KEYBOARD '{DNARROW}'?
In fact, I have a grid which is AllowCellSelection = .F., but it only provides single selection.
I need to enhance it with multiple selection, thus, I just want to add an extra column with check boxes so that user can know he can select multiple records.
No need Shift+Click or Ctrl+Click which is not familiar with idiot users.
I have found this - http://www.tek-tips.com/faqs.cfm?fid=433
It also depends on an extra logical field and it depends Shift+Click and Ctrl+Click.
What you are seeing is quite common for multi-select grids. I've used them SIMILAR to this in the past. However, you are afraid of the extra column in the underlying table. That may/not be true. You don't always have to update the ORIGINAL table, but a temporary CURSOR you are presenting to the user. Ex: If you want to display a list of employees in a table. No, you don't want to keep adding this column to the original employee table as then anyone else trying to do multi-select could falsely get your selection. However, if you pulled into your own local cursor and presented to the user, then no problem. Example...
Thisform.YourGrid.RecordSource = "Employees"
(bound directly to your employee table -- not necessarily the right thing)
vs
use in select( "C_MultiPickEmployees" )
select ;
.F. as IsChosen, ;
E.* ;
from ;
Employees E;
into ;
cursor C_MultiPickEmployees READWRITE
Thisform.YourGrid.RecordSource = "C_MultiPickEmployees"
NOW, you have your extra column without dealing with issues to the underlying table. If you wanted to further filter what you were showing -- such as employees for a certain division/department, then just add that to a WHERE clause, add an Order By if so needed and you are good to go.
As for the "Allow Cell Selection", I've never had to deal with that. I just add a "checkbox" to the first column and set
Thisform.YourGrid.Column[1].CurrentControl = "CheckBoxControl"
(based on the name it is added to the column).
Then, set the column 1's "ControlSource" = "C_MultiPickEmployees.IsChosen" and you should mostly be done.
As for the "CLICK" event trying to force the down arrow. This is more for automatically scrolling to the next record so you can just click, click, click for multiple entries.
Hope this helps clarify things for you.
Related
In App Maker, what is the simplest way to achieve the same result with a dropdown box that you can with a suggest box, which can return the whole record when you make a selection giving you the ability to assign associated record values to other fields on the page?
Consider a data model with three fields, (Code, Description, and Severity). Add a dropdown box to select the Code. Have the selection, (probably using onValueChange or onValueEdit), write the selected Code's Description to a label field beside the dropdown box. The Code's Severity will also be used to affect the style in some way like background color or something, but for this answer, merely assigning the value to a scripting variable will be good enough. It's the record value access and assignment mechanism I am after.
Clarification: This data model will not be the page's datasource. It is a secondary reference table used for assigning a code to a ticket. You can also assume that a record value will be written to a field in the page's datasource as well.
I would appreciate the simplest low code solution as we will have non-programmers attempting this. Thanks.
As long as you leave your value binding on the dropdown blank the following should work:
Set the options binding to:
#datasources.YourDatasource.items
You may want to consider changing the 'Names' binding to be the projection of a particular field in this datasource otherwise the values showing in your dropdown will only be the 'keys' from this datasource.
Then in your onValueEdit event you will gain access to individual fields like this:
var item = widget.datasource.item;
item.YourFieldToEdit1 = newValue.YourOtherDatasourceField1;
item.YourFieldToEdit2 = newValue.YourOtherDatasourceField2;
That would probably be the simplest way.
I am still learning, and looking for help on how to display a label based on one data-sources field value, being within another data-sources field value list.
I have one calculated table, displaying rows of documents within a folder, and wish to use a field representing the document number in that data-source, so that if it's ANYWHERE within another tables field it displays my label.
I've been trying to use projection as I think this is how to achieve it.
I can get it working based on both the current #datasouce.item.fieldnames but need it to base the calculation on all possible numbers in that tables field (Image below should make it easier to understand).
I expect that it has something to do with projections, but can't find anything within the learning templates or anywhere else to resolve the issue.
I think the following should work for you. For the 'Reserved' label have the following binding for the text property:
(#datasources.project_quotes.items..quotenumber).indexOf(#widget.datasource.item.Qnumber) !== -1 ? 'Reserved' : ''
I would suggest alternatively just to include a field in your calculated datasource and making the determination in your server script.
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.
I have a selection list that is generated dynamically, it lists a number of checkboxes that are based on an end-user editable table, as such I have no idea what data, or how much, might be contained in this table and how many checkboxes or what they might contain, other than the primary keys of the table.
The user will select the checks they wish to see, and then control is passed to another page via PostBackUrl. The second page has to figure out which records to show (build it's where clause) based on the checkboxes checked in the previous page.
So, my problem is several-fold. First, asp:CheckBoxes don't have values. This can be worked around by a number of methods. Right now, i'm using a placeholder and dynamically creating the checkboxes in the ItemDataBound event of the DataList. I set the ID to "CheckboxKey1Key2" (where Key1 and Key2 are the primary keys of the check items).
Second, I have to walk through the controls of the PreviousPage to dig out all these values. That in itself is also a pain, but doable.
Now, my thinking is to build the where clause of my Linq2Sql query based on the keys I got from decoding the checked checkbox names. This all seems like a lot of jumping through hoops for something that shouldn't be this difficult. Am I missing something? Does anyone have any better solutions?
Make a class with a structure for your values that will be useful and easy for you to use on the result page. Then when the user clicks whatever it is they click to go to the result page, loop through the DataList, create a collection from the checked items, and you will only need to grab one object instead of everything, when you need to format your query.
Then when you get to the result page, loop through the collection and build the query in the loop. Pretty easy and not much code.
How Can I find all the rows that has been changed in gridview. I can not use Ajax in any form
First get the contents of your grid before it was changed (such as caching the results of the original gridview datasource binding). Then go through the dataset/datatable/however you want to store it, and compare the contents with the current rows of the gridview.
There's no real efficient way to do this, no method like GridView.GetAllChangedRows(). So, what you might do instead is keep a behind the scenes List that you add to each time a row is modified (use the RowUpdated method), then clear this list when needed.
It depends upon how many columns you want to edit in a row.
If you have only one editable column in a row then you can associate a javascript method with that control which you want to modify and in that method you can get a rowid which you can save in another hidden field and in server side you can get all rows whose ids are stored in hidden field.
If you have whole row editable in that case the best approach I think you should save the original data source somewhere and also set a javascript method with rowclick event to get rowid which user selects. Then when user clicks on submit button get all rows whose row ids are stored in hidden field then compare those with same rowid in datasource. This is the best approach from my point of you.
Let me give you an example, suppose there are 1000 rows in a grid and user clicks on only 180 rows. In that case we will compare only 180 rows and wont compare rest of the rows.
Please let me know if somebody has better idea then this.