Flex extending ComboBox - apache-flex

I created a class CustomCombo.as that extends ComboBox. What is happening is that the CustomCombo combobox is showing as being editable. I do not want this and I cant find the properties to set the editable to false.
I also tried setting the combobox's textInput.editable control to false, but to no avail.
Any help would be greatly appreciated.
CustomCombo.as
package custom {
import spark.components.ComboBox;
public class CustomCombo extends ComboBox {
public function CustomCombo() {
super();
// this.editable = false; //<-- THIS DOESNT WORK ***Access of possibly undefined property editable through a reference with static type custom:CustomCombo
// this.textInput.editable = false; //<-- THIS DOESNT WORK ***Cannot access a property or method of a null object reference
}
}
}

After rummaging through the Flex 4 API I found that they suggest to use the DropDownList control. From what I can see is that they removed the editable property from the ComboBox control in Flex 4, but I may be wrong.
I implemented DropDownList and that solved my problem.

I see that you're using spark and not mx. The editable property I referred to is applicable only to mx based list. In spark, ComboBox extends DropDownListBase and is editable by default.
The ComboBox control is a child class of the DropDownListBase control. Like the DropDownListBase control, when the user selects an item from the drop-down list in the ComboBox control, the data item appears in the prompt area of the control.
One difference between the controls is that the prompt area of the ComboBox control is implemented by using the TextInput control, instead of the Label control for the DropDownList control. Therefore, a user can edit the prompt area of the control to enter a value that is not one of the predefined options.
For example, the DropDownList control only lets the user select from a list of predefined items in the control. The ComboBox control lets the user either select a predefined item, or enter a new item into the prompt area. Your application can recognize that a new item has been entered and, optionally, add it to the list of items in the control.
The ComboBox control also searches the item list as the user enters characters into the prompt area. As the user enters characters, the drop-down area of the control opens. It then and scrolls to and highlights the closest match in the item list.
So ideally, you should be using DropDownList in this case.
You're getting null error when trying to access textInput from the constructor because it hasn't been created yet. In mx based controls (Flex-3), you can access it from the creationComplete handler; I'm not quite sure how to do it for spark based controls.
Update: I think I've figured out how to access skin parts in spark (though you might wanna use the DropDownBox instead). You have to override the partAdded method.
override protected function partAdded(partName:String, instance:Object):void
{
super.partAdded(partName, instance);
if (instance == textInput)
{
textInput.editable = false;
}
}
There's one catch though: it may not work in this case. The source code of ComboBox.as says that
the API ignores the visual editable and selectable properties
So DropDownList it is!
Initial answer, posted for mx ComboBox.
This shouldn't happen as the default value of the editable property is false.
Try explicitly setting the value to false from the constructor.
public function CustomCombo() {
super();
this.editable = false;
}

Related

ComboBox selected value not getting translated

My app should have several languages. English is by default. Problem is that if user will switch to different language, everything will be translated except for ComboBox selected value. This is how it looks:
Code behind ComboBox is:
ObservableList<Currency> currencyItem= CurrencyDA.getCurrencies();
currenciesComboBox.setItems(currencyItem);
Callback<ListView<Currency>, ListCell<Currency>> currencyFactory = lv -> new ListCell<Currency>(){
#Override
protected void updateItem(Currency currency, boolean empty){
super.updateItem(currency, empty);
setText(empty ? "" : interfaceBundle.getString("currency_"+currency.getName()));
}
};
currenciesComboBox.setCellFactory(currencyFactory);
currenciesComboBox.setButtonCell(currencyFactory.call(null));
currenciesComboBox.getSelectionModel().selectFirst();
How can I get selected value refreshed?
From the doc
As the ComboBox internally renders content with a ListView, API exists in the ComboBox class to allow for a custom cell factory to be set. For more information on cell factories, refer to the Cell and ListCell classes. It is important to note that if a cell factory is set on a ComboBox, cells will only be used in the ListView that shows when the ComboBox is clicked. If you also want to customize the rendering of the 'button' area of the ComboBox, you can set a custom ListCell instance in the button cell property. One way of doing this is with the following code :
//(note the use of setButtonCell):
Callback<ListView<String>, ListCell<String>> cellFactory = ...;
ComboBox comboBox = new ComboBox();
comboBox.setItems(items);
comboBox.setButtonCell(cellFactory.call(null));
comboBox.setCellFactory(cellFactory);
So the only thing you have to add is :
currenciesComboBox.setButtonCell(currencyFactory.call(null));

dialogPostRun method in RunBaseReport

