3

Example: We have an employee list page, that consists of filter criteria form and employee list grid. One of the criteria you can filter by is manager. If the user wants to pick a manager to filter by, he uses the lookup control and popup window is opened, that also has filter criteria and employee list grid.

Now the problem is, that if the popup window is not an iframe, some of the popup elements will have same names and ids as the owner page. Duplicate ids cause Kendo UI to break as by default MVC wrapper generates script tags with $("#id").kendoThingie.

I have used iframe in the past, but content that does not fit in iframe window like long dropdown lists gets cut off and now IE11 especially causes various issues like https://connect.microsoft.com/IE/feedback/details/802251/script70-permission-denied-error-when-trying-to-access-old-document-from-reloaded-iframe.

What would be the best solution here? Generate unique ids for all elements on Razor pages? Modify partial page content that is retrieved by Ajax making ids unique? Something else?

Arunas
  • 918
  • 1
  • 8
  • 20
  • I'm dealing with this right now. Many Kendo controls do this where they have two ids for the same element. Found this fiddle for selecting duplicate IDs with Jquery. http://jsfiddle.net/P2j3f/2/ – JakeJ May 22 '19 at 18:46

2 Answers2

1

It sounds like you are using a partial page as the content to a Kendo window. If this is the case then just provide your partial with a prefix like so at the top of the page.

@{
    ViewData.TemplateInfo.HtmlFieldPrefix = "MyPrefix"
}

Now when you create a kendo control via the MVC wrapper like so

@(Html.Kendo().DropDownListFor(o => o.SomeProperty)
    .....
)

The name attribute will be generated as "MyPrefix.SomeProperty" and the id attribute will be generated as "MyPrefix_SomeProperty". When accessing it within Jquery I like a shorter variable name so I usually do

string Prefix = ViewData.TemplateInfo.HtmlFieldPrefix

After setting the prefix. Then use

var val = $('#@(Prefix)_SomeProperty').data('kendoDropDownList').value();

Note after this change. If you are posting a form from that partial you will need to add the following attribute to your model parameter on the controller method like so. So that binding happens correctly.

[HttpPost]
public ActionResult MyPartialModal([Bind(Prefix = "MyPrefix")] ModeViewModel model) {
    .....
}

Now with all of that said. As long as you keep your prefixes different for each partial your control ids and names will be unique. To ensure this I usually make my prefix name be the same as my cshtml page that I am creating. You would just need to worry about JS function names. Also, note when closing a kendo window all DOM still exist. You just hide it. If this causes you the same issue you just need to be sure to clear the DOM of the modal on close. Similar to how BurnsBA mentioned. Note because of this is the reason why I try to make sure I use the least amount of kendo windows as possible and just reuse them via the refresh function pointing to a different URL.

$('#my-window').data('kendoWindow').refresh({
    url: someUrlString
    , data: {
        someId: '@Model.MyId'
    }
}).open().center();

Then on the modal page itself. When posting I do the following assuming nothing complicated needs to happen when posting.

var form = $('#my-form'); //Probably want this to be unique. What I do is provide a GUID on the view model

$('#my-window').data('kendoWindow').refresh({
    url: form.attr('action')
    , data: form.serialize()
    , type: 'POST'
}).open().center();
Eddie
  • 186
  • 5
0

We do something similar, and have the same problem. We have create/edit/delete popups that fetch data via ajax. Different viewmodels might reference the same model on the same page, and if you open multiple popups (create item type 1, create item type 2) then the second and subsequent popups can be broken (kendo ui error such that a dropdown is now just a plain textbox). Our solution is to delete all dom entries when the popup is closed so there are no conflicts between ids in different popups. We use bootstrap, so it looks like

<script type="text/javascript">
    $('body').on(
        // hook close even on bootstrap popup
        'hidden.bs.modal', '.modal',
        function () {
            $(this).removeData('bs.modal');
            $(this).find('.modal-content').html(''); // clear dom in popup
        });
</script>

Note that our popup has some outer html elements and identifiers, but the content is all in

<div class="modal-content"> ... </div>
BurnsBA
  • 4,347
  • 27
  • 39