user3818229 user3818229 - 18 days ago 6
Javascript Question

The JS file doesn't work in partial view after it refreshed

This is branch question of "Js file not loaded after partial view is refreshed".
The broblem is that if I put my script in to the main view it doesn't work in partial.
My custom script:

$(function() {
$.ajaxSetup({ cache: false });
var timer = window.setTimeout(function () {
$(".alert").fadeTo(1000).slideUp(1000, function () {
$(this).hide();
});
}, 3000);
$("[data-hide]").on("click", function () {
if (timer != null) {
clearTimeout(timer);
$(this).closest("." + $(this).attr("data-hide")).hide();
}
});
});


The Photo partial view where I need to use my script:

<div class="well">
<h3>
<strong>@Model.Name</strong>
<span class="pull-right label label-primary">@Model.AverageRaiting.ToString("# stars")</span>
</h3>
<span class="lead">@Model.Description</span>
@Html.DialogFormLink("Update", Url.Action("UpdatePhoto", new {id = @Model.PhotoId}), "Update Photo", Url.Action("Photo"))
@Html.Action("InitializeAlerts")
</div>


And partail view "_Alert" which rendering in to the partial where I need to use the script above:

@{
var alerts = TempData.ContainsKey(Alert.TempDataKey)
? (List<Alert>)TempData[Alert.TempDataKey]
: new List<Alert>();

if (alerts.Any())
{
<hr />
}
foreach (var alert in alerts)
{
var dismissableClass = alert.Dismissable? "alert-dismissable" : null;
<div class="alert alert-@alert.AlertStyle fade in @dismissableClass">
@if (alert.Dismissable)
{
<button type="button" class="close" aria-label="close" data-hide="alert">&times;</button>
}
@Html.Raw(alert.Message)
</div>
}
}

Answer

Use a delegated event handler:

$(document).on('click', "[data-hide]", function () 

The jQuery selector is only run at event time, so it will work with dynamically added elements.

It works by listening for the event at a non-changing ancestor element (document is the safest default if nothing else is closer/convenient). It then applies the selector to the elements in the bubble-chain. It then applies your event handler function to only the matching elements that caused the event.

This is very efficient compared to connecting event handlers to individual elements and any speed difference is negligible as you simply cannot click fast enough to notice :)

Comments