How to apply a style to an hiearchial comboBox in XPages - combobox

I have a comboBox in XPages which is showing an hierarcal list of categories and values populates as a vector in SSJS.
I now want to apply a styleheet (bold) to the categories (i.e on only the categories of the generated option tags)
please note that I do not need a lesson in how stylesheets work. I need to know how to add a class or style to the categories in the outputted options tags
how can I do that?
thanks
Thomas
UPDATED MY QUESTION WITH A WORKING CLASS
Mimics a categorized view with 3 columns in a comboBox, category, label and value
public class Utils {
public static List<SelectItem> getGroupedComboboxOptions() {
try {
Database db = ExtLibUtil.getCurrentDatabase();
View vv = db.getView("ProdukterByCat");
Vector v = vv.getColumnValues(0);
List<SelectItem> groupedOptions = new ArrayList<SelectItem>();
SelectItemGroup group;
for (int i = 0; i < v.size(); i++) {
List<SelectItem> options = new ArrayList<SelectItem>();
group = new SelectItemGroup(v.get(i).toString());
ViewEntryCollection nvec = vv.getAllEntriesByKey(v.get(i), true);
ViewEntry entry = nvec.getFirstEntry();
while (entry != null) {
SelectItem option = new SelectItem(entry.getColumnValues().get(2).toString(),entry.getColumnValues().get(1).toString());
options.add(option);
entry = nvec.getNextEntry(entry);
}
group.setSelectItems(options.toArray(new SelectItem[options.size()]));
groupedOptions.add(group);
}
return groupedOptions;
} catch (NotesException e) {
e.printStackTrace();
}
return null;
}
}

A combobox in XPages is rendered using a HTML select tag. If you organise the options in optgroup's (see also Populating selectItems of the combobox (label, value) using a managed bean) you get some default styling out of the box. Example here.
You can even apply additional styling on them with standard CSS by targeting the optgroup. But support for that is limited: it doesn't work on an iPad for example.
If you want more control on how your dropdowns look, I'd suggest to use a plugin like Select2.

Related

Vaadin ComboBox setValue not working

I am having trouble in vaadin combobox after setting a value. here is my code
public class ComponentService implements FieldGroupFieldFactory {
/**
* Create Distributor ComboBox
*/
public ComboBox createComboBoxDistributor(String caption, boolean required) {
ComboBox c = new ComboBox(caption);
BeanItemContainer<Distributor> beans = new BeanItemContainer<Distributor>(Distributor.class);
beans.addAll(distributorService.find(null));
c.setContainerDataSource(beans);
c.setFilteringMode(FilteringMode.CONTAINS);
c.setRequired(required);
return c;
}
}
ComboBox comboDistributor = componentService.createComboBoxDistributor("Disributor", false);
comboDistributor.setValue(this.entity.getCustomer().getDistributor());
You could check if distributorService.find(null).contains(this.entity.getCustomer().getDistributor()) as Vaadin uses the equals function of the Bean (Distributor in this case).
Alternatively you can check if beans.getItemIds().contains(this.entity.getCustomer().getDistributor()); returns true.
If any of the above statements return true, the selection should work.
Maybe the client does not update its content? try getUI().access( () -> getUI().push());

SmartGWT ComboBox default checked items

I am using GWT combobox with Select item (dropdown checkbox)
I want to make some items defaultly checked, but i cant find any solutions..
#Override
protected void success(List<warehouseDTO> t)
{
warehouse_list = t;
for (int i = 0; i < warehouse_list.size(); i++)
{
whl.put(warehouse_list.get(i).getId() + "", warehouse_list.get(i).getName());
}
selectItemMultiplePickList.setValueMap(whl);
selectComboForm.setItems(selectItemMultiplePickList);
}
On new "Article" (thing in warehouse) its good, but on edit i need to have checked by default.
Maybe its posible with setAttribute but cant find list of attributes.
Thanks
You should use the following:
setValues(values);
Here values accepts multiple String values.
Now as you're doing:
whl.put(warehouse_list.get(i).getId() + "", warehouse_list.get(i).getName());
your key for the combobox will be warehouse_list.get(i).getId() and value will be warehouse_list.get(i).getName().
So to show multiple values as selected values, you need to pass multiple warehouse_list.get(i).getId() as values.
For example, if you want show first 3 values as selected, you can do the following:
selectItemMultiplePickList.setValues(
warehouse_list.get(0).getId(),
warehouse_list.get(1).getId(),
warehouse_list.get(2).getId());

