1

Im developing a mvc5 application using codefirst approach. Im returning a json object to a view in this way,

public JsonResult FillItem(int mnId, int sbId)
    {
        var db = new KnittingdbContext();

        var x1 = db.ItemTemplates.Where(a => a.MainGroupId == mnId).Where(a => a.SubGruopId == sbId).FirstOrDefault().Atribute1;
        var x2 = db.ItemTemplates.Where(a => a.MainGroupId == mnId).Where(a => a.SubGruopId == sbId).FirstOrDefault().Atribute2;
        var x3 = db.ItemTemplates.Where(a => a.MainGroupId == mnId).Where(a => a.SubGruopId == sbId).FirstOrDefault().Atribute3;

        var y1 = db.AtributeDetails.Where(a => a.AtributeId == x1).Select(a => new
            {
                AtributeDetailId=a.AtributeDetailId,
                AtributeDetail=a.AtDetailVal,
                AtributeName=a.Atribute.AtributeName,
                AtributeType=a.Atribute.AtributeType
            });
        var y2 = db.AtributeDetails.Where(a => a.AtributeId == x2).Select(a => new
        {
            AtributeDetailId = a.AtributeDetailId,
            AtributeDetail = a.AtDetailVal,
            AtributeName = a.Atribute.AtributeName,
            AtributeType = a.Atribute.AtributeType
        }); 
        var y3 = db.AtributeDetails.Where(a => a.AtributeId == x3).Select(a => new
        {
            AtributeDetailId = a.AtributeDetailId,
            AtributeDetail = a.AtDetailVal,
            AtributeName = a.Atribute.AtributeName,
            AtributeType = a.Atribute.AtributeType
        }); 

        var ad = new[] { y1,y2,y3};

        return Json(ad, JsonRequestBehavior.AllowGet);
    }

There are 2 tables involved here(for my question). Atribute and AtributeDetail tables which has one to many relationship between them.

I want to generate dropdownlists and textboxes dynamically in my view based on the retuned jason object.

Here 'AtributeDetailId' and 'AtributeDetail' are Value and Text elements of dropdownlists to be generated dynamically.

For AtributeType there are two values in database, 'Text' and 'Select'.

In the view, using jquery i want to loop through the jason object(ad) and after checking each object's(objects in jason object) 'AtributeType' if it is 'Text' then i want to generate a textbox(input)or if it is 'Select' i want to generate a dropdown list. Infront of generated textbox or dropdown list i want to show a label based on the particular 'AtributeName'.Here i have only shown 3 objects. But it is varying in actual.

Im struggling to develop correct jquery for this. Below i have shown the jquery i developed up to now. But it is not complete.

    $('#SubGrpId').change(function () {
    $.ajax({
        url: '@Url.Action("FillItem", "Item")', // dont hard code your url's
        type: "GET",
        dataType: "JSON",
        data: { MnId: $('#MainGrpId').val(), SbId: $(this).val() }, // pass the selected value
        success: function (ad) {
            alert("Im In");
            var s = $('<select/>');
            $.each(ad, function (l, u){
                $.each(u, function (i, itemdt) {
                    $('<option />', { value: itemdt.AtributeDetailId, text: itemdt.AtributeDetail }).appendTo(s);
                })
                s.appendTo('#ss');
            })
        },
        error:function(){
            alert("something wrong");
        }
    });
})

It comes to the success function. But it only gives me one ddl and every Atribute Detail get binded to it. Could anyone pls help me to develop correct jquery by checking the condition('Text' or'Select') and generate appropriate Textboxes and ddls with AtributeName infront of those.

This should be in a way that selected values of ddls and entered value in textboxes can be posted back to server.

Withing view's body i have a div with id 'ss'. I want append every generated textbox and ddl in to that div as child divs.

<div id="ss" class="col-md-6">

</div>

Hope i presented my question in a clear way. All help appreciate. Thanks in advance!

Let's assume y1's AtributeType is 'Text'. Then y1 will not have items in it(y1 is empty). That means 'AtributeDetailId' and 'AtributeDetail' in object is no use. Let's say y1's 'AtributeName' is "atribute1" then i want to generate a textbox with label infront of it showing "atribute1".

Let's assume y2's 'AtributeType' is 'Select'. Then y2 has items in it. Here 'AtributeDetailId' and 'AtributeDetail' are important. Let's assume y2 list is consist of 5 elements. "aa","bb","cc","dd","ee" and y2's 'AtributeName' is "atribute2" then i should generate a ddl containing those 5 elements with a label infront of it showing "atribute2".

Let's assume y3's 'AtributeType' is also 'Select'. So there are items in it and it is also a ddl.

