bootstrap load collapse panel with ajax - ajax

I'm trying to load collapsable panels with ajax. I got it working, but my trigger fires on the a tag, so the ajax script is called when you open AND close the panel. It should not load it when you close the panel, this is overload..
My code:
<div class="panel-group" id="accordion">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title"><a data-toggle="collapse" data-parent="#accordion" href="#collapse1">First panel</a></h4>
</div>
<div id="collapse1" class="panel-collapse collapse">
<div class="panel-body">
<div id="depUsers511"><!-- here users will be loaded through ajax --></div>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title"><a data-toggle="collapse" data-parent="#accordion" href="#collapse2">Second panel</a></h4>
</div>
<div id="collapse2" class="panel-collapse collapse">
<div class="panel-body">
<div id="depUsers511"><!-- here users will be loaded through ajax --></div>
</div>
</div>
</div>
The javascript:
$('#accordion a').click(function () {
var collapse_element = event.target;
alert(collapse_element);
var href = this.hash;
var depId = href.replace("#collapse","");
var dataString = 'depId='+ depId + '&do=getDepUsers';
$.getJSON(dir_pre + 'ajax/users.php?' + dataString, function(data) {
$('#depUsers'+depId).html(data);
});
})
The ajax script returns the content of the div.
So, it works, but I'm looking for the correct way to fire the ajax load trigger... i think I need to use the "show.bs.collapse" event, but can't find out how to use this on a panel which contains more than one dynamic panel (with its own ID).

You can try this:
$('#accordion').on('show.bs.collapse', function(e){
var depId = $(e.target).attr('id').replace('collapse','');
...
});

I kind of solved it by adding a "open" class when loaded with data, and removing that same class if clicked when opened:
$('#accordion a').click(function () {
if($(this).hasClass("panelisopen")){
$(this).removeClass("panelisopen");
} else {
var href = this.hash;
var depId = href.replace("#collapse","");
$(this).addClass("panelisopen");
var dataString = 'depId='+ depId + '&dep=1&do=getDepUsers';
$.getJSON(dir_pre + 'ajax/users.php?' + dataString, function(data) {
$('#depUsers'+depId).html(data);
});
}
});
Not the best solution I guess, but it works.

I think instead of depending on element ID, and polluting it with numbers and do the string replacement and so, you can make use of data attributes:
<div class='collapse' data-dep-id="1" />
Then in JS:
var $elementId = $(e.target).data('dep-id')
And the same applies for Ajax URL and other attributes if needed.

Related

How to use Ajax to update RenderBody()

I am trying to work with ajax in order to update only a partial view and not the whole view. In the following example I want to refresh the page-content section.
this is my layout.html.
<body>
<div id="container" class="effect">
#Html.Partial("_head")
<div class="boxed">
<section id="content-container">
#if (ViewData["Errors"] != null)
{
<div class="panel" style="background-color:white;">
<div class="panel-heading">
<h3 class="panel-title">
Page title
</h3>
</div>
</div>
}
<div id="page-content" class="container">
#RenderBody()
</div>
</section>
</div>
</div>
</body>
Partial view _head contains the menu with href links for example:
<a id="a1" href="">Menu Item 1</a>
In layout I am trying to use the following:
<script>
$(document).ready(function () {
$("#a1").click(function () {
A1();
});
function A1( ) {
$.ajax({
url: '#Url.Action("PartialViewMethodFromController", "HomeController")',
success: function (response) {
$('#page-content').html(response);
}
});
}
});
</script>
And my HomeController
public ActionResult PartialViewMethodFromController()
{
var model = service.GetAll();
return PartialView("PartialViewMethodFromController", model);
}
It kinda works - the partialview is refreshing for a moment and the partialview is show correctly and then the whole page goes on and refreshes.
Am I missing something crucial here?

Loading a partial view into a DIV element dynamically is replacing the entire DOM vs the element

