Related
I'm trying to add border-radius to my chartis stacked bar graph, but only to the first and last items.
I have tried to add a :first-child selector on my css application, but it doesn't work well.
Javascript:
var versions = [
{
data:[22],
className: 'stacked-bars content-0'
},
{
data:[103],
className: 'stacked-bars content-1'
},
{
data:[95],
className: 'stacked-bars content-2'
}
];
var chartistStack = new Chartist.Bar('#chartist-stack', {
series : versions
},{
horizontalBars: true,
stackBars: true,
reverseData: true,
height: '200px',
width: '80%',
chartPadding: {
left: 200
},
axisX: {
showGrid: false,
showLabel: false
},
axisY: {
showGrid: false,
showLabel: false
}
}
);
CSS:
.content-0 {
stroke: green;
color: green;
}
.content-1 {
stroke: red;
color: red;
}
.content-2 {
stroke: blue;
color: blue;
}
.stacked-bars > .ct-bar {
stroke-width: 20px;
}
https://codepen.io/luizzdea/pen/ErVwKd
In case you didn't find your answer: since this is an SVG, you can use this:
.stacked-bars:first-child,
.stacked-bars:last-child {
stroke-linecap: round
}
References:
1) https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap
2) https://css-tricks.com/almanac/properties/s/stroke-linecap/
I'm using a plugin called Letter js to animate a four paragraphs using html jQuery and CSS.
The plugin works great but I have an issue trying to delay the animation of each paragraph i.e. paragraph 1 should start after 1 second, paragraph 2 should start after 2 seconds with other words making each paragraph appear gradually.
I tried adding the delay function after content but that didn't work, can anybody help?
// The plugin js (l-by-l.min.js) file is the following:
! function(e) {
e.fn.lbyl = function(n) {
{
var t = e.extend({
content: "",
speed: 10,
type: "fade",
fadeSpeed: 500,
finished: function() {}
}, n),
d = e(this),
s = [],
i = t.content;
e(this).length
}
d.empty(), d.attr("data-time", i.length * t.speed);
for (var p = 0; p < i.length; p++) s.push(i[p]);
e.each(s, function(e, n) {
d.append('<span style="display: none;">' + n + "</span>"), setTimeout(function() {
"show" == t.type ? d.find("span:eq(" + e + ")").show() : "fade" == t.type && d.find("span:eq(" + e + ")").fadeIn(t.fadeSpeed)
}, e * t.speed)
}), setTimeout(function() {
t.finished()
}, i.length * t.speed)
}
}(jQuery);
// My Script is the following:
jQuery(document).ready(function($) {
$(".welcome_Text1_dk").lbyl({
content: "this is paragraph one",
speed: 100, //time between each new letter being added
type: 'fade', // 'show' or 'fade'
fadeSpeed: 500, // Only relevant when the 'type' is set to 'fade'
finished: function() {
console.log('finished')
} // Finished Callback
})
});
jQuery(document).ready(function($) {
$(".welcome_Text2_dk").lbyl({
content: "this is paragraph two",
speed: 100, //time between each new letter being added
type: 'fade', // 'show' or 'fade'
fadeSpeed: 500, // Only relevant when the 'type' is set to 'fade'
finished: function() {
console.log('finished')
} // Finished Callback
})
});
jQuery(document).ready(function($) {
$(".welcome_Text3_dk").lbyl({
content: "this is paragraph three",
speed: 100, //time between each new letter being added
type: 'fade', // 'show' or 'fade'
fadeSpeed: 500, // Only relevant when the 'type' is set to 'fade'
finished: function() {
console.log('finished')
} // Finished Callback
})
});
jQuery(document).ready(function($) {
$(".welcome_Text4_dk").lbyl({
content: "this is paragraph four",
speed: 100, //time between each new letter being added
type: 'fade', // 'show' or 'fade'
fadeSpeed: 500, // Only relevant when the 'type' is set to 'fade'
finished: function() {
console.log('finished')
} // Finished Callback
})
});
#home_dk {
width: 100%;
height: 100vh;
background: #fff;
background-attachment: fixed;
display: flex;
flex-direction: column;
justify-content: center;
}
#welcome_Text_Wrapper_dk {
display: block;
margin-left: auto;
margin-right: auto;
width: auto;
}
.welcome_Text1_dk,
.welcome_Text2_dk,
.welcome_Text3_dk {
color: #b6b69c;
font-size: 2.6em;
font-family: "SuperGroteskWebPro-Bold W01 Rg";
text-transform: uppercase;
text-align: left;
line-height: 1em;
}
.welcome_Text4_dk {
color: #b6b69c;
font-size: 2.6em;
font-family: 'FF_Super_Grotesk';
text-transform: uppercase;
text-align: left;
line-height: 1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="home_dk">
<article id="welcome_Text_Wrapper_dk">
<div class="welcome_Text1_dk"></div>
<div class="welcome_Text2_dk"></div>
<div class="welcome_Text3_dk"></div>
<div class="welcome_Text4_dk"></div>
</article>
</div>
// The plugin js (l-by-l.min.js) file is the following:
! function(e) {
e.fn.lbyl = function(n) {
{
var t = e.extend({
content: "",
speed: 10,
type: "fade",
fadeSpeed: 500,
finished: function() {}
}, n),
d = e(this),
s = [],
i = t.content;
e(this).length
}
d.empty(), d.attr("data-time", i.length * t.speed);
for (var p = 0; p < i.length; p++) s.push(i[p]);
e.each(s, function(e, n) {
d.append('<span style="display: none;">' + n + "</span>"), setTimeout(function() {
"show" == t.type ? d.find("span:eq(" + e + ")").show() : "fade" == t.type && d.find("span:eq(" + e + ")").fadeIn(t.fadeSpeed)
}, e * t.speed)
}), setTimeout(function() {
t.finished()
}, i.length * t.speed)
}
}(jQuery);
// My Script is the following:
jQuery(document).ready(function($) {
// create an array of paragraphs
var myParagraphs = [{
selector: ".welcome_Text1_dk",
content: "this is paragraph one"
}, {
selector: ".welcome_Text2_dk",
content: "this is paragraph two"
}, {
selector: ".welcome_Text3_dk",
content: "this is paragraph three"
}, {
selector: ".welcome_Text4_dk",
content: "this is paragraph four"
}];
// loops it
for (let i = 0; i < myParagraphs.length; i++) {
setTimeout(function() {
$(myParagraphs[i].selector).lbyl({
content: myParagraphs[i].content,
speed: 100, //time between each new letter being added
type: 'fade', // 'show' or 'fade'
fadeSpeed: 500, // Only relevant when the 'type' is set to 'fade'
finished: function() {
console.log('finished')
} // Finished Callback
});
}, 1000 * i);
}
});
#home_dk {
width: 100%;
height: 100vh;
background: #fff;
background-attachment: fixed;
display: flex;
flex-direction: column;
justify-content: center;
}
#welcome_Text_Wrapper_dk {
display: block;
margin-left: auto;
margin-right: auto;
width: auto;
}
.welcome_Text1_dk,
.welcome_Text2_dk,
.welcome_Text3_dk {
color: #b6b69c;
font-size: 2.6em;
font-family: "SuperGroteskWebPro-Bold W01 Rg";
text-transform: uppercase;
text-align: left;
line-height: 1em;
}
.welcome_Text4_dk {
color: #b6b69c;
font-size: 2.6em;
font-family: 'FF_Super_Grotesk';
text-transform: uppercase;
text-align: left;
line-height: 1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="home_dk">
<article id="welcome_Text_Wrapper_dk">
<div class="welcome_Text1_dk"></div>
<div class="welcome_Text2_dk"></div>
<div class="welcome_Text3_dk"></div>
<div class="welcome_Text4_dk"></div>
</article>
</div>
You can use the setTimeout() function.
jQuery(document).ready(function($) {
// run first one here
setTimeout(function(){
// do the second one here
}, 1000); // in milliseconds; 1 second
setTimeout(function(){
// do the third one
}, 2000); // in milliseconds; 2 second
setTimeout(function(){
// do the fourth one here
}, 3000); // in milliseconds; 3 second
// etc.
});
I'm using Subscribe2 and it works great. The form is called using the <div id="element"></div>
However, it shows once per page. I want to show it twice on the same page. One at the top of the page and another at the bottom. How should I go about it?
$(document).ready(function () {
$("#element").subscribe2({
options: {
method: "google",
formkey: "2eiFxDZOpcyjPo9ub7nIwp6vAKUkLIiOxXIPT1TtAAAA",
datakey: "entry.57553044"
},
});
});
This can help you.
Since there are no CDN repository for subscribe2, I have added the files in the custom script/css only.
(function($, window, document, undefined) {
"use strict";
var pluginName = "subscribe2",
defaults = {
buttonText: "Request Invite",
btnClass: "",
inputClass: "",
errorMessages: {
client: "Please enter a valid email address.",
server: "Error contacting server"
},
successMessage: "Thanks. We have added you to our list and you will be notified soon."
};
// Plugin constructor
function Plugin(element, options) {
if (!options.hasOwnProperty("options") || typeof options.options !== "object" || !options.options.hasOwnProperty("formkey") || !options.options.hasOwnProperty("datakey") || typeof options.options.formkey !== "string" || typeof options.options.datakey !== "string") {
console.error("Invalid Options. Refer https://github.com/abhas9/subscribe2");
return;
}
this.element = element;
this.settings = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
// Avoid Plugin.prototype conflicts
$.extend(Plugin.prototype, {
init: function() {
this.appendSubscribeBox();
},
postForm: function(inputValue) {
var data = {}, that = this;
data[this.settings.options.datakey] = inputValue;
var successCallback = function() {
that.inputView.css({
display: "none"
});
that.successMessage.css({
display: "block"
}).html(that.settings.successMessage);
}
$.ajax({
url: "https://docs.google.com/forms/d/" + this.settings.options.formkey + "/formResponse",
type: "POST",
dataType: "xml",
statusCode: {
0: successCallback,
200: successCallback
},
data: data
})
},
submitHandler: function() {
var inputValue = $(this.element).find(".subscribe2-control-input").val();
if (this.validateEmail(inputValue)) {
this.errorMessage.css({
display: "none"
});
this.postForm(inputValue);
} else {
this.errorMessage.html(this.settings.errorMessages.client).css({
display: "block"
});
}
},
inputKeyUp: function(event) {
var inputValue = $(this.element).find(".subscribe2-control-input").val();
if (event.which === 13) {
this.submitHandler();
} else {
this.errorMessage.css({
display: "none"
});
if (this.validateEmail(inputValue)) {
this.validationStatusIcon.css({
display: "block"
}).addClass("subscribe2-valid").removeClass("subscribe2-invalid").html("✓");
} else {
this.validationStatusIcon.css({
display: "block"
}).addClass("subscribe2-invalid").removeClass("subscribe2-valid").html("x");
}
}
},
validateEmail: function(value) {
var re = /^(([^<>()[\]\\.,;:\s#"]+(\.[^<>()[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(value);
},
appendSubscribeBox: function() {
var subscribeInputWrp = $("<div>", {
class: "subscribe2-input-wrp"
});
var subscribeInput = $("<input>", {
type: "email",
class: "subscribe2-control-input " + this.settings.inputClass,
placeholder: "Email",
keyup: this.inputKeyUp.bind(this)
});
this.validationStatusIcon = $("<div>", {
class: "subscribe2-validation-status",
css: {
display: "none"
}
});
subscribeInputWrp.append(subscribeInput, this.validationStatusIcon);
var subscribeButton = $("<button>", {
text: this.settings.buttonText,
class: "subscribe2-btn " + this.settings.btnClass,
click: this.submitHandler.bind(this)
});
this.errorMessage = $("<div>", {
class: "subscribe2-error",
css: {
display: "none"
}
});
this.successMessage = $("<div>", {
class: "subscribe2-success",
css: {
display: "none"
}
});
var clearDiv = $("<div>", {
css: {clear: "both"}
});
this.inputView = $("<div>", {
class: "subscribe2-input-view",
append: [this.errorMessage, subscribeInputWrp, subscribeButton, clearDiv]
})
var subscribeBox = $("<div>", {
class: "subscribe2-wrp"
});
$(this.element).append(subscribeBox.append(this.inputView, this.successMessage));
}
});
// A really lightweight plugin wrapper around the constructor,
// preventing against multiple instantiations
$.fn[pluginName] = function(options) {
return this.each(function() {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName, new Plugin(this, options));
}
});
};
})(jQuery, window, document);
$(document).ready(function () {
$(".element").subscribe2({
options: {
method: "google",
formkey: "2eiFxDZOpcyjPo9ub7nIwp6vAKUkLIiOxXIPT1TtAAAA",
datakey: "entry.57553044"
},
});
});
.subscribe2-wrp {
width: 100%;
max-width: 450px;
border: 1px solid #ccc;
}
.subscribe2-input-view {
padding: 10px 30px;
}
.subscribe2-input-wrp {
width: 70%;
float: left;
margin-right: 5%;
position: relative;
}
.subscribe2-btn {
width: 25%;
float: left;
}
.subscribe2-control-input {
width: 100%;
}
.subscribe2-validation-status {
display: block;
position: absolute;
right: 0;
top: 2px;
border-radius: 50%;
width: 10px;
height: 10px;
text-align: center;
padding: 2px;
font-size: 12px;
line-height: 12px;
vertical-align: middle;
color: #fff;
}
.subscribe2-valid {
background: #49BF49;
border: 1px solid #6DBD6D;
}
.subscribe2-invalid {
background: #c0392b;
border: 1px solid #B13326;
line-height: 9px;
font-family: 'Century Gothic', CenturyGothic, AppleGothic, sans-serif;
}
.subscribe2-success {
padding: 10%;
}
#media only screen and (max-width: 480px) {
.subscribe2-input-wrp {
width: 100%;
}
.subscribe2-btn {
width: 90%;
margin: 10px auto;
}
}
#footer {
position: fixed;
bottom: 0;
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="subscribe2/src/jquery.subscribe2.css">
<div class="element"></div>
<div class="element" id="footer"></div>
I am new to jointJs library and I am trying to add ports to my custom element that contains html code in it. I followed this tutorial (http://www.jointjs.com/tutorial/html-elements) and created my element. But when I try to add ports to it (based on this tutorial: http://www.jointjs.com/tutorial/ports) it does not work.
Another problem I have is that I want the textbox(textarea on my custom shape) to disappear when I click on the blank paper, and just the label with its content stays visible on the element. For that I used the following piece of code (but it does not give me the above-mentioned functionality):
paper.on('blank:pointerdown', function(evt, x, y) { this.$box.find('textarea').toBack(); });
this.model.on('cell:pointerclick', function(evt, x, y) {this.$box.find('textarea').toFront();});
My whole code is as below:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="graph.css">
<script type="text/javascript" src="http://www.jointjs.com/downloads/joint.js" ></script>
<script src="http://www.jointjs.com/downloads/joint.shapes.devs.js" ></script>
<script src="http://www.jointjs.com/downloads/joint.shapes.devs.min.js" ></script>
</head>
<title>Test</title>
<body>
<div id="myholder"></div>
</body>
<script>
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: $('#myholder'),
width: 1500,
height: 700,
model: graph
});
// Create a custom element.
// ------------------------
joint.shapes.html = {};
joint.shapes.html.Element = joint.shapes.basic.Rect.extend({
defaults: joint.util.deepSupplement({
type: 'html.Element',
attrs: {
rect: { stroke: 'none', 'fill-opacity': 0 }
}
}, joint.shapes.basic.Rect.prototype.defaults)
});
// Create a custom view for that element that displays an HTML div above it.
// -------------------------------------------------------------------------
joint.shapes.html.ElementView = joint.dia.ElementView.extend({
template: [
'<div class="html-element">',
'<button class="delete">x</button>',
'<span id="lbl" value="Please write here"></span>',
'<textarea id="txt" type="text" value="Please write here"></textarea>',
'</div>'
].join(''),
initialize: function() {
_.bindAll(this, 'updateBox');
joint.dia.ElementView.prototype.initialize.apply(this, arguments);
this.$box = $(_.template(this.template)());
// Prevent paper from handling pointerdown.
this.$box.find('input,select').on('mousedown click', function(evt) { evt.stopPropagation(); });
// This is an example of reacting on the input change and storing the input data in the cell model.
this.$box.find('textarea').on('change', _.bind(function(evt) {
this.model.set('textarea', $(evt.target).val());
}, this));
this.$box.find('.delete').on('click', _.bind(this.model.remove, this.model));
// Update the box position whenever the underlying model changes.
this.model.on('change', this.updateBox, this);
// Remove the box when the model gets removed from the graph.
this.model.on('remove', this.removeBox, this);
this.updateBox();
},
render: function() {
joint.dia.ElementView.prototype.render.apply(this, arguments);
this.paper.$el.prepend(this.$box);
this.updateBox();
return this;
},
updateBox: function() {
// Set the position and dimension of the box so that it covers the JointJS element.
var bbox = this.model.getBBox();
// Example of updating the HTML with a data stored in the cell model.
paper.on('blank:pointerdown', function(evt, x, y) { this.$box.find('textarea').toBack(); });
this.$box.find('span').text(this.model.get('textarea'));
this.model.on('cell:pointerclick', function(evt, x, y) { this.$box.find('textarea').toFront(); });
this.$box.css({ width: bbox.width, height: bbox.height, left: bbox.x, top: bbox.y, transform: 'rotate(' + (this.model.get('angle') || 0) + 'deg)' });
},
removeBox: function(evt) {
this.$box.remove();
}
});
// Create JointJS elements and add them to the graph as usual.
// -----------------------------------------------------------
var el1 = new joint.shapes.html.Element({
position: { x: 600, y: 250 },
size: { width: 200, height: 100 },
inPorts: ['in'],
outPorts: ['out'],
attrs: {
'.inPorts circle': { fill: 'gray'},
'.outPorts circle': { fill: 'gray'}
},
textarea: 'Start writing'});
graph.addCells([el1]);
paper.on('cell:pointerdblclick', function(cellView, evt, x, y) {
var el2 = new joint.shapes.html.Element({ position: { x: 600, y: 400 }, size: { width: 200, height: 100 }, textarea: 'Start writing'});
var l = new joint.dia.Link({
source: { id: el1.id },
target: { id: el2.id },
attrs: { '.connection': { 'stroke-width': 1, stroke: 'gray' } }
});
graph.addCells([el2, l]);
});
</script>
</html>
I have searched a lot for answers to these problems but I was not successful finding simple and comprehensive ones.
Any help will be appreciated.
Thanks.
I am also new to jointJs and stuck with same problem and found this thread. I have tried and worked successfully.
You have to customize css of element to get better view. Go to working with ports for more work with ports.
Here's the code:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="http://www.jointjs.com/downloads/joint.min.css">
<style type="text/css">
#myholder .html-element{
position: absolute;
margin-left: 8px;
padding: 5px 0 10px 0;
background-color: #fff;
border: 1px solid #eee;
border-radius: 5px;
pointer-events: none;
-webkit-user-select: none;
}
</style>
<script type="text/javascript" src="http://www.jointjs.com/downloads/joint.min.js" ></script>
</head>
<title>Test</title>
<body>
<div id="myholder"></div>
</body>
<script>
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: $('#myholder'),
width: 1500,
height: 700,
model: graph
});
// Create a custom element.
// ------------------------
joint.shapes.html = {};
joint.shapes.html.Element = joint.shapes.basic.Generic.extend(_.extend({}, joint.shapes.basic.PortsModelInterface, {
markup: '<g class="rotatable"><g class="scalable"><rect/></g><g class="inPorts"/><g class="outPorts"/></g>',
portMarkup: '<g class="port<%= id %>"><circle/></g>',
defaults: joint.util.deepSupplement({
type: 'html.Element',
size: { width: 100, height: 80 },
inPorts: [],
outPorts: [],
attrs: {
'.': { magnet: false },
rect: {
stroke: 'none', 'fill-opacity': 0, width: 150, height: 250,
},
circle: {
r: 6, //circle radius
magnet: true,
stroke: 'black'
},
'.inPorts circle': { fill: 'green', magnet: 'passive', type: 'input'},
'.outPorts circle': { fill: 'red', type: 'output'}
}
}, joint.shapes.basic.Generic.prototype.defaults),
getPortAttrs: function (portName, index, total, selector, type) {
var attrs = {};
var portClass = 'port' + index;
var portSelector = selector + '>.' + portClass;
var portCircleSelector = portSelector + '>circle';
attrs[portCircleSelector] = { port: { id: portName || _.uniqueId(type), type: type } };
attrs[portSelector] = { ref: 'rect', 'ref-y': (index + 0.5) * (1 / total) };
if (selector === '.outPorts') { attrs[portSelector]['ref-dx'] = 0; }
return attrs;
}
}));
// Create a custom view for that element that displays an HTML div above it.
// -------------------------------------------------------------------------
joint.shapes.html.ElementView = joint.dia.ElementView.extend({
template: [
'<div class="html-element">',
'<button class="delete">x</button>',
'<span id="lbl" value="Please write here"></span>',
'<textarea id="txt" type="text" value="Please write here"></textarea>',
'</div>'
].join(''),
initialize: function() {
_.bindAll(this, 'updateBox');
joint.dia.ElementView.prototype.initialize.apply(this, arguments);
this.$box = $(_.template(this.template)());
// Prevent paper from handling pointerdown.
this.$box.find('input,select').on('mousedown click', function(evt) { evt.stopPropagation(); });
// This is an example of reacting on the input change and storing the input data in the cell model.
this.$box.find('textarea').on('change', _.bind(function(evt) {
this.model.set('textarea', $(evt.target).val());
}, this));
this.$box.find('.delete').on('click', _.bind(this.model.remove, this.model));
// Update the box position whenever the underlying model changes.
this.model.on('change', this.updateBox, this);
// Remove the box when the model gets removed from the graph.
this.model.on('remove', this.removeBox, this);
this.updateBox();
this.listenTo(this.model, 'process:ports', this.update);
joint.dia.ElementView.prototype.initialize.apply(this, arguments);
},
render: function() {
joint.dia.ElementView.prototype.render.apply(this, arguments);
this.paper.$el.prepend(this.$box);
// this.paper.$el.mousemove(this.onMouseMove.bind(this)), this.paper.$el.mouseup(this.onMouseUp.bind(this));
this.updateBox();
return this;
},
renderPorts: function () {
var $inPorts = this.$('.inPorts').empty();
var $outPorts = this.$('.outPorts').empty();
var portTemplate = _.template(this.model.portMarkup);
_.each(_.filter(this.model.ports, function (p) { return p.type === 'in' }), function (port, index) {
$inPorts.append(V(portTemplate({ id: index, port: port })).node);
});
_.each(_.filter(this.model.ports, function (p) { return p.type === 'out' }), function (port, index) {
$outPorts.append(V(portTemplate({ id: index, port: port })).node);
});
},
update: function () {
// First render ports so that `attrs` can be applied to those newly created DOM elements
// in `ElementView.prototype.update()`.
this.renderPorts();
joint.dia.ElementView.prototype.update.apply(this, arguments);
},
updateBox: function() {
// Set the position and dimension of the box so that it covers the JointJS element.
var bbox = this.model.getBBox();
// Example of updating the HTML with a data stored in the cell model.
// paper.on('blank:pointerdown', function(evt, x, y) { this.$box.find('textarea').toBack(); });
this.$box.find('span').text(this.model.get('textarea'));
this.model.on('cell:pointerclick', function(evt, x, y) { this.$box.find('textarea').toFront(); });
this.$box.css({ width: bbox.width, height: bbox.height, left: bbox.x, top: bbox.y, transform: 'rotate(' + (this.model.get('angle') || 0) + 'deg)' });
},
removeBox: function(evt) {
this.$box.remove();
}
});
// Create JointJS elements and add them to the graph as usual.
// -----------------------------------------------------------
var el1 = new joint.shapes.html.Element({
position: { x: 600, y: 250 },
size: { width: 170, height: 100 },
inPorts: ['in'],
outPorts: ['out'],
textarea: 'Start writing'
});
var el2 = new joint.shapes.html.Element({
position: { x: 600, y: 400 },
size: { width: 170, height: 100 },
inPorts: ['in'],
outPorts: ['out'],
textarea: 'Start writing'
});
graph.addCells([el1, el2]);
</script>
</html>
I have asked a question that no one has answered it. It was how I can make the textarea disappear when I click on the blank paper and appear when I click on the cell: First I thought I have to solve it through the jsonJS events inside the javascript. But I found out that there is a very simple solution for this. I just need to use the hover function in css styling and change the opacity from 0 to 1 when you hover over the box (in your css file) :
.html-element textarea {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 60px;
width: 150px;
border: none;
color: #333;
background-color: white;
padding: 5px;
margin: 5px;
opacity:0;
}
.html-element textarea:hover {
opacity:1;
}
rzkmr's answer worked for me, +1'd his response. (Thank you!)
In his example, to allow the textarea to be used, add this to the css:
.html-element select,
.html-element input,
.html-element textarea,
.html-element button {
/* Enable mouse interaction. */
pointer-events: auto;
}
I've been working on embedding a youtube playlist with Javascript and I can't change the theme to light. All the other parameters work but this one doesn't come through.
This is how think it should work:
var defoptions = {
autoplay: false,
user: null,
playlist: null,
carousel: createCarousel,
player: createPlayer,
thumbnail: createThumbnail,
max_results: 25, // does not apply to playlists
loaded: function () {},
playopts: {
autoplay: 0,
egm: 1,
autohide: 1,
fs: 1,
showinfo: 0,
rel: 0,
theme: light
}
};
Any thoughts?
Thanks!
Here you have the whole thing, it's far from finished but first I need to find out how to change the theme.
<style>
#container{
background-color: #F1F1F1;
padding: 20px;
}
.yt-descript{
max-width: 100px;
font-family: verdana;
font-weight: bold;
font-size: 9pt;
margin: 2px;
}
.player {
width: 100%;
height: 305px;
overflow: hidden;
background-color: #F1F1F1 ;
position: relative;
}
.youtube .carousel {
width: 20%;
height: 100%;
overflow-y: auto;
overflow-x: hidden;
position: absolute;
right: 0px;
z-index: 3;
}
.youtube .thumbnail {
margin-left: 2px;
width: 90%;
border: 1px solid black;
}
.youtube iframe.player {
width: 80%;
height: 100%;
overflow: auto;
border: 0;
}
</style>
<script>
(function () {
function createPlayer(jqe, video, options) {
var ifr = $('iframe', jqe);
if (ifr.length === 0) {
ifr = $('<iframe scrolling="no">');
ifr.addClass('player');
}
var src = 'http://www.youtube.com/embed/' + video.id;
if (options.playopts) {
src += '?';
for (var k in options.playopts) {
src += k + '=' + options.playopts[k] + '&';
}
src += '_a=b';
}
ifr.attr('src', src);
jqe.append(ifr);
}
function createCarousel(jqe, videos, options) {
var car = $('div.carousel', jqe);
if (car.length === 0) {
car = $('<div>');
car.addClass('carousel');
jqe.append(car);
}
$.each(videos, function (i, video) {
options.thumbnail(car, video, options);
});
}
function createThumbnail(jqe, video, options) {
var imgurl = video.thumbnails[0].url;
var img = $('img[src="' + imgurl + '"]');
var desc;
var container;
if (img.length !== 0) return;
img = $('<img align="left">');
img.addClass('thumbnail');
jqe.append(img);
img.attr('src', imgurl);
img.attr('title', video.title);
img.click(function () {
options.player(options.maindiv, video, $.extend(true, {}, options, {
playopts: {
autoplay: 1
}
}));
});
desk = $('<p class="yt-descript">' + video.title + '</p>');
jqe.append(desk);
desk.click(function () {
options.player(options.maindiv, video, $.extend(true, {}, options, {
playopts: {
autoplay: 1
}
}));
});
}
var defoptions = {
autoplay: false,
user: null,
playlist: null,
carousel: createCarousel,
player: createPlayer,
thumbnail: createThumbnail,
max_results: 25, // does not apply to playlists
loaded: function () {},
playopts: {
autoplay: 0,
egm: 1,
autohide: 1,
fs: 1,
showinfo: 0,
rel: 0
}
};
$.fn.extend({
youTubeChannel: function (options) {
var md = $(this);
md.addClass('youtube');
md.addClass('youtube-channel');
var allopts = $.extend(true, {}, defoptions, options);
allopts.maindiv = md;
var JSONurl = "";
if (allopts.playlist) {
JSONurl = 'http://gdata.youtube.com/feeds/api/playlists/' + allopts.playlist + '?alt=json-in-script&format=5&callback=?';
} else if (allopts.user) {
JSONurl = 'http://gdata.youtube.com/feeds/users/' + allopts.user + '/uploads?alt=json-in-script&max-results=' + allopts.max_results.toString() + '&format=5&callback=?';
} else {
console.log('user or playlist must be specified');
}
$.getJSON(JSONurl, null, function (data) {
var feed = data.feed;
var videos = [];
$.each(feed.entry, function (i, entry) {
var video = {
title: entry.title.$t,
id: entry.link[3].href.match('[^/]*$'),
thumbnails: entry.media$group.media$thumbnail
};
videos.push(video);
});
allopts.allvideos = videos;
allopts.carousel(md, videos, allopts);
allopts.player(md, videos[0], allopts);
allopts.loaded(videos, allopts);
});
}
});
})();
// Playlist
$(function () {
$('#player1').youTubeChannel({
playlist: 'PLFE3E2A9A3BDD70BE'
});
});
// Channel
$(function () {
$('#player3').youTubeChannel({
user: 'YTusername',
max_results: 50
});
});
</script>
<div id="container">
<h1>Latest Videos</h1>
<div id="player1" class="player"></div>
</div>
Theme needs to value string values, so try this:
var defoptions = {
autoplay: false,
user: null,
playlist: null,
carousel: createCarousel,
player: createPlayer,
thumbnail: createThumbnail,
max_results: 25, // does not apply to playlists
loaded: function () {},
playopts: {
autoplay: 0,
egm: 1,
autohide: 1,
fs: 1,
showinfo: 0,
rel: 0,
theme: "light",
color: "white"
}
};