I am wanting to use Collapsible DIVs to show and hide content from the user.
I found this jQuery code to do the expand and collapse:
http://webcloud.se/code/jQuery-Collapse/
However the content is already loaded in the divs (its just hidden from view).
So I then found this:
http://www.raymondcamden.com/index.cfm/2011/4/5/Collapsible-content-and-Ajax-loading-with-jQuery-Mobile
Which loads the content into the opening div but also unloads it when it closes!
However its all mixed in with jQuery mobile and so it styled.
I want to be able to style the divs myself. also the first example uses nice bounce or fade effects to bring the content into view.
The reason for doing this is I want to show the user different content such as images or flash files but I don't want everything to load into the page on page load, this would be too much stuff.
So how can I use the first jQuery Collapse example but with loading external pages in?
I liked the question so I spent a little time making something close to a plugin:
//only run the event handler for collapsible widgets with the "data-url" attribute
$(document).delegate('.ui-collapsible[data-url] > .ui-collapsible-heading', 'click', function () {
//cache the collapsible content area for later use
var $this = $(this).siblings('.ui-collapsible-content');
//check if this widget has been initialized yet
if (typeof $this.data('state') === 'undefined') {
//initialize this widget
//update icon to gear to show loading (best icon in the set...)
$this.siblings('.ui-collapsible-heading').find('.ui-icon').removeClass('ui-icon-plus').addClass('ui-icon-gear')
//create AJAX request for data, in this case I'm using JSONP for cross-domain abilities
$.ajax({
//use the URL specified as a data-attribute on the widget
url : $this.closest('.ui-collapsible').data('url'),
type : 'get',
dataType : 'jsonp',
success : function (response) {
//get the height of the new content so we can animate it into view later
var $testEle = $('<div style="position:absolute;left:-9999px;">' + response.copy + '</div>');
$('body').append($testEle);
var calcHeight = $testEle.height();
//remove the test element
$testEle.remove();
//get data to store for this widget, also set state
$this.data({
state : 'expanded',
height : calcHeight,
paddingTop : 10,
paddingBottom : 10
//add the new content to the widget and update it's css to get ready for being animated into view
}).html('<p>' + response.copy + '</p>').css({
height : 0,
opacity : 0,
paddingTop : 0,
paddingBottom : 0,
overflow : 'hidden',
display : 'block'
//now animate the new content into view
}).animate({
height : calcHeight,
opacity : 1,
paddingTop : $this.data('paddingTop'),
paddingBottom : $this.data('paddingBottom')
}, 500);
//re-update icon to minus
$this.siblings('.ui-collapsible-heading').find('.ui-icon').addClass('ui-icon-minus').removeClass('ui-icon-gear')
},
//don't forget to handle errors, in this case I'm just outputting the textual message that jQuery outputs for AJAX errors
error : function (a, b, c) { console.log(b); }
});
} else {
//the widget has already been initialized, so now decide whether to open or close it
if ($this.data('state') === 'expanded') {
//update state and animate out of view
$this.data('state', 'collapsed').animate({
height : 0,
opacity : 0,
paddingTop : 0,
paddingBottom : 0
}, 500);
} else {
//update state and animate into view
$this.data('state', 'expanded').animate({
height : $this.data('height'),
opacity : 1,
paddingTop : $this.data('paddingTop'),
paddingBottom : $this.data('paddingBottom')
}, 500);
}
}
//always return false to handle opening/closing the widget by ourselves
return false;
});
The collapsible HTML looks like this:
<div data-role="collapsible" data-url="http://www.my-domain.com/jsonp.php">
<h3>Click Me</h3>
<p></p>
</div>
Here is a demo: http://jsfiddle.net/YQ43B/6/
Note that for the demo I found the best way to make the initial animation smooth was to add this CSS:
.ui-mobile .ui-page .ui-collapsible .ui-collapsible-content {
padding-top : 0;
padding-bottom : 0;
}
The default padding added by jQuery Mobile is 10px for both top and bottom paddings, I added those values as data-attributes to each widget to maintain the defaults.
Note that this code can be slightly tweaked to show other types of content, I used JSONP simply because you can use it on JSFiddle.
Here is an example that I made :
$(document).ready(function () {
$('.accordian_body').hide();
});
$('.accordian_head').click(function () {
$(this).next().animate(
{ 'height': 'toggle' }, 'fast'
);
Then in HTML
<div class="accordian_head"></div>
<div class="accordian_body"></div>
in CSS you can style the head and body however you like , to add in code behind -
<asp:Literal ID="lit1" runat="server" />
foreach(DataRow dr in DataTable.Rows)
{
lit1.Text = lit1.Text + "<div class=\"accordian_head\">" Whatever you want... "</div><div class=\"accordian_body\">" Whatever in body "</div>
}
Check this link it's in php and shows how to load external link to DIV Ajax can load only internal pages and doesn't work across domains.
Related
I am working on a SharePoint page, utilizing the jslink for the list web part. I have the following code written out:
(function () {
var overrideCurrentContext = {};
overrideCurrentContext.Templates = {};
overrideCurrentContext.Templates.Header = "<div class='ListAccordion'>";
overrideCurrentContext.Templates.Footer = "</div>";
overrideCurrentContext.OnPostRender = OnPostRender;
overrideCurrentContext.Templates.Item = ItemTemplate;
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCurrentContext);
})();
function ItemTemplate(ctx) {
var Title = ctx.CurrentItem["Title"];
var Body = ctx.CurrentItem["Body"];
return "<h2>" + Title + "</h2><p>" + Body + "</p><br/>";
}
function OnPostRender() {
$('.ListAccordion h2').click(function () {
$(this).next().slideToggle();
}).next().hide();
$('.ListAccordion h2').css({
"background-color": "#0B0B61",
"cursor": "pointer",
"color": "white" ,
"border-radius" : "15px",
"padding-left" : "10px"
});
}
The problem I am having, is that my accordion view will not display until I utilize the manual refresh option, or I wait for the Asynchronous Automatic Refresh both under the AJAX option of the web part properties.
The accordion shows up perfect, until I save, or reload the page, but it works if I utilize the ajax options. Is there anything I can do to make sure the accordion shows right away when the page is first opened?
also I have the file saved in my siteassets and this is the link I am using ~site/SiteAssets/Accordions12.js
Add the following to the header of your script editor but replace the middle parts with what your file/location is
<script src="/_catalogs/masterpage/test1/jquery-1.11.2.min.js" type="text/javascript"></script>
So I made a directive for a toggle (drop down) menu in AngularJS. I used the directive for multiple items within the page but I have a small problem. When one item is open and I click another one I want the previous one to close. The event.preventDefault and event.stopPropagation stops the event for the previous item and doesn't close it. Any ideas on how to fix this? Is there a way to perhaps only stop the event within the scope?
app.directive('toggleMenu', function ($document) {
return {
restrict: 'CA',
link: function (scope, element, attrs) {
var opened = false;
var button = (attrs.menuButton ? angular.element(document.getElementById(attrs.menuButton)) : element.parent());
var closeButton = (attrs.closeButton ? angular.element(document.getElementById(attrs.closeButton)) : false);
var toggleMenu = function(){
(opened ? element.fadeOut('fast') : element.fadeIn('fast'));
};
button.bind('click', function(event){
event.preventDefault();
event.stopPropagation();
toggleMenu();
opened = ! opened;
});
element.bind('click', function(event){
if(attrs.stayOpen && event.target != closeButton[0]){
event.preventDefault();
event.stopPropagation();
}
});
$document.bind('click', function(){
if(opened){
toggleMenu();
opened = false;
}
});
}
};
And here's a Fiddle: http://jsfiddle.net/JknUJ/5/
Button opens content and content should close when clicked outside the div. When clicked on button 2 however content 1 doesn't close.
Basic idea is that you need to share the state between all your dropdown submenus, so when one of them is shown, all others are hidden. The simpliest way of storing state (such as opened or closed) are... CSS classes!
We'll create a pair of directives - one for menu, and another for sumbenu. It is more expressive that just divs.
Here is out markup.
<menu>
<submenu data-caption="Button 1">
Content 1
</submenu>
<submenu data-caption="Button 2">
Content 2
</submenu>
</menu>
Look how readable is it! Say thanks to directives:
plunker.directive("menu", function(){
return {
restrict : "E",
scope : {},
transclude : true,
replace : true,
template : "<div class='menu' data-ng-transclude></div>",
controller : function ($scope, $element, $attrs, $transclude){
$scope.submenus = [];
this.addSubmenu = function (submenu) {
$scope.submenus.push(submenu);
}
this.closeAllSubmenus = function (doNotTouch){
angular.forEach($scope.submenus, function(submenu){
if(submenu != doNotTouch){
submenu.close();
}
})
}
}
}
});
plunker.directive("submenu", function(){
return {
restrict : "E",
require : "^menu",
scope : {
caption : "#"
},
transclude : true,
replace : true,
template : "<div class='submenu'><label>{{caption}}</label><div class='submenu-content' data-ng-transclude></div></div>",
link : function ($scope, $iElement, $iAttrs, menuController) {
menuController.addSubmenu($scope);
$iElement.bind("click", function(event){
menuController.closeAllSubmenus($scope);
$iElement.toggleClass("active");
});
$scope.close = function (){
$iElement.removeClass("active");
}
}
}
});
Look thar we restricted them to HTML elements (restrict : "E"). submenu requires to be nested in menu (require : "^menu"), this allows us to inject menu controller to submenu's link function. transclude and replace controls the position of original markup in compiled HTML output (replace=true means that original markup will be replaced with compiled, transclude inserts parts of original markup to compiled output).
When we've done with this, we just say to menu close all your child menus! and menu iterates over submenus, forcing them to close.
We are adding childs to menu controller in addSubmenu function. It is called in submenus link function, thus every compiled instance of submenu adds itself to menu. Now, closing all submenus is as easy as iterating over all children, this is done by closeAllSubmenus in menu controller.
Here is a full Plunker to play with.
I am developing a website and I want to load the data dynamically on scrolling the page,When the scroll bar reaches the bottom of the page I want to load more data from the database using AJAX.
In my web page there is a iframe in which i want to append the new data.Like flipkart.com website. Where on scrolling the page new products are loaded.
Could anyone help me in this regard?
Thanks in advance.
I have tried many times but no luck what i'm getting is only once the GetActivity() is being called,that too when i scroll down its not calling GetActivity(),but when i scroll up from that point it calls javascript function GetActivity()And on repeating this it is not working
here is the code which i used as given by Greg :please look into this and help.
<html>
<head>
<script type="text/javascript" src="jQuery-1.4.1-min.js"></script>
<script type="text/javascript">
$(window).scroll(function() {
var bottom = getBottom(window),
$reset = $("#activity_reset");
if (bottom == $(this).scrollTop() && $reset.val() == 0) {
$reset.val(1);
$("#activity_loading").show();
if ($("#activity_full").val() == 0) {
setTimeout("GetActivity();", 100);
}
}
});
function getBottom(e) {
height = $(document).height();
windowheight = $(e).height();
return height - windowheight;
}
function GetActivity()
{
alert("got it!");
$('div.tt').html('1');
$('div.ttt').html('1');
}
function setting()
{
$('div.tt').html('0');
$('div.ttt').html('0');
}
</script>
</head>
<body onload="return setting()" >
<pre>
<!--here i have used some junk texts so that a scroll bar appears in the browser-->
</pre>
<div style="display:none" id="activity_full" class="ttt"></div>
<div style="display:none" id="activity_reset" class="tt"></div>
</body>
</html>
This will monitor the page and load the function GetActivity() when you scroll down to the bottom of the page; you can put your ajax call in there and edit this accordingly to display the data you wish to have appear on the page.
$(window).scroll(function() {
var bottom = getBottom(window),
$reset = $("#activity_reset");
if (bottom == $(this).scrollTop() && $reset.val() == 0) {
$reset.val(1);
$("#activity_loading").show();
if ($("#activity_full").val() == 0) {
setTimeout("GetActivity();", 1000);
}
}
});
function getBottom(e) {
height = $(document).height();
windowheight = $(e).height();
return height - windowheight;
}
function GetActivity() {
/* ajax call in here */
}
When the window is scrolled the .scroll(function()) is triggered; the getBottom(window) function then calculates the document height and the screen height and subtracts them to see if the user's window has reached the bottom of the screen. $("#activity_reset") is then stored to an identifier for later use.
Once the action is fired your reset value is set to one so that the ajax isn't fired more than once at a time. The loading bar is displayed and a timeout is then set for the GetActivity() function.
$("#activity_reset") -> Should be a hidden div on the page that holds a value of either 1 or 0; it should be initialized as 0 and when the users browser hits the bottom of the page your ajax call is fired and once it is done being loaded you should then set the value back to 0 to allow loading again.
$("#activity_show") -> Should be a hidden div on the page that contains a loading image, or simply text saying that something is loading (not necessary but certainly helps for user experience).
$("#activity_full") -> Is another hidden div that is used to identify when your div is full and should not load anymore content. It should be initialized to 0 and when you have loaded as many items as can fit on the page you can set it to 1 (likely in your GetActivity() function) to prevent any further loading.
Further Explaining:
Inside of your GetActivity() function change the following:
$('div.tt').html('1');
//returns <div class="tt">1</div>
to
$('div.tt').val(1);
//returns <div class="tt" value="1"></div>
Your code is setting the html of the div to be 1, when what you actually want is for the value attribute to be equal to 1 since that is what the script is checking for in the comparison. I also noticed that you are also setting $('div.ttt') to be 1 as well, but this will stop the script from loading any further. This one should only be set to one once a condition has been met and you would no longer like any items to load.
$num = 6; //number of items per page
if($num == 6)
$('div.ttt').val(1);
Hope that clears things up; let me know.
hi
i am loading images on my web site after page load with jquery, i use $(document).ready to load images after page load now i want to specify order so i can load images of my slide show in a manner and have my slide show hidden, after slide show picture load show it.
this is an html part of my code:
<a class="videoThumb imageLightbox" href="images/slider/pic-usa-11-large.jpg">
<img src="/images/blank.gif" class="delayLoad" onmouseover="this.src = './images/slider/pic-usa-11.jpg'" width=" 215px" height="160px"/>
</a>
and i load images after document ready:
$(document).ready(function() {
// Load images once the page has loaded
jQuery("img.delayLoad").each(function() {
// Create a new span element which we will wrap around our image
// Using a span because if the image was inside an <a> tag then online inline elements should be used
var delaySpan = document.createElement("span");
with (jQuery(this)) {
// Handle images that are hidden, otherwise display mode for the span should be block (inline doesn't work properly)
if (css('display') == 'none') {
var _display = 'none' } else {
var _display = 'block' }
// Copy the style from the image into a new object (this means you don't need to worry about styling this span within your CSS)
var cssObj = {
'height' : css('height'),
'width' : css('width'),
'margin-top' : css('margin-top'),
'margin-right' : css('margin-right'),
'margin-bottom' : css('margin-bottom'),
'margin-left' : css('margin-left'),
'background-image' : css('background-image'),
'background-color' : css('background-color'),
'background-repeat' : css('background-repeat'),
// Hack for now, becuase IE doesn't seem to read the background-position property correctly
'background-position' : '50% 50%',
'display' : _display
}
}
// Apply our style properties to our span
jQuery(delaySpan).css(cssObj);
// Wrap the image in the span
jQuery(this).wrap(delaySpan)
// Hide the image (leaving just the span visible
.hide()
// Simulate the mouse over the image, whcih will cause it to switch the img src
.mouseover()
// Remove the mouseover attribute (since we don't want to update the img src every time the user does a mouseover
.removeAttr("onmouseover")
// Simulate the mouse moving out of the image (To reset the image to its normal state)
.mouseout()
// Once the image is loaded, perform a function
.load(function () {
// Fade the image in
// Remove the span by unwrapping the image
jQuery(this).fadeIn().unwrap();
});
});
});
(i used this document: http://www.purplepixelmedia.co.uk/Ourblog/tabid/78/articleType/ArticleView/articleId/80/Using-jQuery-to-loading-images-after-the-page-is-ready.aspx )
now i want to control images load and hide the box before all images are loaded and show the box after page load
how do i can do such task?
thanks
The jQuery Message Queueing plugin lets you perform serial AJAX requests. This may be what you're looking for.
Does anyone know how to trigger the stock jqGrid "Loading..." overlay that gets displayed when the grid is loading? I know that I can use a jquery plugin without much effort but I'd like to be able to keep the look-n-feel of my application consistent with that of what is already used in jqGrid.
The closes thing I've found is this:
jqGrid display default "loading" message when updating a table / on custom update
n8
If you are searching for something like DisplayLoadingMessage() function. It does not exist in jqGrid. You can only set the loadui option of jqGrid to enable (default), disable or block. I personally prefer block. (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:options). But I think it is not what you wanted.
The only thing which you can do, if you like the "Loading..." message from jqGrid, is to make the same one. I'll explain here what jqGrid does to display this message: Two hidden divs will be created. If you have a grid with id=list, this divs will look like following:
<div style="display: none" id="lui_list"
class="ui-widget-overlay jqgrid-overlay"></div>
<div style="display: none" id="load_list"
class="loading ui-state-default ui-state-active">Loading...</div>
where the text "Loading..." or "Lädt..." (in German) comes from $.jgrid.defaults.loadtext. The ids of divs will be constructed from the "lui_" or "load_" prefix and grid id ("list"). Before sending ajax request jqGrid makes one or two of this divs visible. It calls jQuery.show() function for the second div (id="load_list") if loadui option is enable. If loadui option is block, however, then both divs (id="lui_list" and id="load_list") will be shown with respect of .show() function. After the end of ajax request .hide() jQuery function will be called for one or two divs. It's all.
You will find the definition of all css classes in ui.jqgrid.css or jquery-ui-1.8.custom.css.
Now you have enough information to reproduce jqGrid "Loading..." message, but if I were you I would think one more time whether you really want to do this or whether the jQuery blockUI plugin is better for your goals.
I use
$('.loading').show();
$('.loading').hide();
It works fine without creating any new divs
Simple, to show it:
$("#myGrid").closest(".ui-jqgrid").find('.loading').show();
Then to hide it again
$("#myGrid").closest(".ui-jqgrid").find('.loading').hide();
I just placed below line in onSelectRow event of JQ grid it worked.
$('.loading').show();
The style to override is [.ui-jqgrid .loading].
You can call $("#load_").show() and .hide() where is the id of your grid.
its is worling with $('div.loading').show();
This is also useful even other components
$('#editDiv').dialog({
modal : true,
width : 'auto',
height : 'auto',
buttons : {
Ok : function() {
//Call Action to read wo and
**$('div.loading').show();**
var status = call(...)
if(status){
$.ajax({
type : "POST",
url : "./test",
data : {
...
},
async : false,
success : function(data) {
retVal = true;
},
error : function(xhr, status) {
retVal = false;
}
});
}
if (retVal == true) {
retVal = true;
$(this).dialog('close');
}
**$('div.loading').hide();**
},
Cancel : function() {
retVal = false;
$(this).dialog('close');
}
}
});
As mentioned by #Oleg the jQuery Block UI have lots of good features during developing an ajax base applications. With it you can block whole UI or a specific element called element Block
For the jqGrid you can put your grid in a div (sampleGrid) and then block the grid as:
$.extend($.jgrid.defaults, {
ajaxGridOptions : {
beforeSend: function(xhr) {
$("#sampleGrid").block();
},
complete: function(xhr) {
$("#sampleGrid").unblock();
},
error: function(jqXHR, textStatus, errorThrown) {
$("#sampleGrid").unblock();
}
}
});
If you want to not block and not make use of the builtin ajax call to get the data
datatype="local"
you can extend the jqgrid functions like so:
$.jgrid.extend({
// Loading function
loading: function (show) {
if (show === undefined) {
show = true;
}
// All elements of the jQuery object
this.each(function () {
if (!this.grid) return;
// Find the main parent container at level 4
// and display the loading element
$(this).parents().eq(3).find(".loading").toggle(show);
});
return show;
}
});
and then simple call
$("#myGrid").loading();
or
$("#myGrid").loading(true);
to show loading on all your grids (of course changing the grid id per grid) or
$("#myGrid").loading(false);
to hide the loading element, targeting specific grid in case you have multiple grids on the same page
In my issues I used
$('.jsgrid-load-panel').hide()
Then
$('.jsgrid-load-panel').show()