"directions"
Bootstrap 3.3.0 Snippet by irinashuvalova

<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script> <script src="//code.jquery.com/jquery-1.11.1.min.js"></script> <!------ Include the above in your HEAD tag ----------> <div class="direction-wrapper" id="app"> </div> <div id="jsCreateLinkForm" class="input-form js-create-form" style="display: none;" > <p> <label>Ссылка: <input type="text" class="js-link-url" value="http://" /></label> </p> <p class="js-link-title-wrapper"> <label>Название <input type="text" class="js-link-title" value="" disabled="disabled"/></label> </p> <p class="js-link-error-wrapper"> Введенный адрес имеет не верный формат </p> <div class="clear"></div> <button type="button" class="js-btn" data-action="create-link-cancel">Назад</button> <button type="button" class="js-btn" data-action="create-link-accept">Добавить</button> <div class="clear"></div> </div> <div id="jsChangeImage" class="input-form js-change-image-form" style="display: none;" > <div class="image-wrapper js-direction-image"> <img id="imageSource" scr=""/> </div> <input type="file" name="file" id="fileuploader" style="display: none;" accept="image/jpg, image/jpeg, image/gif, image/png"/> <button type="button" class="js-btn" data-action="change-image-cancel">Назад</button> <button type="button" class="js-btn" data-action="change-image-load">Загрузить другое изображение</button> <button type="button" class="js-btn" data-action="change-image-accept">Сохранить</button> </div> <script type="text/x-handlebars-template" id="allDirectionsTemplate"> <h1 class="module-title">Структура компании</h1> <ul class="directions-overview"> {{#each this}} <div class="direction-summary"> <a href="#!/{{ ID }}" class="direction-title">{{ Title }}</a> <a href="#!/{{ ID }}" class="direction-image"> <img src="{{ Cover }}" /></a> <p class="direction-text">{{ Text }}</p> </div> {{/each}} </ul> </script> <script type="text/x-handlebars-template" id="directionTemplate"> <div class="direction"> <div class="left-col"> <div class="direction-info"> <h2 class="module-title">{{ Title }}</h2> <div class="direction-image"> <img src="{{ Cover }}" /> {{#if CanEdit}} <a href="#jsChangeImage" class="js-btn change-image">Изменить изображение</a> {{/if}} </div> <p class="direction-text">{{ Text }}</p> </div> <div class="direction-hierarchy js-hierarchy"> <div class="hierarchy-root"> <p class="root-title">{{ Title }}</p> <a class="direction-link" href="<%= _Consts.UrlToAddressBook %>?defDep={{ ID }}">a</a> </div> {{> children Children}} </div> </div> <div class="right-col"> {{#condition Links.length "||" CanEdit }} <div class="direction-data direction-links-wrapper"> <h3>Полезные ссылки:</h3> <ul class="direction-links js-links-list"> {{#each Links}} {{> link this}} {{/each}} {{#if CanEdit }} <li><a href="#jsCreateLinkForm" class="js-btn" data-action="create-link" type="button">Новая ссылка</a></li> {{/if}} </ul> </div> {{/condition}} <div class="direction-data direction-managers-wrapper"> <h3>Руководитель:</h3> {{> employee Manager }} </div> {{#if Assistants}} <div class="direction-data direction-managers-wrapper"> <h3>Административная поддержка:</h3> {{#each Assistants}} {{> employee this }} {{/each}} </div> {{/if}} </div> </div> </script> <script type="text/x-handlebars-template" id="employeeTemplate"> <div class="employee-wrapper"> <a class="employee-photo" href="<%= _Consts.UrlToProfile %>?user={{ ID }}"> <img src="{{ Photo }}" /> </a> <div class="employee-info"> <a class="employee-title" href="<%= _Consts.UrlToProfile %>?user={{ ID }}">{{ Lastname }} {{ Firstname }}</a> {{#if Position}} <p class="employee-position">{{ Position }}</p> {{/if}} {{#if Phone}} <p class="employee-phone">{{ Phone }}</p> {{/if}} {{#if Email}} <a class="employee-mail" href="mailto:{{ Email }}">{{ Email }}</a> {{/if}} </div> </div> </script> <script type="text/x-handlebars-template" id="departmentTemplate"> <div class="hierarchy-item" data-id="{{ ID }}"> <div class="department-info"> <a class="department-info-title" href="#!/{{ ID }}">{{ Title }}</a> {{#if HasChildren}} <button type="button" class="hierarchy-action js-btn" data-action="hierarchy-action"></button> {{/if}} <a class="direction-link" href="<%= _Consts.UrlToAddressBook %>?defDep={{ ID }}"></a> </div> </div> </script> <script type="text/x-handlebars-template" id="departmentChildrenTemplate"> <div class="heirarchy-children {{#if this }}hierarchy-not-empty {{/if}}"> {{#each this}} {{> department this}} {{/each}} </div> </script> <script type="text/x-handlebars-template" id="linkTemplate"> <li class="direction-link" data-id="{{ ID }}"><a href="{{ Url }}"{{#if InNewWindow}} target="_blank"{{/if}}>{{ Title }}</a><button type="button" class="remove-link js-btn" data-action="remove-link"></button></li> </script>
@import '../../../../WSSC.PRT.PNT6.Core/Layouts/WSSC.PRT.PNT6.Core/styles/props'; .module-title { margin-bottom: 30px; margin-right: 30px; } .direction-wrapper { .direction { .left-col { float: left; width: 70%; .direction-image { position: relative; .change-image { display: none; position: absolute; bottom: 0; width: 100%; padding: 10px 0; background: rgba(0, 0, 0, 0.5); } &:hover { .change-image { display: block; } } } .direction-hierarchy { text-align: center; .hierarchy-root { display: inline-block; width: 335px; height: 120px; margin-bottom: 37px; box-shadow: 0 0 0 1px @baseRed, 0 0 0 6px #ffa9a9; position: relative; } .hierarchy-children { text-align: center; } .hierarchy-item { display: inline-block; vertical-align: top; .department-info { width: 185px; height: 135px; position: relative; } } } .root-title { .webpart-title(); word-break: break-word; .vertical-block-center-height-unknown(); width: 100%; display: block; text-align: center; } .direction-link { position: absolute; color: transparent; bottom: 10px; right: 10px; width: 23px; height: 15px; display: inline-block; background: @structurePplIcon; } .employee-wrapper { .employee-photo { display: inline-block; width: 55px; height: 55px; overflow: hidden; img { width: 100%; } } } } .right-col { float: right; width: 30%; padding-left: 30px; .box-sizing; } } } .hierarchy-root { /*&:before { content: ''; position: absolute; bottom: -34px; left: 50%; border-left: 1px solid #ccc; width: 0; height: 28px; }*/ } .heirarchy-children { .hierarchy-item { box-shadow: 0 0 0 1px #e1e1e1, 0 0 0 6px #eeeeee; margin-right: 35px; margin-bottom: 40px; position: relative; &:nth-child(3n) { margin-right: 0; } &:last-child { margin-right: 0; } } > .hierarchy-item { &:first-child { &:before { content: ''; position: absolute; top: -20px; right: -50%; border-left: 1px solid #ccc; width: 100%; height: 14px; } } &:nth-child(2) { &:before { content: ''; position: absolute; top: -20px; left: -71%; border-top: 1px solid #ccc; border-right: 1px solid #ccc; width: 120.5%; height: 14px; } } &:nth-child(3) { &:before { content: ''; position: absolute; top: -20px; left: -71%; border-top: 1px solid #ccc; border-right: 1px solid #ccc; border-left: 1px solid #ccc; width: 120%; height: 14px; } /*&:after { content: ''; position: absolute; top: -34px; left: -70%; border-left: 1px solid #ccc; width: 120%; height: 15px; }*/ } } .hierarchy-opened { box-shadow: none; margin: 0 auto; > .department-info { box-shadow: 0 0 0 1px #e1e1e1, 0 0 0 6px #eeeeee; margin: 0 auto 40px; } > .department-info .hierarchy-action { background-position: 0 -16px; } &.hierarchy-item:before { display: none !important; } &.hierarchy-item:after { content: ''; position: absolute; top: -20px; left: -71%; border-right: 1px solid #ccc; width: 120.8%; height: 14px; } } } .department-info-title { text-transform: uppercase; font-size: 15px; color: @black; display: block; .vertical-block-center-height-unknown(); width: 100%; text-align: center; } .hierarchy-action { border: 0; min-width: 1px; display: inline-block; position: absolute; bottom: 10px; right: 40px; background: transparent @structureArrowIcon; width: 17px; height: 13px; cursor: pointer; outline: none; &:hover { background-color: transparent; } } .hierarchy-not-empty { position: relative; &:before { height: 14px; border-left: 1px solid #ccc; content: '.'; color: transparent; position: absolute; left: 49.8%; top: -34px; } } /*.hierarchy-opened { .heirarchy-children { &:before { width: 100%; height: 28px; margin-bottom: 20px; border: 1px solid #000000; border-bottom: 0; content: '.'; color: transparent; position: absolute; left: 0; top: -7px; } } }*/ .directions-overview { padding: 0; margin: 0; font-size: 0; .direction-summary { width: 433px; height: 223px; display: inline-block; font-size: 14px; vertical-align: top; box-shadow: 0 0 0 1px #e1e1e1, 0 0 0 6px #eeeeee; padding: 22px; .box-sizing; margin-bottom: 40px; &:nth-child(odd) { margin-right: 40px; margin-left: 6px; } } .direction-title { .webpart-title(); width: 100%; display: inline-block; max-height: 33px; min-height: 33px; overflow: hidden; vertical-align: middle; margin-bottom: 18px; } .direction-text, .direction-image { vertical-align: top; } .direction-image { .img-mask(); display: inline-block; } .direction-text { width: 255px; min-height: 125px; max-height: 125px; overflow: hidden; display: inline-block; } } .direction-info { margin-bottom: 65px; .module-title { margin-right: 0; } .direction-image { .img-mask(160px, 30px); display: inline-block; } .direction-text { width: ~"calc(100% - 195px)"; min-height: 160px; max-height: 160px; overflow: hidden; display: inline-block; } } .direction-data { margin-bottom: 25px; h3 { border-bottom: 2px solid @baseRed; .webpart-title(); padding: 10px 0 12px; margin-bottom: 10px; } .direction-links { display: block; width: 218px; overflow: hidden; position: relative; font-family: Roboto, Arial, sans-serif; list-style-type: none; padding: 0; li { background: url(/_layouts/15/WSSC.PRT.PNT6.Design/Icons/link-icon.png) no-repeat 2px 50%; line-height: 17px; padding-left: 47px; position: relative; min-height: 30px; } a { text-decoration: underline; display: inline-block; margin-top: 8px; max-width: 155px; } .remove-link { cursor: pointer; border: 0; min-width: 1px; position: absolute; display: inline-block; top: 45%; right: -10px; width: 8px; height: 8px; background: url(/_layouts/15/WSSC.PRT.PNT6.Design/Icons/cancel-icon.png) no-repeat; outline: none; } } .employee-wrapper { margin: 20px 0; .employee-photo { .img-mask(90px, 12px); display: inline-block; vertical-align: top; } .employee-info { display: inline-block; padding: 0; width: 110px; vertical-align: top; } .employee-title { color: #000000; text-decoration: underline; font-weight: bold; font-size: 13px; margin-bottom: 8px; display: block; } .employee-position, .employee-phone, .employee-mail { font-weight: 100; font-size: 10px; } .employee-mail { margin-top: 8px; display: inline-block; color: @baseRed; text-decoration: underline; } } } .remove-link { }
var AJAX_URL = '/_layouts/15/wssc.prt.pnt6.core/handlers/ajax.ashx', NAMESPACE = 'WSSC.PRT.PNT6.Structure:Direction:'; Handlebars.registerHelper('condition', function (v1, operator, v2, options) { switch (operator) { case '==': return (v1 == v2) ? options.fn(this) : options.inverse(this); case '===': return (v1 === v2) ? options.fn(this) : options.inverse(this); case '!=': return (v1 != v2) ? options.fn(this) : options.inverse(this); case '!==': return (v1 !== v2) ? options.fn(this) : options.inverse(this); case '<': return (v1 < v2) ? options.fn(this) : options.inverse(this); case '<=': return (v1 <= v2) ? options.fn(this) : options.inverse(this); case '>': return (v1 > v2) ? options.fn(this) : options.inverse(this); case '>=': return (v1 >= v2) ? options.fn(this) : options.inverse(this); case '&&': return (v1 && v2) ? options.fn(this) : options.inverse(this); case '||': return (v1 || v2) ? options.fn(this) : options.inverse(this); default: return options.inverse(this); } }); var directions = (function () { var allDirectionsTemplate = Handlebars.compile($('#allDirectionsTemplate').html()), directionTemplate = Handlebars.compile($('#directionTemplate').html()), linkTemplate = Handlebars.compile($('#linkTemplate').html()), departmentChildrenTemplate = Handlebars.compile($('#departmentChildrenTemplate').html()), currentDirectionID = null, createLinkDebounce = null, $uploader = null, jcropApi = null; Handlebars.registerPartial('link', $('#linkTemplate').html()); Handlebars.registerPartial('employee', $('#employeeTemplate').html()); Handlebars.registerPartial('department', $('#departmentTemplate').html()); Handlebars.registerPartial('children', $('#departmentChildrenTemplate').html()); Handlebars.registerHelper('groupEach', function (every, context, options) { var out = "", subcontext = [], i; if (context && context.length > 0) { for (i = 0; i < context.length; i++) { if (i > 0 && i % every === 0) { out += options.fn(subcontext); subcontext = []; } subcontext.push(context[i]); } out += options.fn(subcontext); } return out; }); function createLink() { $.getJSON(AJAX_URL, { method: NAMESPACE + 'AjaxAddDirectionLink', direction: currentDirectionID, url: $('.js-create-form .js-link-url').val(), title: $('.js-create-form .js-link-title').val(), rand: Math.random() }).then(function (response) { if (response.Error) { console.log(response); } else { $('.js-create-form .js-link-url').val('http://'); $('.js-create-form .js-link-title').val('') .disable(); var $link = $(linkTemplate(response)).css('display', 'none'); if ($('.js-btn[data-action="create-link"]').length) { $('.js-btn[data-action="create-link"]').before($link); } else { $('.js-links-list').append($link); } $link.fadeIn(200); $('.js-btn[data-action="create-link-cancel"]').trigger('click'); } }); } function removeLink($el) { var linkId = $el.data('id'); $.getJSON(AJAX_URL, { method: NAMESPACE + 'AjaxRemoveDirectionLink', id: linkId, rand: Math.random() }).then(function (response) { if (response.Error) { console.log(response); } else { $el.fadeOut(200, function () { $el.remove(); }); } }) } function onUrlInput(url) { url = url.trim(); createLinkDebounce = clearTimeout(createLinkDebounce); if (!url) { return; } if ($('.js-create-form .js-link-title-wrapper').css('display') === 'none') { $('.js-create-form .js-link-error-wrapper').fadeOut(200); $('.js-create-form .js-link-title-wrapper').fadeIn(200); } $('.js-create-form .js-link-title').disable(); $('.js-create-form .js-btn[data-action="create-link-accept"]').disable(); $('.js-create-form .js-link-title').val(''); createLinkDebounce = setTimeout(function () { $('.js-create-form .js-link-title').spin(); $.getJSON(AJAX_URL, { method: 'WSSC.PRT.PNT6.PersonalInfo:LinkActions:GetTitleByUrl', fullUrl: url, rand: Math.random() }).then(function (response) { $('.js-create-form .js-link-title').spin(); if (response.IsSuccess) { $('.js-create-form .js-link-title').val(response.Message); $('.js-create-form .js-link-title').enable(); $('.js-create-form .js-btn[data-action="create-link-accept"]').enable(); } else { $('.js-create-form .js-link-title-wrapper').fadeOut(200); $('.js-create-form .js-link-error-wrapper').fadeIn(200); } }); }, 350); } function showUploader() { if (!$uploader) { $uploader = $('#fileuploader').fileupload({ url: AJAX_URL, replaceFileInput: false, dataType: 'json', formData: { method: NAMESPACE + 'AjaxUploadFile' }, done: function (e, data) { if (data.result.Error) { console.log(data.result); } else { onImageRecieved(data.result.Path); } } }); } $uploader.trigger('click'); } function onImageRecieved(img) { jcropApi.setImage(img, function () { $('#imageSource').attr('src', img); setCropSelection(); }); } function setCropSelection() { var $image = $('#imageSource'), w = $image.width(), h = $image.height(), wC = w / 2, hC = h / 2, maxSelectionSize = Math.min(w, h), sC = maxSelectionSize / 2; jcropApi.setSelect([wC - sC, hC - sC, wC + sC, hC + sC]); } function getChildren(id) { return $.getJSON(AJAX_URL, { method: NAMESPACE + 'AjaxGetDepartmentChildren', depId: id }); } function changeCover() { var selected = jcropApi.tellSelect(); $.getJSON(AJAX_URL, { method: NAMESPACE + 'AjaxChangeDirectionCover', direction: currentDirectionID, coverPath: $('#imageSource').attr('src'), x: selected.x, y: selected.y, w: selected.w, h: selected.h }).then(function (response) { if (response.Error) { console.log(response); } else { $('.direction-image img').attr('src', response.Path); $('.js-change-image-form .js-btn[data-action="change-image-cancel"]').trigger('click'); } }); } function renderChildren($el, children) { var childHtml = departmentChildrenTemplate(children); $el.closest('.heirarchy-children').children().hide(); $el.show(); $el.append(childHtml); $el.addClass('hierarchy-opened'); } function expandChildren($el) { getChildren($el.data('id')).then(function (response) { if (response.Error) { console.log(response); } else { renderChildren($el, response); } }); } function collapseChildren($el) { $el.children('.heirarchy-children').remove(); $el.closest('.heirarchy-children').children().show(); $el.removeClass('hierarchy-opened'); } function getRootDirections() { $('#app').spin('large'); return $.getJSON(AJAX_URL, { method: NAMESPACE + 'AjaxGetDirections' }).then(function (response) { $('#app').spin(); if (response.Error) { console.log(response); } else { return response; } }); } function renderRootDirections(directions) { if (!directions) { return; } var html = allDirectionsTemplate(directions); $('#app').html(html); } function showAllDirections() { getRootDirections().then(renderRootDirections); } function getDirectionInfo(id) { $('#app').spin('large'); return $.getJSON(AJAX_URL, { method: NAMESPACE + 'AjaxGetDirection', id: id }).then(function (response) { $('#app').spin(); if (response.Error) { console.log(response); } else { currentDirectionID = response.ID; return response; } }); } function renderDirection(direction) { if (!direction) { return; } var html = directionTemplate(direction); $('#app').html(html); $('.js-create-form, .js-links-list, .js-hierarchy, .js-change-image-form').off() .on('click', '.js-btn', function () { var $src = $(this), action = $src.data('action'); switch (action) { case 'create-link-accept': createLink(); break; case 'remove-link': removeLink($src.parent()); break; case 'hierarchy-action': var $item = $src.closest('.hierarchy-item'); if ($item.hasClass('hierarchy-opened')) { collapseChildren($item); } else { expandChildren($item); } break; case 'change-image-load': showUploader(); break; case 'change-image-accept': changeCover(); break; } }) .on('keyup', '.js-link-url', function () { var val = $(this).val(); onUrlInput(val); }); $('a[href="#jsCreateLinkForm"]').unbind() .leanModal({ closeButton: '.js-create-form .js-btn[data-action="create-link-cancel"]', top: 300 }); $('a[href="#jsChangeImage"]').unbind() .leanModal({ closeButton: '.js-change-image-form .js-btn[data-action="change-image-cancel"]', top: 300, onShow: function ($el) { var $img = $el.find('#imageSource'); $img.attr('src', direction.Cover); if (jcropApi) { jcropApi.destroy(); } $img.Jcrop({ aspectRatio: 1 }, function () { jcropApi = this; setCropSelection(); }); } }); } function showDirection(id) { getDirectionInfo(id).then(renderDirection); } function onHashChanged() { function getHashValue(hash) { if (hash[0] === '#') { hash = hash.substring(1); } hash = hash.replace('!/', ''); return hash; } var hash = getHashValue(window.location.hash); if (hash.length) { showDirection(hash); } else { showAllDirections(); } } $(window).on('hashchange', onHashChanged); onHashChanged(); })();

Related: See More


Questions / Comments: