scroll-target="document" from within custom element with iron-scroll-threshold - scroll

I want to fire an method of a nested custom element when the document scroll position gets close to the bottom using iron-scroll-threshold.
So, I have an the index.html file like this:
<link rel="import" href="/src/my-app.html">
<body>
<my-app></my-app>
</body>
</html>
and inside the my-app element, I have my-questions element like this:
<iron-pages
selected="[[page]]"
attr-for-selected="name"
fallback-selection="view404"
role="main">
<my-questions name="questions"></my-questions>
<my-view404 name="view404"></my-view404>
</iron-pages>
Now finally inside the my-questions element, I have
<ul id="question-list">
<template is="dom-repeat" items="[[questions]]" sort="_computeSort" as="question">
<poll-result questionkey="[[question.$key]]"></poll-result>
</template>
</ul>
<iron-scroll-threshold on-lower-threshold="_loadMoreQuestions" lower-threshold="400" id="threshold" lower-triggered="{{nearBottom}}" scroll-target="document">
</iron-scroll-threshold>
and my loadMoreQuestions function:
_loadMoreQuestions: function(){
console.log('load more questions fired');
var questionCount = this.$.questionQuery.limitToLast;
this.$.questionQuery.limitToLast = questionCount + 10;
var threshold=this.$.threshold;
threshold.clearTriggers();
},
Now, the _loadMoreQuestions method fires once when the page is loaded, but never again. How can I made this method to fire whenever the document is scrolled 400px from the bottom?

Related

Infinite Scroll on ajax loaded content

I'm doing a WP_Query on let's say page-a.php, that page has a div called target where page-b.php is being loaded into. Page-a is a custom template and page-b is an archive page.
The structure on page A as example:
<body>
<div id="wrap">
<div class="target">
while
<div class="post">
<h1>Title</h1>
<p>Description</p>
</div>
endwhile
<div class="pagination"></div>
</div>
</div>
</body>
On page-b I only include the < post > and < pagination > divs within a regular wp loop.
Now the jQuery:
$(window).load(function() {
$('.target').infinitescroll({
navSelector : ".navigation",
// selector for the paged navigation (it will be hidden)
nextSelector : ".navigation a.next",
// selector for the NEXT link (to page 2)
itemSelector : ".post",
// selector for all items you'll retrieve
debug : true,
loading: {
finishedMsg: '<div class="alert alert-info" style="margin-top:50px"><p class="center">All posts were loaded</p></div>',
img: '',
msg: null,
msgText: "<p style='text-align:center; margin-top:50px;'><i style='font-size:60px; color:#babfc8'class='fa fa-cog fa-spin'></i></p>"
}
}, function(arrayOfNewElems){
$('.post').animate({"opacity":"1","max-height":"150px","padding":"15px 8px"},800, "jswing");
}
);
});
-If I call that script on page-a.php will only work on it, once page-b content is placed on
-If I call on page-a.php and page-b.php it works on first, then when first ajax content is loaded and then (if I apply a new filter) it won't work.
-If I call the script on my ajax response function it will work once, then if I apply another filter and target div refreshes content, I get the
Uncaught TypeError: Cannot call method 'appendTo' of null
div classes called (.target and .post) are present on the page.
What the hell am I doing wrong here. Thanks.
PS: If you need to take a look at the real scripts let me know and I will provide.
I think you need this : http://www.247techblog.com/implement-infinite-scroll-functionality-wordpress-wp-ajax-function/
Just need to call a wp ajax function

Using .load() to Sequentially Load a Series of HTML Documents

