polymer iron-list only loading 20 items - ajax

I have an a test array that I am retrieving from iron-ajax with around 1000 items. I set that return array to the people property of my custom polymer element. Iron-list is displaying the first 20 results, but when i scroll down the rest of the results are not being loaded.
<link rel="import" href="/bower_components/iron-ajax/iron-ajax.html">
<link rel="import" href="/bower_components/iron-list/iron-list.html">
<link rel="import" href="/bower_components/iron-flex-layout/classes/iron-flex-layout.html">
<dom-module id="people-list">
<template>
<iron-list items="[[people]]" as="item" class="flex">
<template>
<div style="background-color:white; min-height:50px;">[[item.city]]</div>
</template>
</iron-list>
<iron-ajax
auto
id="ajaxPeopleList"
method="POST"
url="/people/list"
handle-as="json"
last-response="{{people}}">
</iron-ajax>
</template>
<script>
Polymer({
is: 'people-list',
properties: {
people: {
type: Array
}
}
});
</script>
</dom-module>
I think it may have to do with the height of the screen/iron-list element, but I am stuck and not sure how to proceed.
I can get it load all items if I set the height of the iron-list elements in pixels. But I just want it to fit on the screen. The docs make it look like you can use the iron-flex layout and use the class flex, which is what I tried to do in my sample code, but it has no effect.

This is because nothing is firing the iron-resize event to tell the iron-list to redraw the items. According to the docs:
Resizing
iron-list lays out the items when it recives a notification via the iron-resize event. This event is fired by any element that implements IronResizableBehavior.
By default, elements such as iron-pages, paper-tabs or paper-dialog will trigger this event automatically. If you hide the list manually (e.g. you use display: none) you might want to implement IronResizableBehavior or fire this event manually right after the list became visible again. e.g.
document.querySelector('iron-list').fire('iron-resize');
I've added the following to your code (which is probably a bit of a hack) and got it working:
ready: function () {
document.addEventListener("scroll", function () {
// fire iron-resize event to trigger redraw of iron-list
document.querySelector('iron-list').fire('iron-resize');
});
}

Ben Thomas is right. You're getting the json elements but it's not displayed because the iron-list needs to be redrawn. Since i had the same problem, i went to google polymers website and found THIS code example.
In short for your example:
<script>
// Only execute after DOM and imports (in our case the json file) has been loaded
HTMLImports.whenReady(function() {
Polymer({
is: 'people-list',
properties: {
people: {
type: Array
}
},
attached: function() {
// Use the top-level document element as scrolltarget
this.$.list.scrollTarget = this.ownerDocument.documentElement;
}
});
});

Related

Kendo UI Dropdownlist client-side filter not working if dataBound is used to set selected value

