RGraph + gridstack resize to div - javascript

I am developing an application with gridstack and I want to put several graphics (lines and gauge) in different containers using the RGraph library.
I can not make the graph fill the width and height of the container.
Also when I change the size I want the graphic to adapt to the container.
I have an example:
Code JSFiddle
$(document).ready(function ()
{
var data = [[4,5,8,11,15], [1,3,2,5,9]];
var tips = ['a','b','c','d','e','yf','yh','tt','hh','ll'];
var line = new RGraph.Line('cvs', data)
.set('tooltips', tips)
.set('gutter.left', 50)
.draw();
});
#canvas{
width: 100% !important;
max-width: 100% !important;
height: 70% !important;
align-content:center;
vertical-align:middle;
/*position:static;*/
}
#cvs {
width: 100%;
height: 100%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Serialization demo</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="./gridstack.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.0/jquery-ui.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/gridstack.js/0.3.0/gridstack.min.css" />
<script type="text/javascript" src='https://cdnjs.cloudflare.com/ajax/libs/gridstack.js/0.3.0/gridstack.min.js'></script>
<script type="text/javascript" src='https://cdnjs.cloudflare.com/ajax/libs/gridstack.js/0.3.0/gridstack.jQueryUI.min.js'></script>
<script src="http://www.rgraph.net/libraries/RGraph.common.core.js"></script>
<script src="http://www.rgraph.net/libraries/RGraph.common.dynamic.js"></script>
<script src="http://www.rgraph.net/libraries/RGraph.common.tooltips.js"></script
src="http://www.rgraph.net/libraries/RGraph.common.resizing.js"></script>
<script src="http://www.rgraph.net/libraries/RGraph.line.js"></script>
<style type="text/css">
.grid-stack {
background: lightgoldenrodyellow;
}
.grid-stack-item-content {
color: #2c3e50;
text-align: center;
background-color: #18bc9c;
}
</style>
</head>
<body>
<div class="container-fluid">
<div>
<a class="btn btn-default" id="save-grid" href="#">Save Grid</a>
<a class="btn btn-default" id="load-grid" href="#">Load Grid</a>
<a class="btn btn-default" id="clear-grid" href="#">Clear Grid</a>
</div>
<br/>
<div class="grid-stack" id="grid-stack">
<div class="chart-container" id="tile1" >
<div class="grid-stack-item-content">
<span class="pull-left">Tile 1</span>
<div class="pull-left" style="clear:both">Content</div>
</div>
</div>
<div class="chart-container" id="tile2">
<div class="grid-stack-item-content">
<span class="pull-left">Tile 2</span>
<div class="pull-left" style="clear:both">
<canvas id="cvs" width="600" height="250" style="width: 100%; float: left">[No canvas support]
</canvas>
</div>
</div>
</div>
</div>
<hr/>
<textarea id="saved-data" cols="100" rows="20" readonly="readonly"></textarea>
</div>
<script type="text/javascript">
$(function () {
var options = {
};
$('.grid-stack').gridstack(options);
new function () {
this.serializedData = [
{id: "tile1", x: 0, y: 0, w: 4, h:2},
{id: "tile2", x: 4, y: 0, w: 5, h: 4},
];
this.grid = $('.grid-stack').data('gridstack');
this.loadGrid = function () {
this.grid.removeAll();
var items = GridStackUI.Utils.sort(this.serializedData);
items.forEach(node=>{
var containerElt = $("#" + node.id);
containerElt.attr("data-gs-id", node.id);
containerElt.attr("data-gs-width", node.w);
containerElt.attr("data-gs-height", node.h);
containerElt.attr("data-gs-x", node.x);
containerElt.attr("data-gs-y", node.y);
this.grid.makeWidget(containerElt)
});
return false;
}.bind(this);
this.saveGrid = function () {
this.serializedData = _.map($('.grid-stack > .grid-stack-item:visible'), (el)=> {
el = $(el);
var node = el.data('_gridstack_node');
return {
id: node.id,
x: node.x,
y: node.y,
width: node.width,
height: node.height
};
}, this);
$('#saved-data').val(JSON.stringify(this.serializedData, null, ' '));
return false;
}.bind(this);
this.getSerializedData = function () {
var result = _.map($('.grid-stack > .grid-stack-item:visible'), (el)=> {
el = $(el);
var node = el.data('_gridstack_node');
return {
id: node.id,
x: node.x,
y: node.y,
w: node.width,
h: node.height
};
}, this);
return result;
}.bind(this);
this.clearGrid = function () {
this.grid.removeAll();
return false;
}.bind(this);
$('#save-grid').click(this.saveGrid);
$('#load-grid').click(this.loadGrid);
$('#clear-grid').click(this.clearGrid);
$('#grid-stack').on('change', (event, items) => {
var result = this.getSerializedData();
var json = JSON.stringify(result, null, ' ');
$('#saved-data').val(json);
});
this.loadGrid();
};
});
</script>
</body>
</html>

