2

I'm trying to iterate an array of JSON object to create a dropdown like this but using nested ul li. It seems this simple code is not working. It generates the ul li as expected but .append is not working. I'm not getting the reason. JSFiddle

<form action="save/" method="post">
    <div class="select"></div>        
</form>

Javascript

var jsn = [
    {
        "home": "Home",
        "solutions": {
            "education": "Education",
            "financial_services": "FinancialServices",
            "govt": "Government"
        },
        "products": {
            "PCProducts1": "PCPROducts1",
            "PCProducts2": "PCPROducts2",
            "PCProducts3": "PCPROducts3"
        }
    }
];

function iterObject(jsn, select){
    $.each(jsn, function(key, val){
        if(isplain(val)){
            ret = createOption(key, val);
            $(select).append(ret); //This code is not working
        }else{
            ret = createGroup(key);
            iterObject(val, ret)
        }
        console.log("ret", ret); // This prints expected output         
    });
}
function createOption(val, txt){
    return '<li rel="'+val+'">'+txt+'</li>';
}
createGroup = function (grpname){
    return  '<ul "class"="optiongroup"  "label"='+grpname+'></ul>';
};
function isplain(data){
    if (typeof data === 'number' || typeof data === 'string'){return true;}else{ return false;}
}
iterObject(jsn, '.select');

NOTE UPDATE - Code was not finished while the query was asked. So code in query will not show ul and lis nested. As of now, It should display all theul n lis in .select.

7
  • Why is there a forward slash in your form action? Commented Oct 23, 2015 at 10:21
  • @BFDatabaseAdmin - I'm using python -django, I don't think that has anything to do with the query. Commented Oct 23, 2015 at 10:23
  • did you tried to log ret? put this code before append. console.log(ret); Commented Oct 23, 2015 at 10:29
  • could you please check for $(select).size() if it is 1 ? and if $(select) is an element or an array? Commented Oct 23, 2015 at 10:34
  • @RubenYeghikyan - Tried that no luck Commented Oct 23, 2015 at 10:34

4 Answers 4

3

Now it's working: https://jsfiddle.net/2kd0p25n/

function iterObject(jsn, select){
    $.each(jsn, function(key, val){
        if(isplain(val)){
            ret = createOption(key, val);
            $(".optiongroup").last().append(ret);
        }else{
            ret = createGroup(key);
            $(select).append(ret);
            iterObject(val, '.select')
        }         
    });
}
function createOption(val, txt){
    return '<li rel="'+val+'">'+txt+'</li>';
}
createGroup = function (grpname){
    return  '<ul class="optiongroup"  "label"='+grpname+'></ul>';
};
function isplain(data){
    if (typeof data === 'number' || typeof data === 'string'){return true;}else{ return false;}
}
iterObject(jsn, '.select');
Sign up to request clarification or add additional context in comments.

10 Comments

First of all. The <ul> tags never get appended. This makes <li> tags go nowhere. Then, the original '.select' selector will be used on only the first iteration. Which is wrong also.
@AntonF -Great! +1 for your code .last().append(), This made my work more easy. I was about to use if else to achieve that.
@RayonDabre - Don't mind, But I have asked this query because my code was not working. I think Mehul pointed out the actual bug in my code. Also I appreciate AntonF's answer. It saved my lot of time. But can't accept two answers at a time.
@Laxmikant, you certainly can not accept 2 answers but you need to consider the efforts and quality of answer while accepting. Getting all the li elements was not the intention of the code anyways..
No, It would not. One could easily make out the purpose of createGroup
|
1

Correct the selector:

$('.select').append(ret);

Also, You would need to var scope 'ret' variable as below:

function iterObject(jsn, select){
var ret; 
//Rest of the code
}

JSFiddle

5 Comments

it makes all <li> tags go into <div>. Where are the <ul>'s?
@AntonF, No it's not his fault. My code has not finished yet. I guess its output is correct.
Declaring variables is important, but this is not the solution. "Declaring a variable anywhere in the code is equivalent to declaring it at the top". He calls "iterObject" inside the "each" fn. It makes no difference if he has the var statement at the function top. Check out "var hoisting" @ developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Yes, I agree adding var is not the solution. Correct usage of selector is the solution. Along, with the solution I just highlighted the issue in code.
@MehulSaiya Yes, agree with u. The correct usage of selector is the solution. You could have highlighted the issue suggestion before proposing him to add variable statement, avoiding "also" word before your real answer. Just a suggestion
0
function iterObject(jsn, select){
   $.each(jsn, function(key, val){
        if(isplain(val)){
           ret = createOption(key, val);
           $(select).append(jQuery(ret)); //This code is not working
       }
       else{
           ret = createGroup(key);
           var jQret = jQuery(ret);
           jQuery(select).append(jQret );
           iterObject(val, jQret);
       }
       console.log("ret", ret); // This prints expected output
   });
}

Comments

0

I think this question is interesting as it is related with recursion. Here is my code

JS

var jsn = [
    {
        "home": "Home",
        "solutions": {
            "education": "Education",
            "financial_services": "FinancialServices",
            "govt": "Government"
        },
        "products": {
            "PCProducts1": "PCPROducts1",
            "PCProducts2": "PCPROducts2",
            "PCProducts3": "PCPROducts3"
        }
    }
];

var menuBuilder = (function() {

    var isLeaf= function(obj) {
        return typeof obj !=='object';
    };

    var buildItems = function(objlist) {
        var expected= '';
        var items;

        $.each(objlist, function(key, val) {      

            if(!isLeaf(val)) {
                items= buildItems(val);

                expected+= '<li>' + key;
                expected+= '<ul>' + items + '</ul>';
                expected+= '</li>';
            } else {
                expected+= '<li>' + val + '</li>';
            }
        });

        return expected;
    };    

    var read = function(json) {
        var items= buildItems(json);
        var expect= '';

        if(items==='') return expect;

        expect += '<ul>';
        expect += items;
        expect += '</ul>';

        return expect;
    };

    return {
        read: read
    };

})();


$('#container').append(menuBuilder.read(jsn[0]));

HTML

<div id="container"></div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.