• Our Services
  • Press Releases
  • Hosting Hub
  • Sitemap
  • Login
  • Our WordPress Plugin
  • Blog Posting Services
  • In Twitter
  • In LinkedIn
  • Our Code Repository
J
HARAPHULA
OneStop Shop of Information

Updates

  • Termites in House? Pest Control Services to Save Damage
    •
  • How to Buy Facebook Likes and boost your Reach?
    •
  • CNC Machining in Model Making Dubai for Prototypes
    •
  • Human Behavior in Men and Women Aged 18 to 35
    •
  • Best Nutrition for Active Working Dogs
    •
  • Why Homeowners Love Brown Granite Worktops for their Kitchens?
    •
  • Siding Repair in Cleveland – Why Timely Maintenance is Crucial for your Home?
    •
  • How to Transition to Toxic-Free Sanitary Pads Smoothly?
    •
  • Potassium Feldspar – A Comprehensive Guide
    •
  • What are Textile Chemicals and Why are they Important?
    •
  • How to Detect and Repair Leaks in PPRC Pipes and Fittings?
    •
  • Plumber Islington – MK Plumbers – Your Local Plumbing Experts
    •
  • Top Storage Sheds in Corowa – Reliable and Affordable Options
    •
  • Mastering Pest Control – Learn Online for a Sustainable Future
    •
  • Effective Strategies for Pest Control in Urban Environments
    •

Design MS-Excel like Table using KineticJS on HTML5 Canvas?

KineticJS Examples
May 13, 2016
5 (1 votes)
Design MS-Excel like Table using KineticJS on HTML5 Canvas? Design MS-Excel like Table using KineticJS on HTML5 Canvas?
5 5 92

During my software development experiences I never faced such a challenging stuff to design a table like Microsoft word or excel. Recently with my Ex-employer in a project I found me to design a table like MS-Word. The skills I used here are KineticJS, HTML5 & Jquery.

A table looks very easy to Operate but during the development of a table I faced many critical logical games to handle. In this article I am sharing the complete class for creating a table. The JavaScript class I am sharing here is TableShape which accepts row & column numbers with KineticJS stage & layer. In real-time this class is capable to draw table for you depending upon the row & column values. To implement this you need to copy this js file to your application & while creating the instance for the class TableShape you need to pass parameters only.

In the below TableShape class I have all the ready mate method to do operation with a table. createCell is the method which creates cell for table. Used Splitters to handle cells & rows adjustments. To insert a row into the table we created a function insertRow(). Where by passing the index you can add a row to your table. To delete a row in this class we implemented deleteRow() function. This function accepts index of the row which one you want to delete. Depending upon the index this external function is capable to delete row from your table. Similar to insertRow() & deleteRow() we have insertColumn() & deleteColumn() method. Using getHeight() & getWidth() external function you can retrieve table width & height in your class. During operations to retrieve the x & y positions of table in this class we declared two additional methods getX() & getY(). These methods are added to the exports array of this method. Which you can easily access from your class. Using setWidth() & setHeight() functions you can set table width & height from your external class. To select the table or it’s cells this class contains Select & Deselect methods. You just need to call them from your class to use. Like this there are plenty of functionality you can get with this class.

This class is well tested by our QA team. I don’t think you will get any problems to implement this class. What problems we faced during a table design I don’t want to give you the same pain. Let us reuse the code.

tableShape.js

/*Table Cell related default values*/
var DEFAULT_CELL_STROKE_WIDTH = 1;
var DEFAULT_CELL_WIDTH = 200;
var DEFAULT_CELL_HEIGHT = 100;
var MIN_CELL_DIM = 25;
var DEFAULT_SPANNER_WIDTH = 5;
/*Table Slitter Default Stroke & Width*/
var DEFAULT_SPLITTER_STROKE = "#000000";
var DEFAULT_SPLITTER_WIDTH = 3;

var DEFAULT_SPANNER_STROKE = "darkgray";
/*Table default cell settings*/
var DEFAULT_CELL_FILL = "#FFFFFF";
var DEFAULT_CELL_STROKE = "#000000";
var DEFAULT_CELL_STROKE_SELECTED = "#000000";

