Getting selected values of a list box? - xpages

How do I get the selected items is a list, combobox etc?
I found this bit of code here:
/*****
*** getSelectableValues()
*** prints all selectable values for a given component, f.e. comboboxes, listboxes etc.
***
*** #params id of component
*****/
function getSelectableValues( id ) {
var ComboBox = getComponent( id );
var ChildrenList:java.util.ListIterator;
ChildrenList = ComboBox.getChildren().listIterator();
while (ChildrenList.hasNext()) {
var Child = ChildrenList.next();
/*** process computed / multiple values ***/
if( typeof( Child ) == 'com.ibm.xsp.component.UISelectItemsEx' ){
var hlp = Child.getValue();
for( var i=0; i< hlp.length; i++ ){
/*** print to server console ***/
print( hlp[i].getLabel() + "|" + hlp[i].getValue() );
}
}
/*** process single values ***/
if( typeof( Child ) == 'com.ibm.xsp.component.UISelectItemEx' ){
/*** print to server console ***/
print( Child.getItemLabel() + "|" + Child.getItemValue() );
}
}
}
/*** get all selectable values for element 'comboBox1' ***/
getSelectableValues( 'comboBox1' );
But it seems to get ALL of the items in a list box and not just the selected ones. Any ideas how to modify it to get just the selected values?

Instead of asking the component, ask the data model. For instance, if the list box is bound to:
#{someDoc.someItemName}
...then you can retrieve the selected values by asking the data source:
var selectedValues = someDoc.getValue("someItemName");
If the component is instead bound to a scoped variable:
#{viewScope.selectedValues}
...then just ask that variable:
var selectedValues = viewScope.get("selectedValues");

You can access the selected values with SSJS:
getComponent('comboBox1').value
If you are working with a list box and multiple selection is enabled, you can use Explode to get an array of strings:
#Explode(getComponent('listBox1').value)

Related

How do I make the has_many selector drag and drop sortable with fuelCMS 1.4?

I have created a model and added the $has_many for selecting multiple products. This is working fine but I am unable to make the selected products sortable by drag and drop. I know this is possible I have seen it. But I am unable to find anything in the documentation that shows how to get this done. Here is my model:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
require_once(FUEL_PATH.'models/Base_module_model.php');
/**
* This model handles setting up the form fields for our contact form
*
*/
class Products_category_model extends Base_module_model {
public $required = array('name', 'published');
public $has_many = array('products' => array(FUEL_FOLDER => 'Products_model'));
function __construct()
{
parent::__construct('w_product_categories');
}
/*
This will provide the list of records for display in the Admin Panel
Note how the "excerpt" will display, but truncated
Because we are using some MySQL functions in our select statement,
we pass FALSE in as the second parament to prevent CI auto escaping of fields
*/
function list_items($limit = null, $offset = null, $col = 'name', $order = 'asc', $just_count = false)
{
$this->db->select('id, name, published', FALSE);
$data = parent::list_items($limit, $offset, $col, $order);
return $data;
}
function form_fields($values = array(), $related = array())
{
$fields = parent::form_fields($values, $related);
return $fields;
}
}
class Product_category_model extends Base_module_record {
}
So it is very simple I discovered. I added this in the form fields function:
// Makes the has many drag and drop sortable.
$fields['products']['sorting'] = TRUE;
$fields['products']['after_html'] = "<div style=\"clear:both;font-style:italic\">NOTE: you can sort selected product to your choosing by clicking on the product and then dragging it into the desired placement in the list</div>";

Getting ViewPanel Headers programmatically

This code does provide me the values I am wanting in my comboBox, but I am wondering if there is a way to get the viewColumn ID, viewColumnHeader ID, and number of columns in the viewPanel programmatically. The viewPanel is using a JDBCQuery as the datasource.
var itemList:java.util.Vector = new java.util.Vector;
var colID = "viewColumn"; //default id assigned
var colHeaderID = "viewColumnHeader"; //default id assigned
var end = 10; //max # of viewPanel columns
itemList.add("Select Column");
for(x=1;x<end;x++) {
try {
if(getComponent(colID + x) == null) {
throw ("Only " + (x-1) + " columns in ViewPanel");
x=end;
} else {
var disColID = getComponent(colID + x).getColumnName();
}
var disColHeaderID = getComponent(colHeaderID + x).getValue();
itemList.add(disColHeaderID + "|" + disColID);
} catch (e) {
dBar.info(e.toString());
}
}
itemList
The current way is obviously restricted to only 9 columns and ensuring the viewColumn ID and viewColumnHeader ID have a specific naming structure which would be nice to get away from.
All the columns of a view panel can be accessed by getting the child components of view panel using viewPanelObj.getChildren(). The column headers are a part of view column and after you get the handle of view column you can access the header using viewColumnObj.getHeader().
So a sample SSJS code to access all the view columns and view headers would look something like this:
var viewPnl:com.ibm.xsp.component.xp.XspViewPanel = getComponent("viewPanel1");
var list:java.util.List = viewPnl.getChildren();
for (var i=0 ; i<list.size() ; i++) {
var viewCol:com.ibm.xsp.component.xp.XspViewColumn = list.get(i);
var viewHdr:com.ibm.xsp.component.xp.XspViewColumnHeader = viewCol.getHeader();
// Perform required operations on objects of viewCol & viewHdr
}