Now i have 1 textbox and 2 ddls dynamically generated within the div with id"ss".

And example of the values used for a textbox would be

y1 = [
    { AtributeDetailId=null, AtributeDetail=null, AtributeName="atribute1", AtributeType="Text" }
]

and an example of the values used for a dropdownlist would be

y2 = [
    { AtributeDetailId=1, AtributeDetail="aa", AtributeName="atribute2", AtributeType="select" }, 
    { AtributeDetailId=2, AtributeDetail="bb", AtributeName="atribute2", AtributeType="select" },
    {AtributeDetailId=3, AtributeDetail="cc", AtributeName="atribute2", AtributeType="select" }
]
10
  • You have a variable var s which is a <select> element and you add all options to that. Are you trying to create 3 <select> elements, one for y1, another for y2 and another for y3? Commented Oct 17, 2015 at 5:10
  • Also what do you mean by generate appropriate Textboxes? - nowhere in your code do you generate any inputs. Commented Oct 17, 2015 at 5:12
  • @Stephen Muecke, hey thanks for replying :) no, the number of ddls and input boxes are depend on the 'AtributeType'. If 'AtributeType' is 'Text' then it would be a input box. If it is 'Select' then it would be a ddl. I just posted the jquery here to show my attempt. But it is not complete and it might be wrong. Pls help me with this.. Commented Oct 17, 2015 at 5:17
  • Here if the 'AtributeType' is 'Text' then i should generate a textbox which then user can input some text. Commented Oct 17, 2015 at 5:19
  • Does not quite make sense since y1 is a collection of objects. If it contains (say) 3 items and they are all AtributeType="Text" then do you want 3 textboxes? If they are all AtributeType="Select" do you want one <select> with 3 options? And what if 2 are "Text" and 1 is "Select"? Commented Oct 17, 2015 at 5:20

1 Answer 1

1

Based on your data structure, your script needs to be

var ss = $('#ss');
$('#SubGrpId').change(function () {
  $.ajax({
    ....
    success: function (ad) {
      $.each(ad, function(l, u) {
        // add the label
        var name = u[0].AtributeName;
        var label = $('<label></label>').text(name).attr('for', name);
        s.append(label);
        if (u[0].AtributeType === 'Text') {
          // There is only one item and its for generating a textbox
          var input = $('<input>').attr({ type: 'text', id: name, name: name });
          ss.append(input);
        } else {
          // Its a select
          var select = $('<select></select>').attr({ id: name, name: name });
          // add each option
          $.each(u, function (i, itemdt) {
            select.append($('<option></option>').val(itemdt.AtributeDetailId).text(itemdt.AtributeDetail));
          })
          ss.append(select);
        }
      });
    }
  });
});

Side note: You are making 2 extra unnecessary database calls to generate variables x2 and x3. Instead use

var x = db.ItemTemplates.Where(a => a.MainGroupId == mnId).Where(a => a.SubGruopId == sbId).FirstOrDefault();

and then

var y1 = db.AtributeDetails.Where(a => a.AtributeId == x.Atribute1).Select(a => new

var y2 = db.AtributeDetails.Where(a => a.AtributeId == x.Atribute2).Select(a => new

etc

Edit

You could return objects more directly related to your view by modifying your queries to

var x = db.ItemTemplates.Where(a => a.MainGroupId == mnId).Where(a => a.SubGruopId == sbId).FirstOrDefault();
var ids = new List<int>{ x.Atribute1, x.Atribute2, x.Atribute3 };
var y = db.AtributeDetails.Where(a => aids.Contains(a.AtributeId)).GroupBy(a => a.AtributeName).Select(g => new
{
    Name = g.Key,
    Options = g.Where(z => z.AtributeDetailId != null).Select(x => new
    {
        Value = x.AtributeDetailId,
        Text = x.AtributeDetail
    })
});
return Json(y, JsonRequestBehavior.AllowGet);

and modify the script to

success: function (ad) {
  $.each(ad, function(l, u) {
    // add the label
    var name = u.Name;
    var label = $('<label></label>').text(name).attr('for', name);
    s.append(label);
    if (u.Options.Length == 0) {
      // There is only one item and its for generating a textbox
      var input = $('<input>').attr({ type: 'text', id: name, name: name });
      ss.append(input);
    } else {
      // Its a select
      var select = $('<select></select>').attr({ id: name, name: name });
      // add each option
      $.each(u.Options, function (i, option) {
        select.append($('<option></option>').val(option.Value).text(option.Text));
      })
      ss.append(select);
    }
  });
}
Sign up to request clarification or add additional context in comments.

1 Comment

Refer edit for an alternative which is a bit more efficient and less code in creating your queries.

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.