var TableShape = function (totalRows, totalColumns, stage, layer) {

var exports = {};
var _rows = null;
var _columns = null;
var _stage = null;
var _tbllayer = null;
var _tblgroup = null;
var _embeddedShapes = [];
var _tableIndex = [];

/* Initial values related to Table */
function init() {

_tbllayer = layer;
_tblgroup = new Kinetic.Group({
x: -(_columns / 2) * DEFAULT_CELL_WIDTH,
y: -(_rows / 2) * DEFAULT_CELL_HEIGHT,
width: _columns * DEFAULT_CELL_WIDTH,
height: _rows * DEFAULT_CELL_HEIGHT,
draggable: true
});

var xDisp = (2 * DEFAULT_CELL_STROKE_WIDTH + DEFAULT_SPANNER_WIDTH);
var yDisp = (2 * DEFAULT_CELL_STROKE_WIDTH + DEFAULT_SPANNER_WIDTH);

for (var row = 0; row < _rows; row++) {

_tableIndex[row] = new Array();

for (var col = 0; col < _columns; col++) {

var box = createCell((col == 0) ? (2 * DEFAULT_CELL_STROKE_WIDTH) : (col * DEFAULT_CELL_WIDTH) + (col * xDisp),
(row == 0) ? (2 * DEFAULT_CELL_STROKE_WIDTH) : (row * DEFAULT_CELL_HEIGHT) + (row * yDisp),
DEFAULT_CELL_WIDTH, DEFAULT_CELL_HEIGHT);

_tblgroup.add(box);
_tableIndex[row][col] = box;
}
}

//nameCells();
createSpanners(true);

_tblgroup.on('mouseout', function (e) {
document.body.style.cursor = 'default';
});

_tblgroup.on('click', function (e) {

if (e.shape.getId() != "tableCell" &&
e.shape.getId() != "vSplitter" && e.shape.getId() != "hSplitter" &&
e.shape.getName() != "spanLineCol" && e.shape.getName() != "spanLineRow" &&
event.shiftKey) {
e.shape.parent.setX(_tblgroup.parent.getX() + e.shape.parent.getX() - _tblgroup.parent.getOffset().x);
e.shape.parent.setY(_tblgroup.parent.getY() + e.shape.parent.getY() - _tblgroup.parent.getOffset().y);
e.shape.parent.moveTo(_tbllayer);
e.shape.parentTable = null;
}
else {
// table in table
if (e.shape.getId() == "tableCell" && e.shape.parent != _tblgroup && event.shiftKey) {
//Nothing ToDo
}
else {
groupEmbeddedShapes();
}
}
});
_tblgroup.on('dblclick', function (e) {
});

_tbllayer.add(_tblgroup);
_tblgroup._id = exports._id;
selectCell(_tableIndex[0][0]);
_stage.draw();
}

/* Funtion to Create Cells in Table */
function createCell(cellX, cellY, cellWidth, cellHeight, cellName) {

var cell = new Kinetic.Rect({
id: "tableCell",
name: cellName ? cellName : randomString(5),
x: cellX,
y: cellY,
width: cellWidth,
height: cellHeight,
fill: DEFAULT_CELL_FILL,
stroke: DEFAULT_CELL_STROKE,
strokeWidth: DEFAULT_CELL_STROKE_WIDTH
});

cell.on('click', function (evt) {
selectCell(this);

if (event.ctrlLeft) {
addSplitter(cell, "vertical");
}

if (event.altLeft) {
addSplitter(cell, "horizontal");
}
});

cell.on('mouseover', function (e) {
document.body.style.cursor = 'crosshair';
});

return cell;
}

function updateSplitters(cell) {

if (cell.vSplitters) {

for (var i = 0; i < cell.vSplitters.length; i++) {
var vSplit = cell.vSplitters[i];
var points = vSplit.getPoints();

var curSpltrX = points[0].x + vSplit.getX();

if (curSpltrX < cell.getX()) {
vSplit.setX(cell.getX() - points[0].x + DEFAULT_SPANNER_WIDTH);
}

if (curSpltrX > cell.getX() + cell.getWidth()) {
vSplit.setX(cell.getX() + cell.getWidth() - points[0].x - DEFAULT_SPANNER_WIDTH);
}
points[0].y = cell.getY();
points[1].y = cell.getY() + cell.getHeight();
vSplit.setPoints(points);
vSplit.setY(cell.getY() - points[0].y);
}
}

if (cell.hSplitters) {
for (var i = 0; i < cell.hSplitters.length; i++) {
var hSplit = cell.hSplitters[i];
var points = hSplit.getPoints();

var curSpltrY = points[0].y + hSplit.getY();

if (curSpltrY < cell.getY()) {
hSplit.setY(cell.getY() - points[0].y + DEFAULT_SPANNER_WIDTH);
}

if (curSpltrY > cell.getY() + cell.getHeight()) {
hSplit.setY(cell.getY() + cell.getHeight() - points[0].y - DEFAULT_SPANNER_WIDTH);
}
points[0].x = cell.getX();
points[1].x = cell.getX() + cell.getWidth();
hSplit.setPoints(points);
hSplit.setX(cell.getX() - points[0].x);
}
}
}

function addSplitter(cell, type, evt) {

switch (type) {
case "vertical":
var x, y;

if (evt && evt.x) {
transformEventCoordsToCellCoords(cell, evt);
x = cell.getX() + evt.x;
y = cell.getY();
}
else {
x = cell.getX() + cell.getWidth() / 2;
y = cell.getY();
}

var lineVSplitter = new Kinetic.Line({
id: "vSplitter",
name: cell.getName() + "vSplitter",
points: [x, y, x, y + cell.getHeight()],
stroke: cell.getStroke(),
strokeWidth: DEFAULT_SPLITTER_WIDTH,
draggable: true,
dragOnTop: false
});

lineVSplitter.on('mouseover', function (e) {
$("body").css("cursor", "col-resize");
});

lineVSplitter.on('dragmove', function (e) {
this.setY(0);

var curSpltrX = this.getPoints()[0].x + this.getX();

if (curSpltrX < cell.getX()) {
this.setX(cell.getX() - this.getPoints()[0].x + DEFAULT_SPANNER_WIDTH);
return;
}

if (curSpltrX > cell.getX() + cell.getWidth()) {
this.setX(cell.getX() + cell.getWidth() - this.getPoints()[0].x - DEFAULT_SPANNER_WIDTH);
return;
}
});

lineVSplitter.on('mouseout', function (e) {
$("body").css("cursor", "default");
});

lineVSplitter.on("mousedown dragstart", function () {
_tblgroup.setDraggable(false);
_tblgroup.parent.setDraggable(false);
});

lineVSplitter.on("mouseup dragend", function () {
_tblgroup.setDraggable(true);
_tblgroup.parent.setDraggable(true);
});

_tblgroup.add(lineVSplitter);
if (!cell.vSplitters) cell.vSplitters = [];
cell.vSplitters.push(lineVSplitter);
break;

case "horizontal":
var x, y;

if (evt && evt.y) {
transformEventCoordsToCellCoords(cell, evt);
x = cell.getX();
y = cell.getY() + evt.y;
}
else {
x = cell.getX();
y = cell.getY() + cell.getHeight() / 2;
}

var lineHSplitter = new Kinetic.Line({
id: "hSplitter",
name: cell.getName() + "hSplitter",
points: [x, y, x + cell.getWidth(), y],
stroke: cell.getStroke(),
strokeWidth: DEFAULT_SPLITTER_WIDTH,
draggable: true,
dragOnTop: false
});

lineHSplitter.on('mouseover', function (e) {
$("body").css("cursor", "row-resize");
});

lineHSplitter.on('dragmove', function (e) {
this.setX(0);

var curSpltrY = this.getPoints()[0].y + this.getY();

if (curSpltrY < cell.getY()) {
this.setY(cell.getY() - this.getPoints()[0].y + DEFAULT_SPANNER_WIDTH);
return;
}

if (curSpltrY > cell.getY() + cell.getHeight()) {
this.setY(cell.getY() + cell.getHeight() - this.getPoints()[0].y - DEFAULT_SPANNER_WIDTH);
return;
}
});

lineHSplitter.on('mouseout', function (e) {
$("body").css("cursor", "default");
});

lineHSplitter.on("mousedown dragstart", function () {
_tblgroup.setDraggable(false);
_tblgroup.parent.setDraggable(false);
});

lineHSplitter.on("mouseup dragend", function () {
_tblgroup.setDraggable(true);
_tblgroup.parent.setDraggable(true);
});

_tblgroup.add(lineHSplitter);
if (!cell.hSplitters) cell.hSplitters = [];
cell.hSplitters.push(lineHSplitter);
break;

default:
break;
}
}

function removeSplitters(cell, type, evt) {

switch (type) {
case "vertical":

if (cell.vSplitters) {
if (evt && evt.x) {
transformEventCoordsToCellCoords(cell, evt);
var nearest = 0;

for (var i = 1; i < cell.vSplitters.length; i++) {
var vSplit = cell.vSplitters[i];
var vSplitNearest = cell.vSplitters[nearest];
var splitX = vSplit.getPoints()[0].x + vSplit.getX();
var splitXnearest = vSplitNearest.getPoints()[0].x + vSplitNearest.getX();

if (Math.abs(evt.x - splitXnearest) > Math.abs(evt.x - splitX)) {
nearest = i;
}
}

cell.vSplitters[nearest].remove();
cell.vSplitters.splice(nearest, 1);
if (0 == cell.vSplitters.length) cell.vSplitters = null;
}
else {
for (var i = 0; i < cell.vSplitters.length; i++) {
cell.vSplitters[i].remove();
}

cell.vSplitters = null;
}
}
break;

case "horizontal":
if (cell.hSplitters) {

if (evt && evt.y) {
transformEventCoordsToCellCoords(cell, evt);
var nearest = 0;

for (var i = 1; i < cell.hSplitters.length; i++) {
var hSplit = cell.hSplitters[i];
var hSplitNearest = cell.hSplitters[nearest];
var splitY = hSplit.getPoints()[0].y + hSplit.getY();
var splitYnearest = hSplitNearest.getPoints()[0].y + hSplitNearest.getY();

if (Math.abs(evt.y - splitYnearest) > Math.abs(evt.y - splitY)) {
nearest = i;
}
}

cell.hSplitters[nearest].remove();
cell.hSplitters.splice(nearest, 1);
if (0 == cell.hSplitters.length) cell.hSplitters = null;
}
else {
for (var i = 0; i < cell.hSplitters.length; i++) {
cell.hSplitters[i].remove();
}

cell.hSplitters = null;
}
}
break;

default:
break;
}
}

function moveSplitters(cell, disp) {

if (cell.vSplitters) {
for (var i = 0; i < cell.vSplitters.length; i++) {
cell.vSplitters[i].move(disp.x, disp.y);
}
}

if (cell.hSplitters) {
for (var i = 0; i < cell.hSplitters.length; i++) {
cell.hSplitters[i].move(disp.x, disp.y);
}
}

updateSplitters(cell);
}

function createSpanners(init) {

if (!init) {
// remove previous ones
var rowSpans = _tblgroup.get(".spanLineRow");

for (var i = 0; i < rowSpans.length; i++) {
rowSpans[i].remove();
}

var colSpans = _tblgroup.get(".spanLineCol");

for (var i = 0; i < colSpans.length; i++) {
colSpans[i].remove();
}
}

var row = 0;
for (var col = 1; col < _tableIndex[row].length; col++) {

var cell = _tableIndex[row][col];

var lineCol = new Kinetic.Line({
name: "spanLineCol",
id: col,
points: [cell.getX() - DEFAULT_SPANNER_WIDTH + (2 * DEFAULT_CELL_STROKE_WIDTH), cell.getY(),
cell.getX() - DEFAULT_SPANNER_WIDTH + (2 * DEFAULT_CELL_STROKE_WIDTH), exports.getHeight()],

stroke: DEFAULT_SPANNER_STROKE,
strokeWidth: DEFAULT_SPANNER_WIDTH,
dashArray: [DEFAULT_SPANNER_WIDTH, DEFAULT_SPANNER_WIDTH, DEFAULT_SPANNER_WIDTH, DEFAULT_SPANNER_WIDTH],
lineCap: 'round',
lineJoin: 'round',
draggable: true,
dragOnTop: false
});

lineCol.on('mouseover', function (e) {
$("body").css("cursor", "col-resize");
});

lineCol.on('dragmove', function (e) {
this.setY(0);
spanColumn(e.shape);
});

lineCol.on('mouseout', function (e) {
$("body").css("cursor", "default");
});

lineCol.on("mousedown dragstart", function () {
_tblgroup.setDraggable(false);
_tblgroup.parent.setDraggable(false);
});

lineCol.on("mouseup dragend", function () {
_tblgroup.setDraggable(true);
_tblgroup.parent.setDraggable(true);
});

_tblgroup.add(lineCol);
}

var col = 0;
for (var row = 1; row < _tableIndex.length; row++) {

var cell = _tableIndex[row][col];

var lineRow = new Kinetic.Line({
name: "spanLineRow",
id: row,
points: [cell.getX(), cell.getY() - DEFAULT_SPANNER_WIDTH + (2 * DEFAULT_CELL_STROKE_WIDTH),
exports.getWidth(), cell.getY() - DEFAULT_SPANNER_WIDTH + (2 * DEFAULT_CELL_STROKE_WIDTH)],
stroke: DEFAULT_SPANNER_STROKE,
strokeWidth: DEFAULT_SPANNER_WIDTH,
dashArray: [DEFAULT_SPANNER_WIDTH, DEFAULT_SPANNER_WIDTH, DEFAULT_SPANNER_WIDTH, DEFAULT_SPANNER_WIDTH],
lineCap: 'round',
lineJoin: 'round',
draggable: true,
dragOnTop: false
});

lineRow.on('mouseover', function (e) {
$("body").css("cursor", "row-resize");
});

lineRow.on('dragmove', function (e) {
this.setX(0);
spanRow(e.shape);
});

lineRow.on('mouseout', function (e) {
$("body").css("cursor", "default");
});

lineRow.on("mousedown dragstart", function () {
_tblgroup.setDraggable(false);
_tblgroup.parent.setDraggable(false);
});

lineRow.on("mouseup dragend", function () {
_tblgroup.setDraggable(true);
_tblgroup.parent.setDraggable(true);
});

_tblgroup.add(lineRow);
}

if (exports.selectedCell) {
exports.selectedCell.show();
}
}

function spanColumn(spanner) {

var col = Number(spanner.getId());
var curSpanX = spanner.getPoints()[0].x + spanner.getX();

for (var row = 0; row < _tableIndex.length; row++) {

var lCell = _tableIndex[row][col - 1];
var rCell = _tableIndex[row][col];

if (lCell.getWidth() <= MIN_CELL_DIM && (curSpanX - DEFAULT_SPANNER_WIDTH) <= (lCell.getX() + lCell.getWidth())) {
spanner.setX((lCell.getX() + lCell.getWidth() + (4 * DEFAULT_CELL_STROKE_WIDTH)) - spanner.getPoints()[0].x);
return;
}

if (rCell.getWidth() <= MIN_CELL_DIM && curSpanX >= rCell.getX()) {
spanner.setX((rCell.getX() - (4 * DEFAULT_CELL_STROKE_WIDTH)) - spanner.getPoints()[0].x);
return;
}

var diff = curSpanX - rCell.getX() + (4 * DEFAULT_CELL_STROKE_WIDTH);

lCell.setWidth(lCell.getWidth() + diff);
rCell.setWidth(rCell.getWidth() - diff);

var embShapes = _tblgroup.get("." + rCell.getName());

for (var i = 0; i < embShapes.length; i++) {
embShapes[i].setX(embShapes[i].getX() + diff);
}

updateSplitters(lCell);
updateSplitters(rCell);
}
}

function spanRow(spanner) {

var row = Number(spanner.getId());
var curSpanY = spanner.getPoints()[0].y + spanner.getY();

for (var col = 0; col < _tableIndex[row].length; col++) {

var tCell = _tableIndex[row - 1][col];
var bCell = _tableIndex[row][col];

if (tCell.getHeight() <= MIN_CELL_DIM && (curSpanY - DEFAULT_SPANNER_WIDTH) <= (tCell.getY() + tCell.getHeight())) {
spanner.setY((tCell.getY() + tCell.getHeight() + (4 * DEFAULT_CELL_STROKE_WIDTH)) - spanner.getPoints()[0].y);
return;
}

if (bCell.getHeight() <= MIN_CELL_DIM && curSpanY >= bCell.getY()) {
spanner.setY((bCell.getY() - (4 * DEFAULT_CELL_STROKE_WIDTH)) - spanner.getPoints()[0].y);
return;
}

var diff = curSpanY - bCell.getY() + (4 * DEFAULT_CELL_STROKE_WIDTH);

tCell.setHeight(tCell.getHeight() + diff);
bCell.setHeight(bCell.getHeight() - diff);

var embShapes = _tblgroup.get("." + bCell.getName());

for (var i = 0; i < embShapes.length; i++) {
embShapes[i].setY(embShapes[i].getY() + diff);
}

updateSplitters(tCell);
updateSplitters(bCell);
}
}

/* Function to Select Indivisual Cell in Table*/
function selectCell(cell) {

if (exports.selectedCell && exports.selectedCell.sCell() == cell) return;

if (exports.selectedCell) {
exports.selectedCell.hide();
}
exports.selectedCell = new SelectedCell(cell, null);
exports.selectedCell.show();
_stage.draw();
}

function selectTable() {

if (exports.selectedCell) {
exports.selectedCell.hide();
}

exports.selectedCell = new SelectedCell(null, _tableIndex);
exports.selectedCell.show();
_stage.draw();
}

function resizeRowSpanners(diff, bLeft) {

var rowSpans = _tblgroup.get(".spanLineRow");

for (var i = 0; i < rowSpans.length; i++) {
rowSpans[i].attrs.points[1].x += diff;
}

if (bLeft) {
var colSpans = _tblgroup.get(".spanLineCol");

for (var i = 0; i < colSpans.length; i++) {
colSpans[i].attrs.points[0].x += diff;
colSpans[i].attrs.points[1].x += diff;
}
}

_tblgroup.setWidth(_tblgroup.getWidth() + diff);
}

function resizeColSpanners(diff, bTop) {
var colSpans = _tblgroup.get(".spanLineCol");

for (var i = 0; i < colSpans.length; i++) {
colSpans[i].attrs.points[1].y += diff;
}

if (bTop) {
var rowSpans = _tblgroup.get(".spanLineRow");

for (var i = 0; i < rowSpans.length; i++) {
rowSpans[i].attrs.points[0].y += diff;
rowSpans[i].attrs.points[1].y += diff;
}
}

_tblgroup.setHeight(_tblgroup.getHeight() + diff);
}

function groupEmbeddedShapes() {

var oldRot = _tblgroup.parent.getRotation();
_tblgroup.parent.setRotation(0);

for (var key in _embeddedShapes) {

if (_embeddedShapes.hasOwnProperty(key)) {
var shape = _embeddedShapes[key];
var oldChld = _tblgroup.children.length;

shape.moveTo(_tblgroup);

if (oldChld != _tblgroup.children.length) {

shape.setX(shape.getX() - _tblgroup.parent.getX() + _tblgroup.parent.getOffset().x);
shape.setY(shape.getY() - _tblgroup.parent.getY() + _tblgroup.parent.getOffset().y);

shape.setName("");
bInside = false;

for (var row = 0; row < _tableIndex.length && bInside == false; row++) {
for (var col = 0; col < _tableIndex[row].length; col++) {
cell = _tableIndex[row][col];
if (exports.areShapesOverlapping(cell, shape)) {
shape.setName(cell.getName());
bInside = true;
break;
}
}
}
}

if (!bInside) {
shape.setX(_tblgroup.parent.getX() + shape.getX() - _tblgroup.parent.getOffset().x);
shape.setY(_tblgroup.parent.getY() + shape.getY() - _tblgroup.parent.getOffset().y);
shape.moveTo(_tbllayer);
}
}
}

_tblgroup.parent.setRotation(oldRot);
}

function transformEventCoordsToCellCoords(cell, evt) {

if (cell && evt) {
var m = cell.getAbsoluteTransform();
var n = new Kinetic.Transform();
n.multiply(m);
n.invert();
n.translate(evt.x, evt.y)
evt.x = n.getMatrix()[4];
evt.y = n.getMatrix()[5];
}
}

/* Function to insert Row into the Table */
exports.insertRow = function (index) {

if (index < 0) index = 0;
if (index == undefined || index >= _rows) index = _rows;

var row = new Array();

if (index >= _tableIndex.length) {
for (var col = 0; col < _tableIndex[index - 1].length; col++) {
var refCell = _tableIndex[index - 1][col];
var cell = createCell(refCell.getX(), refCell.getY() + DEFAULT_SPANNER_WIDTH + refCell.getHeight(), refCell.getWidth(), DEFAULT_CELL_HEIGHT);
row.push(cell);
_tblgroup.add(cell);
}

_tableIndex.splice(index, 0, row);
}
else {
for (var col = 0; col < _tableIndex[index].length; col++) {
var refCell = _tableIndex[index][col];
var cell = createCell(refCell.getX(), refCell.getY(), refCell.getWidth(), DEFAULT_CELL_HEIGHT);
row.push(cell);
_tblgroup.add(cell);
}

_tableIndex.splice(index, 0, row);

for (var rowInd = index + 1; rowInd < _tableIndex.length; rowInd++) {
for (var col = 0; col < _tableIndex[rowInd].length; col++) {
var cell = _tableIndex[rowInd][col];

// move linked shapes too
var embShapes = _tblgroup.get("." + cell.getName());

for (var i = 0; i < embShapes.length; i++) {
embShapes[i].move(0, DEFAULT_CELL_HEIGHT + DEFAULT_CELL_STROKE_WIDTH + DEFAULT_SPANNER_WIDTH);
}

moveSplitters(cell, { x: 0, y: DEFAULT_CELL_HEIGHT + DEFAULT_CELL_STROKE_WIDTH + DEFAULT_SPANNER_WIDTH });
}
}
}

_rows++;

createSpanners();
_stage.draw();
}

/* Function to delete Row from the Table */
exports.deleteRow = function (index) {

if (_rows == 1) return;

if (index == undefined) index = _rows - 1;

var diff = _tableIndex[index][0].getHeight();

for (var row = index; row < _tableIndex.length; row++) {
for (var col = 0; col < _tableIndex[row].length; col++) {

var cell = _tableIndex[row][col];
var embShapes = _tblgroup.get("." + cell.getName());

if (row == index) {
// delete linked shapes too
for (var i = 0; i < embShapes.length; i++) {
embShapes[i].remove();
}

removeSplitters(cell, "vertical");
removeSplitters(cell, "horizontal");
}
else {
for (var i = 0; i < embShapes.length; i++) {
embShapes[i].move(0, -(diff + DEFAULT_CELL_STROKE_WIDTH + DEFAULT_SPANNER_WIDTH));
}

moveSplitters(cell, { x: 0, y: -(diff + DEFAULT_CELL_STROKE_WIDTH + DEFAULT_SPANNER_WIDTH) });
}
}
}

_tableIndex.splice(index, 1);
_rows--;

createSpanners();
_stage.draw();
}

/* Function to insert Column into the Table */
exports.insertColumn = function (index) {

if (index < 0) index = 0;
if (index == undefined || index >= _columns) index = _columns;

for (var row = 0; row < _tableIndex.length; row++) {

if (index >= _tableIndex[row].length) {

var refCell = _tableIndex[row][index - 1];
var cell = createCell(refCell.getX() + refCell.getWidth() + DEFAULT_CELL_STROKE_WIDTH + DEFAULT_SPANNER_WIDTH, refCell.getY(), DEFAULT_CELL_WIDTH, refCell.getHeight());
_tableIndex[row].push(cell);
_tblgroup.add(cell);
}
else {
var refCell = _tableIndex[row][index];
var newCell = createCell(refCell.getX(), refCell.getY(), DEFAULT_CELL_WIDTH, refCell.getHeight());
_tableIndex[row].splice(index, 0, newCell);
_tblgroup.add(newCell);

for (var colInd = index + 1; colInd < _tableIndex[row].length; colInd++) {
var cell = _tableIndex[row][colInd];

// move linked shapes too
var embShapes = _tblgroup.get("." + cell.getName());

for (var i = 0; i < embShapes.length; i++) {
embShapes[i].move(DEFAULT_CELL_WIDTH + DEFAULT_CELL_STROKE_WIDTH + DEFAULT_SPANNER_WIDTH, 0);
}

moveSplitters(cell, { x: DEFAULT_CELL_WIDTH + DEFAULT_CELL_STROKE_WIDTH + DEFAULT_SPANNER_WIDTH, y: 0 });
}
}
}

_columns++;
createSpanners();
_stage.draw();
}

/* Function to delete column from the Table */
exports.deleteColumn = function (index) {

if (_columns == 1) return;

if (index == undefined) index = _columns - 1;

var diff = _tableIndex[0][index].getWidth();

for (var row = 0; row < _tableIndex.length; row++) {
for (var col = index; col < _tableIndex[row].length; col++) {

var cell = _tableIndex[row][col];

var embShapes = _tblgroup.get("." + cell.getName());

if (col == index) {
// delete linked shapes too
for (var i = 0; i < embShapes.length; i++) {
embShapes[i].remove();
}

removeSplitters(cell, "vertical");
removeSplitters(cell, "horizontal");
}
else {
for (var i = 0; i < embShapes.length; i++) {
embShapes[i].move(-(diff + DEFAULT_CELL_STROKE_WIDTH + DEFAULT_SPANNER_WIDTH), 0);
}

moveSplitters(cell, { x: -(diff + DEFAULT_CELL_STROKE_WIDTH + DEFAULT_SPANNER_WIDTH), y: 0 });
}
}

_tableIndex[row].splice(index, 1);
}

_columns--;
createSpanners();
_stage.draw();
}

exports.rows = function () {
return _rows;
}

exports.columns = function () {
return _columns;
}

exports.group = function () {
return _tblgroup;
}

exports.getCell = function (row, col) {
if (row >= 0 && row < _rows && col >= 0 && col < _columns) {
return _tableIndex[row][col];
}
}

exports.addShape = function (shape) {

_embeddedShapes[shape._id] = shape;

shape.parentTable = exports;
}

exports.removeShape = function (shape) {

if (_embeddedShapes[shape._id]) {
delete _embeddedShapes[shape._id]
}
}

exports.getSelectedIndex = function () {

var cell = exports.selectedCell.sCell();

if (cell) {
for (var row = 0; row < _tableIndex.length; row++) {
for (var col = 0; col < _tableIndex[row].length; col++) {
if (_tableIndex[row][col] == cell) {
return { row: row, column: col };
}
}
}
}

return null;
}

exports.update = function () {
groupEmbeddedShapes();
}

exports.initDone = function () {

if (_tblgroup.parent && _tblgroup.parent.getId() == "marquee") {
var borderLine = _tblgroup.parent.get(".borderLines")[0];

if (borderLine) {
borderLine.on("click", function (e) {
selectTable();
});
}
}
}

exports.splitCellVertical = function (row, col, evt) {
if (row >= 0 && row < _rows && col >= 0 && col < _columns) {
var cell = _tableIndex[row][col];

addSplitter(cell, "vertical", evt);
}
}

exports.mergeCellVertical = function (row, col, evt) {
if (row >= 0 && row < _rows && col >= 0 && col < _columns) {
var cell = _tableIndex[row][col];

removeSplitters(cell, "vertical", evt);
}
}

exports.splitCellHorizontal = function (row, col, evt) {
if (row >= 0 && row < _rows && col >= 0 && col < _columns) {
var cell = _tableIndex[row][col];

addSplitter(cell, "horizontal", evt);
}
}

exports.mergeCellHorizontal = function (row, col, evt) {
if (row >= 0 && row < _rows && col >= 0 && col < _columns) {
var cell = _tableIndex[row][col];

removeSplitters(cell, "horizontal", evt);
}
}

exports.hasVertSplitters = function (row, col) {
if (row >= 0 && row < _rows && col >= 0 && col < _columns) {
var cell = _tableIndex[row][col];

if (cell.vSplitters) return true;
}

return false;
}

exports.hasHorizSplitters = function (row, col) {
if (row >= 0 && row < _rows && col >= 0 && col < _columns) {
var cell = _tableIndex[row][col];

if (cell.hSplitters) return true;
}
return false;
}

// getters
exports.getId = function () {
return null;
}

exports.getName = function () {
return null;
}

exports.getLayer = function () {
return _tbllayer;
}

exports.getStage = function () {
return _stage;
}

exports.getZIndex = function () {
return _tblgroup.getZIndex();
}

exports.getOffset = function () {
if (_tblgroup.parent && _tblgroup.parent.getId() == "marquee") {
return _tblgroup.parent.getOffset();
}
else {
return _tblgroup.getOffset();
}
}

exports.getScale = function () {
return _tblgroup.getScale();
}

/* Function to get width of the Table */
exports.getWidth = function () {
var row = _rows - 1;
var width = 0 - (2 * DEFAULT_CELL_STROKE_WIDTH);

for (var i = 0; i < _tableIndex[row].length; i++) {
width += _tableIndex[row][i].getWidth() + DEFAULT_CELL_STROKE_WIDTH + DEFAULT_SPANNER_WIDTH;
}

_tblgroup.setWidth(width);

return width;
}

/* Function to get height of the Table */
exports.getHeight = function () {
var col = _columns - 1
var height = 0 - (2 * DEFAULT_CELL_STROKE_WIDTH);

for (var i = 0; i < _tableIndex.length; i++) {
height += _tableIndex[i][col].getHeight() + DEFAULT_CELL_STROKE_WIDTH + DEFAULT_SPANNER_WIDTH;
}

_tblgroup.setHeight(height);

return height;
}

exports.getX = function () {
if (_tblgroup.parent && _tblgroup.parent.getId() == "marquee") {
return _tblgroup.parent.getX();
}
else {
return _tblgroup.getX();
}
}

exports.getY = function () {
if (_tblgroup.parent && _tblgroup.parent.getId() == "marquee") {
return _tblgroup.parent.getY();
}
else {
return _tblgroup.getY();
}
}

// setters
exports.setX = function (val) {
_tblgroup.setX(val);
}

exports.setY = function (val) {
_tblgroup.setY(val);
}

exports.moveTo = function (shp) {
_tblgroup.moveTo(shp);
}

exports.setDraggable = function (val) {
_tblgroup.setDraggable(val);
}

exports.setWidth = function (val, anchor) {

var diff = val - exports.getWidth();

if (anchor) {
var anchorName = anchor.getName();

switch (anchorName) {

case "cpLeft":
for (var row = 0; row < _tableIndex.length; row++) {
for (var col = 0; col < _tableIndex[row].length; col++) {

var cell = _tableIndex[row][col];

if (col == 0) {
var newWidth = cell.getWidth() + diff;

if (newWidth > MIN_CELL_DIM) {
cell.setWidth(newWidth);
if (row == 0) resizeRowSpanners(diff, true);
}
else {
_tblgroup.parent.move(diff, 0);
diff = 0;
}
}
else {
var embShapes = _tblgroup.get("." + cell.getName());

for (var i = 0; i < embShapes.length; i++) {
embShapes[i].move(diff, 0);
}
}

updateSplitters(cell);
}
}
break;

case "cpRight":
var col = _columns - 1;

for (var row = 0; row < _tableIndex.length; row++) {
var cell = _tableIndex[row][col];
var newWidth = cell.getWidth() + diff;

if (newWidth > MIN_CELL_DIM) {
cell.setWidth(newWidth);
if (row == 0) resizeRowSpanners(diff, false);
}

updateSplitters(cell);
}
break;

case "cpTopRight":
case "cpBottomRight":
case "cpTopLeft":
case "cpBottomLeft":
var frac = diff / _columns;
var action = false;

for (var row = 0; row < _tableIndex.length; row++) {
for (var col = 0; col < _tableIndex[row].length; col++) {

var cell = _tableIndex[row][col];
var newWidth = cell.getWidth() + frac;

if (newWidth > MIN_CELL_DIM) {
action = true;
cell.setWidth(newWidth);

for (var cc = col + 1; cc < _tableIndex[row].length; cc++) {
var nCell = _tableIndex[row][cc];

var embShapes = _tblgroup.get("." + nCell.getName());

for (var i = 0; i < embShapes.length; i++) {
embShapes[i].move(frac, 0);
}
}
}

updateSplitters(cell);
}
}

if (action) {
createSpanners();
}
else {
if (anchorName != "cpBottomRight" && anchorName != "cpTopRight") {
_tblgroup.parent.move(diff, 0);
}
}

break;

default:
break;
}
}
}

exports.setHeight = function (val, anchor) {

var diff = val - exports.getHeight();

if (anchor) {
var anchorName = anchor.getName();

switch (anchorName) {

case "cpTop":

for (var row = 0; row < _tableIndex.length; row++) {
for (var col = 0; col < _tableIndex[row].length; col++) {
var cell = _tableIndex[row][col];

if (row == 0) {
var newHeight = cell.getHeight() + diff;

if (newHeight > MIN_CELL_DIM) {
cell.setHeight(newHeight);
if (col == 0) resizeColSpanners(diff, true);
}
else {
_tblgroup.parent.move(0, diff);
diff = 0;
}
}
else {
var embShapes = _tblgroup.get("." + cell.getName());

for (var i = 0; i < embShapes.length; i++) {
embShapes[i].move(0, diff);
}
}

updateSplitters(cell);
}
}
break;

case "cpBottom":
var row = _rows - 1;

for (var col = 0; col < _tableIndex[row].length; col++) {
var cell = _tableIndex[row][col];
var newHeight = cell.getHeight() + diff;

if (newHeight > MIN_CELL_DIM) {
cell.setHeight(newHeight);
if (col == 0) resizeColSpanners(diff, false);
}

updateSplitters(cell);
}
break;

case "cpBottomRight":
case "cpBottomLeft":
case "cpTopLeft":
case "cpTopRight":
var frac = diff / _rows;
var action = false;

for (var row = 0; row < _tableIndex.length; row++) {
for (var col = 0; col < _tableIndex[row].length; col++) {

var cell = _tableIndex[row][col];
var newHeight = cell.getHeight() + frac;

if (newHeight > MIN_CELL_DIM) {
action = true;
cell.setHeight(newHeight);

for (var rr = row + 1; rr < _tableIndex.length; rr++) {
var nCell = _tableIndex[rr][col];

var embShapes = _tblgroup.get("." + nCell.getName());

for (var i = 0; i < embShapes.length; i++) {
embShapes[i].move(0, frac);
}
}
}

updateSplitters(cell);
}
}

if (action) {
createSpanners();
}
else {
if (anchorName != "cpBottomLeft" && anchorName != "cpBottomRight") {
_tblgroup.parent.move(0, diff);
}
}

break;

default:
break;
}
}
}

exports.deSelect = function () {
exports.selectedCell.hide();
_stage.draw();
}

exports.select = function () {
exports.selectedCell.show();
_stage.draw();
}

function randomString() {
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
var string_length = 3;
var randomstring = '';

for (var i = 0; i < string_length; i++) {
var rnum = Math.floor(Math.random() * chars.length);
randomstring += chars.substring(rnum, rnum + 1);
}

return randomstring;
}

exports.checkTableIntersections = function(marquees, shape, core) {

if (core && core.shapeType == "Table") {
return;
}

for (var key in marquees) {
if (marquees.hasOwnProperty(key) && marquees[key].shape().shapeType == "Table") {
var tab = marquees[key].shape();

if (exports.areShapesOverlapping(shape, tab)) {
tab.addShape(shape);
}
else {
tab.removeShape(shape);
}
}
}
}

exports.areShapesOverlapping = function(shape1, shape2) {

var shape1Width = shape1.getWidth();
var shape1Height = shape1.getHeight();
var shape1X = shape1.getX() - shape1.getOffset().x;
var shape1XW = shape1X + shape1Width;
var shape1Y = shape1.getY() - shape1.getOffset().y;
var shape1YH = shape1Y + shape1Height;

var shape2Width = shape2.getWidth();
var shape2Height = shape2.getHeight();
var shape2X = shape2.getX() - shape2.getOffset().x;
var shape2XW = shape2X + shape2Width;
var shape2Y = shape2.getY() - shape2.getOffset().y;
var shape2YH = shape2Y + shape2Height;

// any part of shape on the table
if (((shape1X > shape2X && shape1X < shape2XW) || (shape2X > shape1X && shape2X < shape1XW)) &&
((shape1Y > shape2Y && shape1Y < shape2YH) || (shape2Y > shape1Y && shape2Y < shape1YH))) {
return true;
}
else {
return false;
}
}

exports.shapeType = "Table";
exports._id = randomString(3);
exports.selectedCell = null;

_rows = totalRows;
_columns = totalColumns;
_stage = stage;

init();

exports.parent = _tblgroup;
return exports;
}

