javascriptappceleratorappcelerator-titaniumappcelerator-mobileappcelerator-alloy

Incorrect Data Being Retrieved on ListView Click in Titanium


I'm using a database within my Titanium app to pull data, and in turn loop through display the section headers, then content within each section.

All works great, with the exception of when I tap on any of the first 7 sections, they all return the last section details when I tap the listitem.

Pretty sure this is a simple fix where I'm passing the args across, but I'm struggling to get this working correctly!

Here is my Controller

var args = $.args;

// Here we need to get the courseID and then return the correct sessions for that course
var courseID = args.courseID;
$.courseDetailWindow.title = args.courseTitle.text.toUpperCase();


// open the DB
var db = Ti.Database.open('myDB');

// set the ListSections outside of the loop
var sections = [];

// do the loop of sessions for this course
var sessionRS = db.execute('SELECT session_id, session_name, session_intro, session_course_id FROM sessions WHERE session_course_id = ' + courseID);

while (sessionRS.isValidRow()) {

  var sessionName = sessionRS.fieldByName('session_name');
  var sessionID = sessionRS.fieldByName('session_id');

  // create the List Section
  var listSection = Ti.UI.createListSection({ headerTitle: sessionName});

  // create the data set of drills
  var drillDataSet = [];

  // do the loop of drills for this session
  var drillRS = db.execute('SELECT drill_id, drill_name, drill_intro, drill_instructions, drill_video, drill_duration FROM drills WHERE session_id = ' + sessionID);

  while (drillRS.isValidRow()) {

    var drillName = drillRS.fieldByName('drill_name');
    var drillDuration = drillRS.fieldByName('drill_duration');
    var drillVideo = drillRS.fieldByName('drill_video');
    var drillIntro = drillRS.fieldByName('drill_intro');
    var drillInstructions = drillRS.fieldByName('drill_instructions');

    // push the drill data into the array
    drillDataSet.push({
        template : "drillTemplate",
        drillName : { text : drillName },
        drillDuration : { text  : "Drill - " + drillDuration },
        drillInstructions : { text  : drillInstructions },
        drillIntro : { text  : drillIntro },
        drillIcon : { image  : "images/control-cat-icon.png" },
        drillVideo : { url : drillVideo}
    });

    // assign those drills to the session
    listSection.setItems(drillDataSet);

    // move onto the next drill
    drillRS.next();

  }

  // close the drill DB connection
  drillRS.close();

  // add the session name and drills to the section
  sections.push(listSection);

  // move onto the next session
  sessionRS.next();

}

// close the session DB connection
sessionRS.close();

// Push all of the content to the main ListView
$.courseDetailView.sections = sections;

// Handle the List Row Tap
function openDrillDetail(e) {
    var drillDetailWindow = Alloy.createController('/drillDetail', drillDataSet[e.itemIndex]).getView();

    if (OS_IOS) {
        Alloy.Globals.tabGroup.activeTab.open(drillDetailWindow);
    }

    if (OS_ANDROID) {
        drillDetailWindow.open();
    }
}

The issue would be within the drillDataSet, and it's index. I'm assuming it's returning the last section as I'm essentially overwriting it within each loop. But I'm stuck!

I need the OpenDrillDetail() function to send the correct args across to the next screen.

Here is my XML.

<Alloy>
    <Window id="courseDetailWindow">
      <ScrollView id="courseDetailScrollView">
        <ListView id="courseDetailView" defaultItemTemplate="drillTemplate" onItemclick="openDrillDetail" height="Ti.UI.SIZE">
            <Templates>
                <ItemTemplate name="drillTemplate" id="drillTemplate">
                    <View id="drillOuterView">
                      <View id="greenBlock">
                        <ImageView bindId="drillIcon" id="drillIcon" />
                      </View>
                      <Label bindId="drillName" id="drillName" />
                      <Label bindId="drillDuration" id="drillDuration" />
                    </View>
                </ItemTemplate>
            </Templates>
            <!--<HeaderView id="sessionView">
                <View height="Ti.UI.SIZE" layout="vertical">
                    <Label id="sessionTitle" text="Session 1"></Label>
                </View>>
            </HeaderView>-->
            <ListSection id="drillSection">
                <ListItem template="drillTemplate" id="drillView"/>
            </ListSection>
        </ListView>
      </ScrollView>
    </Window>
</Alloy>

Solution

  • I've rebuild the parts with arrays and it works fine. Two things I've did:

    var sections = [];
    var drillDataSet = [];
    var outer = ["sect", "sect1", "sect2"];
    var counter = 0; 
    
    for (var i = 0; i < outer.length; ++i) {
        var listSection = Ti.UI.createListSection({
            headerTitle: outer[i]
        });
    
        var innerPart = ["test", "test2", "test3", "test4"];
        for (var j = 0; j < innerPart.length; ++j) {
    
            var drillName = innerPart[j];
            drillDataSet.push({
                template: "drillTemplate",
                drillName: {
                    text: drillName + ": " +counter
                }
            });
            listSection.setItems(drillDataSet);
            counter++;
        }
    
        sections.push(listSection);
    }
    
    $.courseDetailView.sections = sections;
    
    function openDrillDetail(e) {
        console.log(e.section.getItemAt(e.itemIndex));
    }