Load External Panel To Jquery Mobile Page - javascript

JQuery Mobile template which utilises a side panel. For simplicity I want to be able to load this panel from an 'external page' / seperate document so that it can be built once and used on many pages.
A bit of research has resulted in me getting the following code to load a string of html into a variable and then loading that variable into each page as the side panel:
/* Get the sidebar-panel as a var */
var side_var = '<div data-role="panel" id="left-panel" data-position="left" data-display="push"><h1>Panel</h1><p>stuff</p></div>';
/* Load the side-panel var to the DOM / page */
$(document).one('pagebeforecreate', function () {
$.mobile.pageContainer.prepend( side_var );
$("#left-panel").panel();
});
This works perfectly, however it still doesn't address the need to build the sidebar / panel as a separate html file.
A bit more work and I discovered this snippet to load a page into a variable:
$.get("http://www.somepage.com", function( side_var ) {}, 'html');
So in theory adding the two together should give me the desired result;
/* Get the sidebar-panel as a var */
$.get("mypage.html", function( side_var ) {}, 'html');
/* Load the side-panel var to the DOM / page */
$(document).one('pagebeforecreate', function () {
$.mobile.pageContainer.prepend( side_var );
$("#left-panel").panel();
});
However, all I get when running this is an eternally rotating AJAX loader.
What am I missing &/or doing wrong??
COMPLETE SOLUTION
Omar's solution below goes most of the way but needs one small but important addition to make the JQM elements display as expected. Here is the complete solution:
$(document).one("pagebeforecreate", function () {
$.get('side-panel.html', function(data) {
//$(data).prependTo($.mobile.pageContainer); //or .prependTo("body");
$.mobile.pageContainer.prepend(data);
$("[data-role=panel]").panel().enhanceWithin(); // initialize panel
}, "html");
});
Each element to be enhanced as a JQM element needs the data-theme adding to tell it which theme to use. Additionally in the JavaScript the initialised panel widget needs to .enhanceWithin() in order for the elements to be rendered with the desired style.

the $.get() function should be wrapped in pagebeforecreate event, to append contents directly once retrieved. Also, you need to initialize retrieved contents.
$(document).one("pagebeforecreate", function () {
$.get('mypage.html', function(data){
$(data).prependTo("body"); // or .prependTo($.mobile.pageContainer);
$("[data-role=panel]").panel(); // initialize panel
}, "html");
});

Related

Scripts not loading after loading new page using AJAX (Barba.js)