var SelectedCell = function (cell, tblIndex) {
var exports = {};
var _selectedCell = cell;
var _tableIndex = tblIndex;

exports.getFill = function () {
if (_selectedCell) {
return _selectedCell.getFill();
}

if (_tableIndex) {
return _tableIndex[0][0].getFill();
}
}

exports.getStroke = function () {
if (_selectedCell) {
return _selectedCell.getStroke();
}

if (_tableIndex) {
return _tableIndex[0][0].getStroke();
}
}

exports.getStrokeWidth = function () {
if (_selectedCell) {
return _selectedCell.getStrokeWidth();
}

if (_tableIndex) {
return _tableIndex[0][0].getStrokeWidth();
}
}

exports.setFill = function (val) {
if (_selectedCell) {
_selectedCell.setFill(val);
return;
}

if (_tableIndex) {
for (var row = 0; row < _tableIndex.length; row++) {
for (var col = 0; col < _tableIndex[row].length; col++) {
_tableIndex[row][col].setFill(val);
}
}
}
}

/* Funtion to set stroke for selected table cell */
exports.setStroke = function (val) {
if (_selectedCell) {
_selectedCell.setStroke(val);

if (_selectedCell.vSplitters) {
for (var i = 0; i < _selectedCell.vSplitters.length; i++) {
_selectedCell.vSplitters[i].setStroke(val);
}
}

if (_selectedCell.hSplitters) {
for (var i = 0; i < _selectedCell.hSplitters.length; i++) {
_selectedCell.hSplitters[i].setStroke(val);
}
}
return;
}

if (_tableIndex) {
for (var row = 0; row < _tableIndex.length; row++) {
for (var col = 0; col < _tableIndex[row].length; col++) {
var cell = _tableIndex[row][col];
cell.setStroke(val);

if (cell.vSplitters) {
for (var i = 0; i < cell.vSplitters.length; i++) {
cell.vSplitters[i].setStroke(val);
}
}

if (cell.hSplitters) {
for (var i = 0; i < cell.hSplitters.length; i++) {
cell.hSplitters[i].setStroke(val);
}
}
}
}
}
}

exports.setStrokeWidth = function (val) {
if (_selectedCell) {
_selectedCell.setStrokeWidth(val);
return;
}

if (_tableIndex) {
for (var row = 0; row < _tableIndex.length; row++) {
for (var col = 0; col < _tableIndex[row].length; col++) {
_tableIndex[row][col].setStrokeWidth(val);
}
}
}
}

exports.sCell = function () {
return _selectedCell;
}

exports.show = function () {

if (_selectedCell) {

_selectedCell.setStrokeWidth(DEFAULT_CELL_STROKE_WIDTH * 4);
_selectedCell.setStroke(_selectedCell.getStroke());
}
else {

for (var row = 0; row < _tableIndex.length; row++) {
for (var col = 0; col < _tableIndex[row].length; col++) {
cl = _tableIndex[row][col];
cl.setStrokeWidth(DEFAULT_CELL_STROKE_WIDTH * 4);
cl.setStroke(cl.getStroke());
}
}
}
}

exports.hide = function () {

if (_selectedCell) {

_selectedCell.setStrokeWidth(DEFAULT_CELL_STROKE_WIDTH);
_selectedCell.setStroke(_selectedCell.getStroke());
}
else {

for (var row = 0; row < _tableIndex.length; row++) {
for (var col = 0; col < _tableIndex[row].length; col++) {
cl = _tableIndex[row][col];
cl.setStrokeWidth(DEFAULT_CELL_STROKE_WIDTH);
cl.setStroke(cl.getStroke());
}
}
}
}

return exports;
}

