21
votes

I have developed one application based a below tree structure:

Default :

  • Category
  • Category
  • Category

While clicking the category :

  • Category
    • Sub Category
      • Product
  • Category

  • Category

Some times:

  • Category

  • Category

    • Product
  • Category

Here i have to implement this concept using the tableview.

Yes i have created the tableview and then i have created the tableviewsection .i have added the categories in the tableviewsection.i have created the tableviewrow within the tableviewsection. If i have clicking the selected category, i have added the subcategory values in these tableviewrow. But some category having the subcategory ... some of the category doesnot have the subcategory.straightly having the products.So can you please explain me

EDIT:

i have follows below code :

    // create menu view
var data = [];

var v1 = Ti.UI.createView({
  height: '100%',
  width: '320dp',
  left: '0%',
  backgroundColor: '#212429'
});

$.drawermenu.drawermenuview.add(v1);

var tableView = Ti.UI.createTableView({
  height: '100%',
  width: '100%',
  separatorColor: '#111214',
  allowsSelection: true,
  style: Ti.UI.iPhone.TableViewStyle.GROUPED
});
v1.add(tableView);

var dataArray = [];
getCategoryList();

function getCategoryList() {
  var sendit = Ti.Network.createHTTPClient({
    onerror: function(e) {
      Ti.API.debug(e.error);
      alert('There was an error during the connection');
    },
    timeout: 10000,
  });
  sendit.open('GET', url + 'android_livedev/client/xxx.php?action=allCategory&category=all');
  sendit.send();
  sendit.onload = function() {
    var response = JSON.parse(this.responseText);
    if (response[0].success == 0) {
      tableView.headerTitle = response[0].message;
    } else {
      tableView.headerTitle = "";
      dataArray = [];
      for (var i = 0; i < response[0].data.length; i++) {
        var customsection = Ti.UI.createView({
          width: Ti.UI.FILL,
          height: Ti.UI.SIZE,
          opened: true,
          id: i,
          categorylist_category_id: response[0].data[i].categoryid,
          categorylist_level: response[0].data[i].category_level,
          backgroundcolor: '#fff',
          length: response[0].data.length,
        });

        var text = Ti.UI.createLabel({
          text: response[0].data[i].category,
          left: 20,
          id: i,
          categorylist_category_id: response[0].data[i].categoryid,
          categorylist_level: response[0].data[i].category_level,
          color: '#000'
        });
        customsection.add(text);

        row = Ti.UI.createTableViewSection({
          headerView: customsection,
        });
        dataArray.push(row);
        customsection.addEventListener('click', function(e) {
          categorylist_category_id = e.source.categorylist_category_id;
          categorylist_level = e.source.categorylist_level;
          categorylist_id = e.source.id;
          if (categorylist_level == "Y") {
            var subcategory = [];
            for (j = 0; j < response[0].data[categorylist_id].subcategorymm.length; j++) {
              var subcategory = Ti.UI.createTableViewRow({
                subcategorylist_category_id: response[0].data[categorylist_id].subcategorymm[j].categoryid,
                layout: 'horizontal',
                top: 5,
                width: "100%",
                backgroundcolor: '#000',
                height: Ti.UI.SIZE,
              });

              var subcategorytext = Ti.UI.createLabel({
                text: response[0].data[categorylist_id].subcategorymm[j].category,
                top: 5,
                width: Ti.UI.FILL,
                font: {
                  fontSize: '18dp'
                },
                color: '#040404',
                wordWrap: true,
                height: Ti.UI.SIZE,
                ellipsize: true
              });
              subcategory.add(subcategorytext);

            };

            row.add(subcategory);


          } else {
            from = "Product";
            var product = Alloy.createController('product').getView();
            product.open();
          }
        });
      };
      tableView.setData(dataArray);
    };
  };


}

var top10Screen = Alloy.createController('top10Screen').getView();
$.drawermenu.drawermainview.add(top10Screen);

Ti.App.addEventListener('settingImg', function(data) {
  $.drawermenu.showhidemenu();
});

$.sample.open();

EDIT:

here the alloy code is given:

sample.xml :

<Alloy>
    <Window class="container">
        <Require type="widget" src="com.drawermenu.widget" id="drawermenu"/>

    </Window>
</Alloy>

i have to open the categories on the slider menu.so that i have using these widget. if i have clicking the categories on the slider menu, need to show the subcategory on the slider menu.this is exact my scope.

this is exactly my json :

[
{
    "message": "Category list found",
    "data": [
        {
            "categoryid": "335",
            "parentid": "0",
            "category": "New In",
            "description": "",
            "meta_description": "",
            "avail": "Y",
            "order_by": "0",
            "product_count": "2",
            "top_product_count": "1",
            "meta_keywords": "",
            "override_child_meta": "N",
            "title_tag": "",
            "lpos": "1",
            "rpos": "4",
            "category_level": "Y",
            "new_category_images": "https://dev101.example.com/xxx/images/C/newin.png",
            "subcategorymm": [
                {
                    "categoryid": "344",
                    "parentid": "335",
                    "category": "subcategory-newin",
                    "description": "",
                    "meta_description": "",
                    "avail": "Y",
                    "order_by": "0",
                    "product_count": "1",
                    "top_product_count": "1",
                    "meta_keywords": "",
                    "override_child_meta": "N",
                    "title_tag": "",
                    "lpos": "2",
                    "rpos": "3",
                    "category_level": "N"
                }
            ]
        },
        {
            "categoryid": "336",
            "parentid": "0",
            "category": "Women's",
            "description": "",
            "meta_description": "",
            "avail": "Y",
            "order_by": "1",
            "product_count": "2",
            "top_product_count": "2",
            "meta_keywords": "",
            "override_child_meta": "N",
            "title_tag": "",
            "lpos": "5",
            "rpos": "6",
            "category_level": "N",
            "new_category_images": "https://dev101.example.com/xxx/images/C/women.png"
        }
    ],
    "success": "1"
}
]