Within a view I am trying to load a partial view from the controller. I am using the Ajax.ActionLink method to make this call
#Ajax.ActionLink("Involved Entities/Resources",
"GetNarratives",
new { id = 4 },
new AjaxOptions { HttpMethod = "GET",
UpdateTargetId = "narrContainer" })
Further down in the page I have a div element with the id of narrContainer
<div id="narratives" class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title"><a data-toggle="collapse" href="#collapseNarrative">Narratives [ #Model.AssociatedNarrative.Count() ]</a></h4>
</div>
<div id="collapseNarrative" class="panel-collapse collapse">
<div class="panel-body">
<div id="narrContainer"></div>
</div>
</div>
</div>
</div>
</div>
The controller has the following code:
public PartialViewResult GetNFIRNarratives(string id)
{
//Get Narratives
fauxModel fm = new fauxtModel();
List<Narrative> narr = new List<Narrative>();
narr = fm.GenerateMockBaseNarratives(4);
return PartialView("_myAssociatedNarrative", narr);
}
The partial view contains fields for the collection:
<!-- Assocaited Narrative-->
#for (int i = 0; i < #Model.Count(); i++)
{
<div class="col-md-12">
<p><strong>Date Entered</strong> #Html.DisplayFor(x => x[i].DateEntered)</p>
</div>
if (!string.IsNullOrWhiteSpace(#Model[i].Title))
{
<div class="col-md-12">
<p><strong>Narrative Title</strong> #Html.DisplayFor(x => x[i].Title) </p>
</div>
}
<div class="col-md-12">
<p>#Html.DisplayFor(x => x[i].NarrativeText)</p>
<hr />
</div>
}
Within the base layout page I have added reference to the unobtrusive-ajax script as
<script src="#Url.Content("~/js/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
And I have confirmed that the key is enabled in the web.config file.
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
When I click on the link to load the narratives the code executes but it does not load the partial in the div element. Instead it is replacing the current view the partial. What I am missing that is causing the partial to be loaded /replacing the current document and what do I need to change to get the partial to render only within the specified div element?
After working through the Post Event more I discovered that the #Ajax.Action was not posting as an AJAX call. This was the result of the jquery-unobtrusive-ajax.js file being outdated and containing deprecated jquery functions (.live()) .
I updated the files through NuGet using
Install-Package Microsoft.jQuery.Unobtrusive.Ajax
and the actions are now working correctly.

Keep Bootstrap Modal open when clicking on a link

I have an Ajax Modal and have a number of links within the modal, however when I click on the links it will reload the page not the content within the Modal. How can I keep the Modal open? The code I am using:
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3>Modal header 2</h3>
</div>
<div class="modal-body">
//content
<div class="modal-footer">
<a class="btn btn-primary" onclick="$('.modal-body > form').submit();">Save Changes</a>
<a class="btn" data-dismiss="modal">Close</a>
</div>
$(document).ready(function() {
// Support for AJAX loaded modal window.
// Focuses on first input textbox after it loads the window.
$('[data-toggle="modal"]').click(function(e) {
e.preventDefault();
var url = $(this).attr('href');
if (url.indexOf('#') == 0) {
$(url).modal('open');
} else {
$.get(url, function(data) {
$('<div class="modal hide fade">' + data + '</div>').modal();
}).success(function() { $('input:text:visible:first').focus(); });
}
});
});
Chose to use an iFrame plugin https://github.com/Nikku/jquery-bootstrap-scripting/pull/69

Twitter-Bootstrap tabs load container content via AJAX

I'm trying to implement this example for Twitter-Bootstrap tabs http://www.dba-resources.com/scripting-programming/ajax-tabs-in-bootstrap-2-1/ loading content via AJAX, but I need to load the content from a div container within the same document, rather than loading multiple documents. The code I'm using is as follows:
jQuery
$(function() {
$("#MainTabs").tab();
$("#MainTabs").bind("show", function(e) {
var contentID = $(e.target).attr("data-target");
var contentURL = $(e.target).attr("href");
if (typeof(contentURL) != 'undefined')
$(contentID).load(contentURL, function(){ $("#MainTabs").tab(); });
else
$(contentID).tab('show');
});
$('#MainTabs div[data-target="#tabone"]').tab("show");
});
HTML
<ul id="MainTabs" class="nav nav-tabs">
<li><div data-target="#tabone" data-toggle="tab">tab One</div></li>
<li><div data-target="#tabtwo" data-toggle="tab" href="/test.html">Tab Two</div></li>
<li><div data-target="#tabthree" data-toggle="tab" href="/test2.html">Tab Three</div></li>
</ul>
<div class="tab-content">
<div class="tab-pane" id="tabone">Content Tab One</div>
<div class="tab-pane" id="tabtwo">Loading...</div>
<div class="tab-pane" id="tabthree">Loading...</div>
</div>
Thank you in advance for any help.
That should be the default behavior if you just pass in the id of the container to the href.
<li><div data-target="#tabone" data-toggle="tab" href="#loadedcontent">tab One</div></li>
....
<div id="loadedcontent">My content</div>
Since you have a special case where you want to load a specific container of the page through an AJAX call. You can do something like this.
HTML
<li><div id="specialTab" data-target="#tabone" data-toggle="tab" href="/ajax.html">tab one</div></li>
JS
$('#specialTab').click(function(e) {
e.preventDefault();
var containerId = '#content'; /** Specify which element container */
var self = $(this);
var url = self.attr('href');
$(self.data('target'))
.load(url +' '+ containerId, function(){
self.tab('show');
});
});

How to trigger Ajax with flash buttons?

I'm working on something where there are 2 links which triggers some Ajax. However I need to turn the links into Flash buttons (AS3). I've never worked with Ajax before, and I have no idea how this can be done.
Edit:
The Ajax:
<script>
$(document).ready(function() {
$('a.catlink').unbind('click').click(function(e)
{
e.preventDefault();
var link = $(this);
var inputs = [];
var cat_type = $(this).attr('href').replace('#', '');
link.attr('disabled', 'disabled');
inputs.push('cat_type=' + escape(cat_type));
$.ajax(
{
type: "POST",
cache: false,
dataType: "html",
url: window.location.href,
data: inputs.join('&'),
success: function(html)
{
var json = $.parseJSON(html);
if (json['status'] == 1)
{
$('div.listing').html(json['html']);
}
link.removeAttr('disabled');
}
});
});
});
</script>
The HTML
<h1 class="section-head">Products
// **The 2 links*** //
<a class="catlink" href="#cinema">cinema</a> <a class="catlink" href="#smart">smart</a></h1>
<div class="listing">
<ul class="listing">
{foreach from=$products item="product_info"}
<li class="clearfix">
<div class="inner-left">
<img height="68" width="90" src="{$product_info.image}" />
<h2 class="normal mt-5">{if $product_info.price != '0'}${$product_info.price}{else}Click for price »{/if}</h2>
</div>
<div class="inner-right">
<h3 class="mb-0">{$product_info.productName}</h3>
<p class="small mb-5"><span class="quiet">{$product_info.category}</span></p>
<p class="mb-15">{$product_info.description}</p>
<a class="button getprice" href="{$product_info.url}">Buy Now</a>
<br><br>
</div>
</li>
{/foreach}
</ul>
</div>
If you're going to use AS3 then you can use ExternalInterface.call() to call a JavaScript function on the page. Though, using Ajax may not be required if you're using AS3 because you can make use of the URLLoader class to do the same thing (call a PHP script and decode a result).
If you describe more accurately what you want to achieve then I shall provide some example code and clarify a little more.

Resources