The problem is when using Kendo UI Dropdownlist with the dataBound method to set the selected value at load.
The reason for setting the value in the DataBound method is to ensure the transport has returned with the dropdownlist's dataitems to prevent a race condition failure. This is not demonstrated in the static example below, but my dataset is coming from the transport server side call.
Setting the dropdownlist's option filter: "startswith" works very well for simple client side filtering however a problem arises due to the use of dataBound. Very little documentation on this, but dataBound is called when the dropdownlist is initialized AND when any method takes action against it including filtering.
By placing debuggers in the inspector tool I was able to observe the filter method working, then the dataBound method being hit again and setting it to the initialized value. The effect is that it looks like the filter simply failed.
See the following example. To recreate the problem, try to use the dropdownlist's filter feature, type "Apple" and observe what happens.
$("#dropdownlist").kendoDropDownList({
dataSource: ["Apples", "Oranges"],
filter: "startswith",
dataBound: function(e) {
$("#dropdownlist").data('kendoDropDownList').value("Oranges");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//kendo.cdn.telerik.com/2016.3.914/js/kendo.all.min.js"></script>
<link href="//kendo.cdn.telerik.com/2016.3.914/styles/kendo.nova.min.css" rel="stylesheet" />
<link href="//kendo.cdn.telerik.com/2016.3.914/styles/kendo.common.min.css" rel="stylesheet" />
<input id="dropdownlist" />
I need a way for the dataBound to only fire on initialization or for the filter to no propagate further thereby avoiding the dataBound call after filtering.
After studying the dropdownlist in the DOM, I found a solution, albeit perhaps a bit hacky, to allow the dataBound initialize and set the value after the transport loads the list and prevents it from hijacking the filter method.
$("#dropdownlist").kendoDropDownList({
dataSource: ["Apples", "Oranges"],
filter: "startswith",
dataBound: function(e) {
if (e.sender.filterInput.val() === "") {
$("#dropdownlist").data('kendoDropDownList').value("Oranges");
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//kendo.cdn.telerik.com/2016.3.914/js/kendo.all.min.js"></script>
<link href="//kendo.cdn.telerik.com/2016.3.914/styles/kendo.nova.min.css" rel="stylesheet" />
<link href="//kendo.cdn.telerik.com/2016.3.914/styles/kendo.common.min.css" rel="stylesheet" />
<input id="dropdownlist" />
By wrapping the dataBound initialization logic with a condition checking to see if the entered filter value (filterInput) is an empty string which it will be on initialization, it allows any subsequent use of the filter to bypass the dataBound logic.
Please post any other insights or better solutions you have to this if you have one.
Going to add that just checking the filterInput value is also going to set the value back to the initial value every time you open the dropdown after this. So after you change the value, it will always reset to "Oranges" whenever you open the dropdown, regardless of whether you changed it to "Apples."
Add another check for !this.value()
$("#dropdownlist").kendoDropDownList({
dataSource: ["Apples", "Oranges"],
filter: "startswith",
dataBound: function(e) {
if (!this.value() && e.sender.filterInput.val() === "") {
$("#dropdownlist").data('kendoDropDownList').value("Oranges");
}
}
});

Set component attribute but don't fire event

I'm new to polymer/webcomponents and I'm trying to set an attribute in a component but don't want the corresponding event to be fired.
Why? Because I want to be able to do two things:
1) When the control changes (by clicking on the checkbox) I want to use the event handler to send this event to a server (using websockets)
2) When the control should change (by an event via websocket) I want to be able to set the checkbox but not fire the event.
Hope I made my point clear. It's very hot in germany right now -> brain is melting ;)
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../paper-checkbox/paper-checkbox.html">
<polymer-element name="webmpc-player">
<template>
<paper-checkbox id="repeat" on-change={{change}}></paper-checkbox> Repeat
<paper-checkbox id="shuffle" on-change={{change}}></paper-checkbox> Shuffle
</template>
<script>
Polymer('webmpc-player', {
ready : function() {
/* Set the component property */
this.$.shuffle.checked = true;
},
change : function(e, detail, sender) {
alert('I don't want to be called!');
}
});
</script>
</polymer-element>
Thank you, this looks like a flaw in paper-checkbox.
I just posted an issue ticket to describe the problem.
https://github.com/Polymer/paper-checkbox/issues/9.

Masonry images overlapping

so I'm working on my Tumblr Theme right now. I'm using Masonry to have all my posts in a 5-column grid and the infinite scroll script to load new images into the grid when I'm scrolling down. Unfortunately, most of the time as I scroll down images are overlapping. I figured out that the problem may be Masonry triggering before the images are loaded, but right now I have no idea how to fix this. I'm already using (window).load instead of (document).ready but the pictures keep overlapping nonetheless. Here's the full code snippet:
<script type="text/javascript" src="http://static.tumblr.com/imovwvl/dJWl20ley/jqueryformasonry.js"></script>
<script type="text/javascript" src="http://static.tumblr.com/imovwvl/rSGl20lfv/masonry.js">
</script>
<script src="http://static.tumblr.com/df28qmy/SHUlh3i7s/jquery.infinitescroll.js"></script>
<script src="http://static.tumblr.com/thpaaos/lLwkowcqm/jquery.masonry.js"></script>
<script type="text/javascript">
$(window).load(function () {
$('.posts').masonry(),
$('.masonryWrap').infinitescroll({
navSelector : "div#navigation",
// selector for the paged navigation (it will be hidden)
nextSelector : "div#navigation a#nextPage",
// selector for the NEXT link (to page 2)
itemSelector : ".entry",
// selector for all items you'll retrieve
bufferPx : 10000,
extraScrollPx: 11000,
loadingImg : "",
loadingText : "<em></em>",
},
// call masonry as a callback.
function() { $('.posts').masonry({ appendedContent: $(this) }); }
);
});
</script>
<script type="text/javascript">$(window).load(function(){$("p").remove(":contains('Source:')");});</script>
Does anyone have an idea on how to get it working? Any help would be appreciated!
Masonry is placing the items absolutely before your images have loaded and take more space.
Utilize Jquery imagesLoaded to overcome this. You may want to initially hide your elements and then show them after they have finished loading. Try something like this:
//Wire masonry onto the photolist with whatever defaults you need
$photolist.imagesLoaded(function () {
$photolist.masonry({
// options
itemSelector: '.photo',
columnWidth: 226,
isFitWidth: true,
gutterWidth: 12
});
});

Load zebra strip in ajax loaded table

I tried to apply a zebra strip with an ajax loaded table but it's not work. I tried googling some suggestion over the net but no luck. Here's my code:
CSS:
<style>
.odd{background:#eeeeee}
</style>
Javascript:
<script src="../jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("tr:even").addClass("even");
$("tr:odd").addClass("odd");
});
//supplier ajax viewer
$(document).ready(function(stripTable) {
$("#supplier_viewer").load("inc/stock_view.php");
$('tr:odd',this).addClass("odd");
var refreshId = setInterval(function() {
$("#supplier_viewer").load('inc/stock_view.php?randval='+ Math.random());
}, 10000);
$('tr:odd',this).addClass("odd");
$.ajaxSetup({ cache: false });
});
</script>
And this is where the table is loaded.
HTML:
<div id="supplier_view"></div>
I've tried to add
$('tr:even',this).addClass("even");
to the load stage but not work. Please suggest.
You are applying the classes to the element before they are actually loaded.
Try applying these classes when the loaded event is fired.
I would also recommend to use FireBug to view the generated html and see if the classes are really applied to the dynamically loaded data. (which I highly suspect not)
Once the data is loaded, you need to execute these two lines
$("tr:even").addClass("even");
$("tr:odd").addClass("odd");
But only after the data has been loaded to the div

What would the be reason JQuery has access to DOM but not ExtJS?

I have a Kohana framework which is building ExtJS objects in one view, which in turn loads (via JQuery AJAX) other views inside of it with a this function:
function replaceContentOnClick(id, route) {
$('body').delegate(('#' + id), 'click', function(){
$.get(route, function(data) {
$('#region_center .x-panel-body').html(data);
});
});
}
This is working fine but only when these child views are merely HTML/Javascript/JQuery, but in the child views I cannot get any ExtJS objects to display, even if I render them to DOM elements that exist and to which I can successfully append JQuery elements. It is as if the DOM doesn't exist for ExtJS at that moment.
The main problem is: the JQuery code successfully fills the element:
<script type="text/javascript">
$('#region_center .x-panel-body').html('this is from jquery...');
</script>
but the ExtJS code fails to fill the same element (an there is no error reported in Firebug/Net panel):
<script type="text/javascript">
var region_center = new Ext.Panel({
id: 'region_center',
region: 'center',
renderTo: '#region_center .x-panel-body',
margins:'10 10 10 10',
padding:'10 10 10 10',
autoScroll:true,
html: 'this is from ExtJS...'
});
</script>
What do I have to do so that ExtJS can access the DOM element as JQuery can?
These two bits of code are doing different things. This code:
<script type="text/javascript">
$('#region_center .x-panel-body').html('this is from jquery...');
</script>
...is accessing the DOM node at '#region_center .x-panel-body' and injecting a new innerHTML value. This code:
<script type="text/javascript">
var region_center = new Ext.Panel({
id: 'region_center',
region: 'center',
renderTo: '#region_center .x-panel-body',
margins:'10 10 10 10',
padding:'10 10 10 10',
autoScroll:true,
html: 'this is from ExtJS...'
});
</script>
...is attempting to render a complete Panel component into itself (i.e., the renderTo config is pointing at the panel with id 'region_center', which is the panel itself). This makes no sense and will not work. You can only render components to an existing DOM node -- in this example, there is no existing DOM node with id 'region_center' because the panel is not yet (and cannot be) rendered.
The equivalent code to do exactly what you're doing in jQuery would be this:
<script type="text/javascript">
Ext.get('#region_center').child('.x-panel-body').update('this is from Ext...');
</script>
Assuming all things are equal in the DOM when this is run, it should execute exactly like your jQuery code.
Now, assuming that your BorderLayout is properly rendered, and it in fact has a center region with id 'region_center', you should be able to add a new panel into it dynamically (make sure the new panel's id is unique). Note that it would be preferable to go through the Component API (instead of the DOM API) to do this as layout will be managed for you in that case. E.g., you'd want to do something like:
// assuming myCenterPanel is a valid *component* ref (NOT a DOM element):
myCenterPanel.add(new Ext.Panel(...));
myCenterPanel.doLayout();
You'd also want to ensure that the center panel has an appropriate layout assigned (via the layout config). If you simply render the new panel directly to the underlying DOM node instead (as you're trying to do above), it may work, but in the long term will probably cause you other issues (again, since you are bypassing Ext's layout manager in that case).

Resources