Windows Form Combobox.Items.Clear() leaves empty slots

I am working on a Windows Form that has multiple comboboxes. Depending on what is chosen in the first combobox determines what items are filled into the second combobox. The issue I am running into is if I choose ChoiceA in ComboBox1, ComboBox2 is clear()ed, then is filled with ChoiceX, ChoiceY, and ChoiceZ. I then choose ChoiceB in ComboBox1, ComboBox2 is clear()ed, but there are no choices to add to ComboBox2, so it should remain empty. The issue is, after choosing ChoiceB, there's a big white box with three empty slots in ComboBox2. So, basically, however many items are cleared N, that's how many empty slots show up after choosing ChoiceB.
This might be a tad confusing, I hope I explained it well enough.
-- EDIT Adding Code, hope it helps clear things up. BTW, mainItemInfo is another "viewmodel" type class. It interfaces back into the form to make updates.
private void cmbType_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownItem item = (DropDownItem)cmbType.SelectedItem;
if (!String.IsNullOrWhiteSpace(item.Text))
{
cmbBrand.Enabled = true;
btnAddBrand.Enabled = true;
mainItemInfo.FillBrands(new Dictionary<string, string> { { "Type", item.Text } });
mainItemInfo.SyncBrands(this);
}
}
public void FillBrands(Dictionary<string, string> columnsWhere)
{
// Clear list
Brands.Clear();
// Get data
StorageData storage = new StorageData(File.ReadAllLines(ItemsFilePath));
// Fill Brands
foreach (string type in storage.GetDistinctWhere(columnsWhere, "Brand"))
{
Brands.Add(type, new DropDownItem(type, type));
}
}
public void SyncBrands(IPopupItemInfo form)
{
form.ClearcmbBrand();
var brands = from brand in Brands.Keys
orderby Brands[brand].Text ascending
select brand;
foreach (var brand in brands)
{
form.AddTocmbBrand(Brands[brand]);
}
}
public void AddTocmbBrand(DropDownItem brand)
{
cmbBrand.Items.Add(brand);
}
public void ClearcmbBrand()
{
cmbBrand.Items.Clear();
}
Simply, you can add an item then clear the combobox again:
cmbBrand.Items.Clear();
cmbBrand.Items.Add(DBNull.Value);
cmbBrand.Items.Clear();
You should able to set the datasource of listbox2 to null to clear it, then set it again with the new data.
So, in pseudo-code, something like:
ItemSelectedInListBox1()
{
List futureListbox2Items = LoadOptionsBaseOnSelectedItem(item)
Listbox2.Datasource = null
Listbox2.Datasource = futureListBox2Items
}
That should refresh the list of items displayed in Listbox2 with no white spaces.
I was able to fix the extra space. I changed the Add and Clear methods to:
public void AddTocmbModel(DropDownItem model)
{
cmbModel.Items.Add(model);
cmbModel.DropDownHeight = cmbModel.ItemHeight * (cmbModel.Items.Count + 1);
}
public void ClearcmbModel()
{
cmbModel.Items.Clear();
cmbModel.DropDownHeight = cmbModel.ItemHeight;
}

How to find matching words in Text Box and Datagrid when VirtualizingStackPanel.IsVirtualizing="true"?

