oc.WidgetInterface is a javascript class which goal is to help to create an iGoogle's like interface
- To do that, the "class" manages a list of rows, each row being able to have any number of
columns, each column having any number of cells.
- A
cell
is composed of a widget (your html code) with an handle which permits to move
the widget through all the rows/columns generated
- When the structure is defined, each widget can be moved from any column to an other column,
the widget adapting itself to the length of the column targeted.
- Added to the multi-row capacities, the other originality of this class is to provide the ability
to create columns of differents widths
There is 2 mode of visualisation:
- A normal mode, where the only visible objects are the
widgets
- An extended mode, where the row and column have also an handle which help to the construction of your page
Normal mode |
Extended mode |
|
|
Note: the css class cell
is composed of an handle (editCell
) and the widget itself (contentCell
).
A reference to jQuery scripts is needed in your html page:
script src="jquery-1.7.2.js"
script src="jquery-ui-1.8.18.custom.min.js"
Creation and initialization of an instance of the "class"
var wI = new oc.WidgetInterface(
"tout",
{cellColor: "#AFAEEE", columnColor : "#FFEFFF", rowColor : "#EEFFFF", marge : 6, radius : "true"}
);
wI.initClassesEvents();
oc.WidgetInterface(id, listOfOptions):
- id : id of the element containing the
iGoogle's like interface
(in my example a div with an id="tout")
- listOfOptions : all the default options that you want to change
List of the options (and default value) that can be change at initialization:
marge : 4,
dimHiddenSelector : 20,
dimCellSelector : 24,
rowColor : "#F77000",
columnColor : "#8F000A",
cellColor : "#0002ED",
noDragColor : "grey",
theRefresh : undefined,
onCellCollapse : undefined,
onSelected : undefined, (v1.1)
postfix : "",
radius : false (v1.4)
Note that the program use fade colors of the 3 original colors.
If you want to keep this functionality, you can't use names colors like red, green...
onCellCollapse(contentCell, collapsed) is a function called after you try to collapses or expand a widget:
- contentCell : the current jQuery element concerned by the action
- collapsed : (boolean) true if collapsed, false if expanded
onSelected(elementSelected) is a function called after a click event on a cell (widget), column or row
(elementSelected is undefined if you delete the last row)
radius : for IE, radius is taken into account only if the version is 9 or upper.
To avoid IE to act like a lower version, don't forget to use
<meta http-equiv="X-UA-Compatible" content="IE=edge">
Tip: if you use the option radius:"true"
, the class cell
has no border. If not, there is a default border of 2px.
You can always overload the css class, but with the radius option at "true", don't add border but use 2 differents background color for
the body and the class contentCell
(like I did in this web site)
In standard mode (99%), the reading of this section is unnecessary
A part of the main css classes names used by oc.widgetInterface can also be renamed (see attached list; by default, selected = "selected" ...)
You can rename these classes if you want to use your own class names, but to do this is only necessary
if you want to use an instance of oc.WidgetInterface inside
another one !
In older version of this web site, this page was build like that :
the first instance has 2 columns ( one for the menu and one for the content),
the right column was constructed with another instance of oc.WidgetInterface
In this case, the 6 options that you have to change are: rowSelector, columnSelector, cellSelector, cell, contentCell, editCell
|
CSS default classes names
selected
rowSelector
editRow
columnSelector
editColumn
cellSelector
cell
editCell
contentCell
|
To do that, you can
- Initialize a postfix at the creation of the class. Example:
widgetI2 = new oc.WidgetInterface("tout2", { postfix: "2" });
- This solution has the same result than redefining all the classes names like that:
widgetI2 = new oc.WidgetInterface("tout2", {
rowSelector : "rowSelector2",
columnSelector : "columnSelector2",
cellSelector : "cellSelector2",
cell: "cell2",
contentCell:"contentCell2",
editCell:"editCell2"
});
If widgetA and widgetB are 2 instances of oc.WidgetInterface and widgetB is used inside widgetA,
to collapse an element of widgetB change the widgetB height, and by consequence, the height of widgetA too.
There is a function theRefresh() called on the collapse event, that you have to define in this case,
to force the refresh.
Example :
var widgetA = new oc.WidgetInterface("id1", { marge: 6 });
...
var widgetB = new oc.WidgetInterface("id2", { marge: 6 , postfix: "2",
theRefresh: function() { widgetA.resizeAll(); }
});
...
A widget is contained in a cell (cellSelector
), itself contained in a column (columnSelector
),
itself contained in a row (rowSelector
)
A click on one of these 3 kind of items adds the class selected
to the selected item.
Only one html item can have the selected
class.
So, to generate a widget, we have to create a row, a column and then the cell that contains the widget.
There are 4 public methods to build our page of widgets:
addRowColumn( start, canRemove, canMove)
addRow ( start, canRemove, canMove)
addColumn ( start, canRemove, canMove)
addCell (widgetId, widgetTitle, widgetHtml, start, canRemove, canMove, handleState)
Common parameters : (all these parameters have a default value)
About canRemove and canMove:
- x cannot be removed ==> x.parent() cannot be removed ...
- if a cell (widget) has canRemove to false, the column which contains the widget cannot be removed
- if a column cannot be removed, the row which contains the column cannot also be removed
- x cannot be moved ==> x.children() cannot be moved ...
- if a row has canMove to false, the row cannot be moved and all the elements inside cannot be moved also
- if a column has canMove to false, the column cannot be moved and all the elements (cells/widgets) inside cannot also be moved
Other parameters:
-
addCell(elt, title, htmlCode, start, canRemove, canMove, handleStatus):
- elt : a value added as an attribute of the div that contains the widget (elt="...").
The next chapter explains the goal of this parameter.
- title : caption shown in the handle of the widget
- htmlCode : code of the cell
Optional parameters:
- start : the target where is added the widget
...
- If start is a column, the widget is add at the last position of the column
- If start is a row, the widget is add at the last position of the first column of the row
- If start is a cell (widget), the new widget is add at the end of the column of the cell.
- If start is undefined, start becomes the html component which contains the
selected
class...
- handleStatus : "none" (no handle), "down" (the widget is collapsed), "up" ("up" is the default value if undefined)
- canRemove/canMove : see
Common parameters
-
addColumn(start, canRemove, canMove):
Optional parameters:
- start : the target where is added the column
...
- If start is a row, a new column is added to the row
- If start is a column, a column is added after it
- If start is a cell (widget), a column is added after the parent column of this cell.
- If start is undefined, start becomes the html component which contains the
selected
class...
- canRemove/canMove : see
Common parameters
-
addRow(start, canRemove, canMove)
Optional parameters:
- start : the target after which is added the row
...
- If start is a row, a new row is added just after it
- If start is a column, a new row is added after the row which contains the column
- If start is a cell (widget), a new row is added after the row which contains the cell.
- If start is undefined, start becomes the html component which contains the
selected
class... (or the first row if the structure is empty).
- canRemove/canMove : see
Common parameters
-
addRowColumn(start, canRemove, canMove)
Same thing than addRow, but automatically adds a column to the new row
(a cell must be in a column, a column must be in a row)
Example:
var l = wI.addRowColumn();
// jQuery search of the column created :
// (note: new row means new first column, so the jQuery ":first" selector is useless)
var c = l.find(".columnSelector");
var e = wI.addCell("x", "new widget", "Hello World !", c);
or (after reading the "..." section of addCell())
var l = wI.addRowColumn();
var e = wI.addCell("x", "new widget", "hello !", l);
Since version 1.1 - 1.2, there is 2 new functions
insertCellBefore(widgetId, widgetTitle, widgetHtml, cellTarget, canRemove, canMove, handleState)
insertCellAt (widgetId, widgetTitle, widgetHtml, columnTarget, cellPosition, canRemove, canMove, handleState)
- insertCellBefore(...) needs to know the jQuery element of class
cellSelector
(cellTarget)
before the new widget has to be inserted
- insertCellAt(...) needs to know the jQuery element of class
columnSelector
(columnTarget)
where the new widget must be insert in the cellPosition
(if cellPosition doesn't exist, the new element is the last element of the column)
elt
is important if you want dynamically build a page from a stored structure (loaded from a cookie by example).
All the structure (rows, columns and cell/widget positions) can be saved in a json format, returned by the
save() function
var json = wI.save();
However, the widget itself is not stored in the json, but the attribute
elt
does.
So if each widget that you can create is associated to an unique elt (an id !), you will be able to rebuild your page!
The best way to rebuild the page is to use the load() function
wI.load(json, getTitle, getHtmlCode);
-
load(json, getTitle, getHtmlCode):
- json: the json structure (got from a cookie, for example)
- getTitle() : an user function. It must have one parameter, which will be replace by the
elt
found in the json structure, and has to return a string used to build the caption widget
- getHtmlCode() : an user function. It must have one parameter, which will be replace by the
elt
found in the json structure, and has to return a string used to build the widget itself
- advancedMode(booleanValue)
- resizeAll()
- resize(...) ... see the
tips
section
- resize(etalon)
- deleteRow(target)
- deleteColumn(target)
- deleteCell(target)
- defineWidthColumns(theRow, arrayOfWidths)
...
you can merge % et px widths !!
The percents sizes are calculated from the total size less the fixed sizes.
Example:
var l = wI.addRowColumn();
wI.addColumn(l);
wI.addColumn(l);
wI.defineWidthColumns(
l,
new Array("612px","50%","50%")
);
See the section
advanced mode
which permits to do the same thing...
- save()
- load(jsonStr, fctTitle, fctContent)
-
resize(idCalibrator)
Version 1.1:
If the surface which contains the interface can change (size in %), the instance of oc.WidgetInterface must recalc the sizes.
The simplest way to do that is to attach an event "on resize" to the window and to call the method resizeAll().
Unfortunatly, I have experimented some problems with IE.
To solve them, you must use a div which will always have the same width that the interface ...
<div id="forCalibration" width="100%"></div>
<div id="myInterface" width="100%"></div>
... and compare after resize than the 2 elements have really the same size.
With the 1.2 version, I simplificate the action with the resize() method.
Here is the code you need to had at your sript to resolve the problem.
Note that resize() fix also a bug (firefox and chrome) when the zoom was used.
var widgetI = new oc.WidgetInterface("myInterface");
...
function myResize() {
widgetI.resize("forCalibration");
}
jQuery(window).on("resize", myResize);
myResize();
When you call initClassesEvents() , oc.WidgetInterface initialize all the events and the css classes
needed for the proper functioning of the JavaScript class.
There is 2 css styles generated dynamically on the head of the document, before all the other styles which can exist
Keep in mind that all the dimension etc... are calculated by the javascript class
so you cannot modified the width, marge, spacing... of the classes which are created by oc.WidgetInterface
However, some attributes like colors can be updated. They are created in the section style oc='editable' .
|
Firebug screenshot:
|
You can read these definitions using for example firebug (screenshot), but you can also (v1.3) use the two functions bellow during the debuging of your page:
widgetI.getCssNotEditable();
widgetI.getCssEditable();
This is what I did in the 2 buttons upper (try them!)
Note that 90% of the css classes are based on six options, that you can change at the call of the constructor:
- marge : used to calculate the distance in pixel between 2 cells (the real distance used is 3*marge)
- dimHiddenSelector : the default height of the handle of the column selector,
and also the default width of the handle of the row selector (which appears in "advanced mode").
You can't use a value less at 20 (px)
- dimCellSelector : the default height of the handle of the cell/widget.
You can't use a value less at 24 (px)
- elementColor : the default color for the handle of the cell/widget
- columnColor : the default color for the handle of the column selector, which appears in "advanced mode"
- rowColor : the default color for the handle of the row selector, which appears in "advanced mode"
There are 6 other colors that are calculated as gradiant of the 3 firsts configurable colors:
they are used when a cell, column or row (classes: cellSelector
, columnSelector
and rowSelector
) has also the class dragOverDrop
or selected
- When you drag a widget/cell over an droppable element (cell/column/row), the droppable element gets the
class dragOverDrop
- When you click on an element (cell/column/row), the selected element gets the
class selected
Here is a screen shot of a personalization example (in my example, "tout" is the id of the div
where oc.WidgetInterface works)
In
advanced mode
, you can directly write the widths like "100px" or "50%".
To confirm the sizes, you have to click in the apply
button ,
just under the remove
button of the line
TIPS: If you have 2 columns, by default the sizes are 50% and 50%.
If you enter the values 70% and 50% and if you choose to apply them, the second column will disapear.
Don't panic ! Just add a new column : the sizes will be recalculated, and the column will reappear
(try to do it on the example)
Remember that you can merge % et px widths !! The percents sizes are calculated from the total size less the fixed sizes.
(see defineWidthColumns
)