Here the categories are listed.But if am clicking the category it will listed out the subcategory.But i can't view the subcategory. Can you check with this and give me a solution .

EDIT:

in this for loop :

 for(j=0;j<response[0].data[categorylist_id].subcategorymm.length;j++){

i have print the values like :

 Ti.API.info(response[0].data[categorylist_id].subcategorymm[j].category);

it means the subcategories are printed well in my console window.But am unable to view the tableviewrow. i know i done a little bit mistake.so can you find out the mistake and give me a solution.

1
Please add the Alloy code, do you have two Windows? I noticed that you added the TableView to the a View which is also added to win and in the last statement, you opened another window --> $.sample.open. It will be also helpful if you added the URL string so I can test your code.Zabady
@Zabady can you please see my updated question and give me a idea or solutionKrishna Veni
@Zabady can you please see my updated question and give me a idea or solutionKrishna Veni
The problem is, I still can't test your code, can you upload your project to github? If you can, I'll clone it and do my best to help you :)Zabady
Can you pls add some screenshots. Do you want it on one page or after you click on table cell, it should go to another page?Adnan

1 Answers

2
votes

Your problem is real and your code seems a bit messy. I recommend you go for something more structured if you want to avoid spending HOURS to get the intended result. For example try to split your current code into multiple functions with a precise goal.

I'll try to help, using some pieces of code I used for my 2-level navigation menu. The logic is the same, but you'll have to add a third layer yourself.

Build menu

I assume in your xml, you have an empty TableView listening for tap (or click) event like this:
<TableView id="menuTable" onSingletap="onTap" />

During initialisation, you can call a function that will add 1st-level empty sections to your TableView.

To add new rows to these Sections, define _createRow which creates, populates and returns a Ti.UI.createTableViewRow depending on its type:

_createRow = function(data, type) {
    var row = Ti.UI.createTableViewRow();
    // populate row with some content here...
    // Save some useful info in the row
    row.listId = data.id;
    row.subItems = data.subItems;
    // What type of row are we creating ?
    if (type === 'node') {
        // Category
        row.isParent = true;
    }
    if (type === 'child') {
        // Customise row as a Product
        row.backgroundColor = '#2a2a2a';
    }
    // There could be a third type for Sub-Category
    return row;
};

Then within each section you add a node row, this row is a parent that shows the Category and saves some information like its category-id, its type and its sub-Items (we'll use this later).

Handle click event (part 1)

If you get an event from the TableView, there are 3 possible cases:

  1. User clicked Category -> show/hide Sub-Category
  2. User clicked Sub-Category -> show/hide Product
  3. User clicked Product -> Navigate to Product

The related code is at the end of this post, as I'll first explain how to handle these cases.

'Open' Category section

If the Section was not opened already, we want to show what's inside. Let's define a function _openSection which will append a new Section just after the Category that was just clicked. Then, append to this Section as many elements as Sub-Categories you have.

function _openSection(index, parentRow) {
    newSection = Ti.UI.createTableViewSection({
        index: parentRow.section.index + 1
    });
    _.each(parentRow.subItems, function(item) {
        newSection.add(_createRow(item, 'child'));
    });
    parentRow.opened = true;
    // Could be animated on iOS:
    $.menuTable.insertSectionAfter(index, newSection);
    // Save which Section is currently open
    currentOpen = newSection;
};

'Close' Category section

Same goes the other way around: an already opened Section can be closed by taping it. Let's just remove the targeted Section from the TableView.

_closeSection = function(index, parentRow) {
    currentOpen = null;
    parentRow.opened = false;
    var removed = $.menuTable.sections[index].rows.length;
    $.menuTable.deleteSection(index);
    return removed;
};

Handle click event (part 2)

Now you've got everything you need to open and close a Category, here is the code to handle it:

_handleMenu = function(evt) {
    var justify = false, openIndex;
    // Clicked Section is already open
    if (evt.row.opened) {
        return _closeSection(evt.section.index + 1, evt.row);
    } else {
        /* Close currently opened Section, to have only one Category
         * opened at the same time (simplifies the solution a lot)
         */
        if (currentOpen) {
            parentSection = $.menuTable.sections[currentOpen.index - 1];
            parentRow = parentSection.rows[0];
            if (currentOpen.index <= evt.section.index) {
                justify = true;
            }
            removed = _closeSection(parentSection.index + 1, parentRow);
        }
        // Set the index we'll be working with:
        openIndex = evt.index;
        // A Section was closed, change the index:
        if (justify) {
            openIndex -= removed;
        }
        // Workaround for parity on Android
        if (OS_ANDROID) {
            evt.row.section = evt.section;
        }
        return _openSection(openIndex, evt.row);
    }
};

Please try to get this code working with 2 layers, then implement the missing 3rd layer to reach your goal.
Don't hesitate asking questions if I was not clear enough ;)
Good luck!