Jump to content

Code works when a page is loaded, but not on a MVC partial view


Ken McCoy

Recommended Posts

The following code works as intended when a page is loaded with the defined elements, but does not if it is to be called on a MVC partial view rendering. I understand why it doesn’t is because the page has already loaded but the elements this code acts on have not been loaded. I have tried referencing the source of the code in the partial view .ascx file and have also tried loading the code within script tags: these do not work. Any help on how I can get this to work on a partial view/page update would be appreciated. Sliding.js

// This is a reduced accordion effect on div class hideableItem elements.//$(document).ready(function () {//	$('.itemHeader').click(function () {// In order to get this to work with a partial page update I had to remove the above two lines and// compliment closing brace & parenthesis, then add the following line.$('.itemHeader').live('click', function () {		// Get the parent of the item that was previously clicked.		var priorSelectedParent = $('.itemHeaderSelected').parent().attr('id');		$('#' + priorSelectedParent + ' .hideableItem').slideUp('fast');		$('#' + priorSelectedParent + ' .itemHeaderSelected').addClass('itemHeader');		$('#' + priorSelectedParent + ' .itemHeader').removeClass('itemHeaderSelected');		// Get the parent of the item that was clicked.		var headerParent = $(this).parent().attr('id');		$('#' + headerParent + ' .hideableItem').slideDown('slow');		$('#' + headerParent + ' .itemHeader').addClass('itemHeaderSelected cornersRoundSmall');		$('#' + headerParent + ' .itemHeaderSelected').removeClass('itemHeader');	})//}); // On pages that utilize the accordion effect this causes the div class openingHeader// to open after the page loads.$(document).read(function () {	$('.hideableItem').hide();	// Needed to add a slight time delay before triggering the click event.	setTimeout(function () {		// Select the openingHeader section be open after the page loads.		$('.openingHeader').trigger('click');	}, 10);});

Background.ascx file where Sliding.js is to be implemented (shortened for brevity).

<script type="text/javascript" src="../../Scripts/Sliding.js"></script> <h2 class="contentTopElement">	Background Information</h2>  <div id="slidingPartial" class="slidingInfo cornersRoundSmall">	<div id="summary">		<h3 class="itemHeader openingHeader">Summary of Qualifications</h3>		<div class="hideableItem">			<p>				Established a...</p>			<p>				Ability to...</p>		  		</div>	</div>	<div id="achievements">		<h3 class="itemHeader">Achievements</h3>		<div class="hideableItem">			<p>				Quality Control...</p>			<p>				USDA Service…</p>		</div>	</div></div>

Index.aspx file that calls various partial views.

 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %> <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">  	<script src="../../Scripts/MicrosoftAjax.debug.js" type="text/javascript"></script>	<script src="../../Scripts/MicrosoftMvcAjax.debug.js" type="text/javascript"></script>	<script type="text/javascript" src="../../Scripts/Sliding.js"></script> 	<div class="relativeWrapper">		<div id="leftColumn">			<ul class="sideMenu">				<li class="selectionItem"><%= Ajax.ActionLink("Introduction","Introduction",new AjaxOptions{UpdateTargetId="columnContent"}) %></li>				<li class="selectionItem"><%= Ajax.ActionLink("Background","Background",new AjaxOptions{UpdateTargetId="columnContent"}) %></li>				<li class="selectionItem"><%= Ajax.ActionLink("Contact","Contact",new AjaxOptions{UpdateTargetId="columnContent"}) %></li>			</ul>		</div>		<div id="rightColumn">			<div id="columnContent">				<%= Html.Partial("Introduction", new AjaxOptions { UpdateTargetId = "columnContent" })%>			</div>		</div>	</div></asp:Content>

Thanks,Ken

Link to comment
Share on other sites

if you are using jquery, then you should be using document.ready to make sure the entire document has been loaded before your javascript executes. Are you checking your error console at all? Currently i see you using document.read.

Link to comment
Share on other sites

If your content is loaded via ajax, then you'll need to attach the event listeners after the content has been loaded.
he is using live, which should take care of it. However, it is deprecated in later version of jquery, which is not noted in this thread.http://api.jquery.com/live/
Link to comment
Share on other sites