BACKGROUND: I'm trying to use .load() to build a site from several
pages, where a user can click a button to load the next page's
content using .load().
PROBLEM: The .load() only works on the first click (loads
content from pagetwo.html), then doesn't load any
content for pages after that.
CODE:
My start page markup looks like this:
<head>
<script src="script.js"></script>
</head>
<body>
<div class="content">
<p>This is page 1.</p>
<button id="pageone">next</button>
</div>
</body>
Then my pages 2-5 contain only partial HTML, to be loaded
into div.content:
Page 2:
<p>This is page 2.</p>
<button id="pagetwo">next</button>
Page 3:
<p>This is page 3.</p>
<button id="pagethree">next</button>
Etc.
My jQuery script.js is loaded only once, with the full start page html:
$(document).ready(function() {
//load pages
$('button#pageone').click(function () {
$("div.content").load("page-two.html");
});
$('button#pagetwo').click(function () {
$("div.content").load("page-three.html");
});
$('button#pagethree').click(function () {
$("div.content").load("page-four.html");
});
});
Any ideas on why only the first .load() request works?
The ID #pagetwo and on onwards are newly introduced elements to the DOM after the first initial $(document).ready(). Thus, you'd have to access it differently there after:
$(document).on('click', 'button#pageone', function() {
$("div.content").load("page-two.html");
});
$(document).on('click', 'button#pagetwo', function() {
$("div.content").load("page-three.html");
});
$(document).on('click', 'button#pagethree', function() {
$("div.content").load("page-four.html");
});
The .on() handler will listen to any new elements through the entire document (As it starts at root) at any one stage. Your initial code was looking for elements that were present on just page load.
To read more about it, See the documentation about the .on() handler regarding new elements at "Direct and delegated events".

How to use AngularJS to lazy load content in a collapsible panel

I am building an application that uses the Bootstrap Collapse component to render a sequence of panels, all of which will initially be in the collapsed state.
Since the page may contain many such panels and each of them may contain a large amount of content, it seems appropriate to populate these panels on demand, by executing an AJAX call when the user expands any panel.
The dynamic content of the page (including the markup for the panels) is rendered using AngularJS, and I assume it's possible to configure Angular to bind to an event on the panel elements, that results in their content being lazy loaded when they expand.
Unfortunately, after looking at the AngularJS docs and the available tutorials, I can't see how best to tackle this. Can anyone throw any light on it?
Thanks in advance,
Tim
This is way old, but the question might still come up now and then. I now find this to be the most suitable solution without polluting your controllers:
(myDirective loading its content via AJAX right after its creation.)
<accordion>
<accordion-group
heading=""
ng-repeat="foo in bar"
ng-init="status = {load: false}"
ng-click="status.load = true">
<myDirective ng-if="status.load"></myDirective>
</accordion-group>
</accordion>
each element created by ng-repeat gets its own $scope, so clicking ab accordion-group will result in only the respective directive being loaded.
edit:
depending on latency and the size of the data that's to be lazy loaded, you might consider using ng-mouseover instead of ng-click. That way loading starts some 100ms before the user opens the accordion which can reduce 'sluggishness' of your UI. Obviously there's the downside of occasionally loading content of groups that are never actually clicked.
#Tim Coulter, I've created something following the idea of #Stewie.
It can definitely be improved, but I guess it's a good starting point.
I've created a small directive to bind the click event of the accordion's panel. When the click event is fired, I passed the panel template via the panel-template= attribute and it updates the main-template which is used inside the panel.
It makes reference to 2 html files (panel1.html and panel2.html) that contains the content of the each panel.
I would recommend to create a service to fetch these files via AJAX - just the way you wanted.
On the code below I created a service called dataService for this purpose and you should bind it to the click event - so files are loaded on demand when the user clicks on it.
Note the the mainTemplate is a common panel to all accordions, so when it changes the all the accordions will have the same content, BUT I am assuming you want to display only one panel at time, right ?!
Anyway as I said before the logic can be improved to fix these little 'gotchas', but I believe the core functionality is there to start with. :)
<!doctype html>
<html ng-app="myApp">
<head>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
<script>
var myApp = angular.module('myApp', []);
myApp.controller('AccordionDemoCtrl', ['$scope', 'dataService', function ($scope, dataService) {
$scope.oneAtATime = true;
$scope.mainTemplate = '';
$scope.groups = [
{
id: "001",
title: "Dynamic Group Header - 1",
content: "Dynamic Group Body - 1",
template: "panel1.html"
},
{
id: "002",
title: "Dynamic Group Header - 2",
content: "Dynamic Group Body - 2",
template: "panel2.html"
}
];
}]);
myApp.factory('dataService', [ '$http', function($http){
return {
getData: function() {
return // you AJAX content data here;
}
}
}]);
myApp.directive('accordionToggle', [function () {
return {
restrict: 'C',
scope: {
mainTemplate: '=',
panelTemplate: '#'
},
link: function (scope, element, iAttrs) {
element.bind('click', function(e){
scope.mainTemplate = scope.panelTemplate;
scope.$apply();
});
}
};
}]);
</script>
</head>
<body ng-controller="AccordionDemoCtrl">
<div class="accordion" id="accordionParent">
<div class="accordion-group" ng-repeat="group in groups" >
<div class="accordion-heading">
<a class="accordion-toggle" main-template="$parent.mainTemplate" panel-template="{{ group.template }}" data-toggle="collapse" data-parent="#accordionParent" href="#collapse{{ $parent.group.id }}">
Collapsible Group Item {{ $parent.group.id }}
</a>
</div>
<div id="collapse{{ group.id }}" class="accordion-body collapse">
<div class="accordion-inner">
<div class="include-example" ng-include="mainTemplate"></div>
</div>
</div>
</div>
</div>
</body>
</html>