Tags:HTML5 Canvas, KineticJS on HTML5 Canvas, MS-Excel like Table, Table using KineticJS
How to Draw Grid on KineticJS Stage?
How to Save image Offline using HTML5 Local Storage?

Related Posts

  • Jquery Interview Questions and Answers for…
  • How to Create div based CSS3 Table without using…
  • HTML5 Canvas Examples to draw Circle, Rectangle,…
  • Frequently asked advanced HTML5 interview Questions…
  • How to drawimage on HTML5 Canvas using Scripting?
  • UI Developer Interview Questions for Experienced…
  • Example of Resume for IT professionals to get their…
  • Tips for Choosing Canvas Printing for your Business
  • Jquery Mobile Tutorial for Beginners with Examples
  • List of HTML5 new Tags introduced in 5th revision of HTML
  • Online free HTML Tutorial for beginners - Learn Web Design
  • Responsive Bootstrap grid system Tutorial with Examples
  • Advanced JavaScript Interview Questions and Answers
  • JQuery String Functions (Replace, Substr, IndexOf,…
  • Best way to learn JavaScript programming for beginners
  • Wordle Tips - How to Win more Often and Optimize…
  • Learn Bootstrap - Bootstrap Tutorial for absolute Beginners
  • Jquery AJAX Example for Load(), Get() and Post() methods
  • Example of Simple Responsive Jquery Range Slider…
  • How to Draw Grid on KineticJS Stage?
  • How to Export data from MySQL to Excel using PHP?
  • How to Draw Graphical Shapes using KineticJS?
  • How to Design a Database? - Database Design for Beginners
  • Proven Health Benefits of Playing Outdoor Games
  • Is CCA the Right Course for Non-IT Background Students?
On-page SEO booster,
Google Friendly,
XML based
PHP/WP Sidebar
FREE Widgets
demo

Popular Categories

  • Miscellaneous589
  • Digitalization298
  • Career Guide244
  • Indian Blog207
  • Business Book177
  • Health & Wellness168
  • Travel & Tourism132
  • Your Financial Advisor120
  • Real Estate Consulting111
  • Shopping97
  • Digital Marketing78
  • Blogging Techniques78
  • Home Remedies70
  • SEO Techniques67
  • Programming62
  • Automobiles57
  • Fashion & Fantacy53
  • Easy Recipes52

Our Popular Links

BootStrap Dropdown list with Checkbox Selected values will Show
Cheapest Cloud Hosting Services for Node.js Applications
How to keep Mashed Potatoes Warm all Dinner Long?
List of Linux Website Hosting Companies
Cheapest Hosting Plans for Joomla Blogs
Linux, PHP, MySQL Hosting Solutions for Freelancers
Hosting Plans for Large Enterprise Websites
Vitamin K Is the Ingredient Said to Fade Dark Circles – Does it Work?
Hosting Limitations for Shared Servers
Why I will Choose VPS Hosting for Game Applications?
SSD Storage Hosting Services with High-Speed MySQL Servers
40 lifelong SEO backlinks (tire 1 + tire 2)
Google friendly multi-niche Blog accepting Guest Posting
Page Speed Optimization Services with FCP, LCP, CLS or image Optimization

i20 Sidebar Widgets

How to Cook delicious parwal vegetable korma recipe?
How to Cook delicious Parwal Vegetable Korma Recipe?
Pointed Gourd is the English name of Parwal (in Hindi). Parwal vegetable korma recipe is one of my Favorite dish. This is a popular Oriya...
Is Frozen Crab as Good as Fresh?
Is Frozen Crab as Good as Fresh?
Crab is a beloved seafood delicacy known for its sweet, tender meat and versatility in various dishes. But when it comes to choosing between fresh...
Peanut Milk to Ice Cream toppings 5 delicious Ways to enjoy Peanuts
Peanut Milk to Ice Cream toppings 5 delicious Ways to enjoy Peanuts
One of the most versatile nuts around, the humble but reliable peanut can be enjoyed in a variety of ways, with the most popular being...
Cooking Tips to prepare Delicious Chinese Chilli Mushroom
Cooking Tips to prepare Delicious Chinese Chilli Mushroom
Chilli Mushroom is an Indo-Chiness recipe. Chilli Mushroom can 2 types Dry or Gravy. We like to eat Chilli Mushroom with butter naan, roti or...
Cooking tips for Hyderabadi Chicken Biryani Recipe
Cooking tips for Hyderabadi Chicken Biryani Recipe
Among many royal recipes Chicken Biryani is the Queen. This is a Muslims recipe. In India Chicken Biryani recipe is more popular at Hyderabad. I...
9 Finger Foods for your reference which Go well with Gin
9 Finger Foods for your reference which Go well with Gin
The demand for gin in Australia is growing, and distillers respond by creating distinct flavours using local ingredients. Australia has long been known for its...

Our Web2 Blogs

Home Remedies
SEO Guest Posting
Digital Marketing
Learn Digital Marketing
Guest Posting Services
Blog for Bloggers
SEO Blog
Blog for Tourism

New Releases

Beyond the Mirror: The Rise of Preventive Skincare in Modern Wellness
October 13, 2025

Beyond the Mirror: The Rise of Preventive Skincare in Modern Wellness

Skin health has moved beyond beauty counters and spa menus to become a central pillar of wellness culture, right alongside nutrition, exercise, and mental balance….

YouTube Advertising Advantages, Limitations and best Practices
July 12, 2025
YouTube Advertising Advantages, Limitations and best Practices
b2b Email Marketing jobs and ZOHO Campaigns for professionals
July 7, 2025
b2b Email Marketing jobs and ZOHO Campaigns for professionals
YouTube Marketing Techniques to minimize Advertising Costs
July 2, 2025
YouTube Marketing Techniques to minimize Advertising Costs
Natural Hair Plantation for Women of any Age no Surgery
July 1, 2025
Natural Hair Plantation for Women of any Age with no Surgery
Eyeliner for Hooded Eyes to apply before applying Eyeshadow
July 1, 2025
Eyeliner for Hooded Eyes to apply before applying Eyeshadow
Comparing Paid and Free Website Builder for Small Business
July 1, 2025
Comparing Paid and Free Website Builder for Small Business
Google Search Console for SEO Tools for every Webmaster
July 1, 2025
Google Search Console for SEO Tools for every Webmaster
Digital Marketing Guest Post best practices to boost Sales
July 1, 2025
Digital Marketing Guest Post best practices to boost Sales
Deep Stretch Marks on Thighs and Belly during Pregnancy
June 26, 2025
Deep Stretch Marks on Thighs and Belly areas during Pregnancy
Fade Pregnancy Stretch Marks appear as Streaks or Lines on the Skin
June 26, 2025
Fade Pregnancy Stretch Marks appear as Streaks or Lines on the Skin
The best Guest Posting Website to boost your Online Presence
June 26, 2025
The best Guest Posting Website to boost your Online Presence
Digital Marketing Firms for Startup WordPress Blogs
June 25, 2025
Hi-Tech Digital Marketing Firms for Startup WordPress Blogs
Best Foods and 7 Day Diet Plan for Weight Loss help for Housewives
June 25, 2025
Prescribed Best Foods with 7 Day Diet Plan for Weight Loss Journey
Advanced Stage 3 Breast Cancer in Men and Women
June 25, 2025
Advanced Stage 3 Breast Cancer in Men and Women but Treatable
Explain Digital Marketing to Content Marketers for Leads
June 25, 2025
Explain Digital Marketing to Content Marketers for Sales Leads
Best Digital Marketing Agencies to boost AdSense Earning
June 24, 2025
Best Digital Marketing Agencies to boost AdSense Earning
Termites in House? Pest Control Services to Save Damage
June 24, 2025
Termites in House? Pest Control Services to Save Damage
explore us...

Our Facebook Groups

Paid Guest Posting Services with lifelong Links

SEO Backlinks, Guest Posting, Link Insertion plus Link Exchange hub

Instant Guest Posting Services with lifelong Do-Follow links

Guest Posting SEO Services with High DA aged Domains

Free or Paid Guest Posting Service in India | UK | USA

Free Guest Posting, Link exchange, SEO, SEM, PBN links, web2 links

Cheap Guest Posting Services with high Authority Blogs

OUR FACILITIES

  • Login
  • Our Background
  • Privacy
  • WordPress.org

CONTACT INFO

  • Reach us
  • WhatsApp 919096266548

OUR SERVICES

  • Blog Posting Opportunity
  • *.fig, *.psd 2 html
  • Video Ads Designing
  • Setup your WordPress Blog
  • Optimizing Google PageSpeed
  • b2b Gmail IDs

WHY ONESTOP?

We are here to bring high Quality Information. As a multi-niche platform we have spend several years for Collecting various useful Stories. Dream to establish a domain where from you can get all your day today required information. We covers Animals to Zoology.
©2014-2025 JHARAPHULA, ALL RIGHTS RESERVED.