I have a RunBaseReport which contains overrided dialog method where I'm adding couple of my controls. One of those controls is a combobox.
Controls enabled() property should be changed when I'm modifying combobox.
So basically I need to know when the value of my dfReportType dialog field changes.
public Object dialog(Object dialog)
{
DialogRunbase dialog = dialog;
;
//adding my combobox
dfReportType = dialog.addFieldValue(typeid(ReportType), ReportType:DefaultType);
//adding some other controls here
return dialog;
}
According to many articles that I found I need to override dialogPostRun Method and do something like this:
public void dialogPostRun(DialogRunbase dialog)
{
super(dialog);
dialog.dialogForm().formRun().controlMethodOverload(true);
dialog.dialogForm().formRun().controlMethodOverloadObject(this);
}
But unfortunately I don't have this method in RunBaseReport class.
Which should be there according to msdn .
Are there any other workarounds?
I'm currently on AX 2012 but I still looked at it. I have the method available in the context menu, but not on the first column. I have to go over "Plus..." to find the method in the second column.
Well, there is no dialogPostRun method in Report object that inherits RunBaseReport, but we have this method in Class that inherits RunBaseReport.
So that was my mistake. I used report object instead of class.
If you want to make custom dialog for the report but you also want to use all default controls you should:
Create class
Inherit RunBaseReport
Override dialog, getFromDialog etc.
Override lastValueElementName method
public identifiername lastValueElementName()
{
//just put name of your report object
return reportStr(YourReportName);
}
Don't forget to add main() method if you going to make call from menuItem.

Telerik RadComboBox AutomaticLoadOnDemand

I use Telerik RadComboBox in my project. I set EnableAutomaticLoadOnDemand="true" on RadComboBox. It works good but when I want to set selected item on load of page event, it doesn't show selected item
With load on demand mode, so combobox does not have any item. It just has item(s) when you action on it.
In my opinion, you should get the specific item and add it to combobox manually on page load event like this way (I'm not sure the structure, just an idea.)
if (!IsPostBack)
{
var itemSelected = service.GetById(Id); //item Id
this.combobox.Items.Add(new RadComboboxItem(itemSelected.Id, itemSelected.Name));
this.combobox.SeletedValue = Id.ToString();
}
RadCombo allows to set up SelectedValue and Text properties even through there are no items in it.

ITemplate, the reason for leaving InstantiateIn(Control container)

I'm implementing the ITemplate interface in ListView control. If i realize it for ItemTemplate in my custom class, everything will be OK. I mean, the runtime will invoke InstantiateIn when i use
ListView.ItemTemplate = new CustomClass();
CustomClass :ITemplate
{
public void InstantiateIn(Control container)
{
HtmlTable table = CreateHeader();
container.Controls.Add(table);
}
...
}
But i want to do the same with ListView.LayoutTemplate. In this case, the runtime invokes InstantiateIn only one time, but every next update it leaves my method. What is the reason for it?
Layout template says how the root container does look like, it is not per item thing.
I have to change my LayoutTemplate after clicking different buttons.
And My LayoutTemplate has a header for the whole ListView. I have to change it, it depends on button.
Also i have two custom classes with implementations of ITemplate (one for ItemTemplate and one for LayoutTemplate). I am going to realise the folowing behaviour:
1). If i click Button1
ListView.ItemTemplate = new CustomItemClass1();
ListView.LayoutTemplate = new CustomLayuotClass1();
2). If i click Button2
ListView.ItemTemplate = new CustomItemClass2();
ListView.LayoutTemplate = new CustomLayuotClass2();
But i can't see my header of LayoutTemplate more, then one time.

How do I change the State in an itemRenderer based on an action in another itemRenderer?

I have a DataGridColumn with an ItemRenderer that extends the Box component. The default display is a Text component. When the user clicks on the text component, I change the State to add a PopUpMenuButton child, and make the Text component invisible. This works fine. However, I only want to allow one PopUpMenuButton to be visible in the DataGrid at a time (similar to how an itemEditor works). I don't want to use an itemEditor, because I've run into too many problems trying to get that to work in this instance.
I am implementing IDropInListItemRenderer in my itemRenderer, in order to access the listData property, which will give me the owner (DataGrid), but I don't know how to "turn off" the "editing" state in other itemRenderers in the DataGrid.
How can I accomplish this?
Thanks.
Here we go. I simply added an Listener for Change Events in the listData.owner - if it is triggered, I update the currentState to null. Works like a charm. Much easier than trying to access the itemRenderers in the column and resetting them all. Better on performance too.
private function label_clickHandler():void
{
showEditor();
}
private function showEditor():void
{
this.currentState = "editingMode";
var ownerListBase:ListBase = ListBase(listData.owner);
ownerListBase.addEventListener(ListEvent.CHANGE, ownerListBase_changeHandler);
}
private function ownerListBase_changeHandler(event:ListEvent):void
{
this.currentState = null;
var ownerListBase:ListBase = ListBase(listData.owner);
ownerListBase.removeEventListener(ListEvent.CHANGE, ownerListBase_changeHandler);
}

Resources