ZK set selected item after AnnotateDataBinder loadAll() - listbox

I'm new to ZK. I have a Listbox with a List as model. When I receive an update event I update the information in the model and then I update the UI using
AnnotateDataBinder binder = (AnnotateDataBinder) vesselsList.getPage().getAttribute("binder");
if (binder != null) {
binder.loadAll();
}
The problem is that after the update, in the following code
List updatedObjects = object.getItems();
for (Object obj : updatedObjects) {
Listitem data = (Listitem) obj;
Object ob = data.getValue();
The data.getValue() is always null.
I have search the internet for many days and I found that the binder launches an onInitRenderLater event after load everything but I can't manage to make it work.
My intent is if I have an item selected before the update,I want it to remain selected and the binder.loadAll().

Did you setValue to your items with annotated databinding ?
<listitem value="#{bean.data}" > .... </listitem>

In zul I made
<listbox model="#{objects_model}" id="objectsList"
and in Java I call the method
public void onAfterRender$objectsList(Event event) {
// select item here after the listbox has been rendered
}
it did the trick

Related

Sitecore Accessing Field value to ASP Control

Can any one tell me if I can use a ASP Control instead of Field Renderer to display the field.Please see below illustration.
Note:I need to do it in the Item Databound Event of Repeater.
I have a template with Field as External Link .Eg :Contact US .One way to display that link in the page is using field renderer as below.
ContactUS.aspx:
<asp:Repeater ID="rptContactUS" runat="server" OnItemDataBound="Menu_OnItemDataBound">
<ItemTemplate>
<item><sc:FieldRenderer ID="frContactUS" runat="server"/></item>
</ItemTemplate>
</asp:Repeater>
ContactUS.aspx.cs:
protected void Menu_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
Field item = (Field)e.Item.DataItem;
if (item != null)
{
FieldRenderer frContactUS= (FieldRenderer)e.Item.FindControl("frContactUS");
if (frContactUS!= null)
{
frContactUS.FieldName = item.Name;
}
}
}
The above code works fine.My Question is Whether I can use a Asp control instead of FieldRenderer and assign the link value from the Field Item to asp href property of the link in item databound event of repeater.If yes,Please tell me how?
Thanks,
Suhas
Yes you can. From what I see in your example you are binding Field to the Menu.
You could also bind a List of Items to your menu. You can then retrieve the item's fields in the repeater like this:
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Item dataItem = (Item)e.Item.DataItem;
System.Web.UI.WebControls.HyperLink hl = (System.Web.UI.WebControls.HyperLink)e.Item.FindControl("hl");
if (hl != null)
{
Sitecore.Data.Fields.LinkField url = dataItem.Fields["linkfield"];
if (url != null)
{
hlMerk.NavigateUrl = url.Url;
hlMerk.Target = url.Target;
// more properties are available check sitecore documentation
}
}
}
}
From here you will have the url field (obviously you should give the correct field name instead of url.
The LinkField has several properties as described in the general Sitecore documentation that can be found # http://sdn.sitecore.net.

Nested bean : a collection inside an object

I got a simple POJO class that i wish to display / update in a form
Using the BeanItem class and the binding of component data, i was able to quickly display the first attributes of may data class. However i've hit a wall for tow related attributes :
my class posses a set of available status, as a list of object 'AppStatus'. it also possess a current status, that is one of the status in the 'available' list.
I would like to display the list in the form as a combobox, with the current status selected.
I'we managed to associate the 'available' attribute with a combobox, but i can't seem to be able to fill this combobox when setting the data source (method setItemDataSource). How do i get the avalaible status list and the current status from my Item ?
I could always use a workaround and add a parameter to the method to get the source objet in addition to the BeanItem, but i would prefer to avoid this if the Item properties can give me my attribute.
Regards
Edit : shortened exemple, with code from Eric R.
class Status {
String id;
Sting label
+ setter /getter
}
class App {
String AppId;
String AppLabel
ArrayList<Status> availablestatus;
Status currentStatus
+setter/getter
}
in the form extension, in the createField of the fieldfactory i added the following lines
if ("status".equals(propertyId)) {
// create the combobox
ComboBox status = new ComboBox(
texts.getString("application.label.status"));
status.setItemCaptionMode(AbstractSelect.ITEM_CAPTION_MODE_PROPERTY);
status.setItemCaptionPropertyId("label");
status.setImmediate(true);
status.setNullSelectionAllowed(false);
IndexedContainer container = new IndexedContainer(
(Collection<ApplicationStatus>) item.getItemProperty(
"availableStatus").getValue());
status.setContainerDataSource(container);
status.setPropertyDataSource(item.getItemProperty("currentStatus"));
return status;
} else...
this didn't work, i do get a combobox, with the correct number of lines, but all empties.
i tried to use a beanContainer instead of a IndexedContainer
BeanContainer<String, ApplicationStatus> container =
new BeanContainer<String, ApplicationStatus>(ApplicationStatus.class);
container.addAll((Collection<ApplicationStatus>) item
.getItemProperty("availableStatus").
container.setBeanIdProperty("id");
the result is slightly better, since i do have the available values in the combobox.
only the currentValue is not selected...
I also tried to use a nestedbean property to get the id of the currentstatus, but the result is still not valid... i get a combobox, with the correct value selected, but i can not see others values anymore, since the combobox is readonly ?(even with setReadOnly(false);)
I suggest my way to resolve this. I don't think this is the nicest way, but it's works.
The beanItem class contains all you need.
I did the following in a simple project and it's work verry well :
ComboBox status = new ComboBox("ComboBox");
status.setImmediate(true);
status.setNullSelectionAllowed(false);
for(Status st : (Collection<Status>)item.getItemProperty("availableStatus").getValue()) {
status.addItem(st);
status.setItemCaption(st, st.getLabel());
}
status.setPropertyDataSource(item.getItemProperty("currentStatus"));
Hope it's works.
Regards Éric
From the vaadin demo site you can get this sample that show how to fill a combobox with countries. You could do the same i would guess (not sure I understand your problem 100%):
myForm.setFormFieldFactory(new MyFormFieldFactory ());
private class MyFormFieldFactory extends DefaultFieldFactory {
final ComboBox countries = new ComboBox("Country");
public MyFormFieldFactory () {
countries.setWidth(COMMON_FIELD_WIDTH);
countries.setContainerDataSource(ExampleUtil.getISO3166Container());
countries
.setItemCaptionPropertyId(ExampleUtil.iso3166_PROPERTY_NAME);
countries.setItemIconPropertyId(ExampleUtil.iso3166_PROPERTY_FLAG);
countries.setFilteringMode(ComboBox.FILTERINGMODE_STARTSWITH);
}
#Override
public Field createField(Item item, Object propertyId,
Component uiContext) {
Field f = (Field)item;
if ("countryCode".equals(propertyId)) {
// filtering ComboBox w/ country names
return countries;
}
return f;
}
}

Prevent selection of a particular item in spark list

I have a Spark List which has a custom itemRenderer for rendering each item in the List.
I wish to prevent an item in that list from being selected (based on some custom logic) by the user.
What is the best way I can achieve this?
Here's how my List is defined:
<s:List id="myList" itemRenderer="com.sample.MyItemRenderer" />
and of course, I have a item renderer defined as the class com.sample.MyItemRenderer.
The selection of items is handled by the list alone as far as I know, so I would say that you can manage it from there. I would have a field on the Objects that are in the list called "selectable" or something like that and when the list item is changing check to see if the new item is actually selectable and if it isn't then you can either have it clear the selection or reset to the previous selection. You can accomplish that by reacting to the "changing" event on the list component and calling "preventDefault" on the IndexChangeEvent as follows:
protected function myList_changingHandler(event:IndexChangeEvent):void {
var newItem:MyObject = myList.dataProvider.getItemAt(event.newIndex) as MyObject;
if(!newItem.selectable) {
event.preventDefault();
}
}
// Jumping ahead ...
<s:List id="myList" changing="myList_changingHandler(event)" // ... continue implementation
The relevant part of the MyObject class is as follows:
public class MyObject {
private var _selectable:Boolean;
public function MyObject(){
}
public function set selectable(value:Boolean):void {
_selectable = value;
}
public function get selectable():Boolean {
return _selectable;
}
}

How to make my ListBox not to call SelectionChanged event, when I assign ItemSource of my list

I have a combobox, that I populate from a web service:
public Configure()
{
InitializeComponent();
WebServiceSoapClient ws = new WebServiceSoapClient();
ws.GetTypesCompleted += new EventHandler<GetTypesCompletedEventArgs>(OnGetTypeCompleted);
ws.GetTypesAsync();
}
void OnGetTypeCompleted(object sender, GetTypesCompletedEventArgs e)
{
if (e.Result != null)
{
List<CodeTableItem> source = e.Result.ToList<CodeTableItem>();
lstType.ItemsSource = source;
lstType.SelectedIndex = -1;
}
}
So when I set the ItemSource property, SelectionChanged event gets fired with SelectedIndex = 0, but user hasn't made this selection yet and I need this list to have no selected value, so I'm setting SelectedIndex to -1, as you can see. As a result, SelectionChanged is called twice.
Can I make it be called only when user selects the item?
Thanks!
I'm using Silverlight 3 and VS 2008
Instead, modify your code so that the SelectionChange event handler isn't defined until after the itemssource and selected index are set.
void OnGetTypeCompleted(object sender, GetTypesCompletedEventArgs e)
{
if (e.Result != null)
{
List<CodeTableItem> source = e.Result.ToList<CodeTableItem>();
lstType.ItemsSource = source;
lstType.SelectedIndex = -1;
lstType.SelectionChanged += new SelectionChangedEventHandler(lstType_SelectionChanged);
}
}
In our application we implemented some code that would set a boolean flag based on the Control.LeftMouseButtonUp() event. When this has been set, it would mean that the user has interacted with the field, and so we can handle the SelectionChanged with different behaviour.
Over the development lifetime of our application this approach was essential so that default bindings would trigger our SelectionChanged logic when we didn't want it to.
If you are an MVVM purist, you'll need to expose the VM as a member variable and then set the bool flag in the VM.
HTH,
Mark

If a key does not exist in the ModelState, how can I add it? aspnetmvc1

I am trying to create a workaround in my controller which handles a bug in ASP.NET MVC v1. The bug occurs if you post a listbox which has nothing selected (http://forums.asp.net/p/1384796/2940954.aspx).
Quick Explanation:
I have a report that accepts two dates from textboxes and one or more selections from a ListBox. Everything works except for validation if the listbox is left with nothing selected.
When the form posts and reaches my controller, the model contains all items necessary. However, the ModelState does not contain a key/value for the listbox. To resolve, I was hoping something like this would do the trick:
if (!ModelState.ContainsKey("TurnTimeReportModel.Criteria.SelectedQueuesList") || ModelState["TurnTimeReportModel.Criteria.SelectedQueuesList"] == null) {
ModelState.Keys.Add("TurnTimeReportModel.Criteria.SelectedQueuesList");
ModelState["TurnTimeReportModel.Criteria.SelectedQueuesList"].Equals(new List<string>());
}
Unfortuantely, this throws the following exception when I try to add the key:
System.NotSupportedException: Mutating a key collection derived from a dictionary is not allowed.
Any ideas?
Thanks in advance!
Use the ModelState.Add method directly:
ModelState.Add("TurnTimeReportModel.Criteria.SelectedQueuesList",
new ModelState{ AttemptedValue = new List<string>() } )
I ended up going with the following which has done the trick:
if (ModelState.ContainsKey("TurnTimeReportModel.Criteria.SelectedQueuesList") && ModelState["TurnTimeReportModel.Criteria.SelectedQueuesList"] == null) {
ModelState["TurnTimeReportModel.Criteria.SelectedQueuesList"].Value = new ValueProviderResult("", "", CultureInfo.CurrentUICulture);
} else if (!ModelState.ContainsKey("TurnTimeReportModel.Criteria.SelectedQueuesList")) {
ModelState.Add("TurnTimeReportModel.Criteria.SelectedQueuesList", new ModelState{Value = new ValueProviderResult("","",CultureInfo.CurrentUICulture)});
}

Resources