I'm exploring the option of using AJAX to give elegant page transitions.
I've tried two methods, the first being a manually coded option taken from this page (https://codyhouse.co/gem/animated-page-transition) and the second option using Barba.js (http://barbajs.org).
With both options the scripts on the website work when the first page is loaded, but when a link is clicked and a different page is loaded via AJAX, none of the scripts work.
Originally I had my scripts loaded into the end of each page using an embedded html file (I'm using ExpressionEngine). After reading a number of posts on this site I thought it might help to put the scripts into their own JS file so that this is cached and each page can then use these scripts but this didn't work either.
Is there a way to tell AJAX or Barba.js to run the scripts each time it changes the page?
Here's my code to start Barba:
<script type="text/javascript">
$(document).ready(function () {
// START BARBA.JS
Barba.Pjax.start();
// BARBA.JS PAGE TRANSITIONS
Barba.Pjax.start();
var FadeTransition = Barba.BaseTransition.extend({
start: function() {
/**
* This function is automatically called as soon the Transition starts
* this.newContainerLoading is a Promise for the loading of the new container
* (Barba.js also comes with an handy Promise polyfill!)
*/
// As soon the loading is finished and the old page is faded out, let's fade the new page
Promise
.all([this.newContainerLoading, this.fadeOut()])
.then(this.fadeIn.bind(this));
},
fadeOut: function() {
/**
* this.oldContainer is the HTMLElement of the old Container
*/
return $(this.oldContainer).animate({ opacity: 0 }).promise();
},
fadeIn: function() {
/**
* this.newContainer is the HTMLElement of the new Container
* At this stage newContainer is on the DOM (inside our #barba-container and with visibility: hidden)
* Please note, newContainer is available just after newContainerLoading is resolved!
*/
var _this = this;
var $el = $(this.newContainer);
$(this.oldContainer).hide();
$el.css({
visibility : 'visible',
opacity : 0
});
$el.animate({ opacity: 1 }, 400, function() {
/**
* Do not forget to call .done() as soon your transition is finished!
* .done() will automatically remove from the DOM the old Container
*/
_this.done();
});
}
});
/**
* Next step, you have to tell Barba to use the new Transition
*/
Barba.Pjax.getTransition = function() {
/**
* Here you can use your own logic!
* For example you can use different Transition based on the current page or link...
*/
return FadeTransition;
};
});
</script>
And here's the script that I'm trying to get to work:
// DROPDOWN MENU
$(function(){
$("ul.dropdown li").hover(function(){
$(this).addClass("hover");
$('ul:first',this).css('visibility', 'visible');
}, function(){
$(this).removeClass("hover");
$('ul:first',this).css('visibility', 'hidden');
});
$("ul.dropdown li ul li:has(ul)").find("a:first").addClass("arrow");
});
Thanks in advance,
Tom
I don't meet barba.js, but in jquery when we use $(function{...}); is like use $(document).ready(function(){...}); It's launched when document is ready. Probably is not launched when your animation ends. I'm not sure, but you can try creating different views, and write your custom javascript code inside onEnter callback method:
view:
<div class="barba-container" data-namespace="homepage">
javscript:
var Homepage = Barba.BaseView.extend({
namespace: 'homepage',
onEnter: function() {
// The new Container is ready and attached to the DOM.
YOUR JS !!!!
},
onEnterCompleted: function() {
// The Transition has just finished.
},
onLeave: function() {
// A new Transition toward a new page has just started.
},
onLeaveCompleted: function() {
// The Container has just been removed from the DOM.
}
});
// Don't forget to init the view!
Homepage.init();
http://barbajs.org/views.html
you question is quit unclear,
basically ajax is used to render loaded page, if your page is already loaded then
just add this script to your root web page, and check if it is working or not after ajax call.

jQuery load dynamic content and make it accessible with a url

I have little time studying JavaScript and jQuery and would like to learn how to load dynamic content in a div of the site by a button and the loaded content create a new url to be indexable and could share with friends social networks, etc.
I created a function that is called with the onclick event of a button. The function takes two parameters, the div where to load the content and the path where the content to be loaded is stored:
function contentLoad(nameDiv, url)
{
$(name).load(url, function() {
});
}
button:
Moon
I do not know if I'll be doing well. The code still being very simple and charge me works perfectly content. But I'd like to load content would generate a new url that was accessible and that the link could be shared. How could I get it?
I think we need to store data loaded into a content with jQuery url when attempting to access, mount everything automatically and show visitors the web with dynamic content already loaded.
See if you can guide me in the process and that steps need to get it. Thanks to all.
You can use "client routes", using the hash tag in your url, and than some js lib which can handle this routes, for instance you can use director js, here is an example:
$(function() {
var author = function () {
// Load your content using AJAX
$("#content").html("author");
};
var viewBook = function (bookId) {
$("#content").html("viewBook: bookId is populated: " + bookId);
};
var routes = {
'/author': author,
'/books/view/:bookId': viewBook
};
var router = Router(routes);
router.init();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Director/1.2.8/director.js"></script>
<div id="content"></div>
<ul>
<li>#/author</li>
<li>#/books/view/1</li>
</ul>

JavaScript/jQuery - Navigation between pages

I would like to know which is the proper way to navigate between pages using ajax calls.
An example, we got this 3 html pages.
users.html (with users.js which initializes it and has its own functions)
cars.html (with cars.js which initializes it and has its own functions)
bills.html (with bills.js which initializes it and has its own functions)
What would be the proper way to go from users.html to cars.html ? I got this problem because I dont know how to "load" the cars.js after doing the ajax call in users.html.
¿If I load it with $.getScript(), how can I remove the users.js after adding the cars.js?
Thanks.
You can try to build a SPA (Single Page Application). You will have one index html file that uses the other html files as templates. For example you have a div main container whose content is replaced with users.html/cars.html/bills.html upon clicking a link.
Routing helps you get that done without refreshing the page. It also supports history.
Look up dependency injection so that you learn how you can download only the js files you depend on.
If you don't use routing and you only change the page content you lose history which is a really neat thing to have.
SPA with Routing and Templating
Routing with Sammy.js
Examples:
<body>
Cars
Bills
<div id="wrapper"></div>
<script src="jquery.js"></script>
<script src="sammy.js"></script>
<script>
(function() {
app.router = Sammy(function () {
var selector = '#wrapper';
this.get('#/cars', function() {
$.get('cars.html', function (view) {
$(selector).html(view);
});
this.get('#/bills', function() {
$.get('bills.html', function (view) {
$(selector).html(view);
});
});
});
app.router.run('#/cars'); //Link to load on app opening
}());
</script>
</body>
You can call page with $.get() like
$.get( "cars.html", function( data ) {
$(document).html(data);
alert( "Load was performed." );
});
In cars.js use all functions with $(document).ready()
but all functions must be:
$(document).on("yourevent","selector",function(){
});
while you load page cars.js will load if you import it in cars.html page
Read more about jquery.get() and jquery.on()

Reinitializing jScroll after AJAX call? (Still loading old href after AJAX load)

I'm paginating search results returned from an AJAX call with jScroll:
$('#search').keyup(function() {
var search = $(this).val();
$.get('/search', {search : search}, function(results) {
$('.scroll-table').html(results);
$('.scroll-table').jscroll();
});
});
After making a new search, when I scroll to the bottom, jScroll loads the content of the last href for the old search.
So if my old _nextHref was /search?query=A&page=3 and I enter B in the search field, instead of loading /search?query=B&page=2 from the new href, it will load /search?query=A&page=3 from the old href.
Apparently calling jscroll() from the ajax success function won't reconstruct it and _nextHref stays set to its old value. I tried destroying it before loading it, but it will keep it fom loading altogether:
$('#search').keyup(function() {
var search = $(this).val();
$('.scroll-table').jscroll.destroy();
$.get('/search', {search : search}, function(results) {
$('.scroll-table').html(results);
$('.scroll-table').jscroll(); /* now jScroll won't load at all */
});
});
Can you please give me an example how to reinitialize jScroll so it loads the new href?
I found a temporary solution by commenting out the following line:
// if (data && data.initialized) return;
This caused a further problem.. If the result list fits a single page (no pagination needed so there is no href on the first page, "Loading..." is displayed on the bottom of the list, because jScroll wanted to GET "/undefined" from the server. Here is how i fixed it:
// Initialization
if (_nextHref != 'undefined') {
$e.data('jscroll', $.extend({}, _data, {initialized: true, waiting: false, nextHref: _nextHref}));
_wrapInnerContent();
_preloadImage();
_setBindings();
} else {
_debug('warn', 'jScroll: nextSelector not found - destroying');
_destroy();
return false;
}
I don't know if there is a better way to do this, but now it works with AJAX calls as I expect it to work. If anyone knows of a proper way to reinitialize the plugin, please share it with us.
UPDATE: I created a proper fork of jScroll allowing it to be reinitialized on each AJAX load, preventing it from loading the old href, using:
$('.scroll').jscroll({
refresh: true
});
Hopefully this functionality gets merged in the main version.
If you don't want to patch jScroll, you can clear the jScroll data in your load (or get) callback:
var pane = $('#myInfiniteScroll');
pane.load(url, function() {
pane.data('jscroll', null);
pane.jscroll({
nextSelector: "link[rel='next']",
autoTrigger: true,
});
});
When you call the jscroll function, pass the same parameters as when you first initialized it (in this example, I defined two configuration parameters, but use what you need.). Better yet, factor that out into its own function so you don't end up duplicating code.

jQuery - bxSlider plugin reloadSlider issues

I'm using jQuery with the bxSlider plugin, here is the link to it just incase: http://bxslider.com/
I'm trying to reload the slider and my custom pager after I've removed certain slides from it.
Here is what I have tried:
$(function() {
var slider = $('#slider').bxSlider({
pagerCustom: '#bx-pager'
});
$('.list').on('click', '.delete', function() {
image = $(this).closest('li').find('[type="hidden"]');
// image.attr('id') contains a string: image-0, image-1, image-2, etc.
$('#slider, #bx-pager').find('.' + image.attr('id')).remove();
slider.reloadSlider({
pagerCustom: '#bx-pager'
}); // I have also tried: slider.reloadSlider();
});
});
It works partially. What happens is the slider gets reloaded just fine but it removes the pager completely when it runs the reload.
Thank you very much for any help.
As long as I see, this is a bug in bxSlider, in fact, when you call the reloadSlider method, internally are called the methods destroySlider and init.
In the destroySlider method the pagerEl element is destroyed, this is right if you are not using a custom one, because it is recreated programmatically in the init method, but if you are using a custom one it can't be recreated programmatically.
I ended up modifying the destroySlider method to check if a custom pager is used, in this case it must not be deleted.
Here is the before (line 1294):
if(slider.pagerEl) slider.pagerEl.remove();
And after:
if (slider.settings.pagerCustom === '') {
if(slider.pagerEl) slider.pagerEl.remove();
}
I'll post the bug on GitHub as soon as I have the time.

Categories

Resources