Skip to content

Instantly share code, notes, and snippets.

@AquilaSands
Created August 18, 2017 08:18
Show Gist options
  • Save AquilaSands/2586a39db881f45fbf90633e0a4376ca to your computer and use it in GitHub Desktop.
Save AquilaSands/2586a39db881f45fbf90633e0a4376ca to your computer and use it in GitHub Desktop.
Aurelia Gist Truncate Custom Attribute
<template>
<require from='./truncate'></require>
<div><p truncate="max.bind:10; text.bind:txt;"></p></div>
<div><p truncate="max.bind:50;">Smile spoke total few great had never their too. Amongst moments do in arrived at my replied. Fat weddings servants but man believed prospect. Companions understood is as especially pianoforte connection introduced. Nay newspaper can sportsman are admitting gentleman belonging his. Is oppose no he summer lovers twenty in. Not his difficulty boisterous surrounded bed. Seems folly if in given scale. Sex contented dependent conveying advantage can use.</p></div>
<br/>
<button type="button" click.delegate="changeTxt()">Change</button>
</template>
import { inject } from 'aurelia-framework';
//import { BindingSignaler } from 'aurelia-templating-resources';
//@inject(BindingSignaler)
export class App {
txt = '';
txt1 = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec justo commodo, pharetra tortor aliquam, sollicitudin dui. Nulla amet. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec justo commodo, pharetra tortor aliquam, sollicitudin dui. Nulla amet.Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec justo commodo, pharetra tortor aliquam, sollicitudin dui. Nulla amet. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nec justo commodo, pharetra tortor aliquam, sollicitudin dui. Nulla amet.';
txt2 = 'Smile spoke total few great had never their too. Amongst moments do in arrived at my replied. Fat weddings servants but man believed prospect. Companions understood is as especially pianoforte connection introduced. Nay newspaper can sportsman are admitting gentleman belonging his. Is oppose no he summer lovers twenty in. Not his difficulty boisterous surrounded bed. Seems folly if in given scale. Sex contented dependent conveying advantage can use.';
signaler;
constructor() {
//this.signaler = signaler;
this.txt = this.txt1;
}
changeTxt = () => {
this.txt = this.txt === this.txt1 ? this.txt2 : this.txt1;
}
}
<!doctype html>
<html>
<head>
<title>Aurelia</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body aurelia-app>
<h1>Loading...</h1>
<script src="https://jdanyow.github.io/rjs-bundle/node_modules/requirejs/require.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/config.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/aurelia.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/babel.js"></script>
<script>
require(['aurelia-bootstrapper']);
</script>
</body>
</html>
.truncateContainer {
width: 200px;
height: 250px;
overflow-x: hidden;
margin: 7px 0 0 0;
background: #fff;
color: #6d6e71;
box-shadow: 0 0 0 0 #fff;
padding: .875rem;
opacity: 0;
transition: all ease-in 0.2s;
}
.truncateContainer.showing {
opacity: 1;
box-shadow: 0 -1px 5px 0 #cdcdcd;
}
.truncateText {
margin: 0;
padding: 0;
}
<template>
<require from="./truncate.css"></require>
<div class="truncateContainer ${show ? 'showing' : ''}">
<p class="truncateText">${originalText}</p>
</div>
</template>
import { inject, bindable, observable, Container, ViewEngine, View, TaskQueue} from 'aurelia-framework';
@inject(Element, Container, ViewEngine, TaskQueue)
export class TruncateCustomAttribute {
@bindable max;
@observable @bindable text;
show = false;
element;
divElement;
originalText;
ellipsis;
viewEngine;
container;
queue;
constructor(element, container, viewEngine, queue) {
this.element = element;
this.container = container;
this.viewEngine = viewEngine;
this.ellipsis = document.createElement('span');
this.ellipsis.appendChild(document.createTextNode('\u2026'));
this.ellipsis.addEventListener('click', this.handleClick);
this.ellipsis.style.cursor ='pointer';
this.queue = queue;
}
bind() {
this.originalText = this.text ? this.text : this.element.innerText;
this.truncate(this.originalText);
}
truncate = (text) => {
if (Number.isInteger(this.max) && text.length > this.max) {
this.element.innerText = text.slice(0, this.max);
this.element.appendChild(this.ellipsis);
}
}
handleClick = e => {
if (!this.show) {
this.showFullText();
}
if (this.show) {
/*
Remove if click is outside of it's client rectangle.
*/
let containerRect = this.divElement.getBoundingClientRect();
let elementRect = this.element.getBoundingClientRect();
let inContainerRect = e.clientX > containerRect.left && e.clientX < containerRect.right && e.clientY > containerRect.top && e.clientY < containerRect.bottom;
let inElementRect = e.clientX > elementRect.left && e.clientX < elementRect.right && e.clientY > elementRect.top && e.clientY < elementRect.bottom;
if (!inContainerRect && !inElementRect) {
this.hideFullText();
}
}
}
showFullText = () => {
this.viewEngine.loadViewFactory('./truncate.html').then(factory => {
const childContainer = this.container.createChild();
const view = factory.create(childContainer);
view.bind(this);
this.addElement(view);
document.addEventListener('mouseup', this.handleClick);
window.setTimeout(() => {
this.show = true;
}, 0);
});
}
hideFullText = () => {
this.show = false;
document.removeEventListener('mouseup', this.handleClick);
// Allow time to complete the transition
window.setTimeout(() => {
this.element.parentNode.removeChild(this.divElement);
}, 200);
}
addElement(view) {
//const body = document.querySelectorAll('body')[0];
this.divElement = document.createElement('div');
view.appendNodesTo(this.divElement);
const elementRect = this.element.getBoundingClientRect();
const left = elementRect.left + window.scrollX;
const height = this.divElement.getBoundingClientRect().height;
var top = elementRect.top + elementRect.height;
top = ((top+height) < window.innerHeight) ? top + window.scrollY : (elementRect.top - height + window.scrollY);
this.divElement.style.top = top + 'px';
this.divElement.style.left = left + 'px';
this.divElement.style.position = 'absolute';
this.divElement.style.zIndex = '2001';
this.element.parentNode.insertBefore(this.divElement, this.element);
}
textChanged = (newVal, oldVal) => {
if(newVal !== oldVal) {
this.originalText = newVal;
this.truncate(this.originalText);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment