I've got a spark list that is part of a CallOutContent, much like this:
<s:CalloutButton id="frequencyChanger" label="{frequencyChangeList.selectedItem.label}">
<s:calloutContent>
<s:BorderContainer>
<s:layout>
<s:VerticalLayout/>
</s:layout>
<s:List id="frequencyChangeList" dataProvider="{Util.getFrequencyList()}" selectedIndex="8" requireSelection="false" changing="frequencyList_changingEvent(event)"/>
</s:BorderContainer>
</s:calloutContent>
</s:CalloutButton>
The dataProvider is an ArrayList with several items of the following structure:
public class ListItem
{
public var label:String;
public var item:Object;
public function PeriodFrequencyListItem(label:String, item:Object) {
this.label=label;
this.item=item;
}
}
The item Object is an Enum.
Background for this is to match the Enum to the corresponding label to be displayed in the List. I would have used a dictionary, but Lists don't work this those (unfortunately).
Anyhow, in the IndexChangeEvent method I can set the selectedItem to the one currently selected:
frequencyChangeList.selectedItem = event.currentTarget.selectedItem;
What I can't do (but desperately need in another part of the class) is to set the selectedItem of the List outside of the IndexChangeEvent method.
Any attempt to set an item with something like the following failed, throwing a null pointer exception.
frequencyChangeList.selectedItem = someListItemObject;
I can set the labels of the CallOutButtons, naturally, that doesn't change the selection of the List.
So, where is the trick to select an item in the list outside of its own 'changing' method?
Any help would be much appreciated.
Cheers!
Have you tried doing this:
myList.selectedIndex = indexOfArray;
see here:
How do I make sure that there is always something selected in a Spark List?
Related
Why does
val fabOpen = view.findViewById(R.id.fab_open) as FloatingActionButton
work correctly and not error out but the kotlin synthetic of
val fabOpen = R.id.fab_open as FloatingActionButton
gives me the
java.lang.Integer cannot be cast to android.support.design.widget.FloatingActionButton
error? They both show that they are casting as FloatingActionButton. Using the synthetics is not only less code, it's better memory management and I'd prefer to do it this way. Is there something I am missing?
****Update**** I forgot to mention I am trying access the FloatingActionButton inside of a fragment if that makes a difference.
R.id.fab_open is a generated integer value that will be set as the ID of your button at inflation, and that you can look up with findViewById like you've shown.
Casting this to a button won't work, think (FloatingActionButton) 2688664731 in Java terms.
If you wish to use Kotlin Android Extensions and its synthetic properties, those are simply named as the ID itself, but they don't come from the R class - and you don't need to assign them to variables or properties. You can simply use your button like this:
fab_open.setOnClickListener { ... }
fab_open.visibility = View.VISIBLE
I figured out the issue.
to access an element in a view using kotlin synthetic it looks like this:
import kotlinx.android.synthetic.main.chatter_main.view.*
class ChatterMain : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.chatter_main, container, false)
return view
}
Above I imported the kotlin synthetic of the view, inflated the view, and
then I accessed the ID of the element like this:
view.fab_open.visibility = GONE or view.fab_open.SetOnClickListener {}
With the Kotlin Synthetic, you don't need to use:
val fabOpen = R.id.fab_open as FloatingActionButton so I removed that statement.
I am currently trying to implement an ember-drag-sort nested list into my Ember.js app.
Is there a way to determine in the dragEnd action which "sub-list" the item has been dropped into? (e.g. a class name, id etc)
In my scenario, I am sorting ember data records that can belong to each other (i.e. a nested, 'tree' structure). When I drag one nested record "into" another (making the dragged record a child of the second record), I need to update the parent attribute in ember-data. My question is, how do you pass some id of the second record (the new parent) to the dragEnd action?
Is this even possible?
EDIT:
To put it another way, I want to be able to identify which list I have dropped the item into.
targetList refers to the array on the dragged side of the component. For pushing the parent to the target list alongside the child, you can take a look at this twiddle.
To simplify identification of lists, the additional arguments feature has been implemented by #rwwagner90 (SO, GitHub).
You can pass some kind of list identifier into the additionalArgs argument to your lists. In this example I'm passing parent records which own the lists:
{{#each parents as |parent|}}
{{#drag-sort-list
items = parent.children
additionalArgs = (hash parent=parent)
dragEndAction = (action 'dragEnd')
as |child|
}}
{{child.name}}
{{/drag-sort-list}}
{{/each}}
In the dragEnd action you can access the parent records that own the source list and the target list:
dragEndAction({ sourceList, sourceIndex, sourceArgs, targetList, targetIndex, targetArgs }) {
if (sourceModel === targetModel && sourceIndex === targetIndex) return;
const item = sourceList.objectAt(sourceIndex);
sourceList.removeAt(sourceIndex);
targetList.insertAt(targetIndex, item);
// Access the parent via `sourceArgs` and `targetArgs`
sourceArgs.parent.save();
targetArgs.parent.save();
}
I am trying to display a small set of hierarchical data and have found the AdvancedDataGrid so terrible in how it handles layout I am going to try and approach it another way using Spark Lists.
I am getting from a MySQL database an ArrayCollection of Lessons. Each Lesson has a parent Topic (I have included a TopicName field within each Lesson for ease) and I want to display the Lessons after grouping them by their respective Topics.
I could create a hierarchical data structure, possibly by using a GroupingCollection2, and wondered if I could display a Spark List of Topics and within the topicItemRenderer I create display a Spark List of Lessons for the given Topic?
Any thoughts very welcome.
Chris
To create a grouped list of data I replaced my AdvancedDataGrid with a Spark List within a Spark List. It now has a layout which is predictable and sizes properly. In my case I know that I only have to display approximately 20 items in my grouped List so I don't really have any performance issues.
This is how I did it:
General -
I created a new mxml component dedicated to the list of Lessons. I organise my code following a Model, View, Presenter pattern so I created LessonList_View (mxml) and LessonList_Presenter (ActionScript class). I have a Model class (Singleton) which the presenter classes instantiate to put/get data. The Model raises events when properties change informing the presenters, who have eventListeners, of the change so that they can update their local properties of which the views are bound. The Model calls PHP methods in a Amfphp Service to acquire data from the MySQL database.
Prepare Data -
I have a relational MySQL database containing a table of Lessons and a table of Topics. Each Lesson has to have one parent Topic. A Topic will have many Lessons. I am using Amfphp to get a subset of Lessons data. Each Lesson row from the database is mapped to a Flex class giving me an ArrayCollection of strongly typed value objects of Type VoLesson. To make life simpler I included the topicName field in my VoLesson ActionScript class, only the topicId is available within the MySQL table, and included this in my SELECT statement when getting the data. I also sort the data by Topic and then by Lesson here so its ready for the next step.
Next I need to create an Array Collection containing ArrayCollections of Lessons of the same Topic. This way, I figured, I can have a parent Spark List displaying Topics and within the ItemRenderer for each Topic List Item I can have a List of Lessons.
Once my LessonList_Presenter has got an ArrayCollection of VoLessons I iterate through it. A new, temporary, ArrayCollection of Lessons (_topicLessons) is populated with Lessons until the topicName changes whereupon I add the current _topicLessons ArrayCollection of VoLessons into a parent ArrayCollection (courseTopicLessons).
The function is as follows:
private function updateCourseTopicLessons():void {
// Reset courseTopicLessons.
this.courseTopicLessons = new ArrayCollection();
// Create a variable to hold the last topicName.
var _topicName:String = "";
// Create an ArrayCollection to hold all of the Lessons for a single Topic.
var _topicLessons:ArrayCollection = new ArrayCollection();
// Iterate through the courseLessons.
for each(var _lesson:VoLesson in this.courseLessons)
{
// check to see if this lesson has a different topicName.
if (_lesson.topicName != _topicName) {
//trace("Different Topic: " + _lesson.topicName);
// Add the previous _topicLessons into the courseTopicLessons ArrayCollection.
if (_topicLessons.length > 0) {
//trace("Adding _topicLessons " + _topicLessons.length + " to courseTopicLessons");
this.courseTopicLessons.addItemAt(_topicLessons, 0)
}
// This is a new Topic. Reset _topicLessons.
//trace("Reset _topicLessons");
_topicLessons = new ArrayCollection();
// Update _topicName.
_topicName = _lesson.topicName;
}
// Add the Lesson to _topicLessons.
//trace("Add Lesson: " + _lesson.lessonTitle + " to _topicLessons")
_topicLessons.addItemAt(_lesson, 0);
}
// Add the previous _topicLessons into the courseTopicLessons ArrayCollection.
if (_topicLessons.length > 0) {
//trace("Adding final _topicLessons " + _topicLessons.length + " to courseTopicLessons")
this.courseTopicLessons.addItemAt(_topicLessons, 0)
}
//trace(this.courseTopicLessons)
}
I used .addItemAt() to keep the sort order correct.
Views and ItemRenderers -
In my LessonList_View I created the List and set it as follows:
<!-- Lessons List -->
<s:List
id="lessonList"
dataProvider="{presenter.courseTopicLessons}"
itemRenderer="views.LessonListTopicItemRenderer_View"
borderVisible="false"
borderColor="0xff69b4"
preventSelection="true"
contentBackgroundAlpha="0">
<s:layout>
<s:VerticalLayout
useVirtualLayout="false"
requestedMinRowCount="1"
gap="8"
paddingTop="8" paddingBottom="8"/>
</s:layout>
</s:List>
I used the borders when checking everything to see the extents of the Lists.
My data provider is an ArrayCollection of ArrayCollections. I want to display List of Topics and within each Topic List Item I want to display a List of Lessons. To display the Topics I know that each ArrayCollection within the parent ArrayCollection will have at least 1 VoLesson (I hope you're following this!). I can display the topicName value from this item. Here is my code for the Lesson List's ItemRenderer:
<s:ItemRenderer
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:presenters="presenters.*"
width="100%" height="100%"
autoDrawBackground="false">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<presenters:LessonListTopicItemRenderer_Presenter id="presenter"/>
</fx:Declarations>
<fx:Script>
<![CDATA[
import models.Globals;
import vo.VoLesson;
override public function set data( value:Object ) : void {
super.data = value;
// Check to see if the data property is null.
if (value== null)
return;
// If the data property is not null.
var _lesson:VoLesson = VoLesson(value[0]);
topicLabel.text = _lesson.topicName;
}
]]>
</fx:Script>
<s:VGroup gap="8" width="100%">
<!-- Divider line between Topics -->
<s:Line id="topicDividerLine" width="100%">
<s:stroke>
<s:SolidColorStroke color="{presenter.selectedActivityColour_Mid}" weight="1" />
</s:stroke>
</s:Line>
<!-- Topic Label -->
<s:Label
id="topicLabel"
styleName="topicStyle"
color="{presenter.selectedActivityColour}"
maxWidth="{presenter.lessonsListTopicColumnWidth}" />
<s:HGroup paddingLeft="{Globals.LESSONS_LIST_TOPIC_COLUMN_WIDTH}">
<s:List
id="lessonList"
dataProvider="{data}"
borderColor="0xadff2f"
itemRenderer="views.LessonListLessonItemRenderer_View"
borderVisible="false"
preventSelection="true">
<s:layout>
<s:VerticalLayout
useVirtualLayout="false"
requestedMinRowCount="1"
gap="16"
paddingTop="8" paddingBottom="8"/>
</s:layout>
</s:List>
</s:HGroup>
</s:VGroup>
The key thing to remember is that the ItemRenderer will be passed only the data for an individual item in the List, in this case an ArrayCollection of VoLesson objects. Within the element I get the topicName for the first item in the ArrayCollection of VoLessons passed in as 'data' and set my Label's text property.
Below the Topic Label I have my List of Lessons which has the same data provider, an ArrayCollection of VoLesson objects for the same Topic. The ItemRenderer for this List is as follows:
<s:ItemRenderer
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:views="views.*"
xmlns:presenters="presenters.*"
height="100%"
autoDrawBackground="false">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<presenters:LessonListLessonItemRenderer_Presenter id="presenter"/>
</fx:Declarations>
<fx:Script>
<![CDATA[
import vo.VoLesson;
override public function set data( value:Object ) : void {
super.data = value;
// Check to see if the data property is null.
if (value== null)
return;
// If the data property is not null.
var _lesson:VoLesson = VoLesson(value);
lessonLabel.text = _lesson.lessonTitle;
}
]]>
</fx:Script>
<s:HGroup gap="8" verticalAlign="middle">
<views:IconLesson_View />
<s:Label
id="lessonLabel"
styleName="lessonStyle"
color="{presenter.textDarkGrey}"/>
</s:HGroup>
Remember that the 'data' object for this ItemRenderer, and there will be one for each item in the List of Lessons, will be a single VoLesson object. In the element I get the lessonTitle property from the VoLesson and set the lessonLabel Label's text property.
Final List
The List appears as follows:
I have spent many days trying to coerce an AdvancedDataGrid to size itself and layout the content properly, it was dreadful. Yesterday I decided to start again and this works so much better. For a simple grouped list I would recommend a similar approach.
Regards
Chris
You could do it that way and it would work, But its not a good idea if you have a lot data. You would have to worry about item renderers. I would probably use a tree and create custom item renderers if need be. May be some code might help.
How can we get the no of list items in bad-forward list of UIWebView? What I wanted to do is when back list is empty (ie. when there is no link to go back) navigate to previous controller. So wanted to know the count in the list.
Thanks in advance
Sayali
you dont want to access backforward list just for that, simply use .canGoBack property.
Here is the way to do it anyways (be carefull, private API here) :
id webview111 = [self _documentView]; /// self - uiwebview subclass
coreWebV = [webview111 webView];
backForwardList = [coreWebV backForwardList];
i want to generate a list of data out of a store. each data item holds a title and a boolean. now i want to have a list of the items, each holding the title and a togglefield (showing the boolean) on the right of the title.
how could I do that?
thnx!
From the Sencha Touch documentation, a List is "a mechanism for displaying data using a list layout template", i.e. html template. If you want a 'list' of components, you'll have to make your own extension of DataView (I think).
A workaround could be to put an html checkbox inside your itemTpl.
Something like (warning - not tested):
itemTpl: '<p>{title}: <input type="checkbox" name="BoolCheckbox" class="boolcheckbox"'
+ "{[(values.bool? 'checked="checked"' : '')]}"
+ '></input></p>'
To run your own code in the XTemplate, you bracket it with {[]}. When in this scope, you have access to a variable 'values', which contains the data for the record.
To detect events, you'd add a listener to the list:
itemtap: function (dataView, index, item, e) {
if (e.getTarget().getClass().toString() == "boolcheckbox") {
// do something
}
}
Some resources on templates:
http://dev.sencha.com/deploy/touch/docs/
http://www.sencha.com/learn/xtemplates-part-i/
http://www.sencha.com/learn/xtemplates-part-ii/