Is there a way to get a s:List to display it's items in reverse order? Not having to make a copy of the dataProvider would be ideal. Thanks.
You can set a Sort on your dataProvider (assuming it implements ICollectionView, like an ArrayCollection for example) and call the Sort.reverse() method. Hope that helps.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/collections/Sort.html
The s:List control does not have the option to show items in reverse order.
All is controlled by manipulating the dataProvider or the "source" of the dataProvide.
Here is how you could achieve this
public function showReverseList(data:Array):void
{
var reverseList:Array;
var i,count = data.length;
for(i = count-1 ; i >= 0 ; i--)
{
// add items in reverse order
reverseList.push(data[i]);
}
myListControl.dataProvider = reverseList;
}
This does the job for me
if (list && list.dataProvider)
{
list.dataProvider = new ArrayCollection((list.dataProvider as ArrayCollection).toArray().reverse());
}
Related
This is the point.
I've followed the suggest linked here More efficient way to append a list item after some text in Google Docs ,whose very helpfull tom me. But i have the problem mentioned at the bottom.
My placeholder is inside a known table within a google doc.
I've tried several ways to figure it out, but i didn't achieve.
Here below there is the portion of code of interest.
Note:
"CarattCentralGas1" is an array of values;
"DescrizioneCentralGas" is another array of values;
My intent is to insert a list, created if the if condition is true, at the placeholder place and than remove it.
Any ideas would be great!`
for (var i=0; i < CarattCentraleGas1.length; ++i)
{ var ValueToTest = CarattCentraleGas1[i][0];
Logger.log(ValueToTest)
if (ValueToTest ==='Presente')
{ var valueToextract = DescrizioniCentraleGas[i][0];
var search = '%Placeholder%';
var Table1 = body.getTables()[0];
var found = Table1.findText(search);
while (found) {
var elem = found.getElement().getParent().getParent();
var index = Table1.getChildIndex(elem);
Table1.insertListItem(index+1, valueToextract+';');
found = Table1.findText(search, found);}
Logger.log(valueToextract)}
}
var Table1Text = Table1.editAsText().replaceText('%CarattCentrale1%',"");
`
this is the template document I want to edit with the script.
I'm trying to add an element list to the list of string, but I found Kotlin does not have an add function like java so please help me out how to add the items to the list.
class RetrofitKotlin : AppCompatActivity() {
var listofVechile:List<Message>?=null
var listofVechileName:List<String>?=null
var listview:ListView?=null
var progressBar:ProgressBar?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_retrofit_kotlin)
listview=findViewById<ListView>(R.id.mlist)
var apiInterfacee=ApiClass.client.create(ApiInterfacee::class.java)
val call=apiInterfacee.getTaxiType()
call.enqueue(object : Callback<TaxiTypeResponse> {
override fun onResponse(call: Call<TaxiTypeResponse>, response: Response<TaxiTypeResponse>) {
listofVechile=response.body()?.message!!
println("Sixze is here listofVechile ${listofVechile!!.size}")
if (listofVechile!=null) {
for (i in 0..listofVechile!!.size-1) {
//how to add the name only listofVechileName list
}
}
//println("Sixze is here ${listofVechileName!!.size}")
val arrayadapter=ArrayAdapter<String>(this#RetrofitKotlin,android.R.layout.simple_expandable_list_item_1,listofVechileName)
listview!!.adapter=arrayadapter
}
override fun onFailure(call: Call<TaxiTypeResponse>, t: Throwable) {
}
})
}
}
A more idiomatic approach would be to use MutableList instead of specifically ArrayList. You can declare:
val listOfVehicleNames: MutableList<String> = mutableListOf()
And add to it that way. Alternatively, you may wish to prefer immutability, and declare it as:
var listOfVehicleNames: List<String> = emptyList()
And in your completion block, simply reassign it:
listOfVehicleNames = response.body()?.message()?.orEmpty()
.map { it.name() /* assumes name() function exists */ }
Talking about an idiomatic approach... 🙄
When you can get away with only using immutable lists (which means usually in Kotlin), simply use + or plus. It returns a new list
with all elements of the original list plus the newly added one:
val original = listOf("orange", "apple")
val modified = original + "lemon" // [orange, apple, lemon]
original.plus("lemon") yields the same result as original + "lemon". Slightly more verbose but might come in handy when combining several collection operations:
return getFruit()
.plus("lemon")
.distinct()
Besides adding a single element, you can use plus to concatenate a whole collection too:
val original = listOf("orange", "apple")
val other = listOf("banana", "strawberry")
val newList = original + other // [orange, apple, banana, strawberry]
Disclaimer: this doesn't directly answer OP's question, but I feel that in a question titled "How to add an item to a list in Kotlin?", which is a top Google hit for this topic, plus must be mentioned.
If you don't want or can't use array list directly use this code for add item
itemsList.toMutableList().add(item)
itemlist : list of your items
item : item you want to add
instead of using a regular list which is immutable just use an arrayListof which is mutable
so your regular list will become
var listofVehicleNames = arrayListOf("list items here")
then you can use the add function
listOfVehicleNames.add("what you want to add")
you should use a MutableList like ArrayList
var listofVechileName:List<String>?=null
becomes
var listofVechileName:ArrayList<String>?=null
and with that you can use the method add
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list/add.html
For any specific class, the following may help
var newSearchData = List<FIRListValuesFromServer>()
for (i in 0 until this.singleton.firListFromServer.size) {
if (searchText.equals(this.singleton.firListFromServer.get(i).FIR_SRNO)) {
newSearchData.toMutableList().add(this.singleton.firListFromServer.get(i))
}
}
val listofVechile = mutableListOf<String>()
Declare mutable list like that and you will be able to add elements to list :
listofVechile.add("car")
https://kotlinlang.org/docs/collections-overview.html
It made more sense in a particular case today to use a standard for (i = 0.. loop rather than a forEach, but I realised I don't know how to access objects of an Ember Array by number.
So lets say we have:
var order = this.get('order');
var orderItems = order.get('orderItems');
orderItems.forEach(function(orderItem) {
orderItem.set('price', 1000);
});
I thought I could do the equivalent as:
var order = this.get('order');
var orderItems = order.get('orderItems');
for (i = 0; i < orderItems.get('length'); i++) {
orderItems[i].set('price', 1000);
}
but I get orderItems[0] is undefined etc.
How do I access the nth element in an ember array in js?
Ember.js Array provides a objectAt method for accessing the nth element, which you can use for iteration.
Your updated code would look like :
var order = this.get('order');
var orderItems = order.get('orderItems');
for (i = 0; i < orderItems.get('length'); i++) {
orderItems.objectAt(i).set('price', 1000);
}
Check out it's documentation here: http://emberjs.com/api/classes/Ember.Array.html#method_objectAt
When I have an array of Sitecore IDs, for example TargetIDs from a MultilistField, how can I query the ContentSearchManager to return all the SearchResultItem objects?
I have tried the following which gives an "Only constant arguments is supported." error.
using (var s = Sitecore.ContentSearch.ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
rpt.DataSource = s.GetQueryable<SearchResultItem>().Where(x => f.TargetIDs.Contains(x.ItemId));
rpt.DataBind();
}
I suppose I could build up the Linq query manually with multiple OR queries. Is there a way I can use Sitecore.ContentSearch.Utilities.LinqHelper to build the query for me?
Assuming I got this technique to work, is it worth using it for only, say, 10 items? I'm just starting my first Sitecore 7 project and I have it in mind that I want to use the index as much as possible.
Finally, does the Page Editor support editing fields somehow with a SearchResultItem as the source?
Update 1
I wrote this function which utilises the predicate builder as dunston suggests. I don't know yet if this is actually worth using (instead of Items).
public static List<T> GetSearchResultItemsByIDs<T>(ID[] ids, bool mustHaveUrl = true)
where T : Sitecore.ContentSearch.SearchTypes.SearchResultItem, new()
{
Assert.IsNotNull(ids, "ids");
if (!ids.Any())
{
return new List<T>();
}
using (var s = Sitecore.ContentSearch.ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
var predicate = PredicateBuilder.True<T>();
predicate = ids.Aggregate(predicate, (current, id) => current.Or(p => p.ItemId == id));
var results = s.GetQueryable<T>().Where(predicate).ToDictionary(x => x.ItemId);
var query = from id in ids
let item = results.ContainsKey(id) ? results[id] : null
where item != null && (!mustHaveUrl || item.Url != null)
select item;
return query.ToList();
}
}
It forces the results to be in the same order as supplied in the IDs array, which in my case is important. (If anybody knows a better way of doing this, would love to know).
It also, by default, ensures that the Item has a URL.
My main code then becomes:
var f = (Sitecore.Data.Fields.MultilistField) rootItem.Fields["Main navigation links"];
rpt.DataSource = ContentSearchHelper.GetSearchResultItemsByIDs<SearchResultItem>(f.TargetIDs);
rpt.DataBind();
I'm still curious how the Page Editor copes with SearchResultItem or POCOs in general (my second question), am going to continue researching that now.
Thanks for reading,
Steve
You need to use the predicate builder to create multiple OR queries, or AND queries.
The code below should work.
using (var s = Sitecore.ContentSearch.ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
var predicate = PredicateBuilder.True<SearchResultItem>();
foreach (var targetId in f.Targetids)
{
var tempTargetId = targetId;
predicate = predicate.Or(x => x.ItemId == tempTargetId)
}
rpt.DataSource = s.GetQueryable<SearchResultItem>().Where(predicate);
rpt.DataBind();
}
So, I am setting the DataSource of my BindingSource to the DefaultViewManager of a DataSet that has a DataRelation. I then set my BindingSource as the UltraGrid's DataSource before applying a RowFilter to the the "SalesOrderSublines" DataView.
public void RefreshData()
{
var dataset = DataService.GetMillWorkOrders()
bindingSource1.DataSource = dataset.DefaultViewManager;
ultraGridSequences.SetDataBinding(bindingSource1, "", true, true);
var dvm = bindingSource1.DataSource as DataViewManager;
dvm.DataViewSettings["SalesOrderSublines"].RowFilter = "LINE_NO = 2;
}
public static DataSet GetMillWorkOrders()
{
DataSet ds = OracleHelper.ExecuteDataset(_connectionString, CommandType.StoredProcedure, SQL.GET_WORK_ORDERS);
ds.Tables[0].TableName = "WorkOrders";
ds.Tables[1].TableName = "SalesOrderSublines";
var dr = new DataRelation("WorkOrderSublines", ds.Tables["WorkOrders"].Columns["WORK_ORDER"], ds.Tables["SalesOrderSublines"].Columns["WORK_ORDER"]);
ds.Relations.Add(dr);
return ds;
}
Then, as the UltraGridRows are initializing I want to hide any parent row ("WorkOrders") that has no visible child rows ("WorkOrderSublines") because of my RowFilter.
private void ultraGridSequences_InitializeRow(object sender, Infragistics.Win.UltraWinGrid.InitializeRowEventArgs e)
{
if (e.Row.Band.Key != "WorkOrders") return;
e.Row.Hidden = e.Row.ChildBands["WorkOrderSublines"].Rows.VisibleRowCount == 0;
}
Although the RowFilter does work properly on the rows in the "WorkOrderSublines" band the VisibleRowCount of the band is still greater than zero and so the parent row is never hidden. My guess is that I want to look for something other than the VisibleRowCount of the ChildBand to determine if the top-level row should be hidden, but I'm stuck. Any help would be greatly appreciated. Thanks ahead of time.
Instead of relying on VisibleRowCount you could simply compare the count of child row filtered vs total count.
void ultraGridSequences_InitializeRow(object sender, Infragistics.Win.UltraWinGrid.InitializeRowEventArgs e)
{
if (e.Row.Band.Key != "WorkOrders") return;
var sublinesBand = e.Row.ChildBands["WorkOrderSublines"]
e.Row.Hidden = sublinesBand.Rows.Count(row => row.IsFilteredOut) ==
sublinesBand.Rows.Count();
}
Should be fine performance-wise so long as we're not talking huge amounts of records?
Using the Filtering within the Grid may be an option rather than using the filtering in the DataSource. The following resources have more details on implementing this:
http://forums.infragistics.com/forums/t/51892.aspx
http://devcenter.infragistics.com/Support/KnowledgeBaseArticle.aspx?ArticleID=7703