TagBuilder does not generate idqiue id attribute values ​​through ajax requests

I have a problem when I use the same template to display some content on a page, and the same template is used to render additional content on a page using an AJAX request.

The following code displays a partial view of the razor:

@model SearchBoxViewModel <div class="smart-search"> @using (Html.BeginForm("Index", "Search", FormMethod.Get, new { @class = "form-horizontal", role = "form" })) { <div class="form-group"> <div class="hidden-xs col-sm-1 col-md-1 col-lg-1 text-right"> @Html.LabelFor(m => m.SearchPhrase, new { @class = "control-label heading" }) </div> <div class="col-xs-8 col-md-9 col-lg-10"> @Html.TextBoxFor(m => m.SearchPhrase, new {@class = "form-control", placeholder = "for products, companies, or therapy areas"}) </div> <div class="col-xs-4 col-sm-3 col-md-2 col-lg-1"> <input type="submit" value="Search" class="btn btn-default"/> </div> <div class="what-to-search hidden-11 col-sm-11 col-sm-offset-1"> <div class="checkbox"> <label> @Html.CheckBoxFor(m => m.WhatToSearch, null, false) @Html.DisplayNameFor(m => m.WhatToSearch) </label> </div> </div> </div> } </div> <!-- /.smart-search --> 

The following code makes an AJAX request:

 $.ajax(anchor.attr("data-overlay-url-action")) .done(function (data) { $("div.overlay").addClass("old-overlay"); $("div.navbar").after(data); $("div.overlay:not(.old-overlay)") .attr("data-overlay-url-action", anchor.attr("data-overlay-url-action")) .hide() .fadeIn(); $("div.old-overlay") .fadeOut() .removeClass("old-overlay"); anchor.addClass("overlay-exists"); }); 

This way you get the same partial razor view on a page twice, once during a page request and once during an AJAX request.

The problem is that TextBoxFor, CheckBoxFor, etc. use TagBuilder.GenerateId to generate the id attribute value, but it does not take into account the generation identifier for several requests in which AJAX may be involved. This causes the page to display the same id value, resulting in JavaScript being interrupted.

The following is HTML that is displayed twice (once during a request and then added to a separate part of the page during an AJAX request):

 <div class="smart-search"> <form role="form" method="get" class="form-horizontal" action="/PharmaDotnet/ux/WebReport/Search"> <div class="form-group"> <div class="hidden-xs col-sm-1 col-md-1 col-lg-1 text-right"> <label for="SearchPhrase" class="control-label heading">Search</label> </div> <div class="col-xs-8 col-md-9 col-lg-10"> <input type="text" value="" placeholder="for products, companies, or therapy areas" name="SearchPhrase" id="SearchPhrase" class="form-control"> </div> <div class="col-xs-4 col-sm-3 col-md-2 col-lg-1"> <input type="submit" class="btn btn-default" value="Search"> </div> <div class="what-to-search hidden-11 col-sm-11 col-sm-offset-1"> <div class="checkbox"> <label> <input type="checkbox" value="true" name="WhatToSearch" id="WhatToSearch"> NewsManager Search Only </label> </div> </div> </div> </form></div> 

This duplicates the identifier SearchPhrase and WhatToSearch.

Is there a way around this, or is there a better way to visualize form elements to avoid this problem?

+5
source share
1 answer

You can specify your own identifier for the elements, and then you would not have this problem with an ID conflict. Did you try to set the identifier manually: Html.TextBoxFor( ... , new { id = "AnythingHere" }) , where the identifier can be just created by Guid? (Note that you will probably need to add a prefix, because Guides can start with a number.

So you can use the following. The manual does not look good and too long. You can go with something shorter, e.g. short guid, DateTime.Ticks , ...

 @{ var id = "chk_" + Guid.NewGuid().ToString(); } @Html.CheckBoxFor(..., new { id = id }) @Html.LabelFor(..., new { @for = id }) 
+2
source

All Articles