You need to create a function to reset and redraw your line, then have that trigger when the window resizes and when the widget is updated (on the change event in gridstack). Make sure not to use extra styles, as they'll actually hinder your result. I've updated your example to work on window resize. It will not update when you resize the widget, but if you resize the window, you'll see the chart continues to fill up the full widget.
http://jsfiddle.net/kqada7zj/46/

Related

Javascript Resize two images by input type range (duplticate) / half completed

As you can see from the snippet below i have this two images.. by dragging the <input type="range"> i want the right one to get bigger and the left one to get smaller, and the opposite.. This is what i have done so far on my own.. it works only for the right one and i can't think a way to do it for the left one in the same time.. For example when the left image will be width = 100% the right must be 40%
Any suggestions ? Thank you
let left = document.getElementById('left');
let right = document.getElementById('right');
let slider = document.getElementById('range-slider');
slider.oninput = function(){
document.getElementById("leftDemo").innerHTML = this.value + "%";
left.style.width = this.value + "%";
//document.getElementById("rightDemo").innerHTML = this.value + "%";
//right.style.width = this.value + "%";
}
* {
box-sizing: border-box;
}
.img-container {
float: left;
width: 40%;
padding: 5px;
}
.clearfix::after {
content: "";
clear: both;
display: table;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
<link rel='stylesheet' type='text/css' media='screen' href='style.css'>
</head>
<body>
<div class="clearfix pt-5">
<div class="img-container">
<img src="https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg" alt="Italy" style="width:40%;" id="left">
<h3 id="leftDemo"></h3>
</div>
<div class="img-container">
<img src="https://thumbs.dreamstime.com/b/environment-earth-day-hands-trees-growing-seedlings-bokeh-green-background-female-hand-holding-tree-nature-field-gra-130247647.jpg" alt="Mountains" style="width:100%;" id="right">
<h3 id="rightDemo"></h3>
</div>
</div>
<div class="container text-center">
<input id="range-slider" type="range" min="40" max="100" >
</div>
<script src="main.js"></script>
</body>
</html>
This works for me.
One is at 100% and the other at 40%.
let left = document.getElementById('left');
let right = document.getElementById('right');
let slider = document.getElementById('range-slider');
slider.oninput = function(){
document.getElementById("leftDemo").innerHTML = this.value + "%";
left.style.width = this.value + "%";
let newVal = (40 + (100 - parseInt(this.value))).toString();
document.getElementById("rightDemo").innerHTML = newVal + "%";
right.style.width = newVal + "%";
}
* {
box-sizing: border-box;
}
.img-container {
float: left;
width: 40%;
padding: 5px;
}
.clearfix::after {
content: "";
clear: both;
display: table;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
<link rel='stylesheet' type='text/css' media='screen' href='style.css'>
</head>
<body>
<div class="clearfix pt-5">
<div class="img-container">
<img src="https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg" alt="Italy" style="width:40%;" id="left">
<h3 id="leftDemo"></h3>
</div>
<div class="img-container">
<img src="https://thumbs.dreamstime.com/b/environment-earth-day-hands-trees-growing-seedlings-bokeh-green-background-female-hand-holding-tree-nature-field-gra-130247647.jpg" alt="Mountains" style="width:100%;" id="right">
<h3 id="rightDemo"></h3>
</div>
</div>
<div class="container text-center">
<input id="range-slider" type="range" min="40" max="100" >
</div>
<script src="main.js"></script>
</body>
</html>
You will need to subtract the value from the max (100) and add the min (40) to the opposite image's new width.
const
left = document.getElementById('left'),
right = document.getElementById('right'),
slider = document.getElementById('range-slider');
const calSizes = (slider) => {
const
value = parseInt(slider.value, 10),
min = parseInt(slider.getAttribute('min'), 10),
max = parseInt(slider.getAttribute('max'), 10);
return [ value, min + max - value ];
};
const resizeImages = (e) => {
const [ value, inverted ] = calSizes(e.target);
left.querySelector('img').style.width = `${value}%`;
right.querySelector('img').style.width = `${inverted}%`;
left.querySelector('h3.scale').textContent = `${value}%`;
right.querySelector('h3.scale').textContent = `${inverted}%`;
};
slider.addEventListener('input', resizeImages);
resizeImages({ target: slider });
.images {
display: flex;
flex-direction: row;
}
.img-container {
flex: 1;
}
.container {
border: thin solid grey;
}
.text-center {
text-align: center;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
<div class="images">
<div class="img-container" id="left">
<img src="https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg" alt="Italy" />
<h3 class="scale"></h3>
</div>
<div class="img-container" id="right">
<img src="https://thumbs.dreamstime.com/b/environment-earth-day-hands-trees-growing-seedlings-bokeh-green-background-female-hand-holding-tree-nature-field-gra-130247647.jpg" alt="Mountains" />
<h3 class="scale"></h3>
</div>
</div>
<div class="container text-center">
<input id="range-slider" type="range" min="40" max="100" value="50">
</div>

Change border height on button click in Javascript

I want the border to increase, every time I press a button.
When the button is pressed, its 'value' is increased by 1. I want the value of the pixel-height of the border of the container to increase as well.
var i = 0;
var heightOfBorder = document.getElementById('test').style;
function buttonClick() {
document.getElementById('incrementValue').value = i++
heightOfBorder = "height: 500px";;
}
// document.getElementById("test").style.height = document.getElementById('incrementValue').value;
#test {
margin-top: 200px;
border: solid black;
width: 200px;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Container size change</title>
<link rel="stylesheet" href="style.css">
<script src="https://code.jquery.com/jquery-3.5.0.js" integrity="sha256-r/AaFHrszJtwpe+tHyNi/XCfMxYpbsRg2Uqn0x3s2zc=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
</head>
<body>
<div id="main" class="container">
<div id="test" class="container" style="height: 50px;">
</div>
<button onclick="buttonClick()" id="incrementButton" type="button" class="btn btn-success">Success</button>
<input id="incrementValue" type="text" name="button" value="0">
</div>
<script src="script.js" charset="utf-8"></script>
</body>
</html>
What am I doing wrong? I am learning to code. Also, side question, does anyone know of a good mentorship program?
Greetings!
You can get current height of the box using offsetHeight and on click add the input value to the box's style.height and remember to add the unit at the end - in your case 'px'.
Here is an example:
var i = 0;
var myEl = document.querySelector('#test');
var initialHeight = myEl.offsetHeight;
function buttonClick() {
document.getElementById('incrementValue').value = i++;
myEl.style.height = initialHeight + i + 'px';
}
<script>
var i = 0;
var heightOfBorder = document.getElementById('test').style;
function buttonClick() {
document.getElementById('incrementValue').value = i++;
let currHgt = heightOfBorder.getPropertyValue('height');
currHgt = +currHgt.slice(0, currHgt.length - 2);
heightOfBorder.setProperty('height', currHgt + i + 'px');
}
</script>
If you want to change height by i value.
just change var
heightOfBorder = document.getElementById('test').style;
to
var heightOfBorder = document.getElementById('test');
and
eightOfBorder = "height: 500px";
to
eightOfBorder.style = "height: 500px";
var i = 0;
var heightOfBorder = document.getElementById('test');
function buttonClick() {
document.getElementById('incrementValue').value = i++
heightOfBorder.style = "height: 500px";
}
// document.getElementById("test").style.height = document.getElementById('incrementValue').value;
#test {
margin-top: 200px;
border: solid black;
width: 200px;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Container size change</title>
<link rel="stylesheet" href="style.css">
<script src="https://code.jquery.com/jquery-3.5.0.js" integrity="sha256-r/AaFHrszJtwpe+tHyNi/XCfMxYpbsRg2Uqn0x3s2zc=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
</head>
<body>
<div id="main" class="container">
<div id="test" class="container" style="height: 50px;">
</div>
<button onclick="buttonClick()" id="incrementButton" type="button" class="btn btn-success">Success</button>
<input id="incrementValue" type="text" name="button" value="0">
</div>
<script src="script.js" charset="utf-8"></script>
</body>
</html>

angular-ui-layout - resize doesn't work properly with an iframe

As you can see in the example, resizing doesn't work properly when using an iframe. You can move the splitter to the left, but not to the right. Does anybody know why this is and how it could be fixed?
<!DOCTYPE html>
<html ng-app="x">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width">
<title>UI.Layout : demo </title>
<link rel="stylesheet" type="text/css" href="https://rawgithub.com/angular-ui/ui-layout/master/src/ui-layout.css"/>
<style>
.html-back {
background: #eee;
}
</style>
</head>
<body>
<div ui-layout options="{ flow : 'column', disableToggle: true }">
<div ui-layout-container size="50%" class="html-back">
AA
</div>
<div ui-layout-container size="50%" class="html-back">
<iframe style="width: 100%; height: 100%;" src=""></iframe>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.9/angular.min.js"></script>
<script src="https://rawgithub.com/angular-ui/ui-layout/master/src/ui-layout.js"></script>
<script>
var app = angular.module("x", ["ui.layout"]);
</script>
</body>
</html>
The problem seems to be that the iframe steals the focus. I managed to prevent this by adding an overlay div while moving the split bar.
<!DOCTYPE html>
<html ng-app="x">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width">
<title>UI.Layout : demo </title>
<link rel="stylesheet" type="text/css" href="https://rawgithub.com/angular-ui/ui-layout/master/src/ui-layout.css"/>
<style>
.html-back {
background: #eee;
}
</style>
</head>
<body>
<div ng-controller="AppController">
<div ui-layout ui-layout-loaded options="{ flow : 'column', disableToggle: true }" id="splitViewContainer">
<div ui-layout-container size="50%" class="html-back">
AA
</div>
<div ui-layout-container class="html-back">
<iframe style="width: 100%; height: 100%;" src=""></iframe>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.9/angular.min.js"></script>
<script src="https://rawgithub.com/angular-ui/ui-layout/master/src/ui-layout.js"></script>
<script>
class AppController {
constructor($document, $element, $scope) {
this.$document = $document;
this.$element = $element;
this.$scope = $scope;
this.mouseDown = this.mouseDown.bind(this);
this.mouseUp = this.mouseUp.bind(this);
this.$scope.$on("ui.layout.loaded", () => {
this.splitter = this.$element.find(".ui-splitbar");
this.splitter.on("mousedown", this.mouseDown);
});
this.overlay = angular.element("<div></div>");
this.overlay.css({
width: "100%",
height: "100%",
"z-index": 1,
position: "absolute",
top: 0,
left: 0
});
}
mouseDown() {
if (!this.splitViewContainer) {
this.splitViewContainer = this.$element.find("#splitViewContainer");
}
this.splitViewContainer.append(this.overlay);
this.$document.one("mouseup", this.mouseUp);
}
mouseUp() {
this.overlay.remove();
}
}
const app = angular.module("x", ["ui.layout"]);
app.controller("AppController", AppController);
</script>
</body>
</html>

Duplicating Entries On Subsequent Months

Weird one. Have two school building calendars being fed by public Google Cal. Can click month-to-month without error, but when I hide one building cal and click to the next month, I end up with duplicate entries that continue to double then triple and continue duping as you click month to month. Here is the code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8' />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/fullcalendar.css" rel="stylesheet" />
<link href="css/fullcalendar.print.css" rel="stylesheet" media="print" />
<link type="image/x-icon" href="http://www.woostercityschools.org/sites/woostercityschools.org/files/favicon_wcs.png" rel="shortcut icon">
<link type="image/x-icon" href="http://www.woostercityschools.org/sites/woostercityschools.org/files/favicon_wcs.png" rel="icon">
<script src="js/moment.min.js"></script>
<script src="js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/fullcalendar.min.js"></script>
<script src="js/gcal.js"></script>
<script>
var allCals = [
{
id: 1,
name: 'High School',
url: 'https://www.google.com/calendar/feeds/CALENDAR_ID_HERE#group.calendar.google.com/public/basic',
color: '#0057b8',
visible: true
},{
id: 2,
name: 'Middle School',
url: 'https://www.google.com/calendar/feeds/CALENDAR_ID_HERE#group.calendar.google.com/public/basic',
color: '#4b4c4c',
visible: true
}
];
var gCals = function(){
var ret = $.grep(allCals, function(a){
return a.visible === true;
});
console.log('called gCals()');
console.log(ret);
return ret;
}
$(document).ready(function() {
//Hide/Show all
$('#hide-all').click(function(){
$('.calendar-list button').each(function(){
$(this).removeClass('btn-calendar-hide');
});
$.each(allCals, function(index,value){
//$('#calendar').fullCalendar('removeEventSource', this);
this.visible = false;
});
$('#calendar').fullCalendar('removeEvents');
});
$('#show-all').click(function(){
$('.calendar-list button').each(function(){
$(this).addClass('btn-calendar-hide');
});
$('#calendar').fullCalendar('removeEvents');
$.each(allCals, function(index,value){
$('#calendar').fullCalendar('addEventSource', allCals[index]);
this.visible = true;
});
});
//Populate buttons
$.each( allCals, function( index, value ){
var tmp = $('<button/>', {
type: 'button',
class: 'btn btn-block btn-calendar',
style: 'background-color: '+value.color,
text: value.name,
id: 'btn_calendar'+value.id,
click: function () {
if ($(this).hasClass('btn-calendar-hide')){
//$('#calendar').fullCalendar('removeEventSource', value);
$( this ).removeClass('btn-calendar-hide');
value.visible = false;
} else {
//$('#calendar').fullCalendar('addEventSource', value);
$( this ).addClass('btn-calendar-hide');
value.visible = true;
}
updateCalendar();
}
});
if (value.visible === true){
tmp.addClass('btn-calendar-hide');
}
$('.calendar-list').append(
tmp
);
});
//Display the calendar
$('#calendar').fullCalendar({
googleCalendarApiKey: 'AIzaSyDiJjIhfkuYrKzwrj0GS3wBN1erVcMsJmM',
eventSources: allCals,
eventClick: function(event) {
// opens events in a popup window
window.open(event.url, 'gcalevent', 'width=700,height=600');
return false;
},
loading: function(bool) {
$('#loading').toggle(bool);
},
header: {
left: 'month,basicWeek,basicDay',
center: 'title',
right: 'today prev,next'
}
});
function updateCalendar(){
$('#calendar').fullCalendar('removeEvents');
$.each(allCals, function(index,value){
if (value.visible === true){
$('#calendar').fullCalendar('addEventSource', allCals[index]);
}
});
}
});
</script>
<style>
a.fc-event:hover, a.fc-event:focus{
color:#000;
}
#loading {
display: none;
position:absolute;
width:96%;
padding:10px;
z-index:999;
border: solid 1px #f8e166;
margin:1% 2%;
}
#loading h3 {
margin:2%;
}
#calendar {
margin: 20px auto;
}
.btn {
border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);
}
.btn-calendar {
background-image: none;
color: #FFFFFF;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.8);
opacity: 0.5;
}
.btn-calendar-hide {
opacity: 1;
}
.btn:hover, .btn:focus {
color: #FFFFFF;
text-decoration: none;
}
#media print {
a[href]:after {
content: none;
}
}
</style>
</head>
<body>
<div id="loading" class="bg-warning">
<h3 class="text-center">Loading...</h3>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-md-2 hidden-print"> <img class="img-responsive center-block" style="margin-top:2em; margin-bottom:2em" src="logo-district.jpg" alt="Wooster City Schools" >
<div class="calendar-list">
<h4>Calendars
<div class="btn-group">
<button id="show-all" type="button" class="btn btn-xs">Show All</button>
<button id="hide-all" type="button" class="btn btn-xs">Hide All</button>
</div>
</h4>
</div>
</div>
<div class="col-md-10">
<p class="text-right hidden-print" style="margin-top:2%"><i class="glyphicon glyphicon-print"></i> Print</p>
<div id="calendar"></div>
</div>
</div>
</div>
</body>
</html>
The problem you've got is that calling $('#calendar').fullCalendar('removeEvents'); deletes the events currently visible on the calendar, but it doesn't remove the source of those events.
That means that when you then go on to call $('#calendar').fullCalendar('addEventSource' next, you are simply adding the same source of events over and over again. Next time you press "next" or "previous" to change the date range, this triggers fullCalendar to request new events for that date range from all the available sources. Since you haven't removed any sources, but have kept adding more, you can see how this then leads to duplication of events in the display.
In one part of your code you've commented out a call to $('#calendar').fullCalendar('removeEventSource' ...but actually that (or the plural "removeEventSources", where appropriate) should be the correct approach. If you remove the source then it will both remove the existing events and also prevent future requests to that source from adding more events again.

Get name of dynamically created div in javascript?

I cannot seem to make my javascript .click() method work with my dynamically created divs. In this code I have divs created each under the class name "class1" but my click method does not seem to detect their existence. Here is my code:
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" media="screen" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
function populate() {
var select = document.getElementById("centres");
for (var i = 1; i <= 10; i++) {
var option = document.createElement("option");
option.value = i;
option.text = i;
select.appendChild(option);
}
}
function divGenerator() {
var div;
for (var i = 1; i <= document.getElementById("centres").selectedIndex + 1; i++) {
div = document.createElement("div");
div.className = "class1";
div.innerHTML = "Space " + i;
div.style.width = "100px";
div.style.height = "100px";
div.style.float = "left";
document.getElementById("container2").appendChild(div);
}
}
function glassLoad() {
path_to_root_dir = "../../Content/";
var myBox = new GlassBox();
myBox.init('myBox', '128px', '62px', 'hidden');
myBox.apos('170px', '150px');
}
// window.onload = populate;
$(function () {
$("container2").on("click", ".class1", function () {
alert("The div was clicked.");
});
});
</script>
<div id="container1" style="width: auto; height: 50px;">
<div id="myBox">Hello World!</div>
<button style="margin: auto; vertical-align: top; float: left; font-size: 16px;" type="button" onclick="divGenerator();">Generate</button>
#Html.DropDownList("centres")
</div>
<div id="container2" style="margin: 10px; float: left;" />
<head>
<script type="text/javascript" src="../../Content/javascripts/glassbox/glassbox.js"></script>
<style type="text/css">
#myBox #myBox_content {
padding: 2px;
font-family: verdana, arial, helvetica;
font-size: 12px;
}
</style>
<title></title>
</head>
<body>
<!--
popup
-->
</body>
And here is what it returns (taken from google chrome):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="description" content="Description of your web page goes here." />
<meta name="keywords" content="Keywords for you web page go here. Each keyword or group of keyword phrases are separated by a comma. Keep this list short and relevant to the content and title of this specific page." />
<title>OneEighty Asset Manager
</title>
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" media="screen" />
</head>
<body>
<div id="header">
<div id="logo">
<p></p>
</div>
</div>
<!-- end #header -->
<div id="menu">
<ul>
<li>Home</li>
<li>About</li>
</ul>
</div>
<!-- end #menu -->
<div id="wrapper">
<div class="btm">
<div id="page">
<h1>
<img src="../../Content/Images/1Eighty.png" alt="" style="height: 100px; width: 750px;" /></h1>
<div id="content">
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" media="screen" />
<script type="text/javascript">
function populate() {
var select = document.getElementById("centres");
for (var i = 1; i <= 10; i++) {
var option = document.createElement("option");
option.value = i;
option.text = i;
select.appendChild(option);
}
}
function divGenerator() {
var div;
for (var i = 1; i <= document.getElementById("centres").selectedIndex + 1; i++) {
div = document.createElement("div");
div.className = "class1";
div.innerHTML = "Space " + i;
div.style.width = "100px";
div.style.height = "100px";
div.style.float = "left";
document.getElementById("container2").appendChild(div);
}
}
function glassLoad() {
path_to_root_dir = "../../Content/";
var myBox = new GlassBox();
myBox.init('#myBox', '128px', '62px', 'hidden');
myBox.apos('170px', '150px');
alert("div clicked");
}
// window.onload = populate;
</script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$("#container2").on("click", ".class1", function () {
path_to_root_dir = "../../Content/";
var myBox = new GlassBox();
myBox.init('#myBox', '128px', '62px', 'hidden');
myBox.apos('170px', '150px');
alert("div clicked");
});
});
</script>
<div id="container1" style="width: auto; height: 50px;">
<button style="margin: auto; vertical-align: top; float: left; font-size: 16px;" type="button" onclick="divGenerator();">Generate</button>
<select id="centres" name="centres"><option>Southdale</option>
<option>Sasolburg</option>
<option>Sandton City</option>
<option>Greenstone</option>
<option>Morningside</option>
<option>Easgate</option>
<option>Bedfordview</option>
<option>Fourways</option>
<option>Linksfield Terrace</option>
<option>Carlton Centre</option>
<option>testcentre1</option>
<option>testcentre2</option>
<option>testcentre3</option>
</select>
</div>
<div id="container2" style="margin: 10px; float: left;" />
<head>
<script type="text/javascript" src="../../Content/javascripts/glassbox/glassbox.js"></script>
<style type="text/css">
#myBox #myBox_content {
padding: 2px;
font-family: verdana, arial, helvetica;
font-size: 12px;
}
</style>
<title></title>
</head>
<body>
<!--
popup
-->
</body>
</div>
<!-- end #content -->
<div style="clear: both;">
</div>
</div>
<!-- end #page -->
</div>
</div>
<div id="footer">
<p>
Copyright (c) 2009 1eightyintra.com. All rights reserved.
</p>
</div>
<!-- end #footer -->
</body>
</html>
Because the element doesn't exist in the DOM on page load, you need to use an event delegate, such as on:
$(function () {
$("body").on("click", ".class1", function () {
alert("The div was clicked.");
});
});
Or for pre-1.7 jQuery, use delegate:
$(function () {
$("body").delegate(".class1", "click", function () {
alert("The div was clicked.");
});
});
click only binds handlers to elements that were present in the DOM when you called it.
Instead, use the jQuery on method:
$(document).ready(function () {
$("body").on("click", ".class1", function () {
alert("The div was clicked.");
});
});
You will need to re-apply the click handler to the newly created divs.

Categories