Checkbox in Tabular Form (Solution to span multiple pages)
437968Dec 13 2007 — edited Jan 9 2008Hi,
We had a case where a large report needed to have check boxes. These check boxes would populate a list of id's which we then processed for a specific task. By default APEX doesn't support this.
After spending some time on this, I thought I'd post my solution to help any others who experience the same problems. For this example we will use P10
1. Create a new "normal" report.
SELECT e.*, APEX_ITEM.CHECKBOX(1,e.EMPNO,'onClick="updateList(this);"',:P10_LIST, ',') AS Cancel,
FROM emp e
2. Create a hidden item called P10_LIST
3. Add an HTML region to the page whose template is "No Template" (do this so it doesn't show up. Call the region "JavaScript". Set its sequence to 1
4. Add the following in the JavaScript region:
<script src="http://SERVER_NAME/String.js" type="text/javascript"></script>
<script src="http://SERVER_NAME/Ajax.js" type="text/javascript"></script>
<script type="text/javascript">
function updateList(pObject){
vItem = 'P10_LIST';
myAjax = new Ajax();
vList = myAjax.getItemValue(vItem);
//Determine to remove or add from list
if (pObject.checked) {
//Add item
vList = vList.listAppend(pObject.value);
}
else{
//Remove from list
vList = vList.listRemoveItem(pObject.value);
}//if
//Set the session value
myAjax.setItemValue(vItem,vList);
//Set the HTML value
document.getElementById(vItem).value = vList;
}
</script>
This script:
- Loads the List from the session
- Modifies the list
- Stores it in the session
5. The JavaScript region references 2 files, which you'll need to add to your server. They are as follows:
Ajax.js
function Ajax(){
// TODO: Enter proper names etc.
this.appProcessNameNull = 'AJAX_null';
this.appProcessNameReturnItem = 'AJAX_ReturnItem';
this.tempItem = 'P0_AJAX_TEMP';
}
/**
* TODO: Document
* Sets Item in session
*/
Ajax.prototype.setItemValue = function(pItem,pValue,pAppProcess){
if (pAppProcess == null)
pAppProcess = this.appProcessNameNull;
var get = new htmldb_Get(null,$x('pFlowId').value,'APPLICATION_PROCESS=' + pAppProcess,0);
get.add(pItem,pValue);
gReturn = get.get();
}
/**
* TODO: Document
* @param pItem Name of item to get
* @param pTempItem Name of temp item
* @param pAppProcess Application Process to call which will return item
* @return session value
*/
Ajax.prototype.getItemValue = function(pItem,pTempItem,pAppProcess){
if (pTempItem == null)
pTempItem = this.tempItem;
if (pAppProcess == null)
pAppProcess = this.appProcessNameReturnItem;
var get = new htmldb_Get(null,$x('pFlowId').value,'APPLICATION_PROCESS=' + pAppProcess,0);
get.add(pTempItem,pItem);
gReturn = get.get();
return gReturn;
}
String.js
// From http://www.somacon.com/p355.php
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g,"");
}
// From http://www.somacon.com/p355.php
String.prototype.ltrim = function() {
return this.replace(/^\s+/,"");
}
// From http://www.somacon.com/p355.php
String.prototype.rtrim = function() {
return this.replace(/\s+$/,"");
}
/**
* Appends value to list
* @param pValue Value to add to list
* @param pDelimeter Defaults to comman
*/
String.prototype.listAppend = function(pValue, pDelimeter){
if (pDelimeter == null)
pDelimeter = ',';
vStr = this;
if (vStr.length == 0)
vStr = pValue;
else
vStr = vStr + pDelimeter + pValue;
return vStr;
}
/**
* Removes a value from list
* @param pValue Value to remove from list
* @param pDelimeter Defaults to comman
*/
String.prototype.listRemoveItem = function(pValue, pDelimeter){
if (pDelimeter == null)
pDelimeter = ',';
vStr = this;
vStr = pDelimeter + vStr + pDelimeter;
// Remove value
vStr = vStr.replace(pDelimeter + pValue + pDelimeter, pDelimeter);
//Remove prefix and suffix items
if (vStr.length > 0 & vStr.charAt(0) == pDelimeter){
vStr = vStr.substring(1);
}
if (vStr.length > 0 & vStr.charAt(vStr.length-1) == pDelimeter){
vStr = vStr.substring(0,vStr.length - 1);
}
return vStr;
}
6. On Page 0 Create a hidden Item called: P0_AJAX_TEMP
(Note: this is can be used for all your AJAX calls)
7. Create an Application Process called: "AJAX_null". Process Text: null;
8. Create an Application Process called: "AJAX_ReturnItem". Process Text:
begin
htp.prn(v(v('P0_AJAX_TEMP')));
end;
If you look at the Ajax.js you'll notice points 6,7, and 8 are all customizable etc... I just put it in so you can test right away.
Now the user can select items on multiple pages (if pagination applies). Once they hit a submit button you can use P10_LIST to process your values.
Hope this helps.
Martin