Why does DotNetNuke unexpectedly replace my DOM elements

75 views Asked by At

I am developing a 9.13 DotNetNuke custom module and on one of my settings pages a have a custom input field to upload files to my API controller, but whenever I try to make ANY ajax request to the server, DNN automatically replaces my file input field styles, so it creates a span with dnnInputFileWrapper class, and it overrides my original input field. Additionally, it removes event handlers. Here is how my DOM looks before the ajax request:

<div class="btn btn-primary btn-file" tabindex="500">
   <i class="bi-folder2-open"></i>
   <span class="hidden-xs">Browse …</span>
   <input id="my-input" type="file" multiple="">
</div>

And after:

<div class="btn btn-primary btn-file" tabindex="500">
   <i class="bi-folder2-open"></i>  
   <span class="hidden-xs">Browse …</span>
   <span class="dnnInputFileWrapper dnnSecondaryAction">Choose File
      <input id="my-input" type="file" multiple="">
   </span>
</div>

And UI looks like so:

before ajax request

after ajax request

I tried to overwrite the default DotNetNuke CSS classes and it worked fine until I faced the problem with removed event handlers

1

There are 1 answers

0
Vladyslav On

I've found the answer. If you're facing the problem you should add the normalFileUpload class to your input field type="file".

After inspecting DotNetNuke dnn.jquery.js file I found the function which handles the wrapping functionality and the line of code which allow us to avoid this behaviour and it looks like this:

(function ($) {
  $.fn.dnnFileInput = function (options) {
    var opts = $.extend({}, $.fn.dnnFileInput.defaultOptions, options);

    return this.each(function () {
      var $ctrl = $(this);
      if ($ctrl.hasClass('normalFileUpload')) return;

      if (this.wrapper)
        return;

      //ignore decoration for elements in rad control.
      if ($ctrl.parents().hasClass("RadUpload"))
        return;

      // if this.wrapper is undefined, then we check if parent node is a wrapper
      if (this.parentNode && this.parentNode.tagName.toLowerCase() == 'span' && $ctrl.parent().hasClass('dnnInputFileWrapper')) {
        return;
      }

      this.wrapper = $("<span class='dnnInputFileWrapper " + opts.buttonClass + "'></span>");
      var text = $ctrl.data('text');
      text = text || 'Choose File';
      this.wrapper.text(text);
      $ctrl.wrap(this.wrapper);
      $ctrl.data("wrapper", $ctrl.parent());

      if (opts.showSelectedFileNameAsButtonText) {
        $ctrl.change(function () {
          var val = $(this).val();
          if (val != '') {
            var lastIdx = val.lastIndexOf('\\') + 1;
            val = val.substring(lastIdx, val.length);
          } else {
            val = text;
          }
          $(this).data("wrapper").get(0).childNodes[0].nodeValue = val;
        });
      }
    });
  };

  $.fn.dnnFileInput.defaultOptions = {
    buttonClass: 'dnnSecondaryAction',
    showSelectedFileNameAsButtonText: true
  };
})(jQuery);

At least it works with DNN version 9.13