I have Datagrid and Text Box in my Form. Datagrid is showing me existing items in my stock. I use Text Box to search and set focus to that row which is matching with my Text Box. Now it is working fine when VirtualizingStackPanel.IsVirtualizing="false" but it is very slow and getting a lot RAM resource.
Here is my code for this.
public IEnumerable<Microsoft.Windows.Controls.DataGridRow> GetDataGridRows(Microsoft.Windows.Controls.DataGrid grid)
{
var itemsSource = grid.ItemsSource as IEnumerable;
if (null == itemsSource) yield return null;
foreach (var item in itemsSource)
{
var row = grid.ItemContainerGenerator.ContainerFromItem(item) as Microsoft.Windows.Controls.DataGridRow;
if (null != row) yield return row;
}
}
private void SearchBoxDataGrid_TextChanged(object sender, TextChangedEventArgs e)
{
var row = GetDataGridRows(AssortDataGrid);
/// go through each row in the datagrid
foreach (Microsoft.Windows.Controls.DataGridRow r in row)
{
DataRowView rv = (DataRowView)r.Item;
// Get the state of what's in column 1 of the current row (in my case a string)
string t = rv.Row["Ассортимент"].ToString().ToLower();
if (t.StartsWith(SearchBoxDataGrid.Text.ToLower()))
{
AssortDataGrid.SelectedIndex = r.GetIndex();
AssortDataGrid.ScrollIntoView(AssortDataGrid.SelectedItem);
break;
}
}
}
What I want is to make it VirtualizingStackPanel.IsVirtualizing="true" but in this case my method is not working. I know why it is not working, my code will work only for showing part of Datagrid.
What do you recommend? How to fix this issue? Any idea will be appreciated. If you give any working code it will be fantastic. I hope I could explain my problem.
Virtualization means that WPF will reuse the UI components, and simply replace the DataContext behind the components.
For example, if your Grid has 1000 items and only 10 are visible, it will only render around 14 UI items (extra items for scroll buffer), and scrolling simply replaces the DataContext behind these UI items instead of creating new UI elements for every item. If you didn't use Virtualization, it would create all 1000 UI items.
For your Search to work with Virutalization, you need to loop through the DataContext (DataGrid.Items) instead of through the UI components. This can either be done in the code-behind, or if you're using MVVM you can handle the SeachCommand in your ViewModel.
I did a little coding and make it work. If anyone needs it in future please, use it.
Firstly I am creating List of Products
List<string> ProductList;
Then on Load Method I list all my products to my Product List.
SqlCommand commProc2 = new SqlCommand("SELECT dbo.fGetProductNameFromId(ProductID) as ProductName from Assortment order by ProductName desc", MainWindow.conn);
string str2;
SqlDataReader dr2 = commProc2.ExecuteReader();
ProductList = new List<string>();
try
{
if (dr2.HasRows)
{
while (dr2.Read())
{
str2 = (string)dr2["ProductName"];
ProductList.Insert(0, str2.ToLower ());
}
}
}
catch (Exception ex)
{
MessageBox.Show("An error occured while trying to fetch data\n" + ex.Message);
}
dr2.Close();
dr2.Dispose();
After that I did some changes in SearchBoxDataGrid_TextChanged
private void SearchBoxDataGrid_TextChanged(object sender, TextChangedEventArgs e)
{
int pos = 0;
string typedString = SearchBoxDataGrid.Text.ToLower();
foreach (string item in ProductList)
{
if (!string.IsNullOrEmpty(SearchBoxDataGrid.Text))
{
if (item.StartsWith(typedString))
{
pos = ProductList.IndexOf(item);
AssortDataGrid.SelectedIndex = pos;
AssortDataGrid.ScrollIntoView(AssortDataGrid.SelectedItem);
break;
}
}
}
}
Now it works when VirtualizingStackPanel.IsVirtualizing="true".
That is all.

How can I get items from current page in PagedCollectionView?

I've got my objects in PagedCollectionView bound to DataGrid and DataPager.
var pcView = new PagedCollectionView(ObservableCollection<Message>(messages));
How can I easily get items from current page in PagedCollectionView from my ViewModel? I wish there were something like this:
var messagesFromCurrentPage = pcView.CurrentPageItems; // error: no such a property
There are properties like SourceCollection, PageIndex and Count but I don't find them useful in this case. What am I missing here?
If you want to get select items you can just use Linq to do it.
var items = pcView.Where(i => i.SomeCondition == true);
Make sure you add a using statement for System.Linq.
Edit: Whenever I have a question as to what is really going on I just look at the code using Reflector (or ILSpy). In this case here is the relevant code inside GetEnumerator() which is how the Select or Where gets the items in the list:
List<object> list = new List<object>();
if (this.PageIndex < 0)
{
return list.GetEnumerator();
}
for (int i = this._pageSize * this.PageIndex; i < Math.Min(this._pageSize * (this.PageIndex + 1), this.InternalList.Count); i++)
{
list.Add(this.InternalList[i]);
}
return new NewItemAwareEnumerator(this, list.GetEnumerator(), this.CurrentAddItem);
So you can see how it is returning only the items in the current page from this code.

Resources