• 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?
4 5 82

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

  • How to Create div based CSS3 Table without using…
  • How to Draw Graphical Shapes using KineticJS?
  • How to Draw Arrow Head Line using KineticJS?
  • How to Design a Database? - Database Design for Beginners
  • Learn Bootstrap - Bootstrap Tutorial for absolute Beginners
  • Using XMLHttpRequest How to Bind Data from XML to…
  • Metric Conversion Table - Standard Measurement Units
  • How to Draw Line using Mouse in KineticJS?
  • How to display data from JSON to HTML table using PHP?
  • How to export Data from SQL tables to a Excel file…
  • How to Create ASP.NET inline Table using data from a…
  • Beautiful Study Tables which you can buy from Urban Ladder
  • How to Open JQuery Modal Popup with disabled Parent Window?
  • How to Draw Grid on KineticJS Stage?
  • HTML5 Table Sorting and Pagination using AngularJS
  • How to Display JSON Data in a Table using AngularJS?
  • How Connected Line will move with the Shape using KineticJS?
  • Picnic Table Covers Finest additions to your…
  • Online free HTML Tutorial for beginners - Learn Web Design
  • Project Estimation Techniques for Software…
  • Extendable Dining Tables - A blend of Functionality…
  • SqlDataReader to DataSet Converter VB.NET Function
  • Responsive Bootstrap grid system Tutorial with Examples
  • How to export DataTable to Excel file using VB.NET?
  • List of frequently used common SQL Queries with Example
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

Reduce the Distance by Sending Flowers to your Lover
Reduce the Distance by Sending Flowers to your Lover
When we fall in love we often go through hardships of being away from each other. For some the hardships are of the family, for...
An American Honeymoon - Popular Destination for Honeymooners
An American Honeymoon – Popular Destination for Honeymooners
The USA is a popular destination for honeymooners from all over the world, and with so many different and wonderful locations to visit as a...
Most Memorable best Honeymoon destinations of Incredible India
12 Most Memorable best Honeymoon Destinations of Incredible India
Environment effects Honeymoon. To have a successful honeymoon trip geography matters. Many newly married couples work hard to find out a best Honeymoon destinations. Honeymoon...
What to get my boyfriend for Valentines Day? - Gift ideas for him
What to get my boyfriend for Valentines Day? – Gift ideas for him
As Valentine’s Day is approaching, you might be perplexed with the thought “what do I gift my boyfriend?” There is abundance of chocolates, cards, flowers,...
Flower Power - Creative Ways to Surprise your Valentine with Blooms
Flower Power – Creative Ways to Surprise your Valentine with Blooms
Valentine’s Day is just around the corner, and what better way to express your love than with a beautiful bouquet of flowers? Flowers have long...
Sаvе thе rеlаtiоnѕhiр 5 Rеаѕоnѕ tо gо for Cоuрlеѕ Counseling
Sаvе thе rеlаtiоnѕhiр 5 Rеаѕоnѕ tо gо for Cоuрlеѕ Counseling
Marriages are made in hеаvеn; hоwеvеr some соuрlеѕ might find it fоrgеd аѕ thеу have tо bеаr ѕеvеrаl mеntаl аnd physical рrоblеmѕ related tо their...

Our Web2 Blogs

Home Remedies
SEO Guest Posting
Digital Marketing
Learn Digital Marketing
Publishing Services
Guest Posting Services
Blog for Bloggers
OneStop Shop

New Releases

YouTube Advertising Advantages, Limitations and best Practices
July 12, 2025

YouTube Advertising Advantages, Limitations and best Practices

YouTube has become one of the most influential digital platforms for advertising, offering businesses a dynamic way to reach global audiences. With billions of users…

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
ICICI Bank Vehicle Loan for newly Opened Transportation Agencies
June 24, 2025
ICICI Bank Vehicle Loan for newly Opened Transportation Agencies
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.