0

SCENARIO

I am developing a kind of report builder. User selects the report from a select and click a button. A form with the required parameters is dynamically created and rendered. Some parameters are rendered as selects, bound to db tables.

  1. How the form is called:

    var data = { 'ReportId': $('#Reports option:selected').val() };
    $.ajax({
        type: 'GET',
        url: '/statistics/ReportBuilder/GetReportParameters',
        dataType: 'text',
        data: data,
        success: function(data){
            $('#divReportParameters').html(data);
        },
        complete: function(){
            mkNamespace.utils.dom.hideLoader($('#content'));
        }
    });
    
  2. GetReportParameters.cshtml. The form is a view made up of a simple container:

          @model ReportBuilderModel
          <div>
              <h3>@Model.Report.Label</h3>
          </div>
          <div>
              <form id='frmReportParameters' action='@Url.Action("GetReport")' method="post">
                  @Html.Partial("~/Views/Shared/Controls/_ParametricForm.cshtml", Model.Parameters)
                  <input type = "hidden" id="reportId" name="reportId" value="@Model.Report.Id" />
                  <input id="btnGetReport" type="button" value="Estrai Report" />
              </form>
          </div>
    
  3. _ParametricForm.cshtml. The actual parameters list is rendered using the _ParametricForm partial view. The partial is made up of two parts. The first part render a <table>, cycles on the parameters collection, creates a row and put the corresponding GUI element in the row. The second part render a <script> block with the onchange event handlers.

        @model FormParameterCollection
    
        <table class="tableForm parametricForm">
        @foreach (FormParameter par in Model) { 
            <tr>
                <td class="fieldLabel">@par.Label</td>
                <td class="fieldInput">
                    @switch(par.Type){
                        case FormParameterType.Input:
                            <input name="@par.Name" type="text" class="fieldText" />
                            break;
                        case FormParameterType.Select:
                            <select name="@par.Name" class="fieldSelect">
                            @if (!string.IsNullOrWhiteSpace(par.DefaultLabel) || !string.IsNullOrWhiteSpace(par.DefaultValue))
                            { 
                                <option value="@par.DefaultValue" data-tag="">@par.DefaultLabel</option>
                            }
                            @foreach (DataSourceItem item in DataSourceManager.Current[par.DataSource])
                            {
                                <option value="@item.Value" data-tag="@item.Tag">@item.Label</option>
                            }
                            </select>
                            break;
                        case FormParameterType.MultiSelect:
                            <select name="@par.Name" class="fieldSelect" multiple="multiple" size="6">
                            @if (!string.IsNullOrWhiteSpace(par.DefaultLabel) || !string.IsNullOrWhiteSpace(par.DefaultValue))
                            { 
                                <option value="@par.DefaultValue" data-tag="">@par.DefaultLabel</option>
                            }
                            @foreach (DataSourceItem item in DataSourceManager.Current[par.DataSource])
                            {
                                <option value="@item.Value" data-tag="@item.Tag">@item.Label</option>
                            }
                            </select>
                            break;
                        case FormParameterType.Date:
                            @Html.JQueryUI().Datepicker(par.Name, DateTime.Now)
                            break;
                        default:
                            <input name="@par.Name" type="text" class="fieldText" />
                            break;
                    }
                </td>
            </tr>
        }
        </table>
        <script type="text/javascript">
            //dynamically bind the onchange events of the parametes
            $(document).ready(function(){
                @foreach (FormParameter par in Model) {
                <text>
                    @if(!String.IsNullOrEmpty(par.ParentParameter)){        //the onchange event is bound for the 'parent related' parameters (e.g. shop & categories)
                        <text>
                        $('.tableForm.parametricForm').on('change', '[name="@par.ParentParameter"]', function (e) {
                            var parentId = e.target.value;
    
                            $('[name="@par.Name"] > option').hide();
                            $('[name="@par.Name"] > option').filter(function () {
                                var tag = $(this).attr('data-tag');
                                return (tag == '' ? true : (JSON.parse($(this).attr('data-tag'))['@par.ParentParameter'] == parentId) || (parentId == ''));
                            }).show();
                        });
                        </text>
                    }
                </text>
                }
            });
    
            //bind jQueryUI functions after the ajax call
            $('.tableForm').jQueryUIHelpers();
        </script>
    

QUESTION

Now, do not mind all the details. All this stuff perfectly runs on Firefox.

In Chrome e IE, the <script> block in the _ParametricForm partial is correctly returned in the response (checked with the debugger), but the onchange event handlers are not executed.

So, the issue is not in the partial view logic, as the response is correctly created in all the browsers. But the issue seems to be related to the browser engines.

How to solve this?

Alberto De Caro
  • 4,849
  • 9
  • 42
  • 72

2 Answers2

0

You set the data type as text, so it's going to treat it as text and not process it at all. Set to "html".

Chris Pratt
  • 207,690
  • 31
  • 326
  • 382
0

if its a form field then would keyup / keypress be suitable? If you want changes then try on focusout compare current and previous value for changes.

onchange is only triggered when the control is blurred. (source)

Community
  • 1
  • 1
Jo E.
  • 6,278
  • 11
  • 44
  • 79