$(document).read(function () { That should say ready, not read. If your content is loaded via ajax, then you'll need to attach the event listeners after the content has been loaded.
if you are using jquery, then you should be using document.ready to make sure the entire document has been loaded before your javascript executes. Are you checking your error console at all? Currently i see you using document.read.
he is using live, which should take care of it. However, it is deprecated in later version of jquery, which is not noted in this thread.http://api.jquery.com/live/
While trying a variety of things and then changing back to the original code I made the type-o "read" instead of "ready." After making that correction the code still does not work. The first function in the script file is working correctly. Implementing the second function is what is giving me the trouble.(Thanks for the tip about .live, I will follow up on that.) Ken
Link to comment
Share on other sites

can you just post the javascript as you have it now? updates and all, and please provide any error messages you are getting in the console, if any. I'm not sure what you are referring to as first and second functions at this point.

Link to comment
Share on other sites

By second function I am refering to the code that starts $(document).ready(... Here is the current code...

 // This is a reduced accordion effect on div class hideableItem elements.//$(document).ready(function () {//	$('.itemHeader').click(function () {// In order to get this to work with a partial page update I had to remove the above two lines and// compliment closing brace & parenthesis, then add the following line.$('.itemHeader').live('click', function () {// Get the parent of the item that was previously clicked.		var priorSelectedParent = $('.itemHeaderSelected').parent().attr('id');		$('#' + priorSelectedParent + ' .hideableItem').slideUp('fast');		$('#' + priorSelectedParent + ' .itemHeaderSelected').addClass('itemHeader');		$('#' + priorSelectedParent + ' .itemHeader').removeClass('itemHeaderSelected');		// Get the parent of the item that was clicked.		var headerParent = $(this).parent().attr('id');		$('#' + headerParent + ' .hideableItem').slideDown('slow');		$('#' + headerParent + ' .itemHeader').addClass('itemHeaderSelected cornersRoundSmall');		$('#' + headerParent + ' .itemHeaderSelected').removeClass('itemHeader');	})//}); // On pages that utilize the accordion effect this causes the div class openingHeader// to open after the page loads.$(document).ready(function () {	$('.hideableItem').hide();	// Needed to add a slight time delay before triggering the click event.	setTimeout(function () {		// Select the openingHeader section be open after the page loads.		$('.openingHeader').trigger('click');	}, 10);}); 

Thanks, Ken

Edited by Ken McCoy
Link to comment
Share on other sites

yikes. can to try that again? also, if you read up on document.ready, you will find that all your JS code should be in there. The point being that all possible DOM elements will by that time be ready for whatever JS may need to act on them. I would at least start there before posting back with a cleaned up version of your post.http://api.jquery.com/ready/

Edited by thescientist
Link to comment
Share on other sites

Sorry for the mess. I will try again. As to your comment concerning document.ready, that is where I am having problems. If I am running a web form page it works as it should, the problem is that now I am trying to use it with a partial page postback. Please refer to my original post and notice the Background.ascx file, this is the html I want to apply the javascript to. The Index.aspx uses the Ajax.ActionLink's to provide the selectable updates to the page. Therefore, the elements within the Background.ascx file are not present when the page loads.

// This is a reduced accordian effect on div class hideableItem elements.$(document).ready(function () {	$('.itemHeader').on('click', function () {		// Get the parent of the item that was previously clicked.		var priorSelectedParent = $('.itemHeaderSelected').parent().attr('id');		$('#' + priorSelectedParent + ' .hideableItem').slideUp('fast');		$('#' + priorSelectedParent + ' .itemHeaderSelected').addClass('itemHeader');		$('#' + priorSelectedParent + ' .itemHeader').removeClass('itemHeaderSelected');		// Get the parent of the item that was clicked.		var headerParent = $(this).parent().attr('id');		$('#' + headerParent + ' .hideableItem').slideDown('slow');		$('#' + headerParent + ' .itemHeader').addClass('itemHeaderSelected cornersRoundSmall');		$('#' + headerParent + ' .itemHeaderSelected').removeClass('itemHeader');	})}); // On pages that utilize the accordian effect this causes the div class openingHeader// to open after the page loads.$(document).ready(function () {	$('.hideableItem').hide();	// Needed to add a slight time delay before triggering the click event.	setTimeout(function () {		// Select the 'Summary' section be open after the page loads.		$('.openingHeader').trigger('click');	}, 10);});

I would guess there is a better way to implement the above code (and I would appreciate being shown how to do that). Thank you,Ken

Link to comment
Share on other sites

Eureka! While I was hoping for a JavaScript answer to completely solve this problem (and would still appreciate one if possible) I did find a solution and wanted to share it so that others may benefit.There were two issues in this problem: attaching click events to the itemHeader class elements and getting the hideableItem class elements to hide after the partial page update. The following is what had to be changed to correct the issues.

  • I had to do away with $(document).ready event statements wrapping the two functions and name them.
  • Use the on() method to attach a handler to the click event.
  • Within the page calling the partial update I had to modify the Ajax.ActionLink method by adding an additional property, OnSuccess, to the AjaxOptions list. OnSuccess calls the javascript function hidingItems when the partial page update is successfully completed.

Here is the code with the corrections. Sliding.js

 // Event handler attachment that attachs the showItem handler to the click event.$(document).on('click', '.itemHeader', showItem); // Causes the previously unhidden hideableItem to hide and shows the current clicked item// thereby providing the accordion effect.function showItem() {	// Get the parent of the item that was previously clicked.	var priorSelectedParent = $('.itemHeaderSelected').parent().attr('id');	$('#' + priorSelectedParent + ' .hideableItem').slideUp('slow');	$('#' + priorSelectedParent + ' .itemHeaderSelected').addClass('itemHeader');	$('#' + priorSelectedParent + ' .itemHeader').removeClass('itemHeaderSelected');	// Get the parent of the item that was clicked.	var headerParent = $(this).parent().attr('id');	$('#' + headerParent + ' .hideableItem').slideDown('slow');	$('#' + headerParent + ' .itemHeader').addClass('itemHeaderSelected cornersRoundSmall');	$('#' + headerParent + ' .itemHeaderSelected').removeClass('itemHeader');} // On pages that utilize the accordion effect this causes the div class openingHeader// to open after the page loads.function hidingItems() {	$('.hideableItem').hide();	// Needed to add a slight time delay before triggering the click event.	setTimeout(function () {		// Select the 'Summary' section be open after the page loads.		$('.openingHeader').trigger('click');	}, 10);}

Index.aspx

<li class="selectionItem"><%= Ajax.ActionLink("Background","Background", new AjaxOptions{UpdateTargetId="columnContent", OnSuccess="hidingItems"}) %></li>

Thank you to all of you who took your time looking into this problem for me and provided me with direction and/or insight on how to correct the problem. :P Ken

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...