Problem
On one Form I have a Multilist where each item has a "name" and an "ID number". I'd like my app to do the following:
After I select an item, it will go to the "profile" screen and then it will display all the information about that person, based on the "ID number" that I will get from the Storage.
Question
How can I get the information from the Multilist item I just clicked?
And then, how can I save that info so I can use it in the "before show (Profile screen)" so I can retrieve the info from Storage.
Thnaks
I will suggest you use a MultiButton instead of Multilist, then you can add actionEvent to individual element.
You can save individual element into static variables in the actionEvent and use it in the before show of your profile form. For example:
Declare this globally:
private static String UserName = "";
And initialize it as follows:
Container content = new Container(new BoxLayout(BoxLayout.Y_AXIS));
content.setScrollableY(true);
for (int i = 0; i < YourItemsLength; i++) {
final MultiButton mb = new MultiButton("Blablabla");
mb.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
UserName = mb.getTextLine1(); // or anything you want it to be
//show the profile form here
}
});
content.addComponent(mb);
}
content.revalidate();
In the beforeShow() of profile, call UserName and you should be able to use the value. Do the same for all the values you need.
I totally agree with Diamonds answer and I think that's the best/simplest way to create a list of items. However, if you do still want to use MultiList you need to implement a ListModel or use DefaultListModel.
From your question I assume you just used the MultiList and filled out the values?
In that case when there is an action event on the list you can just get the instance of the list the invoke Map m = (Map)myList.getSelectedItem();
The map should return key/value pairs containing your data. You can have hidden keys within that data simple by naming them differently from rendererd list elements so you can have something like "id" as the key.
Related
I'm trying set the text in my listView to the string value in my FavJokes class.
class FavJokes {
var index: Int? = null
var string: String? = null
}
When ever a user favorites a joke, I create a FavObject instance and assign it values for the index(as the Jokes are stored in an array) and the string value of the joke.
val newFav = FavJokes()
newFav.index = primaFreeze!!
newFav.string = ("${questionProvider.quesRegistry[primaFreeze!!]}... ${answerProvider.ansRegistry[primaFreeze!!]}")
favorites.add(newFav)
When I try to use this array of FavJoke objects as the datasource for my listView what I see is my project id and ".FavJokes#ee8e3e" show up on the listView itself.
I don't think I should populate the listView with just the string value for the joke because for my setOnItemClick{} method, the view I segue to is going to need the index of the joke in order to populate the textView with the correct joke.
I'm new to kotlin/Java started learning it about 3 days ago, but I do have some Swift experience. In Swift I could use an IndexPath object to get/set the values for my tableView. Is there such an object or a method that I can access and set the TextView.text values in Kotlin/Java?
In Android you set an adapter on the list view and then add a setOnItemClickListener, which when called will be provided with the index of the item in the list.
One the simplest adapters is an ArrayAdapter.
Here is a tutorial from a familiar source.
And here is a quick example from some existing code.
in OnCreateView I get my list view.
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
val rootView = inflater!!.inflate(R.layout.fragment_target_selection, container, false)
targetList = rootView.findViewById(R.id.names_list) as ListView
return rootView
}
then in my onResume I receive an array of objects which I then use to create my adapter.
disposables.add(telescopeInterface.namesListStream.subscribe {
println("here is the names list")
namesList = it
namesListAdapter = ArrayAdapter(this.context, android.R.layout.simple_list_item_1, namesList?.names)
println("setting up list view with the updated list")
setupListView()
})
then in the setupListView() I assign the adapter to the list view and add a listener.
private fun setupListView() {
namesListAdapter?.let { targetList.adapter = it }
targetList.setOnItemClickListener { adapterView, view, i, l ->
targetSelectionListenter?.targetSelected()
val entry = adapterView.getItemAtPosition(i)
println("item $entry")
telescopeInterface.sendSelectedTarget(entry as DSOCatalogNameEntry)
}
}
The full object remains in the list, the adapter is just used to select what is displayed in the list view, then you get the index of the selection, which you then use to extract the full object from your source list.
In page edit mode I want to show a read-only text that is based on a page property value. The text could for example be "A content review reminder email will be sent 2015-10-10", where the date is based on the page published date + six months (a value that will be configurable and therefore can change anytime). So far I've tried to accomplish something like this by adding another property on the page.
I've added the property CurrentReviewReminderDate to an InformationPage class we use. In page edit mode the property name is shown, but it doesn't have a value. How do I do to show the value in page edit mode (preferably as a label)?
[CultureSpecific]
[Display(
Name = "Review reminder date",
Description = "On this date a reminder will be sent to the selected mail to remember to verify page content",
Order = 110)]
[Editable(false)]
public virtual string CurrentReviewReminderDate
{
get
{
var daysUntilFirstLevelReminder =
int.Parse(WebConfigurationManager.AppSettings["PageReviewReminder_DaysUntilFirstLevelReminder"]);
if (CheckPublishedStatus(PagePublishedStatus.Published))
{
return StartPublish.AddDays(daysUntilFirstLevelReminder).ToString();
}
return "";
}
set
{
this.SetPropertyValue(p => p.CurrentReviewReminderDate, value);
}
}
EPiServer internally uses the GetPropertyValue method (i.e. the opposite of SetPropertyValue) when retrieving content for the UI.
This makes sense, otherwise your "made-up" value would be stored as the real value whenever the content is saved. This would make fall-back values etc impossible to implement.
So, this is by-design (and quite wisely so) in EPiServer. :)
However, you can customize how properties work by:
Using custom editors by applying UI hints
Modifying property metadata (for example, to display a generated value as a watermark in a textbox without interfering with the actual value being saved)
I could be misunderstanding what you're trying to do, but off the top of my head it looks like a custom editor could be a viable option for your use case?
Another solution would be to hook into the LoadedPage-event and add the value from there. This might not be the best way performance-wise since you need to do a CreateWritableClone, but depending on the site it might not matter.
[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class EventInitialization : IInitializableModule
{
public void Initialize(InitializationEngine context)
{
ServiceLocator.Current.GetInstance<IContentEvents>().LoadedContent += eventRegistry_LoadedContent;
}
void eventRegistry_LoadedContent(object sender, ContentEventArgs e)
{
var p = e.Content as EventPage;
if (p != null)
{
p = p.CreateWritableClone() as EventPage;
p.EventDate = p.StartPublish.AddDays(10);
e.Content = p;
}
}
}
I'm new to Blackberry and I'm currently working on it. I have an ObjectChoiceField that uses a string array as its dataset. How can i update the display of the ObjectChoiceField list based on the change of array elements?
I want to do similar thing like notifyDataSetChanged() on Android development.
Update your ObjectChoiceField instance (let say myObjectChoiceField), via setChoices(String[] newChoices) method. Assume newChoicesStringArray is a String array with new option values.
Application.getApplication().invokeLater(new Runnable() {
public void run() {
myObjectChoiceField.setChoices(newChoicesStringArray);
}
});
invokeLater() is used to avoid UI event locking upong field update action.
I'm currently using a Gwt CellTable, bound to my GAE/Objectify backend via RPC calls.
All right now! :-)
Then I want to sort columns, so I read http://code.google.com/intl/it-IT/webtoolkit/doc/latest/DevGuideUiCellTable.html#columnSorting
The Async Remote sorting sections shows very well how to get sorting into my AsyncDataProvider but... how can I retrieve the name of the column the user wants to sort?
It shows this code: ColumnSortList sortList = table.getColumnSortList();
But how can I get String names from that? I simply want to know "surname" or "soldDate", the name of the field the column is bound to! Then I will pass it to my rpc service, and use it to sort data server-side query(...).order(<field_name>)
Am I missing something?
UPD: interesting stuff here: http://groups.google.com/group/google-web-toolkit/browse_thread/thread/77a0eaf8086218a6/effb8d3abe69270b#effb8d3abe69270b
You can keep a list of column names ordered as they are in the table:
List<String> columnNames = new ArrayList<String>();
table.addColumn(surnameColumn, "surname");
columnNames.add("surname");
// add the other columns
Then when you need to get the sort column name:
String sortColumnName;
ColumnSortList sortList = table.getColumnSortList();
if (sortList != null && sortList.size() != 0){
Column <MyEntity, ?> sortColumn = (Column <MyEntity, ?>)
sortList.get(0).getColumn();
Integer columnIndex = table.getColumnIndex(sortColumn);
sortColumnName = columnNames.get(columnIndex);
}
// do your rpc call
*where MyEntity is your data object displayed in the cell table.
A bit late to the party, but here's a more straight-forward solution based off of the current documentation (see section 'ColumnSorting with AsyncDataProvider').
When we're adding our columns we can simply set the dataStoreName:
TextColumn<MyData> surname = new TextColumn<MyData>() {
...
}
surname.setSortable(true);
surname.setDataStoreName("surname"); // Set the column name
table.getColumnSortList().push(surname);
table.addColumn(surname, "Last Name"); // eg. A different name for the UI
Then we can retrieve the column's dataStoreName later when sorting:
#Override
protected void onRangedChanged(HasData<MyData> display) {
...
ColumnSortList.ColumnSortInfo info = table.getColumnSortList().get(0);
String sortColumn = info.getColumn().getDataStoreName(); // Get the column name
boolean sortIsAscending = info.isAscending();
rpcService.requestMyData(
sortColumn,
sortIsAscending,
new AsyncCallback<ArrayList<MyData>>() {...}
);
...
}
Using this method we can pass the column name directly to our RPC method. It even allows us to use a different name (eg. the database column name) than the column name used on the UI/client side.
I have used something like this as an application column object.
public class ScrollTableColumn
{
// --------------------------------------------------------------- Field(s)
private int sequence;
private Column column;
private Header header;
private int size;
private int calculatedSize;
private boolean show;
private PartialColumn partialColumn;
private ColumnNameEnum columnName;
}
Now create a HashMap of the above as follows:
Map<Column, ScrollTableColumn> columnMap
= new HashMap<Column, ScrollTableColumn>();
Add all the columns as you create them both in the ScrollTableColumn and in the columnMap.
Finally you can get the required name as:
ColumnSortList sortList = dataTable.getColumnSortList();
Column<?, ?> column = sortList.get(0).getColumn();
ColumnNameEnum = columnMap.get(column);
String name = ColumnNameEnum.getName();
The proper way is to extend the base column class which will allow you to override cell rendering, pass in column configuration via your constructor, and most importantly set the DataStoreName which is where you should store the field name for the column. Lastly you should not reuse the onrangechanged fire, but access the columnsort handler directly by overriding it. on range change and column sort handler should call some type of method that you have to update your grid. I call mine updateGrid for sanity. This allows you to set any grid parameters used by your async request to specific sort column and direction. The main reason you want to use column sort handler is to access the ColumnSort event which contains your sort direction information
your column class that extends the base GWT column. You can also extend date or number columns too.
public GridStringColumn(String fieldName, String text, String tooltip, boolean defaultShown, boolean sortable, boolean hidden) {
super(new TextCell());
setDataStoreName(fieldName);
this.text_ = text;
this.tooltip_ = tooltip;
this.defaultShown_ = defaultShown;
setSortable(sortable);
this.hidden_ = hidden;
}
create your handler
dataGrid.addColumnSortHandler(new DataGridSortEvent());
your sort event class
protected class DataGridSortEvent implements ColumnSortEvent.Handler {
#Override
public void onColumnSort(ColumnSortEvent event) {
ColumnSortList sortList = dataGrid_.getColumnSortList();
if (sortList != null && sortList.size() > 0) {
Column<T, ?> sortColumn = (Column<T, ?>) sortList.get(0).getColumn();
LOG.info("col_sorta: " + event.isSortAscending());
LOG.info("col_index: " + sortColumn.getDataStoreName());
updateDataList();
}
}
}
updateDataList is your method you use to make the actual AJAX request to your server side. rather then logging you sould store this info in private members of your datagrid class so that your request can parameterize them.
you could also make this work for local caching too, just make a copy of the data from your server locally then return a sorted collection of that cached collection, rather then calling the updateDataList method.
Now you do not need to store a separate list for just string names, which is waste of memory not to mention a synchronicity issue if the column order is change from user interaction or whatever.
I want to show all fields of a certain ListItem. This includes LookUpFields and ChoiceFields. But I only seem to be able to show Textfields, like Title. How can I show all fields of my ListItem?
The problem is that I get an error when I try to show other fields of a listitem the way I got 'Title' to show, as if the strings I type in don't exist as fields in that listitem. But they do exist and are populated with values!
What is good way to show custom fields of a listitem without getting ObjectReference errors?
Also I get this error: The given key was not present in the dictionary.
private void foo()
{
using (ClientContext context = new ClientContext(ApplicationContext.Current.Url))
{
_list = context.Web.Lists.GetByTitle("MyList").Title);
_items = _list.GetItems(CamlQuery.CreateAllItemsQuery());
context.Load(_items);
context.ExecuteQueryAsync(
new ClientRequestSucceededEventHandler(OnListItemsRequestSucceeded),
new ClientRequestFailedEventHandler(OnListItemsRequestFailed));
}
}
private void OnListItemsRequestSucceeded(Object sender, ClientRequestSucceededEventArgs args)
{
// this is not called on the UI thread
Dispatcher.BeginInvoke(ShowListItemDetails);
}
public void ShowListItemDetails()
{
foreach (ListItem i in _items)
{
TextBox_Details.Text += i["Title"].ToString() + Environment.NewLine;
// Now the rest of the fields of this item.
}
}
Edit: What also is a big problem is I cant get the debugger working. This code is running as a Silverlight webpart on a local Sharepoint site. I attach the debugger to the iexplorer.exe but it won't break.
If I could get the debugger to work it would be a great help indeed.
you have tell the query what all fields you need to pull from lists
CamlQuery camlQuery = new CamlQuery();
camlQuery.ListItemCollectionPosition = itemPosition;
camlQuery.ViewXml =
#"<View>
<ViewFields>
<FieldRef Name='Title'/>
<FieldRef Name='Category'/>
<FieldRef Name='Estimate'/>
</ViewFields>
<RowLimit>10</RowLimit>
</View>";
ListItemCollection listItems = list.GetItems(camlQuery);
clientContext.Load(listItems);
clientContext.ExecuteQuery();
for more details
http://msdn.microsoft.com/en-us/library/ee857094.aspx#SP2010ClientOM_Accessing_Large_Lists
To get item properties you will need to specify all the item properties you need in the second parameter of the ClientContext.Load method
e.g
string server = "http://localhost";
ClientContext context = new ClientContext(server);
Web web = context.Web;
var spList = web.Lists.GetByTitle("MyTitle");
CamlQuery query = new CamlQuery();
var items = spList.GetItems(query);
context.Load(items,
itema => itema.Include(
item => item,
item => item["ComplexProperty"]));
context.ExecuteQuery();`