Permalink
Browse files

Extract NestedList JS in a file.

  • Loading branch information...
jecisc committed Jan 6, 2017
1 parent 5f5088c commit 21c053535c963a69caa67b7f71197656972d7fdb
@@ -0,0 +1,171 @@
list
nestedListJs
^ '/**
* This function toggle the expand/collapse of an item of the list.
* @param element The element to toggle.
*/
function expandCollapse(element) {
var li = $(element).closest("li");
li.toggleClass("expanded");
li.children("ul").toggle("medium");
li.toggleClass("collapsed");
}
function post(path, parameters) {
var form = $("<form></form>");
form.attr("method", "post");
form.attr("action", path);
$.each(parameters, function (key, value) {
var field = $("<input>");
field.attr("type", "hidden");
field.attr("name", key);
field.attr("value", value);
form.append(field);
});
// The form needs to be a part of the document in
// order for us to be able to submit it.
$(document.body).append(form);
form.submit();
}
/**
* This method is called when a user click on an element of the list and notify the server that an element was selected.
*
* @param event The click event.
*/
function goTo(event) {
var list = $(event.target).closest(".listContainer")[0];
var tmp = {};
tmp[list.dataset.lclickcb] = $(event.target).closest("li").attr("index");
post(list.dataset.url, tmp);
}
function loadBefore(start, end, listContainer) {
load(start, end, listContainer, true);
}
function loadAfter(start, end, listContainer) {
load(start, end, listContainer, false);
}
/**
* I will load X elements of a list and I will delete the previous or the next elements.
*
* @param start The starting element to add.
* @param end The end element to add.
* @param listContainer The list to complete.
* @param shouldDeleteLast A boolean saying if we should delete the first or the last elements.
*/
function load(start, end, listContainer, shouldDeleteLast) {
var dataObj = {};
dataObj[listContainer.dataset.cbid] = start + ":" + end;
$.ajax({
url: listContainer.dataset.url,
type: "POST",
data: dataObj,
success: function (html_code) {
// We use a document fragment to speed up the addition and deletion of the elements on the browser
var docFrag = document.createDocumentFragment();
var scrolling = listContainer.scrollTop;
var list = listContainer.getElementsByClassName("expList")[0];
for (var i = 0; i < listContainer.dataset.loadingstep; i++) {
if (shouldDeleteLast) {
scrolling = scrolling + ($(list.children[list.children.length - i]).height());
} else {
scrolling = scrolling - ($(list.children[i]).height());
}
}
docFrag.appendChild(list);
if (shouldDeleteLast) {
list = $(list).prepend(html_code)[0];
} else {
list = $(list).append(html_code)[0];
}
while (list.children.length > listContainer.dataset.listmaxsize) {
if (shouldDeleteLast) {
list.removeChild(list.lastChild);
} else {
list.removeChild(list.firstChild);
}
}
listContainer.appendChild(list);
listContainer.scrollTop = scrolling;
},
error: function () {
location.reload();
}
});
}
function obtainLastIndex(listContainer) {
var children = listContainer.children[0].children;
return parseInt(children[children.length - 1].getAttribute("index"));
}
function obtainFirstIndex(listContainer) {
var children = listContainer.children[0].children;
return parseInt(children[0].getAttribute("index"));
}
/**
* I define a function to load more elements when we are at the beginning or at the end of the list.
*/
function defineExpandable() {
$(".listContainer").scroll(function (e) {
// If we have less elements in the list than the max we can show, just do nothing.
if(e.currentTarget.dataset.listmaxsize == e.currentTarget.getElementsByClassName("expList")[0].children.length) {
var tempLastIndex;
if (0.2 > (e.currentTarget.scrollTop) / e.currentTarget.scrollHeight) {
tempLastIndex = obtainFirstIndex(e.currentTarget);
if (tempLastIndex < e.currentTarget.dataset.lastindexasked) {
//this test is to avoid asking multiple time to the server
e.currentTarget.dataset.lastindexasked = tempLastIndex;
loadBefore(parseInt(e.currentTarget.dataset.lastindexasked) - parseInt(e.currentTarget.dataset.loadingstep), parseInt(e.currentTarget.dataset.lastindexasked) - 1, e.currentTarget);
}
}
if (0.8 < (e.currentTarget.scrollTop + $(e.currentTarget).height()) / e.currentTarget.scrollHeight) {
tempLastIndex = obtainLastIndex(e.currentTarget);
if (tempLastIndex > e.currentTarget.dataset.lastindexasked) {
//this test is to avoid asking multiple time to the server
e.currentTarget.dataset.lastindexasked = tempLastIndex;
loadAfter(parseInt(e.currentTarget.dataset.lastindexasked) + 1, parseInt(e.currentTarget.dataset.lastindexasked) + parseInt(e.currentTarget.dataset.loadingstep), e.currentTarget);
}
}
}
});
}
function scrollToSelection() {
$("div.isSelected").each(scrollTo);
}
/**
* I will scroll a list to his selected node passed as parameter.
* @param aSelectedNode The node to scroll to.
*/
function scrollTo(index, aSelectedNode) {
var selection = $(aSelectedNode.parentNode);
var children = $(selection.closest(".expList")).children();
var dec = 0;
while ($(children).index(selection) == -1) {
selection = selection.parent();
}
for (var i = 0; i < $(children).index(selection); i++) {
dec += $(children[i]).height();
}
selection.closest(".listContainer")[0].scrollTop = dec;
}
window.addEventListener("load", function () {
scrollToSelection();
defineExpandable();
});'
@@ -1,3 +1,3 @@
accessing
selectorsToInclude
^ #(#nestedListCss #sliderCss #mdlDialogJs #calendarWidgetCss #paginationWidgetCss #getmdlselectminCss #getmdlselectminJs #iconCss #materialminJs #dialogpolyfillminCss #dialogpolyfillminJs #robotoCss)
^ #(#nestedListCss #nestedListJs #sliderCss #mdlDialogJs #calendarWidgetCss #paginationWidgetCss #getmdlselectminCss #getmdlselectminJs #iconCss #materialminJs #dialogpolyfillminCss #dialogpolyfillminJs #robotoCss)
@@ -1,3 +1,7 @@
accessing
actionBlock: anObject
actionBlock := anObject
actionBlock: aBlock
self
assert: aBlock argumentCount = 1
description:
'This block must take one argument; it will be the clicked entity in the list'.
actionBlock := aBlock
@@ -11,8 +11,7 @@ displayResearchFieldDiv: html
position: relative;
width: calc(100% - 20px);';
with: [
html mdlTextFieldContainer
with: [
html mdlTextFieldContainer: [
html mdlTextFieldLabel
for: fieldId;
style: 'position: absolute;';

This file was deleted.

Oops, something went wrong.
@@ -1,3 +1,3 @@
rendering
hasDraggableItems
^ true
^ self dragAndDropBlock notNil
@@ -0,0 +1,3 @@
private
idFor: aSymbol
^ aSymbol, self id
@@ -0,0 +1,15 @@
rendering
renderAnchor: aNode withId: anId index: anIndex inDiv: div indentedBy: anInteger on: html
| anchor |
anchor := html anchor.
self actionBlock ifNotNil: [ anchor onClick: 'goTo(event)' ].
anchor
with: [ html span
class: #item;
id: anId;
with: [ html text: ((self format value: aNode element) ifEmpty: [ $  ]) ].
self renderHelpOf: aNode element at: anId on: html ].
aNode children
ifNotEmpty: [ html div
onClick: 'expandCollapse(this)';
class: #icon ]
@@ -1,12 +1,14 @@
rendering
renderContentOn: html
self ensureId: html.
html div
id: (self idFor: #nestedList);
class: #nestedList;
class: self listStyle;
with: [
self flag: #TODO. "put style in css"
self displayResearchFieldDiv: html.
html div
id: (self idFor: #listContent);
class: #listContent;
style: 'height: 500px;';
class: #withSearch if: self displayResearchField;
with: [ self renderListOn: html ] ]
@@ -2,4 +2,11 @@ rendering
renderIconOf: anItem on: html
self iconBlock ifNil: [ ^ self ].
html render: (self iconBlock value: anItem)
self
assert: (self iconBlock argumentCount between: 1 and: 2)
description:
'The icon block should have 1 or 2 arguments only. The first argument should be the item to display. If this is the only parameter the block should return a WAComponent to render. The second optional parameter will be an html canvas if you want to render directly something without passing by a component.'.
self iconBlock argumentCount = 1
ifTrue: [ html render: (self iconBlock value: anItem) ]
ifFalse: [ self iconBlock value: anItem value: html ]
Oops, something went wrong.

0 comments on commit 21c0535

Please sign in to comment.