").addClass("miller-col-title-text").append($("
").text(category.categoryName));
267 |
268 | if (!readOnly) {
269 | var millerColAction = $("
").addClass("miller-col-actions");
270 | millerColAction.append($("
").addClass("material-icons").addClass("action-edit").addClass("miller-col-title-icons").text("edit"));
271 | millerColAction.append($("
").addClass("material-icons").addClass("action-add").addClass("miller-col-title-icons").text("add"));
272 | millerColTitleText.append(millerColAction);
273 | }
274 |
275 | millerColTitle.addClass("miller-col-title");
276 | millerColTitle.append(millerColTitleText);
277 |
278 | newMillerCol.append(millerColTitle);
279 |
280 | var millerColBody = $("
").addClass("miller-col-body");
281 |
282 | for (var i = 0; i < category.items.length; ++i) {
283 |
284 | var millerColListItem = buildColListItem(category.items[i], readOnly);
285 |
286 | millerColBody.append(millerColListItem);
287 |
288 | }
289 |
290 | newMillerCol.append(millerColBody);
291 |
292 | newMillerCol.insertBefore(getLoadingCol.call(this));
293 |
294 | }
295 |
296 | return this;
297 |
298 | } else if ("addItem" == args[0]) {
299 |
300 | var addedItemData = args[1];
301 |
302 | var listParentAddedItem = $(this).find(getColListItemSelector()).filter("[data-item-id = '" + addedItemData.parentId + "']");
303 |
304 | if (null != listParentAddedItem) {
305 | var parentAlreadyWithChildren = listParentAddedItem.data("has-children");
306 | listParentAddedItem.data("has-children", true);
307 | listParentAddedItem.attr("data-has-children", true);
308 | if (!parentAlreadyWithChildren) {
309 | listParentAddedItem.append($("
").addClass("material-icons").text("navigate_next").addClass("has-children"));
310 | }
311 | }
312 | var colContainer = getMillerColContainers.call(this).filter("[data-category-id='" + addedItemData.categoryId + "']");
313 |
314 | if (null == colContainer) {
315 | if (isDebugEnabled) {
316 | console.log("Cant find category with id: " + addedItemData.categoryId);
317 | }
318 | return;
319 | }
320 |
321 | var colListItemContainer = colContainer.find(getColListItemContainer());
322 |
323 | colListItemContainer.append(buildColListItem(addedItemData, false));
324 |
325 | return this;
326 |
327 |
328 | } else if ("updateCategory" == args[0]) {
329 |
330 | var updatedCategoryData = args[1];
331 |
332 | var updatedCategory = $(this).find(getColContainerSelector()).filter("[data-category-id = '" + updatedCategoryData.categoryId + "']");
333 |
334 | if (null != updatedCategory) {
335 | console.log("updating category name");
336 | updatedCategory.find(".miller-col-title-text").find("span").first().text(updatedCategoryData.categoryName);
337 | updatedCategory.attr("data-category-name", updatedCategoryData.categoryName);
338 | updatedCategory.attr("data-is-lowest-level", updatedCategoryData.isLowestLevel);
339 | }
340 |
341 | return this;
342 |
343 | }else if ("updateItem" == args[0]) {
344 |
345 | var updatedtemData = args[1];
346 |
347 | var listUpdatedItem = $(this).find(getColListItemSelector()).filter("[data-item-id = '" + updatedtemData.itemId + "']");
348 |
349 | if (null != listUpdatedItem) {
350 | listUpdatedItem.find(".list-item-text").text(updatedtemData.itemName);
351 | listUpdatedItem.attr("data-item-name", updatedtemData.itemName);
352 | listUpdatedItem.find(".list-item-icon").text(updatedtemData.itemIcon);
353 | listUpdatedItem.attr("data-item-icon", updatedtemData.itemIcon);
354 | }
355 |
356 | return this;
357 |
358 | } else if ("deleteItem" == args[0]) {
359 |
360 | var deletedItemData = args[1];
361 |
362 | var listDeletedItem = $(this).find(getColListItemSelector()).filter("[data-item-id = '" + deletedItemData.itemId + "']");
363 |
364 | var listParentItem = $(this).find(getColListItemSelector()).filter("[data-item-id = '" + deletedItemData.parentId + "']");
365 |
366 | if (null != listParentItem) {
367 | var childrenLeft = $(this).find(getColListItemSelector()).filter("[data-parent-id = '" + deletedItemData.parentId + "']");
368 | if (null == childrenLeft || childrenLeft.length == 0) {
369 | listParentItem.data("has-children", false);
370 | listParentItem.attr("data-has-children", false);
371 | listParentItem.find("i").filter(".has-children").remove();
372 | }
373 | }
374 |
375 | //remove children col container.
376 | $(listDeletedItem).closest(getColContainerSelector()).next(getColContainerSelectorExcludeColLoading()).remove();
377 |
378 | if (null != listDeletedItem)
379 | listDeletedItem.remove();
380 |
381 | return this;
382 |
383 | }else if ("destroy" == args[0]) {
384 |
385 | if (isInitialized.call(this)) {
386 | // remove all miller-column object events
387 | $(this).find("*").addBack().off();
388 |
389 | // remove all window events related to miller-column object
390 | $(window).off("." + $(this).attr("id"));
391 |
392 | // remove specific attributes
393 | $(this).removeAttr("millerized");
394 | $(this).removeAttr("data-is-read-only");
395 | $(this).removeAttr("style");
396 |
397 | // empty miller-column object
398 | $(this).empty();
399 |
400 | if (isDebugEnabled)
401 | console.log("miller-column destroyed !");
402 | } else {
403 | if (isDebugEnabled)
404 | console.log("miller-column is not initialized so nothing to destroy ...");
405 | }
406 |
407 | return;
408 |
409 | } else if ("ismillerized" == args[0]) {
410 |
411 | return isInitialized.call(this);
412 | }
413 |
414 |
415 | function buildColListItem(item, readOnly) {
416 |
417 | var millerColListItem = $("
").addClass("miller-col-list-item");
418 |
419 | millerColListItem.attr("data-has-children", item.hasChildren);
420 | millerColListItem.attr("data-item-id", item.itemId);
421 | millerColListItem.attr("data-parent-id", item.parentId);
422 | millerColListItem.attr("data-category-id", item.categoryId);
423 | millerColListItem.attr("data-is-deletable", item.isDeletable);
424 | millerColListItem.attr("data-item-name", item.itemName);
425 | millerColListItem.attr("data-item-icon", item.itemIcon);
426 |
427 | var $listItemIcon = $("
").addClass("material-icons list-item-icon");
428 | millerColListItem.append($listItemIcon);
429 |
430 | if (item.itemIcon != "" && item.itemIcon != null)
431 | $listItemIcon.text(item.itemIcon);
432 |
433 | millerColListItem.append($("
").text(item.itemName).addClass("list-item-text"));
434 |
435 | if (item.hasChildren)
436 | millerColListItem.append($("
").addClass("material-icons").text("navigate_next").addClass("has-children"));
437 |
438 | if (false == readOnly) {
439 | var listItemActions = $("
").addClass("list-item-actions").append($("
").addClass("material-icons").addClass("edit").text("edit"));
440 | listItemActions.append($("
").addClass("material-icons").addClass("delete").text("delete"));
441 |
442 | millerColListItem.append(listItemActions);
443 | }
444 |
445 | if(item.numChildren != null && item.numChildren != 0){
446 |
447 | millerColListItem.append($("
").addClass("num-children-badge").text(item.numChildren));
448 |
449 | }
450 |
451 | return millerColListItem;
452 | }
453 |
454 | function getTotalInnerColsWidth() {
455 |
456 | var totalWidth = 0;
457 |
458 | if (isDebugEnabled) {
459 | console.log("About to calculate total width ...");
460 | }
461 |
462 | getMillerColContainers.call(this).each(function () {
463 |
464 | if (isViewHidden.call(this))
465 | return;
466 |
467 | totalWidth += $(this).outerWidth();
468 |
469 | if (isDebugEnabled) {
470 | console.log("added width: " + $(this).outerWidth())
471 | }
472 |
473 | });
474 |
475 | //include loading col width if it is showing.
476 | totalWidth = totalWidth + (!isViewHidden.call(getLoadingCol.call(this)) ? getLoadingCol.call(this).outerWidth() : 0);
477 |
478 | if (isDebugEnabled) {
479 | console.log("totalColsWidth: " + totalWidth + " body width:" + $(this).outerWidth());
480 | }
481 |
482 | return totalWidth;
483 | }
484 |
485 | function init() {
486 |
487 | hideNavCols.call(this);
488 |
489 | hideLoadingCol.call(this);
490 |
491 | resizeMillerColumn.call(this);
492 |
493 | initialize.call(this);
494 |
495 | }
496 |
497 | function hideNavCols() {
498 |
499 | hidePrevNavCol.call(this);
500 | hideNextNavCol.call(this);
501 |
502 | }
503 |
504 | function initialize() {
505 |
506 | if (getMillerColsBody.call(this).length == 0) { //if user has not build the miller ui structure using html manually
507 |
508 | var preNav = $("
")
509 | .addClass("miller-col-nav nav-prev hidden")
510 | .append($("
")
511 | .addClass("material-icons")
512 | .text("navigate_before"));
513 |
514 |
515 | var millerColsBody = $("
")
516 | .addClass("miller-cols-body");
517 |
518 | var millerColLoading = $("
")
519 | .addClass("miller-col-loading-container col-loading hidden")
520 | .append($("
")
521 | .addClass("miller-col-body")
522 | .append($("
")
523 | .addClass("miller-col-list-item loading-icon-container spinner")));
524 |
525 | millerColsBody.append(millerColLoading);
526 |
527 | var nextNav = $("
")
528 | .addClass("miller-col-nav nav-next hidden")
529 | .append($("
")
530 | .addClass("material-icons")
531 | .text("navigate_next"));
532 |
533 | $(this).append(preNav).append(millerColsBody).append(nextNav);
534 |
535 | }
536 |
537 | $(this).addClass("miller-cols-container-wrapper");
538 |
539 | $(this).css({
540 | height: settings.height
541 | });
542 |
543 | $(this).attr("millerized", "");
544 | $(this).attr("data-is-read-only", settings.isReadOnly);
545 | }
546 |
547 | function isInitialized() {
548 | return $(this).is("[millerized]");
549 | }
550 |
551 | function getMillerColContainers() {
552 | return $(this).find(".miller-col-container")
553 | }
554 |
555 | function getColLoadingSelector() {
556 | return ".col-loading";
557 | }
558 |
559 | function getLoadingCol() {
560 | return $(this).find(getColLoadingSelector())
561 | }
562 |
563 | function showLoadingCol() {
564 | return showView.call(getLoadingCol.call(this));
565 | }
566 |
567 | function hideLoadingCol() {
568 | return hideView.call(getLoadingCol.call(this));
569 | }
570 |
571 | function getPrevNav() {
572 | return $(this).find(".miller-col-nav.nav-prev");
573 | }
574 |
575 | function getNextNav() {
576 | return $(this).find(".miller-col-nav.nav-next");
577 | }
578 |
579 | function getMillerColsBody() {
580 | return $(this).find(".miller-cols-body");
581 | }
582 |
583 | function getColListItemSelector() {
584 | return ".miller-col-body .miller-col-list-item"
585 | }
586 |
587 | function getColListItemContainer() {
588 | return ".miller-col-body"
589 | }
590 |
591 | function getColContainerSelector() {
592 | return ".miller-col-container"
593 | }
594 |
595 | function getColContainerSelectorExcludeColLoading() {
596 | return ".miller-col-container:not(.col-loading)"
597 | }
598 |
599 |
600 | function getFirstVisibleCol() {
601 |
602 | var firstVisibleCol = getMillerColsBody.call(this).find(".miller-col-container:not(.hidden):first");
603 |
604 | return firstVisibleCol.length != 0 ? firstVisibleCol :
605 | (isViewHidden.call(getLoadingCol.call(this)) ? null : getLoadingCol.call(this));
606 | }
607 |
608 | function hasLeftHiddenCol() {
609 | return isViewHidden.call(getFirstVisibleCol.call(this).prev());
610 | }
611 |
612 | function hasRightHiddenCol() {
613 | return isViewHidden.call(getLastVisibleCol.call(this).next().not(getColLoadingSelector()));
614 | }
615 |
616 | function getLastVisibleCol() {
617 |
618 | return !isViewHidden.call(getLoadingCol.call(this)) ? getLoadingCol.call(this) :
619 | getMillerColsBody.call(this).find(".miller-col-container:not(.hidden):last");
620 |
621 | }
622 |
623 | function isViewHidden() {
624 | return $(this).hasClass(MILLER_COL_HIDDEN_CLASS);
625 | }
626 |
627 | function hideView() {
628 | if (!isViewHidden.call(this))
629 | $(this).addClass(MILLER_COL_HIDDEN_CLASS);
630 | }
631 |
632 | function showView() {
633 | if (isViewHidden.call(this))
634 | $(this).removeClass(MILLER_COL_HIDDEN_CLASS);
635 | }
636 |
637 | function showPrevNavCol() {
638 | showView.call(getPrevNav.call(this))
639 | }
640 |
641 | function isNextNavColHidden() {
642 | return isViewHidden.call(getNextNav.call(this));
643 | }
644 |
645 | function isPrevNavColHidden() {
646 | return isViewHidden.call(getPrevNav.call(this))
647 | }
648 |
649 | function showNextNavCol() {
650 | showView.call(getNextNav.call(this));
651 | }
652 |
653 | function hidePrevNavCol() {
654 | hideView.call(getPrevNav.call(this));
655 | }
656 |
657 | function hideNextNavCol() {
658 | hideView.call(getNextNav.call(this))
659 | }
660 |
661 | function isOverFlowing() {
662 |
663 | //the body must at least show one column
664 | if ($(getMillerColsBody.call(this)).children(":not(.hidden)").length <= 1)
665 | return false;
666 |
667 | return getMillerColsBody.call(this).outerWidth() + 1 < getTotalInnerColsWidth.call(getMillerColsBody.call(this))
668 | }
669 |
670 | function overFlowsWith(child) {
671 |
672 | var millerColsBody = getMillerColsBody.call(this);
673 |
674 | return isOverFlowing.call(this) ||
675 | millerColsBody.outerWidth() + 1 < getTotalInnerColsWidth.call(millerColsBody) + child.outerWidth()
676 | }
677 |
678 | function selectItem() {
679 |
680 | if ($(this).is(SELECTOR_IS_SELECTED))
681 | return;
682 |
683 | $(this).addClass(CLASS_SELECTED);
684 | }
685 |
686 | function deselectItem() {
687 | $(this).removeClass(CLASS_SELECTED);
688 | }
689 |
690 | function removeTrailingColContainers() {
691 | $(this).nextAll(":not(.col-loading)").remove();
692 | }
693 |
694 | function getCategoryItem() {
695 |
696 | var categoryItem = new CategoryItem();
697 |
698 | categoryItem.setCategoryId($(this).attr("data-category-id"));
699 | categoryItem.setItemId($(this).attr("data-item-id"));
700 | categoryItem.setItemName($(this).attr("data-item-name"));
701 | categoryItem.setItemIcon($(this).attr("data-item-icon"));
702 | categoryItem.setHasChildren($(this).attr("data-has-children"));
703 | categoryItem.setIsDeletable($(this).attr("data-is-deletable"));
704 | categoryItem.setParentId($(this).attr("data-parent-id"));
705 |
706 | return categoryItem;
707 |
708 | }
709 |
710 | function getCategory() {
711 |
712 | var category = new Category();
713 |
714 | category.setCategoryId($(this).attr("data-category-id"));
715 | category.setCategoryName($(this).attr("data-category-name"));
716 | category.setIsLowestLevel($(this).attr("data-is-lowest-level"));
717 | category.setParentId($(this).attr("data-parent-id"));
718 |
719 | return category;
720 |
721 | }
722 |
723 |
724 | function scaleUpLeft() {
725 |
726 | while (!isOverFlowing.call(this) && hasLeftHiddenCol.call(this)) {
727 |
728 | showView.call(getFirstVisibleCol.call(this).prev())
729 |
730 | }
731 |
732 | //undo the last show if there is overflow
733 | if (isOverFlowing.call(this)) {
734 | hideView.call(getFirstVisibleCol.call(this))
735 | }
736 |
737 | if (!hasLeftHiddenCol.call(this)) {
738 | hidePrevNavCol.call(this);
739 | }
740 |
741 |
742 | if (!hasLeftHiddenCol.call(this) && !isNextNavColHidden.call(this) && !overFlowsWith.call(this, getLastVisibleCol.call(this).next()))
743 | resizeMillerColumn.call(this, SHRINK_DIRECTION_RIGHT, SCALE_TYPE_SCALE_UP);
744 |
745 | }
746 |
747 | function scaleDownLeft() {
748 |
749 | while (isOverFlowing.call(this)) {
750 |
751 | hideView.call(getFirstVisibleCol.call(this));
752 |
753 | showPrevNavCol.call(this);
754 |
755 | }
756 |
757 | }
758 |
759 | function scaleUpRight() {
760 |
761 | while (!isOverFlowing.call(this) && hasRightHiddenCol.call(this)) {
762 |
763 | showView.call(getLastVisibleCol.call(this).next());
764 |
765 | if (!hasRightHiddenCol.call(this)) {
766 | hideNextNavCol.call(this);
767 | break;
768 | }
769 |
770 | }
771 |
772 | if (!hasRightHiddenCol.call(this) && !isPrevNavColHidden.call(this) && !overFlowsWith.call(this, getFirstVisibleCol.call(this).prev())
773 | )
774 | resizeMillerColumn.call(this, SHRINK_DIRECTION_LEFT, SCALE_TYPE_SCALE_UP)
775 |
776 |
777 | }
778 |
779 | function scaleDownRight() {
780 |
781 | while (isOverFlowing.call(this)) {
782 |
783 | hideView.call(getLastVisibleCol.call(this));
784 | showNextNavCol.call(this);
785 |
786 | }
787 |
788 | }
789 |
790 | function resizeMillerColumn(direction, scaleType) {
791 |
792 | scaleType = scaleType || SCALE_TYPE_SCALE_DOWN;
793 |
794 | direction = direction || SHRINK_DIRECTION_LEFT;
795 |
796 | switch (direction) {
797 |
798 | case SHRINK_DIRECTION_RIGHT:
799 |
800 | switch (scaleType) {
801 |
802 | case SCALE_TYPE_SCALE_DOWN:
803 | scaleDownRight.call(this);
804 | break;
805 |
806 | case SCALE_TYPE_SCALE_UP:
807 | scaleUpRight.call(this);
808 | break;
809 |
810 | default:
811 | console.error("Unkown scaleType: " + scaleType);
812 |
813 | }
814 | break;
815 |
816 | case SHRINK_DIRECTION_LEFT:
817 |
818 | switch (scaleType) {
819 | case SCALE_TYPE_SCALE_DOWN:
820 | scaleDownLeft.call(this);
821 | break;
822 |
823 | case SCALE_TYPE_SCALE_UP:
824 | scaleUpLeft.call(this);
825 | break;
826 |
827 | default:
828 | console.error("Unknown scaleType:" + scaleType)
829 | }
830 |
831 | break;
832 |
833 | default:
834 | console.error("Unknown hideDirection: " + direction)
835 |
836 | }
837 |
838 |
839 | }
840 |
841 |
842 | var waitForFinalEvent = (function () {
843 | var timers = {};
844 | return function (callback, ms, uniqueId) {
845 | if (!uniqueId) {
846 | uniqueId = "Don't call this twice without a uniqueId";
847 | }
848 | if (timers[uniqueId]) {
849 | clearTimeout(timers[uniqueId]);
850 | }
851 | timers[uniqueId] = setTimeout(callback, ms);
852 | };
853 | })();
854 |
855 |
856 | return this.each(function () {
857 |
858 | var millerColumn = this;
859 |
860 | init.call(millerColumn);
861 |
862 | if (args[0] && args[0]["initData"]) { //arg[0] root col
863 |
864 | //hide all cols except col load b/se arg[0] => root col
865 | $(millerColumn).find(getColContainerSelectorExcludeColLoading()).remove();
866 |
867 | $(millerColumn).millerColumn("addCol", args[0]["initData"]);
868 |
869 | }
870 |
871 | getPrevNav.call(millerColumn).on("click", function () {
872 |
873 | showView.call(getFirstVisibleCol.call(millerColumn).prev());
874 |
875 | if (!hasLeftHiddenCol.call(millerColumn))
876 | hidePrevNavCol.call(millerColumn);
877 |
878 | resizeMillerColumn.call(millerColumn, SHRINK_DIRECTION_RIGHT);
879 |
880 | });
881 |
882 | getNextNav.call(millerColumn).on("click", function () {
883 |
884 | showView.call(getLastVisibleCol.call(millerColumn).next());
885 |
886 | if (!hasRightHiddenCol.call(millerColumn))
887 | hideNextNavCol.call(millerColumn);
888 |
889 | resizeMillerColumn.call(millerColumn, SHRINK_DIRECTION_LEFT);
890 |
891 | });
892 |
893 |
894 | getMillerColsBody.call(millerColumn).on("DOMNodeInserted", function (event) {
895 |
896 | //resize only if col is added.
897 | if (!$(event.target).is(getColContainerSelector()))
898 | return;
899 |
900 | if (isDebugEnabled) {
901 | console.log("Dom inserted..");
902 | }
903 |
904 | hideLoadingCol.call(millerColumn);
905 |
906 | resizeMillerColumn.call(millerColumn, SHRINK_DIRECTION_LEFT);
907 |
908 | });
909 |
910 |
911 | getMillerColsBody.call(millerColumn).on("DOMNodeRemoved", function (event) {
912 |
913 | //resize only if col is removed.
914 | if (!$(event.target).is(getColContainerSelector()))
915 | return;
916 | if (isDebugEnabled) {
917 | console.log("Dom removed..");
918 | }
919 |
920 | resizeMillerColumn.call(millerColumn, SHRINK_DIRECTION_LEFT, SCALE_TYPE_SCALE_UP);
921 |
922 | });
923 |
924 | /**
925 | * Fires item-selected event when an item is selected along with the necessary data.
926 | */
927 | getMillerColsBody.call(millerColumn).on("click", getColListItemSelector(), function () {
928 |
929 | var currentColContainer = $(this).closest(getColContainerSelector());
930 |
931 | removeTrailingColContainers.call(currentColContainer);
932 |
933 | if (!isNextNavColHidden.call(millerColumn))
934 | hideNextNavCol.call(millerColumn);
935 |
936 | if ($(this).data(HAS_CHILDREN) == true) {
937 | showLoadingCol.call(millerColumn);
938 | }
939 |
940 | resizeMillerColumn.call(millerColumn, SHRINK_DIRECTION_LEFT, SCALE_TYPE_SCALE_DOWN);
941 |
942 | deselectItem.call((currentColContainer).find(getColListItemSelector()));
943 |
944 | selectItem.call(this);
945 |
946 | //Firing item-selected event.
947 | var data = getCategoryItem.call(this);
948 |
949 | $(this).trigger("item-selected", data);
950 |
951 | //check if item data is already provided during init
952 |
953 | var children = currentColContainer.data("children");
954 |
955 | console.log("children:" + children)
956 |
957 | if(children){
958 |
959 | for(var i = 0; i < children.length; ++i){
960 |
961 | if(data.itemId === children[i].itemId){
962 |
963 | if(children[i].childCategory){
964 |
965 | $(millerColumn).millerColumn("addCol", children[i].childCategory);
966 |
967 | }
968 |
969 | break;
970 | }
971 |
972 | }
973 |
974 | }
975 |
976 | if (isDebugEnabled) {
977 | console.log("fired item-selected event: " + JSON.stringify(data))
978 | }
979 |
980 | });
981 |
982 | getMillerColsBody.call(millerColumn).on("click", ".list-item-actions .edit", function (event) {
983 |
984 | var currentItemContainer = $(this).closest(getColListItemSelector());
985 |
986 | //Firing edit-item event.
987 | var data = getCategoryItem.call(currentItemContainer);
988 |
989 | $(currentItemContainer).trigger("edit-item", data);
990 |
991 | if (isDebugEnabled) {
992 | console.log("fired edit item event: " + JSON.stringify(data));
993 | }
994 |
995 | event.stopPropagation();
996 |
997 | });
998 |
999 | getMillerColsBody.call(millerColumn).on("click", ".list-item-actions .delete", function (event) {
1000 |
1001 | var currentItemContainer = $(this).closest(getColListItemSelector());
1002 |
1003 | //Firing delete-item event.
1004 | var data = getCategoryItem.call(currentItemContainer);
1005 |
1006 | $(currentItemContainer).trigger("delete-item", data);
1007 |
1008 | if (isDebugEnabled) {
1009 | console.log("fired delete item event: " + JSON.stringify(data));
1010 | }
1011 |
1012 | event.stopPropagation();
1013 |
1014 | });
1015 |
1016 | getMillerColsBody.call(millerColumn).on("click", ".miller-col-actions .action-add", function () {
1017 |
1018 | var currentColContainer = $(this).closest(getColContainerSelector());
1019 | var parentColContainer = currentColContainer.prev();
1020 |
1021 | //Firing add-item event.
1022 | var data = getCategory.call(currentColContainer);
1023 |
1024 | if (parentColContainer)
1025 | data.parentId = $(parentColContainer).find(getColListItemSelector()).filter(SELECTOR_IS_SELECTED).data("item-id");
1026 |
1027 | $(currentColContainer).trigger("add-item", data);
1028 |
1029 | if (isDebugEnabled) {
1030 | console.log("fired add item event: " + JSON.stringify(data));
1031 | }
1032 |
1033 | });
1034 |
1035 | getMillerColsBody.call(millerColumn).on("click", ".miller-col-actions .action-edit", function () {
1036 |
1037 | var currentColContainer = $(this).closest(getColContainerSelector());
1038 | var parentColContainer = currentColContainer.prev();
1039 |
1040 | //Firing edit-column-title event.
1041 | var data = getCategory.call(currentColContainer);
1042 |
1043 | if (parentColContainer){
1044 | data.parentId = $(parentColContainer).find(getColListItemSelector()).filter(SELECTOR_IS_SELECTED).data("item-id");
1045 | data.prevColumnId = $(parentColContainer).find(getColListItemSelector()).filter(SELECTOR_IS_SELECTED).data("category-id");
1046 | }
1047 |
1048 | $(currentColContainer).trigger("edit-column-title", data);
1049 |
1050 | if (isDebugEnabled) {
1051 | console.log("fired edit-column-title event: " + JSON.stringify(data));
1052 | }
1053 |
1054 | });
1055 |
1056 |
1057 | $(window).on("resize." + $(millerColumn).attr("id"), function (event) {
1058 |
1059 | waitForFinalEvent(function () {
1060 |
1061 | if (!isInitialized.call(millerColumn))
1062 | return;
1063 |
1064 | if (isDebugEnabled) {
1065 | console.log("window resized..");
1066 | }
1067 |
1068 | if ($(window).outerWidth() == windowWidth)
1069 | return;
1070 |
1071 | if (isDebugEnabled) {
1072 | console.log("About to resize: old width:" + windowWidth + " new one: " + $(window).outerWidth());
1073 | }
1074 |
1075 | //disable nav cols
1076 | hideNavCols.call(millerColumn);
1077 |
1078 | if ($(window).outerWidth() < windowWidth) {
1079 | resizeMillerColumn.call(millerColumn, SHRINK_DIRECTION_LEFT, SCALE_TYPE_SCALE_DOWN);
1080 | } else {
1081 | resizeMillerColumn.call(millerColumn, SHRINK_DIRECTION_LEFT, SCALE_TYPE_SCALE_UP);
1082 | }
1083 |
1084 | //re-enable navs
1085 | if (hasRightHiddenCol.call(millerColumn))
1086 | showNextNavCol.call(millerColumn);
1087 |
1088 | if (hasLeftHiddenCol.call(millerColumn))
1089 | showPrevNavCol.call(millerColumn);
1090 |
1091 | windowWidth = $(window).outerWidth();
1092 |
1093 | }, 500, $(millerColumn).attr("id"));
1094 |
1095 | });
1096 |
1097 | });
1098 |
1099 | }
1100 |
1101 | })(jQuery);
1102 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "responsive-miller-column",
3 | "version": "1.0.0",
4 | "description": " Jquery plugin that implements Miller Columns with responsive design.",
5 | "main": "js/miller.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/dsharew/responsive-miller-column.git"
12 | },
13 | "keywords": [
14 | "jquery-plugin",
15 | "ecosystem:jquery"
16 | ],
17 | "author": "dsharew",
18 | "license": "ISC",
19 | "bugs": {
20 | "url": "https://github.com/dsharew/responsive-miller-column/issues"
21 | },
22 | "homepage": "https://github.com/dsharew/responsive-miller-column#readme"
23 | }
24 |
--------------------------------------------------------------------------------
/tutorial/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/tutorial/miller.css:
--------------------------------------------------------------------------------
1 | ::-webkit-scrollbar {
2 | background: rgba(0, 0, 0, 0);
3 | width: 6px;
4 | }
5 |
6 | ::-webkit-scrollbar-thumb {
7 | background: rgba(0, 0, 0, 0.3);
8 | height: 30px;
9 | border-radius: 2px;
10 | }
11 |
12 | * [class^=miller] {
13 | box-sizing: border-box;
14 | padding: 0;
15 | margin: 0;
16 | }
17 |
18 | .miller-cols-container-wrapper {
19 | max-width: 75%;
20 | margin: auto;
21 | position: relative;
22 | z-index: 1;
23 | background-color: #fff;
24 | }
25 |
26 | .miller-cols-body {
27 | display: flex;
28 | display: -ms-flexbox;
29 | display: -webkit-box;
30 | overflow: hidden;
31 | height: 100%;
32 | min-height: 300px;
33 | position: relative;
34 | z-index: 1;
35 | margin: 0 auto;
36 | border-left: 1px solid #DBDBDB;
37 | }
38 |
39 | .miller-col-container,
40 | .miller-col-loading-container {
41 | border: 1px solid #DBDBDB;
42 | border-left: 0;
43 | display: -ms-flexbox;
44 | display: -webkit-box;
45 | display: flex;
46 | -webkit-box-orient: vertical;
47 | -webkit-box-direction: normal;
48 | -ms-flex-direction: column;
49 | flex-direction: column;
50 | -webkit-box-flex: 1;
51 | -ms-flex: 1;
52 | flex: 1;
53 | position: relative;
54 | padding: 0;
55 | overflow-wrap: break-word;
56 | }
57 |
58 | .miller-col-list-item.selected {
59 | background: #eaeaea;
60 | color: rgba(0, 0, 0, 0.9);
61 | }
62 |
63 | .miller-col-loading-container .miller-col-body {
64 | width: 100%;
65 | height: 100%;
66 | }
67 |
68 | .miller-col-body {
69 | -webkit-overflow-scrolling: touch;
70 | margin-top: 48px;
71 | padding-top: 0;
72 | overflow-y: auto;
73 | }
74 |
75 | .miller-col-loading-container.col-loading .loading-icon-container {
76 | position: absolute;
77 | top: 10%;
78 | left: 45%;
79 | height: 5rem;
80 | width: 5rem;
81 | transform: translate(-50%, -50%);
82 | background-size: contain;
83 | }
84 |
85 | .miller-col-nav {
86 | position: absolute;
87 | top: 50%;
88 | transform: translateY(-50%);
89 | }
90 |
91 | .miller-col-nav .material-icons {
92 | font-size: 3em;
93 | font-weight: 300;
94 | float: right;
95 | }
96 |
97 | .miller-col-nav:hover > * {
98 | cursor: pointer;
99 | color: #777;
100 | }
101 |
102 | .miller-col-nav.nav-prev {
103 | left: 0;
104 | transform: translateX(-100%);
105 | }
106 |
107 | .miller-col-nav.nav-next {
108 | right: 0;
109 | transform: translateX(100%);
110 | }
111 |
112 | .miller-col-loading-container.hidden,
113 | .miller-col-container.hidden {
114 | display: none;
115 | }
116 |
117 | .miller-col-nav.hidden {
118 | visibility: hidden;
119 | opacity: 0;
120 | }
121 |
122 | .miller-col-title {
123 | border-bottom: 1px solid #DBDBDB;
124 | text-align: center;
125 | padding: 10px;
126 | font-weight: 900;
127 | -webkit-box-shadow: 0px 5px 4px rgba(0, 0, 0, 0.05);
128 | -moz-box-shadow: 0px 5px 4px rgba(0, 0, 0, 0.05);
129 | box-shadow: 0px 5px 4px rgba(0, 0, 0, 0.05);
130 | position: absolute;
131 | z-index: 10;
132 | height: 48px;
133 | background: #fff;
134 | width: 100%;
135 | }
136 |
137 | .miller-col-title .material-icons.action-add{
138 | position: absolute;
139 | top: 50%;
140 | transform: translateX(-100%) translateY(-50%);
141 | }
142 |
143 | .miller-col-title .material-icons.action-add:hover{
144 | font-weight: bold;
145 | color: gray;
146 | }
147 |
148 | .miller-col-title-text {
149 | text-transform: uppercase;
150 | font-size: 90%;
151 | font-weight: 700;
152 | letter-spacing: 1px;
153 | }
154 |
155 | .miller-col-actions {
156 | float: right;
157 | }
158 |
159 | .miller-col-actions .material-icons {
160 | cursor: pointer;
161 | }
162 |
163 | .miller-col-container,
164 | .miller-col-loading-container {
165 | min-width: 210px;
166 | max-width: 400px;
167 | }
168 |
169 | .miller-col-list-item {
170 | padding: 10px;
171 | font-weight: 300;
172 | display: table;
173 | width: 100%;
174 | color: rgba(0, 0, 0, 0.75);
175 | position: relative;
176 | text-align: left;
177 | word-break: break-all;
178 | min-height: 44px;
179 | }
180 |
181 | .miller-col-list-item .num-children-badge{
182 | border-radius: 50%;
183 | padding: 5px;
184 | border: 1px solid #ddd;
185 | color: #666;
186 | text-align: center;
187 | position: absolute;
188 | right: 35px;
189 | top: 50%;
190 | transform: translateY(-50%);
191 | }
192 |
193 | .miller-col-list-item > * {
194 | vertical-align: middle;
195 | }
196 |
197 | .miller-col-list-item .list-item-text .list-item-icon {
198 | float: left;
199 | padding-top: 4px;
200 | padding-bottom: 4px;
201 | }
202 |
203 | .list-item-icon{
204 | margin-right: 10px;
205 | }
206 |
207 | .miller-col-list-item .has-children {
208 | position: absolute;
209 | top: 50%;
210 | transform: translateY(-50%);
211 | right: 15px;
212 | }
213 |
214 | .miller-col-list-item .list-item-actions {
215 | position: absolute;
216 | right: 12px;
217 | display: none;
218 | }
219 |
220 | .miller-col-list-item[data-has-children="true"] .list-item-actions {
221 | right: 40px;
222 | }
223 |
224 | .miller-col-list-item:hover .list-item-actions {
225 | display: inline;
226 | }
227 |
228 | .miller-col-list-item:hover .material-icons,
229 | .miller-col-list-item.selected .material-icons {
230 | color: #777;
231 | }
232 |
233 | .list-item-actions .material-icons {
234 | padding-left: 8px;
235 | opacity: 0.6;
236 | }
237 |
238 | .list-item-actions .material-icons:hover {
239 | opacity: 1;
240 | }
241 |
242 | .miller-col-list-item:hover {
243 | background: rgba(0, 0, 0, 0.05);
244 | cursor: pointer;
245 | }
246 |
247 | .text-node {
248 | white-space: nowrap;
249 | }
250 |
251 |
252 | /*
253 | Spinner style.
254 | */
255 |
256 | .spinner {
257 | min-width: 24px;
258 | min-height: 24px;
259 | }
260 |
261 | .spinner:before {
262 | content: 'Loading…';
263 | position: absolute;
264 | top: 50%;
265 | left: 50%;
266 | width: 16px;
267 | height: 16px;
268 | margin-top: -10px;
269 | margin-left: -10px;
270 | }
271 |
272 | .spinner:not(:required):before {
273 | content: '';
274 | border-radius: 50%;
275 | border: 2px solid rgba(0, 0, 0, .3);
276 | border-top-color: rgba(0, 0, 0, .6);
277 | animation: spinner .6s linear infinite;
278 | -webkit-animation: spinner .6s linear infinite;
279 | }
280 |
281 | @keyframes spinner {
282 | to {
283 | transform: rotate(360deg);
284 | }
285 | }
286 |
287 | @-webkit-keyframes spinner {
288 | to {
289 | -webkit-transform: rotate(360deg);
290 | }
291 | }
292 |
293 | /* hide badge icon when user hovers on list item being on editable mode */
294 |
295 | .miller-cols-container-wrapper[data-is-read-only="false"] .miller-col-list-item:hover .num-children-badge{
296 | display: none;
297 | }
298 |
299 |
--------------------------------------------------------------------------------
/tutorial/miller.js:
--------------------------------------------------------------------------------
1 | /**
2 | * v1.3.2.0
3 | */
4 |
5 | function Category() {
6 |
7 | var _this = this;
8 |
9 | _this.categoryId = guid();
10 |
11 | _this.setCategoryId = function (categoryId) {
12 |
13 | _this.categoryId = categoryId;
14 |
15 | };
16 |
17 | _this.getCategoryId = function () {
18 | return _this.categoryId;
19 | };
20 |
21 |
22 | _this.setCategoryName = function (categoryName) {
23 |
24 | _this.categoryName = categoryName;
25 |
26 | };
27 | _this.getCategoryName = function () {
28 | return _this.categoryName;
29 | };
30 |
31 |
32 | _this.setParentId = function (parentId) {
33 |
34 | _this.parentId = parentId;
35 |
36 | };
37 | _this.getParentId = function () {
38 | return _this.parentId;
39 | };
40 |
41 |
42 | _this.setIsLowestLevel = function (isLowestLevel) {
43 | _this.isLowestLevel = isLowestLevel;
44 | };
45 | _this.getIsLowestLevel = function () {
46 | return _this.isLowestLevel
47 | };
48 |
49 | _this.setItems = function (categoryItems) {
50 | _this.items = categoryItems;
51 | };
52 | _this.getItems = function () {
53 | return _this.items
54 | }
55 |
56 |
57 | }
58 |
59 | function CategoryItem() {
60 |
61 | var _this = this;
62 |
63 | _this.itemId = guid();
64 |
65 | _this.setItemId = function (itemId) {
66 |
67 | _this.itemId = itemId;
68 |
69 | };
70 |
71 | _this.getItemId = function () {
72 | return _this.itemId;
73 | };
74 |
75 |
76 | _this.setItemName = function (itemName) {
77 |
78 | _this.itemName = itemName;
79 |
80 | };
81 | _this.getItemName = function () {
82 | return _this.itemName;
83 | };
84 |
85 |
86 | _this.setItemIcon = function (itemIcon) {
87 |
88 | _this.itemIcon = itemIcon;
89 |
90 | };
91 | _this.getItemIcon = function () {
92 | return _this.itemIcon;
93 | };
94 |
95 |
96 | _this.setParentId = function (parentId) {
97 |
98 | _this.parentId = parentId;
99 |
100 | };
101 | _this.getParentId = function () {
102 | return _this.parentId;
103 | };
104 |
105 |
106 | _this.setCategoryId = function (categoryId) {
107 |
108 | _this.categoryId = categoryId;
109 |
110 | };
111 | _this.getCategoryId = function () {
112 | return _this.categoryId;
113 | };
114 |
115 |
116 | _this.setHasChildren = function (hasChildren) {
117 | _this.hasChildren = hasChildren;
118 | };
119 | _this.getHasChildren = function () {
120 | return _this.hasChildren
121 | };
122 |
123 | _this.setNumChildren = function(numChildren) {
124 | _this.numChildren = numChildren;
125 | _this.setHasChildren(numChildren != 0);
126 | };
127 |
128 | _this.getNumChildren = function(){
129 | return _this.numChildren;
130 | };
131 |
132 | _this.isDeletable = true;
133 | _this.setIsDeletable = function (isDeletable) {
134 | _this.isDeletable = isDeletable;
135 | };
136 |
137 | _this.getIsDeletable = function () {
138 | return _this.isDeletable
139 | };
140 |
141 |
142 | }
143 |
144 | function guid() {
145 | function s4() {
146 | return Math.floor((1 + Math.random()) * 0x10000)
147 | .toString(16)
148 | .substring(1);
149 | }
150 |
151 | return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
152 | s4() + '-' + s4() + s4() + s4();
153 | }
154 |
155 |
156 | (function ($) {
157 |
158 | $.fn.millerColumn = function (options) {
159 |
160 | var settings = {
161 | isReadOnly: true,
162 | height: '400px'
163 | };
164 |
165 | var isDebugEnabled = true;
166 |
167 | var args = Array.prototype.slice.call(arguments);
168 |
169 | if (typeof args[0] != "string")
170 | settings = $.extend(settings, options);
171 |
172 | //using var instead of const to support IE
173 | var SCALE_TYPE_SCALE_UP = "scaleup";
174 | var SCALE_TYPE_SCALE_DOWN = "scaledown";
175 | var SHRINK_DIRECTION_LEFT = "left";
176 | var SHRINK_DIRECTION_RIGHT = "right";
177 | var MILLER_COL_HIDDEN_CLASS = "hidden";
178 |
179 | var CLASS_SELECTED = "selected";
180 |
181 | var SELECTOR_IS_SELECTED = ".selected";
182 |
183 | var HAS_CHILDREN = "has-children";
184 |
185 | var windowWidth = $(window).outerWidth();
186 |
187 | //TODO: Refactor hard coded class and attribute names.
188 |
189 | if ("addCol" == args[0]) {
190 |
191 | if (!isInitialized.call(this)) {
192 | if (isDebugEnabled) {
193 | console.log("element is is not initialized as a miller column. You need to call jQuery('#id).millerColumn() first.");
194 | }
195 | return;
196 | }
197 |
198 |
199 | if (args[1].jquery) {
200 |
201 | //WARNING: this arg type is deprecated.
202 | args[1].insertBefore(getLoadingCol.call(this));
203 |
204 |
205 | } else if (args[1].categoryId) { //args[1] to detect if it is a valid category obj
206 |
207 | try {
208 |
209 | if (!args[1].categoryId) {
210 | hideLoadingCol.call(this);
211 | return;
212 | }
213 |
214 |
215 | var lastVisibleCol = getLastVisibleCol.call(this);
216 | var lastVisibleNonColLoadingContainer = lastVisibleCol.is(".col-loading") ? lastVisibleCol.prev() : lastVisibleCol;
217 |
218 | if(lastVisibleNonColLoadingContainer.length !== 0 && args[1].categoryId === lastVisibleNonColLoadingContainer.data("category-id")){
219 |
220 | console.warn("Category is already added, ignoring addCol call ...");
221 | hideLoadingCol.call(this);
222 | return;
223 |
224 | }
225 |
226 |
227 | var selectedListItem = lastVisibleNonColLoadingContainer.find(getColListItemSelector()).filter(".selected");
228 |
229 |
230 | for (var j = 0; args[1].items && j < args[1].items.length; ++j) {
231 |
232 | var item = args[1].items[j];
233 |
234 | if (selectedListItem.length != 0 && selectedListItem.data("item-id") != item.parentId) {
235 |
236 | console.warn("Response expired; current selected item is not same as the parent of provided list item.");
237 | hideLoadingCol.call(this);
238 | return;
239 |
240 | }
241 |
242 | }
243 |
244 |
245 | } catch (error) {
246 | console.error(error);
247 | hideLoadingCol.call(this);
248 | }
249 |
250 | var readOnly = JSON.parse($(this).attr("data-is-read-only"));
251 |
252 | if (readOnly && args[1].items.length == 0)
253 | return;
254 |
255 | var newMillerCol = $("
");
256 |
257 | newMillerCol.addClass("miller-col-container");
258 | newMillerCol.attr("data-category-id", args[1].categoryId);
259 | newMillerCol.attr("data-category-name", args[1].categoryName);
260 | newMillerCol.attr("data-is-lowest-level", args[1].isLowestLevel);
261 | newMillerCol.attr("data-parent-id", args[1].parentId);
262 |
263 | var millerColTitle = $("
"),
264 | millerColTitleText = $("
").addClass("miller-col-title-text").append($("
").text(args[1].categoryName));
265 |
266 | if (!readOnly) {
267 | var millerColAction = $("
").addClass("miller-col-actions").append($("
").addClass("material-icons").addClass("action-add").text("add"));
268 | millerColTitleText.append(millerColAction);
269 | }
270 |
271 | millerColTitle.addClass("miller-col-title");
272 | millerColTitle.append(millerColTitleText);
273 |
274 | newMillerCol.append(millerColTitle);
275 |
276 | var millerColBody = $("
").addClass("miller-col-body");
277 |
278 | for (var i = 0; i < args[1].items.length; ++i) {
279 |
280 | var millerColListItem = buildColListItem(args[1].items[i], readOnly);
281 |
282 | millerColBody.append(millerColListItem);
283 |
284 | }
285 |
286 | newMillerCol.append(millerColBody);
287 |
288 | newMillerCol.insertBefore(getLoadingCol.call(this));
289 |
290 | }
291 |
292 | return this;
293 |
294 | } else if ("addItem" == args[0]) {
295 |
296 | var addedItemData = args[1];
297 |
298 | var listParentAddedItem = $(this).find(getColListItemSelector()).filter("[data-item-id = '" + addedItemData.parentId + "']");
299 |
300 | if (null != listParentAddedItem) {
301 | var parentAlreadyWithChildren = listParentAddedItem.data("has-children");
302 | listParentAddedItem.data("has-children", true);
303 | listParentAddedItem.attr("data-has-children", true);
304 | if (!parentAlreadyWithChildren) {
305 | listParentAddedItem.append($("
").addClass("material-icons").text("navigate_next").addClass("has-children"));
306 | }
307 | }
308 | var colContainer = getMillerColContainers.call(this).filter("[data-category-id='" + addedItemData.categoryId + "']");
309 |
310 | if (null == colContainer) {
311 | if (isDebugEnabled) {
312 | console.log("Cant find category with id: " + addedItemData.categoryId);
313 | }
314 | return;
315 | }
316 |
317 | var colListItemContainer = colContainer.find(getColListItemContainer());
318 |
319 | colListItemContainer.append(buildColListItem(addedItemData, false));
320 |
321 | return this;
322 |
323 |
324 | } else if ("updateItem" == args[0]) {
325 |
326 | var updatedtemData = args[1];
327 |
328 | var listUpdatedItem = $(this).find(getColListItemSelector()).filter("[data-item-id = '" + updatedtemData.itemId + "']");
329 |
330 | if (null != listUpdatedItem) {
331 | listUpdatedItem.find(".list-item-text").text(updatedtemData.itemName);
332 | listUpdatedItem.attr("data-item-name", updatedtemData.itemName);
333 | listUpdatedItem.find(".list-item-icon").text(updatedtemData.itemIcon);
334 | listUpdatedItem.attr("data-item-icon", updatedtemData.itemIcon);
335 | }
336 |
337 | return this;
338 |
339 | } else if ("deleteItem" == args[0]) {
340 |
341 | var deletedItemData = args[1];
342 |
343 | var listDeletedItem = $(this).find(getColListItemSelector()).filter("[data-item-id = '" + deletedItemData.itemId + "']");
344 |
345 | var listParentItem = $(this).find(getColListItemSelector()).filter("[data-item-id = '" + deletedItemData.parentId + "']");
346 |
347 | if (null != listParentItem) {
348 | var childrenLeft = $(this).find(getColListItemSelector()).filter("[data-parent-id = '" + deletedItemData.parentId + "']");
349 | if (null == childrenLeft || childrenLeft.length == 0) {
350 | listParentItem.data("has-children", false);
351 | listParentItem.attr("data-has-children", false);
352 | listParentItem.find("i").filter(".has-children").remove();
353 | }
354 | }
355 |
356 | //remove children col container.
357 | $(listDeletedItem).closest(getColContainerSelector()).next(getColContainerSelectorExcludeColLoading()).remove();
358 |
359 | if (null != listDeletedItem)
360 | listDeletedItem.remove();
361 |
362 | return this;
363 |
364 | }else if ("destroy" == args[0]) {
365 |
366 | if (isInitialized.call(this)) {
367 | // remove all miller-column object events
368 | $(this).find("*").addBack().off();
369 |
370 | // remove all window events related to miller-column object
371 | $(window).off("." + $(this).attr("id"));
372 |
373 | // remove specific attributes
374 | $(this).removeAttr("millerized");
375 | $(this).removeAttr("data-is-read-only");
376 | $(this).removeAttr("style");
377 |
378 | // empty miller-column object
379 | $(this).empty();
380 |
381 | if (isDebugEnabled)
382 | console.log("miller-column destroyed !");
383 | } else {
384 | if (isDebugEnabled)
385 | console.log("miller-column is not initialized so nothing to destroy ...");
386 | }
387 |
388 | return;
389 |
390 | } else if ("ismillerized" == args[0]) {
391 |
392 | return isInitialized.call(this);
393 | }
394 |
395 |
396 | function buildColListItem(item, readOnly) {
397 |
398 | var millerColListItem = $("
").addClass("miller-col-list-item");
399 |
400 | millerColListItem.attr("data-has-children", item.hasChildren);
401 | millerColListItem.attr("data-item-id", item.itemId);
402 | millerColListItem.attr("data-parent-id", item.parentId);
403 | millerColListItem.attr("data-category-id", item.categoryId);
404 | millerColListItem.attr("data-is-deletable", item.isDeletable);
405 | millerColListItem.attr("data-item-name", item.itemName);
406 | millerColListItem.attr("data-item-icon", item.itemIcon);
407 |
408 | var $listItemIcon = $("
").addClass("material-icons list-item-icon");
409 | millerColListItem.append($listItemIcon);
410 |
411 | if (item.itemIcon != "" && item.itemIcon != null)
412 | $listItemIcon.text(item.itemIcon);
413 |
414 | millerColListItem.append($("
").text(item.itemName).addClass("list-item-text"));
415 |
416 | if (item.hasChildren)
417 | millerColListItem.append($("
").addClass("material-icons").text("navigate_next").addClass("has-children"));
418 |
419 | if (false == readOnly) {
420 | var listItemActions = $("
").addClass("list-item-actions").append($("
").addClass("material-icons").addClass("edit").text("edit"));
421 | listItemActions.append($("
").addClass("material-icons").addClass("delete").text("delete"));
422 |
423 | millerColListItem.append(listItemActions);
424 | }
425 |
426 | if(item.numChildren != null && item.numChildren != 0){
427 |
428 | millerColListItem.append($("
").addClass("num-children-badge").text(item.numChildren));
429 |
430 | }
431 |
432 | return millerColListItem;
433 | }
434 |
435 | function getTotalInnerColsWidth() {
436 |
437 | var totalWidth = 0;
438 |
439 | if (isDebugEnabled) {
440 | console.log("About to calculate total width ...");
441 | }
442 |
443 | getMillerColContainers.call(this).each(function () {
444 |
445 | if (isViewHidden.call(this))
446 | return;
447 |
448 | totalWidth += $(this).outerWidth();
449 |
450 | if (isDebugEnabled) {
451 | console.log("added width: " + $(this).outerWidth())
452 | }
453 |
454 | });
455 |
456 | //include loading col width if it is showing.
457 | totalWidth = totalWidth + (!isViewHidden.call(getLoadingCol.call(this)) ? getLoadingCol.call(this).outerWidth() : 0);
458 |
459 | if (isDebugEnabled) {
460 | console.log("totalColsWidth: " + totalWidth + " body width:" + $(this).outerWidth());
461 | }
462 |
463 | return totalWidth;
464 | }
465 |
466 | function init() {
467 |
468 | hideNavCols.call(this);
469 |
470 | hideLoadingCol.call(this);
471 |
472 | resizeMillerColumn.call(this);
473 |
474 | initialize.call(this);
475 |
476 | }
477 |
478 | function hideNavCols() {
479 |
480 | hidePrevNavCol.call(this);
481 | hideNextNavCol.call(this);
482 |
483 | }
484 |
485 | function initialize() {
486 |
487 | if (getMillerColsBody.call(this).length == 0) { //if user has not build the miller ui structure using html manually
488 |
489 | var preNav = $("
")
490 | .addClass("miller-col-nav nav-prev hidden")
491 | .append($("
")
492 | .addClass("material-icons")
493 | .text("navigate_before"));
494 |
495 |
496 | var millerColsBody = $("
")
497 | .addClass("miller-cols-body");
498 |
499 | var millerColLoading = $("
")
500 | .addClass("miller-col-loading-container col-loading hidden")
501 | .append($("
")
502 | .addClass("miller-col-body")
503 | .append($("
")
504 | .addClass("miller-col-list-item loading-icon-container spinner")));
505 |
506 | millerColsBody.append(millerColLoading);
507 |
508 | var nextNav = $("
")
509 | .addClass("miller-col-nav nav-next hidden")
510 | .append($("
")
511 | .addClass("material-icons")
512 | .text("navigate_next"));
513 |
514 | $(this).append(preNav).append(millerColsBody).append(nextNav);
515 |
516 | }
517 |
518 | $(this).addClass("miller-cols-container-wrapper");
519 |
520 | $(this).css({
521 | height: settings.height
522 | });
523 |
524 | $(this).attr("millerized", "");
525 | $(this).attr("data-is-read-only", settings.isReadOnly);
526 | }
527 |
528 | function isInitialized() {
529 | return $(this).is("[millerized]");
530 | }
531 |
532 | function getMillerColContainers() {
533 | return $(this).find(".miller-col-container")
534 | }
535 |
536 | function getColLoadingSelector() {
537 | return ".col-loading";
538 | }
539 |
540 | function getLoadingCol() {
541 | return $(this).find(getColLoadingSelector())
542 | }
543 |
544 | function showLoadingCol() {
545 | return showView.call(getLoadingCol.call(this));
546 | }
547 |
548 | function hideLoadingCol() {
549 | return hideView.call(getLoadingCol.call(this));
550 | }
551 |
552 | function getPrevNav() {
553 | return $(this).find(".miller-col-nav.nav-prev");
554 | }
555 |
556 | function getNextNav() {
557 | return $(this).find(".miller-col-nav.nav-next");
558 | }
559 |
560 | function getMillerColsBody() {
561 | return $(this).find(".miller-cols-body");
562 | }
563 |
564 | function getColListItemSelector() {
565 | return ".miller-col-body .miller-col-list-item"
566 | }
567 |
568 | function getColListItemContainer() {
569 | return ".miller-col-body"
570 | }
571 |
572 | function getColContainerSelector() {
573 | return ".miller-col-container"
574 | }
575 |
576 | function getColContainerSelectorExcludeColLoading() {
577 | return ".miller-col-container:not(.col-loading)"
578 | }
579 |
580 |
581 | function getFirstVisibleCol() {
582 |
583 | var firstVisibleCol = getMillerColsBody.call(this).find(".miller-col-container:not(.hidden):first");
584 |
585 | return firstVisibleCol.length != 0 ? firstVisibleCol :
586 | (isViewHidden.call(getLoadingCol.call(this)) ? null : getLoadingCol.call(this));
587 | }
588 |
589 | function hasLeftHiddenCol() {
590 | return isViewHidden.call(getFirstVisibleCol.call(this).prev());
591 | }
592 |
593 | function hasRightHiddenCol() {
594 | return isViewHidden.call(getLastVisibleCol.call(this).next().not(getColLoadingSelector()));
595 | }
596 |
597 | function getLastVisibleCol() {
598 |
599 | return !isViewHidden.call(getLoadingCol.call(this)) ? getLoadingCol.call(this) :
600 | getMillerColsBody.call(this).find(".miller-col-container:not(.hidden):last");
601 |
602 | }
603 |
604 | function isViewHidden() {
605 | return $(this).hasClass(MILLER_COL_HIDDEN_CLASS);
606 | }
607 |
608 | function hideView() {
609 | if (!isViewHidden.call(this))
610 | $(this).addClass(MILLER_COL_HIDDEN_CLASS);
611 | }
612 |
613 | function showView() {
614 | if (isViewHidden.call(this))
615 | $(this).removeClass(MILLER_COL_HIDDEN_CLASS);
616 | }
617 |
618 | function showPrevNavCol() {
619 | showView.call(getPrevNav.call(this))
620 | }
621 |
622 | function isNextNavColHidden() {
623 | return isViewHidden.call(getNextNav.call(this));
624 | }
625 |
626 | function isPrevNavColHidden() {
627 | return isViewHidden.call(getPrevNav.call(this))
628 | }
629 |
630 | function showNextNavCol() {
631 | showView.call(getNextNav.call(this));
632 | }
633 |
634 | function hidePrevNavCol() {
635 | hideView.call(getPrevNav.call(this));
636 | }
637 |
638 | function hideNextNavCol() {
639 | hideView.call(getNextNav.call(this))
640 | }
641 |
642 | function isOverFlowing() {
643 |
644 | //the body must at least show one column
645 | if ($(getMillerColsBody.call(this)).children(":not(.hidden)").length <= 1)
646 | return false;
647 |
648 | return getMillerColsBody.call(this).outerWidth() + 1 < getTotalInnerColsWidth.call(getMillerColsBody.call(this))
649 | }
650 |
651 | function overFlowsWith(child) {
652 |
653 | var millerColsBody = getMillerColsBody.call(this);
654 |
655 | return isOverFlowing.call(this) ||
656 | millerColsBody.outerWidth() + 1 < getTotalInnerColsWidth.call(millerColsBody) + child.outerWidth()
657 | }
658 |
659 | function selectItem() {
660 |
661 | if ($(this).is(SELECTOR_IS_SELECTED))
662 | return;
663 |
664 | $(this).addClass(CLASS_SELECTED);
665 | }
666 |
667 | function deselectItem() {
668 | $(this).removeClass(CLASS_SELECTED);
669 | }
670 |
671 | function removeTrailingColContainers() {
672 | $(this).nextAll(":not(.col-loading)").remove();
673 | }
674 |
675 | function getCategoryItem() {
676 |
677 | var categoryItem = new CategoryItem();
678 |
679 | categoryItem.setCategoryId($(this).attr("data-category-id"));
680 | categoryItem.setItemId($(this).attr("data-item-id"));
681 | categoryItem.setItemName($(this).attr("data-item-name"));
682 | categoryItem.setItemIcon($(this).attr("data-item-icon"));
683 | categoryItem.setHasChildren($(this).attr("data-has-children"));
684 | categoryItem.setIsDeletable($(this).attr("data-is-deletable"));
685 | categoryItem.setParentId($(this).attr("data-parent-id"));
686 |
687 | return categoryItem;
688 |
689 | }
690 |
691 | function getCategory() {
692 |
693 | var category = new Category();
694 |
695 | category.setCategoryId($(this).attr("data-category-id"));
696 | category.setCategoryName($(this).attr("data-category-name"));
697 | category.setIsLowestLevel($(this).attr("data-is-lowest-level"));
698 | category.setParentId($(this).attr("data-parent-id"));
699 |
700 | return category;
701 |
702 | }
703 |
704 |
705 | function scaleUpLeft() {
706 |
707 | while (!isOverFlowing.call(this) && hasLeftHiddenCol.call(this)) {
708 |
709 | showView.call(getFirstVisibleCol.call(this).prev())
710 |
711 | }
712 |
713 | //undo the last show if there is overflow
714 | if (isOverFlowing.call(this)) {
715 | hideView.call(getFirstVisibleCol.call(this))
716 | }
717 |
718 | if (!hasLeftHiddenCol.call(this)) {
719 | hidePrevNavCol.call(this);
720 | }
721 |
722 |
723 | if (!hasLeftHiddenCol.call(this) && !isNextNavColHidden.call(this) && !overFlowsWith.call(this, getLastVisibleCol.call(this).next()))
724 | resizeMillerColumn.call(this, SHRINK_DIRECTION_RIGHT, SCALE_TYPE_SCALE_UP);
725 |
726 | }
727 |
728 | function scaleDownLeft() {
729 |
730 | while (isOverFlowing.call(this)) {
731 |
732 | hideView.call(getFirstVisibleCol.call(this));
733 |
734 | showPrevNavCol.call(this);
735 |
736 | }
737 |
738 | }
739 |
740 | function scaleUpRight() {
741 |
742 | while (!isOverFlowing.call(this) && hasRightHiddenCol.call(this)) {
743 |
744 | showView.call(getLastVisibleCol.call(this).next());
745 |
746 | if (!hasRightHiddenCol.call(this)) {
747 | hideNextNavCol.call(this);
748 | break;
749 | }
750 |
751 | }
752 |
753 | if (!hasRightHiddenCol.call(this) && !isPrevNavColHidden.call(this) && !overFlowsWith.call(this, getFirstVisibleCol.call(this).prev())
754 | )
755 | resizeMillerColumn.call(this, SHRINK_DIRECTION_LEFT, SCALE_TYPE_SCALE_UP)
756 |
757 |
758 | }
759 |
760 | function scaleDownRight() {
761 |
762 | while (isOverFlowing.call(this)) {
763 |
764 | hideView.call(getLastVisibleCol.call(this));
765 | showNextNavCol.call(this);
766 |
767 | }
768 |
769 | }
770 |
771 | function resizeMillerColumn(direction, scaleType) {
772 |
773 | scaleType = scaleType || SCALE_TYPE_SCALE_DOWN;
774 |
775 | direction = direction || SHRINK_DIRECTION_LEFT;
776 |
777 | switch (direction) {
778 |
779 | case SHRINK_DIRECTION_RIGHT:
780 |
781 | switch (scaleType) {
782 |
783 | case SCALE_TYPE_SCALE_DOWN:
784 | scaleDownRight.call(this);
785 | break;
786 |
787 | case SCALE_TYPE_SCALE_UP:
788 | scaleUpRight.call(this);
789 | break;
790 |
791 | default:
792 | console.error("Unkown scaleType: " + scaleType);
793 |
794 | }
795 | break;
796 |
797 | case SHRINK_DIRECTION_LEFT:
798 |
799 | switch (scaleType) {
800 | case SCALE_TYPE_SCALE_DOWN:
801 | scaleDownLeft.call(this);
802 | break;
803 |
804 | case SCALE_TYPE_SCALE_UP:
805 | scaleUpLeft.call(this);
806 | break;
807 |
808 | default:
809 | console.error("Unknown scaleType:" + scaleType)
810 | }
811 |
812 | break;
813 |
814 | default:
815 | console.error("Unknown hideDirection: " + direction)
816 |
817 | }
818 |
819 |
820 | }
821 |
822 |
823 | var waitForFinalEvent = (function () {
824 | var timers = {};
825 | return function (callback, ms, uniqueId) {
826 | if (!uniqueId) {
827 | uniqueId = "Don't call this twice without a uniqueId";
828 | }
829 | if (timers[uniqueId]) {
830 | clearTimeout(timers[uniqueId]);
831 | }
832 | timers[uniqueId] = setTimeout(callback, ms);
833 | };
834 | })();
835 |
836 |
837 | return this.each(function () {
838 |
839 | var millerColumn = this;
840 |
841 | init.call(millerColumn);
842 |
843 | if (args[0] && args[0]["initData"]) { //arg[0] root col
844 |
845 | //hide all cols except col load b/se arg[0] => root col
846 | $(millerColumn).find(getColContainerSelectorExcludeColLoading()).remove();
847 |
848 | $(millerColumn).millerColumn("addCol", args[0]["initData"]);
849 |
850 | }
851 |
852 | getPrevNav.call(millerColumn).on("click", function () {
853 |
854 | showView.call(getFirstVisibleCol.call(millerColumn).prev());
855 |
856 | if (!hasLeftHiddenCol.call(millerColumn))
857 | hidePrevNavCol.call(millerColumn);
858 |
859 | resizeMillerColumn.call(millerColumn, SHRINK_DIRECTION_RIGHT);
860 |
861 | });
862 |
863 | getNextNav.call(millerColumn).on("click", function () {
864 |
865 | showView.call(getLastVisibleCol.call(millerColumn).next());
866 |
867 | if (!hasRightHiddenCol.call(millerColumn))
868 | hideNextNavCol.call(millerColumn);
869 |
870 | resizeMillerColumn.call(millerColumn, SHRINK_DIRECTION_LEFT);
871 |
872 | });
873 |
874 |
875 | getMillerColsBody.call(millerColumn).on("DOMNodeInserted", function (event) {
876 |
877 | //resize only if col is added.
878 | if (!$(event.target).is(getColContainerSelector()))
879 | return;
880 |
881 | if (isDebugEnabled) {
882 | console.log("Dom inserted..");
883 | }
884 |
885 | hideLoadingCol.call(millerColumn);
886 |
887 | resizeMillerColumn.call(millerColumn, SHRINK_DIRECTION_LEFT);
888 |
889 | });
890 |
891 |
892 | getMillerColsBody.call(millerColumn).on("DOMNodeRemoved", function (event) {
893 |
894 | //resize only if col is removed.
895 | if (!$(event.target).is(getColContainerSelector()))
896 | return;
897 | if (isDebugEnabled) {
898 | console.log("Dom removed..");
899 | }
900 |
901 | resizeMillerColumn.call(millerColumn, SHRINK_DIRECTION_LEFT, SCALE_TYPE_SCALE_UP);
902 |
903 | });
904 |
905 | /**
906 | * Fires item-selected event when an item is selected along with the necessary data.
907 | */
908 | getMillerColsBody.call(millerColumn).on("click", getColListItemSelector(), function () {
909 |
910 | var currentColContainer = $(this).closest(getColContainerSelector());
911 |
912 | removeTrailingColContainers.call(currentColContainer);
913 |
914 | if (!isNextNavColHidden.call(millerColumn))
915 | hideNextNavCol.call(millerColumn);
916 |
917 | if ($(this).data(HAS_CHILDREN) == true) {
918 | showLoadingCol.call(millerColumn);
919 | }
920 |
921 | resizeMillerColumn.call(millerColumn, SHRINK_DIRECTION_LEFT, SCALE_TYPE_SCALE_DOWN);
922 |
923 | deselectItem.call((currentColContainer).find(getColListItemSelector()));
924 |
925 | selectItem.call(this);
926 |
927 | //Firing item-selected event.
928 | var data = getCategoryItem.call(this);
929 |
930 | $(this).trigger("item-selected", data);
931 |
932 | if (isDebugEnabled) {
933 | console.log("fired item-selected event: " + JSON.stringify(data))
934 | }
935 |
936 | });
937 |
938 | getMillerColsBody.call(millerColumn).on("click", ".list-item-actions .edit", function (event) {
939 |
940 | var currentItemContainer = $(this).closest(getColListItemSelector());
941 |
942 | //Firing edit-item event.
943 | var data = getCategoryItem.call(currentItemContainer);
944 |
945 | $(currentItemContainer).trigger("edit-item", data);
946 |
947 | if (isDebugEnabled) {
948 | console.log("fired edit item event: " + JSON.stringify(data));
949 | }
950 |
951 | event.stopPropagation();
952 |
953 | });
954 |
955 | getMillerColsBody.call(millerColumn).on("click", ".list-item-actions .delete", function (event) {
956 |
957 | var currentItemContainer = $(this).closest(getColListItemSelector());
958 |
959 | //Firing delete-item event.
960 | var data = getCategoryItem.call(currentItemContainer);
961 |
962 | $(currentItemContainer).trigger("delete-item", data);
963 |
964 | if (isDebugEnabled) {
965 | console.log("fired delete item event: " + JSON.stringify(data));
966 | }
967 |
968 | event.stopPropagation();
969 |
970 | });
971 |
972 | getMillerColsBody.call(millerColumn).on("click", ".miller-col-actions .action-add", function () {
973 |
974 | var currentColContainer = $(this).closest(getColContainerSelector());
975 | var parentColContainer = currentColContainer.prev();
976 |
977 | //Firing add-item event.
978 | var data = getCategory.call(currentColContainer);
979 |
980 | if (parentColContainer)
981 | data.parentId = $(parentColContainer).find(getColListItemSelector()).filter(SELECTOR_IS_SELECTED).data("item-id");
982 |
983 | $(currentColContainer).trigger("add-item", data);
984 |
985 | if (isDebugEnabled) {
986 | console.log("fired add item event: " + JSON.stringify(data));
987 | }
988 |
989 | });
990 |
991 |
992 | $(window).on("resize." + $(millerColumn).attr("id"), function (event) {
993 |
994 | waitForFinalEvent(function () {
995 |
996 | if (!isInitialized.call(millerColumn))
997 | return;
998 |
999 | if (isDebugEnabled) {
1000 | console.log("window resized..");
1001 | }
1002 |
1003 | if ($(window).outerWidth() == windowWidth)
1004 | return;
1005 |
1006 | if (isDebugEnabled) {
1007 | console.log("About to resize: old width:" + windowWidth + " new one: " + $(window).outerWidth());
1008 | }
1009 |
1010 | //disable nav cols
1011 | hideNavCols.call(millerColumn);
1012 |
1013 | if ($(window).outerWidth() < windowWidth) {
1014 | resizeMillerColumn.call(millerColumn, SHRINK_DIRECTION_LEFT, SCALE_TYPE_SCALE_DOWN);
1015 | } else {
1016 | resizeMillerColumn.call(millerColumn, SHRINK_DIRECTION_LEFT, SCALE_TYPE_SCALE_UP);
1017 | }
1018 |
1019 | //re-enable navs
1020 | if (hasRightHiddenCol.call(millerColumn))
1021 | showNextNavCol.call(millerColumn);
1022 |
1023 | if (hasLeftHiddenCol.call(millerColumn))
1024 | showPrevNavCol.call(millerColumn);
1025 |
1026 | windowWidth = $(window).outerWidth();
1027 |
1028 | }, 500, $(millerColumn).attr("id"));
1029 |
1030 | });
1031 |
1032 | });
1033 |
1034 | }
1035 |
1036 | })(jQuery);
--------------------------------------------------------------------------------