2

This is the view of my json result action,its consisting property ID , IsChecked checkboxes and Propery title columns .

enter image description here

at this view I can checked or uncheck of these check boxes .

once I select specific check boxes and click Create Brochure I want to pass those values to another controller method.

Ex: lets say I checked first two results

property ID | IsChecked
          1 |   True

          2 |   True

I want to send above values to another controller once I click, how can I do that.

this is HTML code

<table class="table">
    <thead>
        <tr>
            <th>Property ID</th>
            <th>IsChecked</th>
            <th>Property Tile</th>
        </tr>
    </thead>
    <tbody id="table"></tbody>
</table>

<table id="template" class="table" style="display: none;">
    <tr>
        <td></td>
        <td></td>
        <td></td>
    </tr>


</table>
<div style="width:50%; float:left;text-align:left"><button id="resetborchure" type="button" class="btn btn-warning submit">Reset Brochure</button> </div>
<div style="width:50%; float:left;text-align:right"><button id="createborchure" type="button" class="btn btn-danger submit" onclick="location.href='@Url.Action("Create_Brochure", "Brochure")'">Create Brochure</button> </div>

I have following json script to retrieve data from a data table

<script type="text/javascript">

        var url = '@Url.Action("FetchProductProperties")';
        var editUrl = '@Url.Action("Edit")';

        var template = $('#template');
        var table = $('#table');
        $('#search').click(function () {
            table.empty();
            $.getJSON(url, { function (populated_data) {
                $.each(populated_data, function (index, item) {
                    var clone = template.clone();
                    var cells = clone.find('td');
                    cells.eq(0).text(item.ID);

                    if (item.CheckOrNot === true)
                    {
                        cells.eq(1).html("<input type='checkbox' value='1' checked='" + item.CheckOrNot + "'>");
                    }
                    else
                    {
                        cells.eq(1).html("<input type='checkbox' value='0'>");
                    }

                    cells.eq(2).text(item.Name);
                    table.append(clone.find('tr'));
                });
            });
        });

        $('#resetborchure').click(function () {
            table.empty();
        });

</script>
kez
  • 2,273
  • 9
  • 64
  • 123
  • So you want to send only those data to controller, which is checked and this will be on click of create borchure right? You want it do using ajax or normal post? – Guruprasad J Rao Oct 06 '15 at 05:42
  • 1
    Ahhh. I pulling my hair out. This will simply not work. You can do this easily by just returning a partial view (where the partial view generates each row with the checkbox, hidden input for the ID property and the display text/label in a `for` loop as I have commented in your previous questions. –  Oct 06 '15 at 06:13
  • But if you really want to do it this way then you need to generate the controls correctly with indexers and including a checkbox with `value="true" and and hidden input associated with `value="false"` otherwise binding will fail. Refer [this answer](http://stackoverflow.com/questions/29161481/post-a-form-array-without-successful/29161796#29161796) for an example of what you need to do to dynamically add the items using json data. –  Oct 06 '15 at 06:16
  • @GuruprasadRao your correct , as normal post wil be better since I want new page after I click – kez Oct 06 '15 at 07:29
  • @StephenMuecke I have tried to do this using partialview,but since this chain of process I thought it will be better going this way – kez Oct 06 '15 at 07:42
  • @StephenMuecke this is my partialview effort https://dotnetfiddle.net/D55Ndw , since its won't work out decided to come up with this way – kez Oct 06 '15 at 07:45
  • Returning a partial and adding it to the DOM will be far less code, easier and more robust). The DotNetFiddle is of no use (it can't be run or tested and you don't have a partial anyway - just the main view) –  Oct 06 '15 at 07:50
  • @StephenMuecke can you give me example to do this using partial view – kez Oct 06 '15 at 08:37
  • No time right now, but I'll add something in a hour or 2. –  Oct 06 '15 at 08:40
  • @StephenMuecke thanks you're very helpful – kez Oct 06 '15 at 08:40
  • @StephenMuecke is there anything I can do with this in dynamic way . I have put this inside my jsonresult controller `var dictionary = populated_data.ToDictionary(v => v.ID, v => v.CheckOrNot);` then for button I add this`
    ` then pass result and direct to actionresult I used this script `$('#createbrochure').click(function () { $.getJSON(url, $('table').serialize(), function (dictionary) { }); })`
    – kez Oct 06 '15 at 09:50
  • @kez, Sorry, you have lost me with your last comment :) Have just added an answer using a partial and also json (you may need to modify it a bit based on your actual property names) but I suggest you get this working first and then we can address other issues. The key to all this is that the form controls must be correctly named with indexers otherwise you will never be able to bind it when you post. –  Oct 06 '15 at 10:01

2 Answers2

2

You have not shown your models or what the FetchProductProperties() is doing, but assuming it is creating a collection of objects (say) List<ProductPropertyVM> where ProductPropertyVM contain properties int ID, string Title and bool IsChecked then the easiet way to handle this would be to return a partial view rather than json. For example in the controller

public ActionResult FetchProductProperties(...)
{
  List<ProductPropertyVM> data = ..... // your query
  return PartialView("_ProductProperty", data);
}

and the _ProductProperty.cshtml partial view

@model List<ProductPropertyVM>
<table>
  ... // thead elements
  <tbody>
    @for(int i = 0; i < Model.Count; i++)
    {
      <tr>
        <td>
          @Html.DisplayFor(m => m[i].ID)
          @Html.HiddenFor(m => m[i].ID)
        </td>
        <td>@Html.CheckBoxFor(m => m[i].IsChecked)</td>
        <td>@Html.DisplayFor(m => m[i].Title)</td>
      </tr>
    }
  </tbody>
</table>
.... // buttons

Then in the main view include a placeholder to render the partial

<div id="productproperties"></div>

and modify the script to

$('#search').click(function () {
  $('#productproperties').load(url, { .... }); // add data to be passed to the method as required
});

If you do want to do this by returning json - i.e. the method has return Json(data, JsonRequestBehavior.AllowGet); then you need to generate the controls with the correct name attributes including indexers. The html for each row would need to be (where # is the indexer - starting a zero and ? is the value from the json data)

<tr>
  <td>
    <span> // value of ID property </span>
    <input type="hidden" name="[#].ID value="?" />
  </td>
  <td>
    <input type="checkbox" name="[#].IsChecked" value="true" />
    <input type="hidden" name="[#].IsChecked" value="false" />
  </td>
  <td>
    <span> value of Title property </span>
  </td>
</tr>

The easiest way to generate this is to have this as a template inside a hidden div (say <div id="template">) and outside the form element. Then in the $.each() function, clone the template, and update the values, including updating the indexer.

$.each(data, function (index, item) {
  var clone = $('#template').clone();
  // update indexers
  clone.html($(clone).html().replace(/\[#\]/g, '[' + index + ']'));
  // update input values as display text
  var cells = clone.find('td');
  cells.eq(0).children('span').text(item.ID);
  cells.eq(0).children('input').val(item.ID);
  cells.eq(1).children('input').first().prop('checked', item.IsChecked)
  cells.eq(2).children('span').text(item.Title);
  table.append(clone.html());
});

Refer this DotNetFiddle for an example of the json approach

In both cases this will post back to a method which has a parameter List<ProductPropertyVM> model

  • I integrate your code , but no result come out then , I placed a debug point at `FetchProductProperties` method but it doesn't invoking – kez Oct 06 '15 at 10:34
  • I don't know what your `FetchProductProperties()` does or what parameters it has so I can't comment. But give me 20 minutes and I will create a DotNetFiddle for you to show you how it works :) –  Oct 06 '15 at 10:41
  • I'll create all my code inside DotNetFiddle just to show you – kez Oct 06 '15 at 10:44
  • I have added a link to a DotNetFiddle to show how it works (just click the button to add some sample rows). Suggest you also inspect the html it generates. Note I has a couple of typos in the script which have now been corrected. I will have a look at yours later but its not much use because it cannot be run. –  Oct 06 '15 at 11:16
  • really appreciate your help always ,but now how pass that checked values along with ID to another controller – kez Oct 06 '15 at 11:20
  • That depends. Are you doing a normal submit, or via ajax (so you stay on the same page). And based on your previous question, did you also want to pass the values of the dropdownlist you have shown above this table? –  Oct 06 '15 at 11:31
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/91479/discussion-between-stephen-muecke-and-kez). –  Oct 06 '15 at 11:35
  • Give me an hour or 2 and I will have a look :) –  Oct 07 '15 at 04:05
  • @kez, I don't understand why you think you would need to do. All you need to to use `$('form').serialize()` to post every thing back to the controller as I indicated in chat. You do have a habit of wanting to over-complicate everything :) –  Oct 07 '15 at 04:45
  • but here I'm not binding my results to form noh, I'm binding results to Table, am I correct – kez Oct 07 '15 at 04:47
  • using this syntax inside jsonresult `var dictionaryDATA = populated_data.ToDictionary(v => v.ID, v => v.CheckOrNot);` I able to get all the dynamic results set set , is there anything I can get that 'dictionaryDATA' using ajax – kez Oct 07 '15 at 04:50
  • All you need is to have the table inside a `
    ` element. Let me update my fiddle to show you what you can do (give me 20 min)
    –  Oct 07 '15 at 04:51
  • I have updated the [DotNetFiddle](https://dotnetfiddle.net/yC8qTc). Click on the 'Fetch Product Properties', check some of the checkboxes and click 'Create Brochure'. It posts the values to the controller and sends back a message stating which ID's were selected. –  Oct 07 '15 at 05:09
  • I vaguely remember that you wanted to redirect when you post to the `Create_Brochure()` method, in which case you would use a normal submit button, not ajax (because ajax calls do not redirect) - but the fiddle is just proving what you can do. –  Oct 07 '15 at 05:38
  • thats worked thanks , you always navigate me for correct side – kez Oct 07 '15 at 06:14
1

If you wanna continue with above code then follow this: Remove button onclick properties.It's better use ajax.

<div style="width:50%; float:left;text-align:right"><button id="createborchure" type="button" class="btn btn-danger submit">Create Brochure</button> </div>

Now Implement the button click properties like this:

$('#createborchure').click(function () {
        var data=[];
 $('#table tr').each(function(){
           // creating json data based on checked row.
           $this=$(this)
           var value=$this.find('input:checked').val();
           if(value=="1"){
            var row={"id":$(this).find("td").eq(0).html(),
                      "Ischecked":"true",
                       "title":$(this).find("td").eq(2).html()}
            data.push(row);
           }        
 });
  // Now use Ajax to send data to controller
  $.ajax({
  type: "POST",
  contentType: "application/json; charset=utf-8",
  url: "/Brochure/Create_Brochure",
  data: data,
  success: function (result) {
       //do somthing here
  }
   });
   });

Hope this will help.

Mahbubur Rahman
  • 4,961
  • 2
  • 39
  • 46
  • what do u mean by find ID?You just place this code in script and see what happen. Hopefully it will work fine. – Mahbubur Rahman Oct 06 '15 at 10:12
  • Ahh just saw it how you binding it, but once I add this method , I put debug point at "Create_Brohure" method and debug and tested, but seems likes it doesnt invoking – kez Oct 06 '15 at 10:15
  • check your browser console. Is it showing any error with ajax invoking?? – Mahbubur Rahman Oct 06 '15 at 10:22
  • of course. u wanted this **once I select specific check boxes and click Create Brochure I want to pass those values to another controller method.** In my code i have created the click function. Inside click function first i have created the json data in table format based on which check box are selected. Then sent this data to controller using Ajax.It's so simple.One more thing, you have created your table data in a very weird way. You can do it using simple jquery. Thanks for your effort. – Mahbubur Rahman Oct 07 '15 at 08:27