Img onkeydown don't work

Why this code don't work properly?
<img src="picture.jpg" id="picture"/>
<script>
document.getElementById('picture').onkeydown = function() {alert('tekst');}
</script>
Your image doesn't have focus so it won't listen to the 'onkeydown' event. I'm not sure if it is possible to give an image focus in order for your onkeydown event to work.
Instead you could place your image within an a-tag which can have focus and therefore can listen to the onkeydown event.
Something like this:
<a id="picture" href="#">
<img src="picture.jpg" />
</a>
<script>
// The a tag
var picture = document.getElementById('picture');
// You have to put focus on the atag (or any element that you want to have for you onkeydown event.
picture.focus();
// Now your event will work
picture.onkeydown = function() {
alert('tekst');
}
</script>

Why does my cycle slideshow hide all the slides?

The jQuery plugin cycle looks for elements of class slideshow. I want to add this class to a <ul> element to make a slideshow out of its <li>s. But when I add the slideshow class to the <ul> element, all <li> disappear and I get no slideshow whatsoever.
The HTML looks like this:
<ul>
<li>
<h3 class="expander">...</h3>
<div class="content">
<p>...</p>
<h4>...</h4>
<ul class="slideshow">
<li>...</li>
<li>...</li>
</ul>
</div>
</li>
...
</ul>
As you see, the slideshow <ul> is included in another list. This parent list consists of headers which reveal the content of each list item on click. I am hiding all the .contents programmatically when the DOM is ready. Then, I add a click listener to the .expanders so they can show the hidden .contents.
It is inside these .contentss that I have .slideshows which use the cycle plugin to cycle through their list items.
The other weird thing about all this is that the slideshow's worked perfectly before I transformed my headers into toggles for their associated content. Indeed, when I added the toggle functionality to the headers, the slides are no longer visible. But then if I take away the slideshow class, they are visible again. Of course, they no longer have slideshow functionnality...
Here is the javascript for all this:
$(document).ready(function()
{
var expanders = $('.expander');
expanders.each(function()
{
$('.content', $(this).parent()).toggle();
$(this).click(function()
{
$('.content', $(this).parent()).toggle("blind", {"easing":"easeInOutCirc"}, "normal");
});
});
$('.slideshow').each(function() {
var parent = $(this).parent();
$(this).cycle(
{
fx: 'scrollHorz',
easing: 'easeInOutCirc',
timeout: 0,
nowrap: 1
});
});
});
Any idea what could be causing this problem?
Apparently, I needed to move the cycle code above the toggle code, like this:
$(document).ready(function()
{
$('.slideshow').each(function() {
var parent = $(this).parent();
$(this).cycle(
{
fx: 'scrollHorz',
easing: 'easeInOutCirc',
timeout: 0,
nowrap: 1
});
});
var expanders = $('.expander');
expanders.each(function()
{
$('.content', $(this).parent()).toggle();
$(this).click(function()
{
$('.content', $(this).parent()).toggle("blind", {"easing":"easeInOutCirc"}, "normal");
});
});
});
I don't know why this works though, so better answers would be appreciated.

Resources