yii cgridview export into excel not working on pagination

my code export into excel works fine, 1 to 10 rows export if I filters rows that my code export filtered rows as my criteria. If I click to next page e.g 11 to 20 and then click on export button, export only first page 1 to 10 rows.
in my admin view export button code:
<div id='menub'><?php $this->widget('zii.widgets.CMenu', array(
'encodeLabel'=>false,
'htmlOptions'=>array(
'class'=>'actions'),
'items'=>array(
array(
'label'=>'<img align="absmiddle" alt = "'.Yii::t('internationalization','Export'). '" src = "'.Yii::app()->request->baseUrl.'/images/export.jpg" />',
//'label'=>'Export',
'url'=>array('expenses/excel'),
),
),
));
above link call to excel method in expenses controller.
code in my controller:
public function actionExcel() {
$issueDataProvider = $_SESSION['report-excel'];
$i = 0;
$data = array();
//fix column header.
//Could have used something like this - $data[]=array_keys($issueDataProvider->data[0]->attributes);.
//But that would return all attributes which i do not want
//$data[]=array_keys($issueDataProvider->data[0]->attributes);
$data[$i]['expenses_type_id'] = 'Type';
$data[$i]['amount'] = 'Amount';
$data[$i]['exp_date'] = 'Date';
$data[$i]['description'] = 'Description';
$i++;
//populate data array with the required data elements
foreach($issueDataProvider->data as $issue)
{
$data[$i]['expenses_type_id'] = $issue->expensesType->name;
$data[$i]['amount'] = $issue['amount'];
$data[$i]['exp_date'] = $issue['exp_date'];
$data[$i]['description'] = $issue['description'];
$i++;
}
Yii::import('application.extensions.phpexcel.JPhpExcel');
$xls = new JPhpExcel('UTF-8', false, 'test');
$xls->addArray($data);
$xls->generateXML('test_file');
}
I save data in
$_SESSION['report-excel']
and in my Model:
public function getSearchCriteria()
{
$criteria=new CDbCriteria;
if(!empty($this->from_date) && empty($this->to_date))
{
$criteria->condition = "exp_date >= '$this->from_date'"; // date is database date column field
}elseif(!empty($this->to_date) && empty($this->from_date))
{
$criteria->condition = "exp_date <= '$this->to_date'";
}elseif(!empty($this->to_date) && !empty($this->from_date))
{
$criteria->condition = "exp_date >= '$this->from_date' and exp_date <= '$this->to_date'";
}
$criteria->with = 'expensesType';
$criteria->join = 'LEFT JOIN expenses_type p ON t.expenses_type_id = p.id';
//s$criteria->compare('id',$this->id,true);
$criteria->compare('p.name',$this->expenses_type_id,true);
$criteria->compare('amount',$this->amount,true);
$criteria->compare('exp_date',$this->exp_date,true);
$criteria->compare('description',$this->description,true);
$criteria->order ='exp_date DESC';
return $criteria;
}
public function search()
{
// #todo Please modify the following code to remove attributes that should not be searched.
$data = new CActiveDataProvider(get_class($this), array(
'pagination'=>array('pageSize'=> Yii::app()->user->getState('pageSize',
Yii::app()->params['defaultPageSize']),),
'criteria'=>$this->getSearchCriteria(),
));
$_SESSION['report-excel']=$data;
return new CActiveDataProvider(get_class($this), array(
'criteria'=>$this->getSearchCriteria(),
));
every thing is works fine but on pagination.
kindly help.
CActiveDataProvider holds a set of items(all).So when you call actionExcel() the $page param is lost. So when you do actionAdmin() in your controller or search() in your model save your $_GET['page'] to an other session value. then set it when you do actionExcel().
$_GET['page'] = $_SESSION['your_session_page_value'];
Hope this helps
Best Regards

Best way of dynamically binding xpages field values to backend document

I am having a form with multiple fields like "Persp_1", "Persp_2", "Persp_3"...., Goal_1, Goal_2, Goal_3.... etc. Currently I am assigning the values from the xPage component to the backend document via a common function as belows:
function pushDataToBackEnd(sourceDoc:NotesDocument, fieldArray){
try{
for(var i=0; i<fieldArray.length;i++){
for(var j=0; j<12; j++){
a = j+1;
var fieldName = fieldArray[i] + "_" + a;
var fieldValue = getComponent(fieldName).getValue();
if(fieldValue != ""){
sourceDoc.replaceItemValue(fieldName,fieldValue);
}
}
}
return true;
}
catch(exp){
return exp
}
return true;
}
The problem is I also need to bind the components of the xPage with the backend fields on the notes form. Is there a way in which I can do this.
Use a custom control and a repeat control to dynamic bind fields. With the backend data.
Check out this post
Dynamic Data Binding?

Dropdown field - first item should be blank

Using sharepoint build in lookup column and it set to required field. SharePoint automatically selects the first item in the dropdown box (kinda misleading for the end users).
Is there a way to display blank or Null for the first row of this drop down box?
(I am open to any solution. I prefer javascript type solution)
For Choice fields, the default value is configured in the column settings. If the "Default value" input box is populated, delete the value in order to use no default value.
Edit
For Lookup fields, the field seems to change dramatically if it is required. Fields that are NOT required have a "(None)" value by default. However, toggling the field to required will remove the "(None)" value and the first value is selected automatically.
One thing I found, is that if you use JavaScript to add the null value to the dropdown and then try to press OK you get an error page: "An unexpected error has occurred." As a workaround, I wrote some more code to do a quick validation that the field has a value before the form is submitted. If the field has no value, then it will prompt the user and cancel the submit. (Note: this code is only attached to the OK buttons so you may get errors while editing EditForm.aspx.. just choose a value for your lookup field and you'll be able to edit like normal)
Anyways, onto the code... I think the only line you'll need to change is var fieldTitle = 'Large Lookup Field'; to update it to the name of your field.
<script type="text/javascript">
function GetDropdownByTitle(title) {
var dropdowns = document.getElementsByTagName('select');
for (var i = 0; i < dropdowns.length; i++) {
if (dropdowns[i].title === title) {
return dropdowns[i];
}
}
return null;
}
function GetOKButtons() {
var inputs = document.getElementsByTagName('input');
var len = inputs.length;
var okButtons = [];
for (var i = 0; i < len; i++) {
if (inputs[i].type && inputs[i].type.toLowerCase() === 'button' &&
inputs[i].id && inputs[i].id.indexOf('diidIOSaveItem') >= 0) {
okButtons.push(inputs[i]);
}
}
return okButtons;
}
function AddValueToDropdown(oDropdown, text, value, optionnumber){
var options = oDropdown.options;
var option = document.createElement('OPTION');
option.appendChild(document.createTextNode(text));
option.setAttribute('value',value);
if (typeof(optionnumber) == 'number' && options[optionnumber]) {
oDropdown.insertBefore(option,options[optionnumber]);
}
else {
oDropdown.appendChild(option);
}
oDropdown.options.selectedIndex = 0;
}
function WrapClickEvent(element, newFunction) {
var clickFunc = element.onclick;
element.onclick = function(event){
if (newFunction()) {
clickFunc();
}
};
}
function MyCustomExecuteFunction() {
// find the dropdown
var fieldTitle = 'Large Lookup Field';
var dropdown = GetDropdownByTitle(fieldTitle);
if (null === dropdown) {
alert('Unable to get dropdown');
return;
}
AddValueToDropdown(dropdown, '', '', 0);
// add a custom validate function to the page
var funcValidate = function() {
if (0 === dropdown.selectedIndex) {
alert("Please choose a value for " + fieldTitle + ".");
// require a selection other than the first item (our blank value)
return false;
}
return true;
};
var okButtons = GetOKButtons();
for (var b = 0; b < okButtons.length; b++) {
WrapClickEvent(okButtons[b], funcValidate);
}
}
_spBodyOnLoadFunctionNames.push("MyCustomExecuteFunction");
</script>
In response Kit Menke, I've made a few changes to the code so it will persist previous value of the dropdown. I have added the following lines of code to AddValueToDropdown()....
function AddValueToDropdown(oDropdown, text, value, optionnumber){
var selectedIndex
if (oDropdown.options.selectedIndex)
selectedIndex = oDropdown.options.selectedIndex;
else
selectedIndex = -1;
// original code goes here
// changed last line of code (added "selectedIndex+1")
oDropdown.options.selectedIndex = selectedIndex+1;
}
To improve on top of Aaronster's answer: AddValueToDropdown can be done that way:
var injectedBlankValue = false;
function AddValueToDropdown(oDropdown, text, value, optionnumber) {
for (i = 0; i < oDropdown.options.length; i++) {
option = oDropdown.options[i];
if(option.getAttribute('selected')) // If one is already explicitely selected: we skip the whole process
return;
}
var options = oDropdown.options;
var option = document.createElement('OPTION');
option.appendChild(document.createTextNode(text));
option.setAttribute('value', value);
if (typeof (optionnumber) == 'number' && options[optionnumber]) {
oDropdown.insertBefore(option, options[optionnumber]);
}
else {
oDropdown.appendChild(option);
}
// changed last line of code (added 'selectedIndex+1')
oDropdown.options.selectedIndex = 0;
injectedBlankValue = true;
}
This is needed for document libraries where "add" and "set properties" are two distinct pages.
And funcValidate starts with:
var funcValidate = function () {
if (!injectedBlankValue)
return true;
All these changes is to make the whole thing work with document libraries.

Resources