Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
E
ecommerce-ui
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
ecommerce-ui
Commits
c56accc9
Commit
c56accc9
authored
Nov 06, 2013
by
Sven Franck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rewrite factory to handle widgets, gadgets, elements
parent
e1636c58
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
1286 additions
and
881 deletions
+1286
-881
js/erp5_loader.js
js/erp5_loader.js
+1286
-881
No files found.
js/erp5_loader.js
View file @
c56accc9
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
// ERP5 custom methods
// ERP5 custom methods
var
erp5
=
{};
var
erp5
=
{};
// JQM content
gen
erator
// JQM content
erate
erator
var
factory
=
{};
var
factory
=
{};
/* ====================================================================== */
/* ====================================================================== */
...
@@ -272,8 +272,8 @@
...
@@ -272,8 +272,8 @@
// NOTE: method must be present or added to validation handler
// NOTE: method must be present or added to validation handler
if
(
prevail
.
properties
.
external_validator
||
if
(
prevail
.
properties
.
external_validator
||
spec
.
properties
.
external_validator
)
{
spec
.
properties
.
external_validator
)
{
validation_list
+=
prevail
.
properties
.
external_validator
||
validation_list
+=
(
prevail
.
properties
.
external_validator
||
spec
.
properties
.
external_validator
;
spec
.
properties
.
external_validator
)
;
}
}
// required
// required
...
@@ -600,7 +600,7 @@
...
@@ -600,7 +600,7 @@
/* ====================================================================== */
/* ====================================================================== */
/* ********************************************************************** */
/* ********************************************************************** */
/*
"mapping to erp5"
*/
/*
Factory Mappings (to ERP5)
*/
/* ********************************************************************** */
/* ********************************************************************** */
factory
.
map_buttons
=
erp5
.
map_buttons
;
factory
.
map_buttons
=
erp5
.
map_buttons
;
factory
.
map_actions
=
erp5
.
map_actions
;
factory
.
map_actions
=
erp5
.
map_actions
;
...
@@ -608,923 +608,1403 @@
...
@@ -608,923 +608,1403 @@
factory
.
map_utils
=
erp5
.
map_utils
;
factory
.
map_utils
=
erp5
.
map_utils
;
/* ********************************************************************** */
/* ********************************************************************** */
/*
JQM "Bar"
*/
/*
Factory Utils
*/
/* ********************************************************************** */
/* ********************************************************************** */
factory
.
util
=
{};
/*
/*
* Generate a generic bar (table wrapper, controlbar, collapsible header)
* Forward to factory generator depending on "generate". This method will
* @method generateToolbar
* handle generation of elements, widgets (and gadgets?)
* @param {object} config Elements to add to the bar
* @method forward
* @param {boolean} slot Wrap element in a slot container
* @param {object} spec Configuration object for the element to be created
* @param {string} reference Gadget reference pointer
* @return {object} HTML object containing generated elements
* @returns {array} HTML fragment and flag for popups to be created
*/
*/
factory
.
generateToolbar
=
function
(
elements
,
slot
,
reference
)
{
factory
.
util
.
forward
=
function
(
spec
)
{
var
element
,
switch
(
spec
.
generate
)
{
m
,
// widget generator
n
,
case
"
widget
"
:
o
,
return
factory
[
"
generate
"
+
spec
.
type
](
spec
);
item
,
break
;
trigger_element
,
// gadget generator
target
,
case
"
gadget
"
:
include
,
wrapped_in_slot
,
add_to_first
,
flag
=
{},
config
=
{},
container
=
document
.
createDocumentFragment
();
if
(
slot
)
{
break
;
wrapped_in_slot
=
true
;
// HTML element generator (case "undefined")
default
:
switch
(
spec
.
type
)
{
case
"
input
"
:
case
"
select
"
:
return
factory
.
generateFormElement
(
spec
,
false
);
break
;
default
:
return
factory
.
generateElement
(
spec
.
type
,
spec
.
direct
,
spec
.
attributes
,
spec
.
logic
);
break
;
}
break
;
}
}
};
// loop functionalities
/*
for
(
m
=
0
;
m
<
elements
.
length
;
m
+=
1
)
{
* Loop over a selection of elements and generate the respective content
element
=
elements
[
m
];
* @method generateFromArray
if
(
wrapped_in_slot
)
{
* @param {array} spec Array containing the elements to generate
target
=
factory
.
generateElement
(
* @param {string} type Requesting widget
"
div
"
,
{},
{
"
data-slot
"
:
true
,
"
data-slot-id
"
:
element
.
slot
}
* @param {object} hack
);
* @return {object} fragment HTML object containing the elements
}
else
{
*/
target
=
container
;
// TODO: refactor. Remove hack!!!!
}
// NOTE: this can only handle fully described elements in an array (no li!)
factory
.
util
.
generateFromArray
=
function
(
spec
,
type
,
hack
)
{
var
i
,
target
,
class_list
,
element
,
order
,
fragment
=
document
.
createDocumentFragment
();
trigger_element
=
element
.
element
||
element
.
widget
;
for
(
i
=
0
;
i
<
spec
.
length
;
i
+=
1
)
{
// TODO: don't set in every case (because of controlgroup);
element
=
spec
[
i
];
target
=
undefined
;
switch
(
trigger_element
.
type
)
{
// class string
case
"
input
"
:
if
(
element
.
direct
)
{
case
"
select
"
:
order
=
i
===
0
?
"
ui-first-child
"
:
trigger_element
.
attributes
[
"
data-reference
"
]
=
reference
;
(
i
===
(
spec
.
length
-
1
)
?
"
ui-last-child
"
:
"
"
);
target
.
appendChild
(
factory
.
generateFormElement
(
trigger_element
,
false
)
element
.
direct
.
className
=
(
element
.
direct
.
className
||
""
)
+
order
+
(
element
.
type
===
"
a
"
?
(
"
ui-btn ui-shadow
"
+
factory
.
generateIconClassString
(
element
))
:
"
"
);
}
switch
(
type
)
{
case
"
panel
"
:
// TODO: refactor panel_element CSS!
target
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
panel_element
"
+
(
i
===
0
?
"
panel_element_first panel_header
"
:
((
i
===
spec
.
length
-
1
)
?
"
panel_element_last
"
:
"
"
))
}
);
);
break
;
// HACK: this adds the panel close button, don't do this here!
case
"
controlgroup
"
:
if
(
i
===
0
&&
hack
)
{
for
(
o
=
0
;
o
<
element
.
children
.
length
;
o
+=
1
)
{
target
.
appendChild
(
hack
);
element
.
children
[
o
].
attributes
[
"
data-reference
"
]
=
reference
;
}
}
target
.
appendChild
(
factory
.
generateControlgroup
({
"
type
"
:
"
controlgroup
"
,
"
direction
"
:
trigger_element
.
direction
,
"
class
"
:
trigger_element
.
widget_class
,
"
buttons
"
:
element
.
children
}));
break
;
break
;
default
:
case
"
navbar
"
:
trigger_element
.
attributes
[
"
data-reference
"
]
=
reference
;
target
=
factory
.
generateElement
(
target
.
appendChild
(
factory
.
generateElement
(
"
li
"
,
trigger_element
.
type
,
{
"
className
"
:
"
ui-block-
"
+
util
.
toLetters
(
i
+
1
).
toLowerCase
()}
trigger_element
.
direct
,
);
(
trigger_element
.
attributes
),
(
trigger_element
.
logic
)
));
break
;
break
;
case
"
header
"
:
// TODO: mercy, refactor!
if
(
spec
.
length
>
1
&&
i
!==
1
)
{
target
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
ui-
"
+
((
i
===
0
?
"
first
"
:
(
i
===
2
?
"
last
"
:
"
no
"
))
+
"
-wrap
"
)
}
);
}
};
};
// generate with/without wrapper
// TODO: do differently...
if
(
target
)
{
if
(
element
.
global_popup
)
{
target
.
appendChild
(
factory
.
util
.
forward
(
element
));
flag
.
global_popup
=
true
;
fragment
.
appendChild
(
target
);
}
if
(
element
.
local_popup
)
{
flag
.
local_popup
=
true
;
}
if
(
wrapped_in_slot
)
{
container
.
appendChild
(
target
);
}
else
{
}
else
{
container
=
target
;
fragment
.
appendChild
(
factory
.
util
.
forward
(
element
))
;
}
}
}
}
return
[
container
,
flag
];
return
fragment
;
};
/**
* Generate a form wrapper
* @method wrapInForm
* @param {object} spec Configuration
* @return {object} form object of fragment
*/
factory
.
util
.
wrapInForm
=
function
(
id
)
{
if
(
id
)
{
return
factory
.
generateElement
(
"
form
"
,
{
"
method
"
:
"
POST
"
,
"
action
"
:
"
#
"
,
"
id
"
:
id
},
{
"
data-ajax
"
:
false
}
);
}
return
document
.
createDocumentFragment
();
};
};
/* ********************************************************************** */
/* ********************************************************************** */
/* JQM Page */
/* Factory Methods */
/* ********************************************************************** */
/* ********************************************************************** */
/* JQM POPUP */
/* ********************************************************************** */
/* ********************************************************************** */
/**
/**
* Generate an empty JQM page
* Generate a pre-enhanced popup and necessary elements
* @method generatePage
* Full options (with defaults)
* @param {object} config Config object based on parsed link
* {
* @param {object} layout Layout for the page to generate
* "generate": "widget",
* @return {object} HTML fragment
* "type":"popup",
*/
* "class_list": "",
// NOTE: we are defaulting to fixed toolbars!
* "theme": "",
factory
.
generatePage
=
function
(
config
,
layout
)
{
* "id": null,
var
page
=
factory
.
generateElement
(
* "property_dict": {
"
div
"
,
* "overlay-theme": null,
{
* "transition": "fade",
"
id
"
:
config
.
id
,
* "position-to": "window",
"
className
"
:
"
ui-page
"
+
(
"
ui-page-theme-
"
+
layout
.
theme
||
""
)
+
* "tolerance": "30,30,30,30",
"
"
+
((
layout
.
fix
&&
layout
.
fix
===
false
)
?
""
:
* "shadow": true
"
ui-page-header-fixed ui-page-footer-fixed
"
)
* },
},
{
* "form": null,
"
data-module
"
:
config
.
id
,
* "children": [],
"
data-role
"
:
"
page
"
,
* }
"
data-url
"
:
config
.
url
,
* @method generatePopup
"
data-external-page
"
:
true
,
* @param {object} spec JSON configuration for popup to be generated
"
tabindex
"
:
0
,
* @param {string} scope id of page to append popup
"
data-enhanced
"
:
true
* @return {object} documentFragment (global)/placeholder element (local)
*/
// TODO: missing state
// TODO: generate without referencing IDs
// NOTE: scope (element id) will make the popup local
factory
.
generatePopup
=
function
(
spec
,
scope
)
{
var
target
,
popup
,
wrap
,
id
,
config
,
container
,
placeholder
;
if
(
spec
===
undefined
)
{
util
.
errorHandler
({
"
error
"
:
"
GeneratePopup: Missing configuration
"
});
}
else
{
container
=
document
.
createDocumentFragment
();
config
=
spec
.
property_dict
||
{};
id
=
spec
.
id
||
(
scope
?
(
scope
+
"
-popup
"
)
:
"
global_popup
"
);
// container
container
.
appendChild
(
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
ui-popup-screen ui-screen-hidden
"
+
(
config
.
overlay_theme
?
(
"
ui-overlay-
"
+
config
.
overlay_theme
)
:
""
),
"
id
"
:
id
+
"
-screen
"
}
));
// popup wrapper
wrap
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
ui-popup-container ui-corner-all ui-popup-hidden
"
+
"
ui-popup-truncate
"
+
(
config
.
transition
||
"
fade
"
),
"
id
"
:
id
+
"
-popup
"
}
);
// popup
popup
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
ui-popup ui-body-
"
+
spec
.
theme
+
(
config
.
shadow
?
"
ui-overlay-shadow
"
:
"
"
)
+
"
ui-corner-all
"
+
spec
.
class_list
,
"
id
"
:
id
},
{
"
data-transition
"
:
config
.
transition
||
"
fade
"
,
"
data-role
"
:
"
popup
"
,
"
data-enhanced
"
:
"
true
"
,
"
data-position-to
"
:
config
.
position
||
"
window
"
,
"
data-tolerance
"
:
config
.
tolerance
||
"
30,30,30,30
"
},
{
"
data-theme
"
:
spec
.
theme
||
null
,
"
data-overlay-theme
"
:
config
.
overlay_theme
||
null
}
);
// placeholder
placeholder
=
factory
.
generateElement
(
"
div
"
,
{
"
id
"
:
id
+
"
-placeholder
"
},
{
"
style
"
:
"
display:none;
"
}
);
// form
target
=
factory
.
util
.
wrapInForm
(
spec
.
form
);
// children/action buttons
if
(
spec
.
children
)
{
popup
.
appendChild
(
factory
.
util
.
generateFromArray
(
spec
.
children
,
"
popup
"
)
);
}
}
);
// set state
// assemble popup to target (form/fragment) to wrapper to container
target
.
appendChild
(
popup
);
wrap
.
appendChild
(
target
);
container
.
appendChild
(
wrap
);
return
page
;
// add to DOM if scoped
if
(
scope
)
{
document
.
getElementById
(
scope
).
appendChild
(
container
);
// and return the placeholder for JQM
return
placeholder
;
}
// also add placeholder to fragment
container
.
appendChild
(
placeholder
);
return
container
;
}
};
};
/* ********************************************************************** */
/* ********************************************************************** */
/*
JQM Table
*/
/*
JQM Header
*/
/* ********************************************************************** */
/* ********************************************************************** */
/*
/**
* Generates a table header based on configuration and portal_type
* Generates JQM header. Header buttons are wrapped in controlgroups!
* @method generateTableHeader
* Full options (with defaults)
* @param {object} settings Configuration for table to create
* {
* @param {object} fields Field configurations for this portal Type
* "generate": "widget",
* "type": "Header",
* "class_list": "",
* "theme": "",
* "id": null,
* "form": null,
* "property_dict": {
* "title": "",
* "title_i18n":"",
* "fixed": true
* },
* "children": [],
* }
* @method generateHeader
* @param {object} spec JSON configuration
* @param {string} scope Id of page header should be appended to
* @return {object} HTML fragment
*/
*/
// TODO: single row ok. multi row to make
// NOTE: Logos should be added as children of the header!
factory
.
generateTableHeader
=
function
(
settings
,
fields
)
{
// NOTE: page title set in pagehandler, this only sets a placeholder
var
k
,
factory
.
generateHeader
=
function
(
spec
,
scope
)
{
l
,
var
config
,
id
,
title
,
wrap
,
position
,
children
,
header
,
target
;
cell
,
field
,
config
,
field_config
,
property
,
keys
,
title
,
set
,
text
,
action
,
temp
=
{},
link
=
undefined
,
check
=
settings
.
configuration
.
table
.
checkbox_rows
,
merger
=
settings
.
configuration
.
table
.
mergeable_columns
,
target
=
settings
.
layout
[
0
].
columns
,
table_header
=
factory
.
generateElement
(
"
thead
"
),
row
=
factory
.
generateElement
(
"
tr
"
);
// tickbox - all
if
(
check
)
{
// allow to select all records (not only visible)
action
=
settings
.
configuration
.
table
.
select_all
?
"
check_all
"
:
"
check_all_visible
"
;
cell
=
factory
.
generateElement
(
"
th
"
,{},{},{});
if
(
spec
===
undefined
)
{
config
=
{
util
.
errorHandler
({
"
error
"
:
"
Generate Header: Missing configuration
"
});
"
type
"
:
"
input
"
,
}
else
{
"
direct
"
:
{
config
=
spec
.
property_dict
||
{};
"
id
"
:
settings
.
portal_type_title
+
"
_check_all
"
,
id
=
spec
.
id
||
(
scope
?
(
scope
+
"
-header
"
)
:
"
global_header
"
);
"
className
"
:
"
action
"
children
=
spec
.
children
.
length
},
position
=
children
===
2
?
1
:
(
children
===
0
?
0
:
1
);
// title
title
=
{
"
type
"
:
"
h1
"
,
"
direct
"
:
{
"
className
"
:
"
translate ui-title
"
},
"
attributes
"
:
{
"
attributes
"
:
{
"
type
"
:
"
checkbox
"
,
"
data-i18n
"
:
config
.
title_i18n
||
""
,
"
value
"
:
"
Select All/Unselect All
"
,
"
role
"
:
"
heading
"
,
"
data-iconpos
"
:
"
notext
"
,
"
aria-level
"
:
"
1
"
"
data-reference
"
:
settings
.
base_element
.
direct
.
id
,
"
data-action
"
:
action
},
},
"
logic
"
:
{}
"
logic
"
:
{
"
text
"
:
config
.
title
||
"
\
u00A0
"
}
}
}
cell
.
appendChild
(
factory
.
generateFormElement
(
config
,
false
,
true
));
spec
.
children
.
splice
(
position
,
0
,
title
);
row
.
appendChild
(
cell
);
}
// reverse columns so they are mergeable :-)
// header
if
(
merger
)
{
header
=
factory
.
generateElement
(
target
=
util
.
reverseArray
(
target
);
"
div
"
,
}
{
"
id
"
:
id
,
"
className
"
:
"
ui-header
"
+
(
spec
.
class_list
||
"
"
)
+
(
config
.
fixed
?
"
ui-header-fixed
"
:
"
"
)
+
"
slidedown ui-bar-
"
+
(
spec
.
theme
||
"
inherit
"
)
},
{
"
data-role
"
:
"
header
"
,
"
data-theme
"
:
spec
.
theme
,
"
data-enhanced
"
:
"
true
"
,
"
role
"
:
"
banner
"
},
{
"
data-position
"
:
config
.
fixed
?
"
fixed
"
:
null
}
);
for
(
l
=
0
;
l
<
target
.
length
;
l
+=
1
)
{
// form
link
=
undefined
;
target
=
factory
.
util
.
wrapInForm
(
spec
.
form
);
field
=
target
[
l
];
config
=
{};
property
=
field
.
title
;
field_config
=
{};
if
(
field
.
show
)
{
// children/action buttons (wrap first/last)
// TODO: good mapping?
if
(
spec
.
children
)
{
field_config
=
fields
[
field
.
title
];
target
.
appendChild
(
factory
.
util
.
generateFromArray
(
spec
.
children
,
"
header
"
)
);
}
if
(
field
.
merge
===
undefined
)
{
// assemble
if
(
field_config
)
{
header
.
appendChild
(
target
);
config
[
"
data-i18n
"
]
=
field_config
.
widget
.
title_i18n
;
}
// add to DOM if scoped
if
(
field
.
persist
===
undefined
)
{
if
(
scope
)
{
config
[
"
data-priority
"
]
=
field
.
priority
||
6
;
document
.
getElementById
(
scope
).
appendChild
(
header
);
}
return
undefined
;
if
(
field_config
)
{
title
=
temp
[
property
]
||
field_config
.
widget
.
title
;
}
else
{
title
=
property
;
}
if
(
settings
.
configuration
.
table
.
sorting_columns
&&
field
.
sort
)
{
text
=
{}
// sorting link
link
=
factory
.
generateElement
(
"
a
"
,
{
"
className
"
:
"
action ui-sorting ui-btn ui-icon-sort
"
+
"
ui-icon ui-btn-icon-right
"
},
{
"
data-action
"
:
"
sort
"
,
"
data-i18n
"
:
""
,
"
data-reference
"
:
settings
.
base_element
.
direct
.
id
,
"
data-column-title
"
:
field
.
title
},
{
"
text
"
:
title
}
);
}
else
{
text
=
{
"
text
"
:
title
}
}
cell
=
factory
.
generateElement
(
"
th
"
,
{
"
className
"
:
"
translate
"
},
config
,
text
);
if
(
link
)
{
cell
.
appendChild
(
link
);
}
if
(
merger
)
{
row
.
insertBefore
(
cell
,
(
set
===
undefined
?
null
:
row
.
childNodes
[
check
?
1
:
0
])
);
set
=
true
;
}
else
{
row
.
appendChild
(
cell
);
}
}
else
{
temp
[
field
.
merge
]
=
field
.
merge_title
;
}
}
}
}
table_header
.
appendChild
(
row
);
return
table_header
;
return
header
;
}
};
};
/*
/* ********************************************************************** */
* Generate table rows based on configuration and data provided. Needed
/* JQM PANEL */
* to switch between editable and readonly table rows
/* ********************************************************************** */
* @method generateTableRow
/**
* @param {object} settings Configuration for table row to create
* Generates a JQM panel (needs enhancement!)
* @param {object} item Data for this table row
* Full spec example (with defaults):
* @returns table_row
* {
* "generate": "widget",
* "type": "panel",
* "class_list": null,
* "id": null,
* "theme": null,
* "property_dict" : {
* "close": true
* },
* "children": []
* }
* @method generatePanel
* @param {object} config JSON configuration
* @param {string} scope
* @param {string} scope id of page to append panel
* @return {object} HTML fragment
*/
*/
factory
.
generateTableRow
=
function
(
settings
,
item
)
{
// TODO: Needs pre-enhancement!
var
k
,
factory
.
generatePanel
=
function
(
spec
,
scope
)
{
l
,
var
config
,
id
,
panel
,
closer
;
i
,
cell
,
property
,
field
,
link
,
value
,
fetch_value
,
button
,
logic
,
keys
,
action_menu
,
action_buttons
,
action_controls
,
set
,
temp
=
{},
row
=
factory
.
generateElement
(
"
tr
"
),
target
=
settings
.
layout
[
0
].
columns
,
check
=
settings
.
configuration
.
table
.
checkbox_rows
,
merger
=
settings
.
configuration
.
table
.
mergeable_columns
;
if
(
check
)
{
if
(
spec
===
undefined
)
{
cell
=
factory
.
generateElement
(
"
th
"
,{},{},{});
util
.
errorHandler
({
"
error
"
:
"
Generate Panel: Missing configuration
"
});
cell
.
appendChild
(
factory
.
generateFormElement
(
}
else
{
config
=
spec
.
property_dict
||
{};
id
=
spec
.
id
||
(
scope
?
(
scope
+
"
-panel
"
)
:
"
global_panel
"
);
// panel
panel
=
factory
.
generateElement
(
"
div
"
,
{
{
"
type
"
:
"
input
"
,
"
id
"
:
id
,
"
direct
"
:
{
"
className
"
:
"
panel
"
+
(
spec
.
class_list
||
""
)
"
id
"
:
"
select_
"
+
item
.
_id
,
},
"
name
"
:
"
select_
"
+
item
.
_id
,
{
"
className
"
:
"
action
"
"
data-role
"
:
"
panel
"
,
"
data-theme
"
:
spec
.
theme
,
"
data-position
"
:
"
left
"
,
"
data-display
"
:
"
push
"
,
"
data-position-fixed
"
:
true
}
);
// close button, needs to go into first panel element
// TODO: refactor!!!!!
if
(
config
.
close
)
{
closer
=
factory
.
generateElement
(
"
a
"
,
{
"
href
"
:
"
#
"
,
"
className
"
:
"
panel-close ui-icon-remove ui-btn
"
+
"
ui-btn-icon-notext ui-shadow ui-corner-all
"
},
},
"
attributes
"
:
{
{
"
type
"
:
"
checkbox
"
,
"
data-enhanced
"
:
true
,
"
value
"
:
"
Select item
"
,
"
data-i18n
"
:
""
,
"
data-iconpos
"
:
"
notext
"
,
"
data-rel
"
:
"
close
"
"
data-action
"
:
"
check
"
,
"
data-reference
"
:
settings
.
base_element
.
direct
.
id
},
},
"
logic
"
:
{}
{
"
text
"
:
"
Close
"
}
},
);
false
,
}
true
));
row
.
appendChild
(
cell
);
}
// reverse if mergable columns
// form
if
(
merger
)
{
target
=
factory
.
util
.
wrapInForm
(
spec
.
form
);
target
=
util
.
reverseArray
(
target
);
// children
if
(
spec
.
children
)
{
target
.
appendChild
(
factory
.
util
.
generateFromArray
(
spec
.
children
,
"
panel
"
,
closer
)
);
}
// assemble
panel
.
appendChild
(
target
);
// add to DOM if scoped
if
(
scope
)
{
document
.
getElementById
(
scope
).
appendChild
(
panel
);
return
undefined
;
}
return
panel
;
}
}
};
// loop fields to display
/* ********************************************************************** */
for
(
l
=
0
;
l
<
target
.
length
;
l
+=
1
)
{
/* JQM Footer */
field
=
target
[
l
];
/* ********************************************************************** */
property
=
field
.
title
;
/**
value
=
item
[
property
];
* Generates JQM footer with navbar or controlgroup based on JSON config
* Full options (with defaults):
* {
* "generate":"widget",
* "type": "footer",
* "class_list": null,
* "id": "null",
* "theme": "slapos-white",
* "form": null,
* "property_dict": {
* "fixed": true
* },
* "children": []
* }
* @method generateFooter
* @param {object} spec JSON configuration
* @param {string} scope ID of element to append footer to
* @return {object} HTML fragment
*/
factory
.
generateFooter
=
function
(
spec
,
scope
)
{
var
config
,
id
,
footer
,
target
;
if
(
field
.
show
)
{
if
(
spec
===
undefined
)
{
if
(
field
.
merge
===
undefined
)
{
util
.
errorHandler
({
"
error
"
:
"
Generate Footer: Missing config
"
});
cell
=
factory
.
generateElement
(
"
td
"
,{},{},{});
}
else
{
// TODO: links should reflect value but communicate key aswell
config
=
spec
.
property_dict
||
{};
link
=
"
#
"
+
settings
.
portal_type_title
+
"
::
"
+
item
.
_id
;
id
=
spec
.
id
||
(
scope
?
(
scope
+
"
-footer
"
)
:
"
global_footer
"
)
;
// TODO: crap...refactor whole section
// footer
// fetch non portal_type values
footer
=
factory
.
generateElement
(
if
(
value
===
undefined
&&
field
.
action
===
false
)
{
"
div
"
,
// TODO: bah
{
// fetchValue = priv.getERP5property(item._id, field.lookup);
"
id
"
:
id
,
if
(
fetchValue
.
error
)
{
"
className
"
:
"
ui-footer
"
+
(
spec
.
class_list
||
"
"
)
+
value
=
"
N/A
"
;
(
config
.
fixed
?
"
ui-footer-fixed
"
:
"
"
)
+
}
"
slideup ui-bar-
"
+
(
spec
.
theme
||
"
inherit
"
),
}
},
{
"
data-role
"
:
"
footer
"
,
"
data-theme
"
:
spec
.
theme
,
"
data-enhanced
"
:
"
true
"
,
"
role
"
:
"
contentinfo
"
},
{
"
data-position
"
:
config
.
fixed
?
"
fixed
"
:
undefined
}
);
if
(
field
.
actions
)
{
// form
action_controls
=
{
"
direction
"
:
"
horizontal
"
,
"
class
"
:
""
,
"
buttons
"
:[]};
target
=
factory
.
util
.
wrapInForm
(
spec
.
form
);
for
(
i
=
0
;
i
<
field
.
actions
.
length
;
i
+=
1
)
{
action_button
=
factory
.
map_buttons
[
field
.
actions
[
i
]];
if
(
action_button
)
{
action_controls
.
buttons
.
push
({
"
type
"
:
"
a
"
,
"
direct
"
:
{
"
href
"
:
action_button
.
href
,
"
className
"
:
action_button
.
classes
+
"
translate ui-btn ui-btn-icon-notext ui-shadow ui-corner-all ui-icon-
"
+
action_button
.
icon
},
"
attributes
"
:
{
"
data-enhanced
"
:
"
true
"
,
"
data-i18n
"
:
action_button
.
text_i18n
,
"
data-action
"
:
field
.
actions
[
i
]},
"
logic
"
:
{
"
text
"
:
action_button
.
text
}
});
}
}
action_menu
=
factory
.
generateControlgroup
(
action_controls
);
cell
.
appendChild
(
action_menu
);
}
else
if
(
field
.
status
)
{
cell
.
appendChild
(
factory
.
generateLinkButton
({
"
type
"
:
"
a
"
,
"
direct
"
:
{
"
href
"
:
link
,
"
className
"
:
"
status error ui-btn-inline ui-btn translate responsive ui-btn-icon-left ui-shadow ui-corner-all ui-icon-bolt
"
},
"
attributes
"
:
{
"
data-i18n
"
:
"
[title:
"
+
item
.
status
.
message_i18n
+
"
;
"
+
item
.
status
.
error_i18n
+
"
]
"
,
"
data-icon
"
:
"
bolt
"
,
"
title
"
:
item
.
status
.
message
},
"
logic
"
:
{
"
text
"
:
item
.
status
.
state
}
}));
}
else
{
// default
if
(
field
.
image
)
{
logic
=
{
"
img
"
:
item
.
image
}
}
else
{
// TODO: lame merge
if
(
temp
[
property
])
{
value
+=
"
"
+
temp
[
property
];
//delete temp[property];
}
logic
=
{
"
text
"
:
value
}
}
// TODO: a link in every cell? binding?
// children
// don't touch this just for some status
if
(
spec
.
children
)
{
if
(
settings
.
configuration
.
table
.
linkable_rows
)
{
target
.
appendChild
(
cell
.
appendChild
(
factory
.
generateElement
(
factory
.
util
.
generateFromArray
(
spec
.
children
,
"
footer
"
)
"
a
"
,
);
{
"
className
"
:
"
table_link
"
,
"
href
"
:
link
},
{},
logic
));
}
else
{
cell
.
appendChild
(
factory
.
generateElement
(
"
span
"
,
{},
{},
logic
));
}
}
// Grrr...
if
(
merger
)
{
row
.
insertBefore
(
cell
,
(
set
===
undefined
?
undefined
:
row
.
childNodes
[
check
?
1
:
0
])
);
set
=
true
;
}
else
{
row
.
appendChild
(
cell
);
}
}
else
{
// keep the value of cells to be merged
temp
[
field
.
merge
]
=
value
;
}
}
}
// assemble
footer
.
appendChild
(
target
);
return
footer
;
}
}
return
row
;
};
};
/*
/* ********************************************************************** */
* Generates a table body based on configuration and data provided from JIO
/* JQM Controlgroup */
* @method generateTableBody
/* ********************************************************************** */
* @param {object} settings Configuration for table body to create
/**
* @param {object} answer from JIO
* Generate an controlgroup = a button or action menu
* @returns {object} table_body
* {
* "generate": "controlgroup",
* "id": null,
* "class_list": null,
* "theme": null,
* "form": null,
* "property_dict": {
* "direction": "horizontal"
* },
* "children": [
* {"type":a, "direct": {}, "attributes": {}, "logic": {}}
* ]
* }
* @method generateControlgroup
* @param {object} spec Configuration for controlgroup
* @return controlgroup
*/
*/
factory
.
generateTableBody
=
function
(
settings
,
answer
)
{
factory
.
generateControlgroup
=
function
(
spec
)
{
var
l
,
var
config
,
group
,
direction
,
controls
,
target
;
row
,
item
,
property
,
field
,
error
,
max
,
table_body
=
factory
.
generateElement
(
"
tbody
"
,{},{
"
data-update
"
:
"
true
"
});
if
(
answer
&&
answer
.
data
.
total_rows
>
0
)
{
if
(
spec
===
undefined
)
{
max
=
answer
.
data
.
total_rows
;
util
.
errorHandler
({
"
error
"
:
"
Generate Controlgroup: Missing config
"
});
}
else
{
config
=
spec
.
property_dict
||
{};
direction
=
config
.
direction
||
"
vertical
"
;
for
(
l
=
0
;
l
<
max
;
l
+=
1
)
{
// group
item
=
answer
.
data
.
rows
[
l
].
doc
;
group
=
factory
.
generateElement
(
row
=
factory
.
generateTableRow
(
settings
,
item
);
"
div
"
,
table_body
.
appendChild
(
row
);
{
"
className
"
:
"
ui-corner-all ui-controlgroup
"
+
(
spec
.
class_list
||
""
)
+
"
ui-controlgroup-
"
+
direction
},
{
"
data-role
"
:
"
controlgroup
"
,
"
data-enhanced
"
:
"
true
"
,
"
data-type
"
:
direction
}
);
// controls
controls
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
ui-controlgroup-controls
"
}
);
// children
if
(
spec
.
children
)
{
controls
.
appendChild
(
factory
.
util
.
generateFromArray
(
spec
.
children
,
"
controlgroup
"
)
);
}
}
// form
target
=
factory
.
util
.
wrapInForm
(
spec
.
form
);
// assemble
group
.
appendChild
(
controls
);
target
.
appendChild
(
group
);
return
target
;
}
};
/* ********************************************************************** */
/* JQM Navbar */
/* ********************************************************************** */
/* Generate a navbar
* Full example of spec with all options:
* {
* "generate": "widget",
* "type": "navbar",
* "class_list": null,
* "id": null,
* "theme": "slapos-white",
* "property_dict": {},
* "children":[],
* "form": null
* }
* @method generateNavbar
* @param {object} config Configuration options
* @returns navbar HTML fragment
*/
factory
.
generateNavbar
=
function
(
spec
)
{
var
navbar
,
controls
,
target
;
if
(
spec
===
undefined
)
{
util
.
errorHandler
({
"
error
"
:
"
Generate Navbar: Missing Configuration
"
});
}
else
{
}
else
{
// error or 0 results
config
=
spec
.
property_dict
||
{};
row
=
factory
.
generateElement
(
"
tr
"
);
l
=
settings
.
layout
[
0
].
columns
.
length
;
if
(
answer
===
undefined
)
{
// navbar
error
=
"
Error retrieving Data
"
;
navbar
=
factory
.
generateElement
(
}
else
if
(
answer
.
data
.
total_rows
===
0
)
{
"
div
"
,
error
=
"
No records found. Please modify your search!
"
;
{
"
className
"
:
"
navbar ui-navbar
"
+
(
spec
.
class_list
||
""
)},
}
else
{
{
"
data-role
"
:
"
navbar
"
,
"
role
"
:
"
navigation
"
,
"
data-enhanced
"
:
"
true
"
}
error
=
"
Internal error generating gadget
"
;
);
}
if
(
settings
.
configuration
.
table
.
checkbox_rows
)
{
// controls
l
+=
1
;
controls
=
factory
.
generateElement
(
"
ul
"
,
{
"
className
"
:
"
ui-grid-
"
+
util
.
toLetters
(
spec
.
children
.
length
-
1
).
toLowerCase
()
}
);
// children
if
(
spec
.
children
)
{
controls
.
appendChild
(
factory
.
util
.
generateFromArray
(
spec
.
children
,
"
navbar
"
)
);
}
}
row
.
appendChild
(
factory
.
generateElement
(
// form
"
th
"
,
target
=
factory
.
util
.
wrapInForm
(
spec
.
form
);
{
"
style
"
:
"
text-align: center; line-height: 2em;
"
},
{
"
colspan
"
:
l
},
// assemble
{
"
text
"
:
error
}
navbar
.
appendChild
(
controls
);
));
target
.
appendChild
(
navbar
);
table_body
.
appendChild
(
row
);
return
target
;
}
}
return
table_body
;
};
};
/* ********************************************************************** */
/* ********************************************************************** */
/* JQM Listview */
/* JQM Listview */
/* ********************************************************************** */
/* ********************************************************************** */
/*
/*
* Generate a JQM listview
* Generate a JQM listview
* Default spec with defaults and single list item with all options!
* {
* "generate": "gadget",
* "type": "listview",
* "class_list": "",
* "form": null,
* "theme": "slapos-black",
* "property_dict": {
* "alt_icon": null
* "numbered": false
* "inset": true,
* "reveal": true,
* "filter": true,
* "input": "#foo"
* "placeholder": null,
* "filter_theme": null,
* "divider_theme": "slapos-white",
* "autodividers": true,
* "count_theme": "slapos-white",
* "form_item": true
* "collapsible_item": true
* },
* "children": [
* {
* "type": "item/divider",
* "external": true,
* "href": "index.html",
* "icon": "foo"/null,
* "title": null,
* "title_i18n":"",
* "left": {
* "icon": "foo",
* "img": "http://www.xyz.com/img/foo.png",
* "alt": null
* },
* "center": {
* "count": 3689,
* "text": [
* {"aside": true, "type":"p", "text":"foo", "text_i18n":null}
* ]
* },
* "right": {
* "radio": true,
* "checkbox": true,
* "action": "foo",
* "href": "http://www.foo.com",
* "title": null,
* "title_i18n": "",
* "external": true
* }
* ]
*}
* @method generateListview
* @method generateListview
* @param {object}
config
JSON configuration
* @param {object}
spec
JSON configuration
* @return HTML object
* @return HTML object
*/
*/
// TODO: refactor
// TODO: add to form support via children
factory
.
generateListview
=
function
(
config
)
{
// TODO: add collapsible support if needed
var
i
,
item_config
,
item
,
list
,
target
,
skip
;
// TODO: mesh with live data!
// TODO: redo like the above and handle the array creation in arrayHandler
list
=
factory
.
generateElement
(
// WARNING: JQM does not support enhanced on listview - update JQM!
config
.
element
.
type
,
factory
.
generateListview
=
function
(
spec
)
{
config
.
element
.
direct
,
var
fragment
,
config
.
element
.
attributes
,
config
,
config
.
element
.
logic
||
{}
list
,
);
i
,
// TODO: this is crap! redo item API!
item
,
for
(
i
=
0
;
i
<
config
.
items
.
length
;
i
+=
1
)
{
props
,
item_config
=
config
.
items
[
i
];
divider
,
if
(
item_config
.
type
===
"
divider
"
)
{
static
,
j
,
block
,
target
,
icon
,
auto
,
last
,
theme
;
if
(
spec
===
undefined
)
{
util
.
errorHanlder
({
"
error
"
:
"
Generate listview: Missing configuration
"
});
}
else
{
fragment
=
document
.
createDocumentFragment
();
config
=
spec
.
property_dict
||
{};
// filter
if
(
config
.
filter
)
{
// NOTE: if input provided, the filter is already there!
// TODO: need a proper id!
if
(
config
.
input
===
undefined
)
{
fragment
.
appendChild
(
factory
.
generateFormElement
({
"
type
"
:
"
input
"
,
"
direct
"
:{
"
id
"
:
"
filter_items
"
,
"
className
"
:
"
action
"
},
"
attributes
"
:{
"
data-action
"
:
"
search
"
,
"
data-enhanced
"
:
true
,
"
data-i18n
"
:
""
,
"
placeholder
"
:
"
Search
"
,
"
data-icon
"
:
"
search
"
},
"
logic
"
:{
"
clear
"
:
"
true
"
}}
));
}
}
// list
list
=
factory
.
generateElement
(
config
.
numbered
?
"
ol
"
:
"
ul
"
,
{
"
className
"
:
"
ui-listview
"
+
(
config
.
inset
?
"
ui-listview-inset ui-corner-all ui-shadow
"
:
""
)
},
{
"
data-role
"
:
"
listview
"
,
"
data-enhanced
"
:
true
},
{
"
data-filter
"
:
config
.
filter
||
null
,
"
data-input
"
:
config
.
input
||
null
,
"
data-filter-theme
"
:
config
.
filter_theme
||
null
,
"
data-filter-placeholder
"
:
config
.
placeholder
||
null
,
"
data-divider-theme
"
:
config
.
divider_theme
||
null
}
);
// generate items
for
(
i
=
0
;
i
<
spec
.
children
.
length
;
i
+=
1
)
{
props
=
spec
.
children
[
i
];
divider
=
props
.
type
===
"
divider
"
?
true
:
undefined
;
static
=
(
props
.
href
===
undefined
&&
!
divider
)
?
true
:
undefined
;
icon
=
props
.
icon
;
theme
=
config
.
divider_theme
||
spec
.
theme
||
"
inherit
"
;
// autodividers
if
(
config
.
autodividers
)
{
auto
=
props
.
text
[
0
].
text
.
slice
(
0
,
1
).
toUpperCase
();
if
(
last
!==
auto
)
{
list
.
appendChild
(
factory
.
generateElement
(
"
li
"
,
{
"
className
"
:
"
ui-li-divider ui-bar-
"
+
theme
+
(
i
===
0
?
"
ui-first-child
"
:
((
i
===
spec
.
children
.
length
-
1
)
?
"
ui-last-child
"
:
""
))
},
{},
{
"
text
"
:
auto
}
));
last
=
auto
;
}
}
// list item
item
=
factory
.
generateElement
(
item
=
factory
.
generateElement
(
"
li
"
,
"
li
"
,
{
{
"
className
"
:
"
ui-li-divider ui-bar-
"
+
config
.
theme
+
"
className
"
:
divider
?
(
"
ui-li-divider ui-bar-
"
+
theme
)
:
""
+
(
i
===
0
?
"
ui-first-child
"
:
""
)
(
i
===
0
?
"
ui-first-child
"
:
((
i
===
spec
.
children
.
length
-
1
)
?
"
ui-last-child
"
:
""
))
+
(
static
?
"
ui-li-static ui-body-inherit
"
:
""
)
+
(
props
.
center
.
count
?
"
ui-li-has-count
"
:
""
)
+
(
config
.
alt_icon
?
"
ui-icon-alt
"
:
""
)
+
(
props
.
left
?
(
props
.
left
.
icon
?
"
ui-li-has-icon
"
:
""
)
+
(
props
.
left
.
img
?
"
ui-li-has-thumb
"
:
""
)
:
""
)
+
(
props
.
right
?
"
ui-li-has-alt
"
:
"
"
)
+
(
config
.
form_item
?
"
ui-field-contain
"
:
""
)
+
(
config
.
reveal
?
"
ui-screen-hidden
"
:
""
)
},
},
{},
{
{
"
data-role
"
:
"
list-divider
"
,
"
data-role
"
:
divider
?
"
divider
"
:
null
,
"
role
"
:
"
heading
"
,
"
role
"
:
divider
?
"
heading
"
:
null
,
"
data-i18n
"
:
item_config
.
text_i18n
"
data-icon
"
:
icon
===
null
?
false
:
},
(
icon
===
undefined
?
null
:
icon
)
{
"
text
"
:
item_config
.
text
}
);
}
else
{
item
=
factory
.
generateElement
(
"
li
"
,
{
"
className
"
:
"
listview_item
"
+
((
item_config
.
left
&&
item_config
.
left
.
icon
)
?
"
listview_icon
"
:
""
)
+
(
i
===
config
.
items
-
1
?
"
ui-last-child
"
:
""
)
}
}
);
);
// link or no link
if
(
item_config
.
middle
.
href
)
{
if
(
config
.
role
)
{
target
=
factory
.
generateElement
(
"
a
"
,
{
"
href
"
:
item_config
.
middle
.
href
,
"
className
"
:
"
ui-btn ui-btn-icon-right
"
+
(
item_config
.
right
?
item_config
.
right
.
icon
:
"
ui-icon-carat-r
"
)
}
);
}
else
{
target
=
factory
.
generateElement
(
"
a
"
,
{
"
href
"
:
item_config
.
middle
.
href
}
);
}
}
else
{
// not done yet
skip
=
true
;
target
=
item
;
}
if
(
item_config
.
left
&&
item_config
.
left
.
icon
)
{
if
(
static
||
divider
)
{
target
.
appendChild
(
factory
.
generateElement
(
target
=
item
;
"
span
"
,
}
else
{
// link
target
=
factory
.
generateElement
(
"
a
"
,
{
"
className
"
:
"
ui-btn
"
+
(
icon
===
null
?
""
:
"
ui-btn-icon-right ui-icon-
"
+
(
icon
===
undefined
?
"
carat-r
"
:
icon
)),
"
href
"
:
props
.
href
,
},
{
"
title
"
:
props
.
title
||
""
,
"
data-i18n
"
:
"
[title]
"
+
(
props
.
title_i18n
||
""
)
},
{
{
"
className
"
:
"
ui-li-icon ui-li-icon-custom ui-icon-
"
+
item_config
.
left
.
icon
+
"
ui-icon
"
,
"
data-external
"
:
props
.
external
?
true
:
null
"
innerHTML
"
:
"
"
}
}
)
)
;
);
}
}
if
(
item_config
.
middle
.
title
)
{
target
.
appendChild
(
factory
.
generateElement
(
// image
"
h3
"
,
if
(
props
.
left
)
{
{},
if
(
props
.
left
.
img
)
{
{
"
data-i18n
"
:
item_config
.
middle
.
title_i18n
},
target
.
appendChild
(
factory
.
generateElement
(
{
"
text
"
:
item_config
.
middle
.
title
}
"
img
"
,
));
{
"
src
"
:
props
.
left
.
img
,
"
alt
"
:
props
.
left
.
alt
}
));
}
// custom icon
if
(
props
.
left
.
icon
)
{
target
.
appendChild
(
factory
.
generateElement
(
"
span
"
,
{
"
className
"
:
"
ui-li-icon ui-li-icon-custom ui-icon-
"
+
props
.
left
.
icon
+
"
ui-icon
"
},
{},
{
"
text
"
:
"
\
u00A0
"
}
));
}
}
}
if
(
item_config
.
middle
.
subtitle
)
{
// text elements/aside elements
target
.
appendChild
(
factory
.
generateElement
(
for
(
j
=
0
;
j
<
props
.
center
.
text
.
length
;
j
+=
1
)
{
"
p
"
,
block
=
props
.
center
.
text
[
j
];
{},
target
.
appendChild
(
{
"
data-i18n
"
:
item_config
.
middle
.
subtitle_i18n
},
factory
.
generateElement
(
{
"
text
"
:
item_config
.
middle
.
subtitle
}
block
.
type
,
));
{
"
className
"
:
block
.
aside
?
"
ui-li-aside
"
:
""
},
{
"
data-i18n
"
:
block
.
text_i18n
||
""
},
{
"
text
"
:
block
.
text
}
)
);
}
}
if
(
item_config
.
middle
.
info
)
{
// count bubble
if
(
props
.
center
.
count
)
{
target
.
appendChild
(
factory
.
generateElement
(
target
.
appendChild
(
factory
.
generateElement
(
"
span
"
,
"
span
"
,
{
"
className
"
:
"
ui-li-count ui-body-
"
+
(
config
.
count_theme
||
spec
.
theme
)
},
{},
{},
{
"
data-i18n
"
:
item_config
.
middle
.
info_i18n
},
{
"
text
"
:
props
.
center
.
count
}
{
"
text
"
:
item_config
.
middle
.
info
}
));
}
// NOTE: if we made a link, target = a, else target = item
if
(
static
||
divider
)
{
item
=
target
;
}
else
{
item
.
appendChild
(
target
);
}
// split
if
(
props
.
right
)
{
// split button
if
(
props
.
right
.
link
)
{
item
.
appendChild
(
factory
.
generateElement
(
"
a
"
,
{
"
href
"
:
props
.
right
.
href
,
"
className
"
:
"
ui-btn ui-btn-icon-notext ui-icon-
"
+
props
.
right
.
icon
+
"
ui-btn-
"
+
(
config
.
split_theme
||
spec
.
theme
||
"
inherit
"
),
},
{
"
title
"
:
props
.
right
.
title
||
""
,
"
data-i18n
"
:
"
[title]
"
+
(
props
.
right
.
title_i18n
||
""
)
},
{
"
data-external
"
:
props
.
right
.
external
||
null
}
));
// split check/radio
if
(
props
.
right
.
check
||
props
.
right
.
radio
)
{
item
.
appendChild
(
factory
.
generateFormElement
(
{
"
type
"
:
"
input
"
,
"
direct
"
:
{
"
id
"
:
"
select_
"
+
props
.
right
.
check
?
i
:
""
,
"
name
"
:
"
select_
"
+
i
},
"
attributes
"
:
{
"
type
"
:
props
.
right
.
check
?
"
checkbox
"
:
"
radio
"
,
"
data-i18n
"
:
""
,
"
value
"
:
"
Select item
"
,
"
data-iconpos
"
:
"
notext
"
,
},
"
logic
"
:
{}
},
false
,
true
));
}
}
}
// done
list
.
appendChild
(
item
);
}
// assemble
fragment
.
appendChild
(
list
);
return
fragment
;
}
};
/* ********************************************************************** */
/* JQM "Bar" */
/* ********************************************************************** */
/*
* Generate a generic bar (table wrapper, controlbar, collapsible header)
* @method generateToolbar
* @param {object} config Elements to add to the bar
* @param {boolean} slot Wrap element in a slot container
* @param {string} reference Gadget reference pointer
* @returns {array} HTML fragment and flag for popups to be created
*/
factory
.
generateToolbar
=
function
(
elements
,
slot
,
reference
)
{
var
element
,
m
,
n
,
o
,
item
,
trigger_element
,
target
,
include
,
wrapped_in_slot
,
add_to_first
,
flag
=
{},
config
=
{},
container
=
document
.
createDocumentFragment
();
if
(
slot
)
{
wrapped_in_slot
=
true
;
}
// loop functionalities
for
(
m
=
0
;
m
<
elements
.
length
;
m
+=
1
)
{
element
=
elements
[
m
];
if
(
wrapped_in_slot
)
{
target
=
factory
.
generateElement
(
"
div
"
,
{},
{
"
data-slot
"
:
true
,
"
data-slot-id
"
:
element
.
slot
}
);
}
else
{
target
=
container
;
}
trigger_element
=
element
.
element
||
element
.
widget
;
// TODO: don't set in every case (because of controlgroup);
switch
(
trigger_element
.
type
)
{
case
"
input
"
:
case
"
select
"
:
trigger_element
.
attributes
[
"
data-reference
"
]
=
reference
;
target
.
appendChild
(
factory
.
generateFormElement
(
trigger_element
,
false
)
);
break
;
case
"
controlgroup
"
:
for
(
o
=
0
;
o
<
element
.
children
.
length
;
o
+=
1
)
{
element
.
children
[
o
].
attributes
[
"
data-reference
"
]
=
reference
;
}
target
.
appendChild
(
factory
.
generateControlgroup
({
"
type
"
:
"
controlgroup
"
,
"
direction
"
:
trigger_element
.
direction
,
"
class
"
:
trigger_element
.
widget_class
,
"
buttons
"
:
element
.
children
}));
break
;
default
:
trigger_element
.
attributes
[
"
data-reference
"
]
=
reference
;
target
.
appendChild
(
factory
.
generateElement
(
trigger_element
.
type
,
trigger_element
.
direct
,
(
trigger_element
.
attributes
),
(
trigger_element
.
logic
)
));
));
}
break
;
if
(
skip
===
undefined
)
{
};
item
.
appendChild
(
target
);
}
// TODO: do differently...
if
(
element
.
global_popup
)
{
flag
.
global_popup
=
true
;
}
if
(
element
.
local_popup
)
{
flag
.
local_popup
=
true
;
}
if
(
wrapped_in_slot
)
{
container
.
appendChild
(
target
);
}
else
{
container
=
target
;
}
}
list
.
appendChild
(
item
);
}
}
return
[
container
,
flag
];
return
list
;
};
};
/* ********************************************************************** */
/* ********************************************************************** */
/*
JQM POPUP
*/
/*
JQM Page
*/
/* ********************************************************************** */
/* ********************************************************************** */
/**
/**
* Generate a pre-enhanced popup and necessary elements (without content!)
* Generate an empty JQM page
* @method generatePopup
* @method generatePage
* @param {object} config JSON configuration for popup to be generated
* @param {object} config Config object based on parsed link
* @param {string} scope id of page to append popup
* @param {object} layout Layout for the page to generate
* @return {object} documentFragment
* @return {object} HTML fragment
*/
*/
// TODO: make sure popups work inside the page, too
// NOTE: we are defaulting to fixed toolbars!
factory
.
generatePopup
=
function
(
config
,
scope
)
{
factory
.
generatePage
=
function
(
config
,
layout
)
{
var
popup
,
var
page
=
factory
.
generateElement
(
popup_wrap
,
constructor_id
,
popup_id
,
container
=
document
.
createDocumentFragment
(),
placeholder
=
function
(
id
)
{
return
factory
.
generateElement
(
"
div
"
,
{
"
id
"
:
id
+
"
-placeholder
"
},
{
"
style
"
:
"
display:none;
"
}
);
};
// NOTE: passing both config and scope undefined creates global popup
// Passing a scope will make the popup local, passing config only,
// makes it global
// set identifier in case config and/or scope are undefined
if
(
config
===
undefined
)
{
config
=
{
"
widget_class
"
:
scope
?
"
local_popup
"
:
""
};
constructor_id
=
scope
?
util
.
generateUuid
()
:
"
global_popup
"
;
}
else
{
constructor_id
=
config
.
id
}
popup_id
=
constructor_id
+
(
scope
?
(
"
_
"
+
scope
)
:
""
);
container
.
appendChild
(
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
ui-popup-screen ui-screen-hidden
"
+
(
config
.
overlay_theme
?
"
ui-overlay-
"
+
config
.
overlay_theme
:
""
),
"
id
"
:
popup_id
+
"
-screen
"
}
));
popup_wrap
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
ui-popup-container ui-corner-all ui-popup-hidden
"
+
"
ui-popup-truncate
"
+
(
config
.
transition
||
"
fade
"
),
"
id
"
:
popup_id
+
"
-popup
"
}
);
popup
=
factory
.
generateElement
(
"
div
"
,
"
div
"
,
{
{
"
className
"
:
"
ui-popup ui-body-
"
+
config
.
theme
+
"
id
"
:
config
.
id
,
(
config
.
shadow
?
"
ui-overlay-shadow
"
:
"
"
)
+
"
className
"
:
"
ui-page
"
+
(
"
ui-page-theme-
"
+
layout
.
theme
||
""
)
+
"
ui-corner-all
"
+
config
.
widget_class
,
"
"
+
((
layout
.
fix
&&
layout
.
fix
===
false
)
?
""
:
"
id
"
:
popup_id
"
ui-page-header-fixed ui-page-footer-fixed
"
)
},
},
{
{
"
data-module
"
:
config
.
id
,
"
data-transition
"
:
config
.
transition
||
"
fade
"
,
"
data-role
"
:
"
page
"
,
"
data-role
"
:
"
popup
"
,
"
data-url
"
:
config
.
url
,
"
data-enhanced
"
:
"
true
"
,
"
data-external-page
"
:
true
,
"
data-position-to
"
:
config
.
position
||
"
window
"
"
tabindex
"
:
0
,
},
"
data-enhanced
"
:
true
{
"
data-theme
"
:
config
.
theme
||
null
,
"
data-overlay-theme
"
:
config
.
overlay_theme
||
null
,
"
data-tolerance
"
:
config
.
tolerance
||
"
30,30,30,30
"
}
}
);
);
popup_wrap
.
appendChild
(
popup
);
// set state
container
.
appendChild
(
popup_wrap
);
// local popup = needs to go on the page... needs enhancement, because
// we don't jQuery here...
if
(
scope
)
{
document
.
getElementById
(
scope
).
appendChild
(
container
);
return
placeholder
(
popup_id
);
}
// global popup also gets a placeholder
container
.
appendChild
(
placeholder
(
popup_id
));
return
container
;
return
page
;
};
};
/* ********************************************************************** */
/* ********************************************************************** */
/*
JQM Navbar
*/
/*
JQM Table
*/
/* ********************************************************************** */
/* ********************************************************************** */
/* Generate a navbar
/*
* @method generateNavbar
* Generates a table header based on configuration and portal_type
* @param {object} config Configuration options
* @method generateTableHeader
* @returns navbar HTML fragment
* @param {object} settings Configuration for table to create
* @param {object} fields Field configurations for this portal Type
*/
*/
factory
.
generateNavbar
=
function
(
config
)
{
// TODO: single row ok. multi row to make
var
i
,
navbar
,
controls
;
factory
.
generateTableHeader
=
function
(
settings
,
fields
)
{
var
k
,
navbar
=
factory
.
generateElement
(
l
,
"
div
"
,
cell
,
{
"
className
"
:
"
navbar ui-navbar
"
+
(
config
.
type_class
||
""
)},
field
,
{
"
data-role
"
:
"
navbar
"
,
"
role
"
:
"
navigation
"
,
"
data-enhanced
"
:
"
true
"
}
config
,
);
field_config
,
controls
=
factory
.
generateElement
(
property
,
"
ul
"
,
keys
,
{
title
,
"
className
"
:
"
ui-grid-
"
+
set
,
util
.
toLetters
(
config
.
buttons
.
length
-
1
).
toLowerCase
()
text
,
}
action
,
);
temp
=
{},
link
=
undefined
,
check
=
settings
.
configuration
.
table
.
checkbox_rows
,
merger
=
settings
.
configuration
.
table
.
mergeable_columns
,
target
=
settings
.
layout
[
0
].
columns
,
table_header
=
factory
.
generateElement
(
"
thead
"
),
row
=
factory
.
generateElement
(
"
tr
"
);
for
(
i
=
0
;
i
<
config
.
buttons
.
length
;
i
+=
1
)
{
// tickbox - all
button
=
config
.
buttons
[
i
];
if
(
check
)
{
button
.
direct
[
"
className
"
]
+=
"
ui-btn ui-shadow
"
+
// allow to select all records (not only visible)
factory
.
generateIconClassString
(
button
);
action
=
settings
.
configuration
.
table
.
select_all
?
"
check_all
"
:
"
check_all_visible
"
;
item
=
factory
.
generateElement
(
cell
=
factory
.
generateElement
(
"
th
"
,{},{},{});
"
li
"
,
{
"
className
"
:
"
ui-block-
"
+
util
.
toLetters
(
i
+
1
).
toLowerCase
()}
config
=
{
);
"
type
"
:
"
input
"
,
item
.
appendChild
(
factory
.
generateLinkButton
(
button
));
"
direct
"
:
{
"
id
"
:
settings
.
portal_type_title
+
"
_check_all
"
,
"
className
"
:
"
action
"
},
"
attributes
"
:
{
"
type
"
:
"
checkbox
"
,
"
value
"
:
"
Select All/Unselect All
"
,
"
data-iconpos
"
:
"
notext
"
,
"
data-reference
"
:
settings
.
base_element
.
direct
.
id
,
"
data-action
"
:
action
},
"
logic
"
:
{}
}
cell
.
appendChild
(
factory
.
generateFormElement
(
config
,
false
,
true
));
row
.
appendChild
(
cell
);
}
controls
.
appendChild
(
item
);
// reverse columns so they are mergeable :-)
if
(
merger
)
{
target
=
util
.
reverseArray
(
target
);
}
}
navbar
.
appendChild
(
controls
);
return
navbar
;
for
(
l
=
0
;
l
<
target
.
length
;
l
+=
1
)
{
};
link
=
undefined
;
field
=
target
[
l
];
config
=
{};
property
=
field
.
title
;
field_config
=
{};
/* ********************************************************************** */
if
(
field
.
show
)
{
/* JQM Footer */
// TODO: good mapping?
/* ********************************************************************** */
field_config
=
fields
[
field
.
title
];
/**
* Generates JQM footer with navbar or controlgroup based on JSON config
* @method generateFooter
* @param {object} config JSON configuration
* @return {object} HTML fragment
*/
factory
.
generateFooter
=
function
(
config
)
{
var
footer
,
wrap
;
footer
=
factory
.
generateElement
(
if
(
field
.
merge
===
undefined
)
{
"
div
"
,
if
(
field_config
)
{
{
config
[
"
data-i18n
"
]
=
field_config
.
widget
.
title_i18n
;
"
className
"
:
"
ui-footer
"
+
}
(
config
.
widget_class
||
"
"
)
+
if
(
field
.
persist
===
undefined
)
{
(
config
.
fixed
?
"
ui-footer-fixed
"
:
"
"
)
+
"
slideup ui-bar-
"
+
config
[
"
data-priority
"
]
=
field
.
priority
||
6
;
(
config
.
theme
||
"
inherit
"
),
}
},
if
(
field_config
)
{
{
title
=
temp
[
property
]
||
field_config
.
widget
.
title
;
"
data-role
"
:
"
footer
"
,
}
else
{
"
data-theme
"
:
config
.
theme
,
title
=
property
;
"
data-enhanced
"
:
"
true
"
,
}
"
role
"
:
"
contentinfo
"
if
(
settings
.
configuration
.
table
.
sorting_columns
&&
field
.
sort
)
{
},
text
=
{}
{
// sorting link
"
id
"
:
config
.
id
||
undefined
,
link
=
factory
.
generateElement
(
"
data-position
"
:
config
.
fixed
?
"
fixed
"
:
undefined
"
a
"
,
{
"
className
"
:
"
action ui-sorting ui-btn ui-icon-sort
"
+
"
ui-icon ui-btn-icon-right
"
},
{
"
data-action
"
:
"
sort
"
,
"
data-i18n
"
:
""
,
"
data-reference
"
:
settings
.
base_element
.
direct
.
id
,
"
data-column-title
"
:
field
.
title
},
{
"
text
"
:
title
}
);
}
else
{
text
=
{
"
text
"
:
title
}
}
cell
=
factory
.
generateElement
(
"
th
"
,
{
"
className
"
:
"
translate
"
},
config
,
text
);
if
(
link
)
{
cell
.
appendChild
(
link
);
}
if
(
merger
)
{
row
.
insertBefore
(
cell
,
(
set
===
undefined
?
null
:
row
.
childNodes
[
check
?
1
:
0
])
);
set
=
true
;
}
else
{
row
.
appendChild
(
cell
);
}
}
else
{
temp
[
field
.
merge
]
=
field
.
merge_title
;
}
}
}
);
// navbar or controlgroup
if
(
config
.
type
===
"
navbar
"
)
{
wrap
=
factory
.
generateNavbar
(
config
);
}
else
{
wrap
=
factory
.
generateControlgroup
(
config
);
}
}
footer
.
appendChild
(
wrap
);
table_header
.
appendChild
(
row
);
return
foot
er
;
return
table_head
er
;
};
};
/* ********************************************************************** */
/*
/* JQM Header */
* Generate table rows based on configuration and data provided. Needed
/* ********************************************************************** */
* to switch between editable and readonly table rows
/**
* @method generateTableRow
* Generates JQM header. Header buttons are wrapped in controlgroups!
* @param {object} settings Configuration for table row to create
* @method generateHeader
* @param {object} item Data for this table row
* @param {object} config JSON configuration
* @returns table_row
* @return {object} HTML fragment
*/
*/
// TODO: logo instead of header
factory
.
generateTableRow
=
function
(
settings
,
item
)
{
factory
.
generateHeader
=
function
(
config
)
{
var
k
,
var
header
,
l
,
group
,
wrap
,
i
,
i
,
direction
,
cell
,
addTitle
;
property
,
field
,
link
,
value
,
fetch_value
,
button
,
logic
,
keys
,
action_menu
,
action_buttons
,
action_controls
,
set
,
temp
=
{},
row
=
factory
.
generateElement
(
"
tr
"
),
target
=
settings
.
layout
[
0
].
columns
,
check
=
settings
.
configuration
.
table
.
checkbox_rows
,
merger
=
settings
.
configuration
.
table
.
mergeable_columns
;
// title
if
(
check
)
{
addTitle
=
function
(
title
,
i18n
)
{
cell
=
factory
.
generateElement
(
"
th
"
,{},{},{});
return
factory
.
generateElement
(
cell
.
appendChild
(
factory
.
generateFormElement
(
"
h1
"
,
{
"
className
"
:
"
translate ui-title
"
},
{
{
"
data-i18n
"
:
i18n
||
""
,
"
type
"
:
"
input
"
,
"
role
"
:
"
heading
"
,
"
direct
"
:
{
"
aria-level
"
:
"
1
"
"
id
"
:
"
select_
"
+
item
.
_id
,
"
name
"
:
"
select_
"
+
item
.
_id
,
"
className
"
:
"
action
"
},
"
attributes
"
:
{
"
type
"
:
"
checkbox
"
,
"
value
"
:
"
Select item
"
,
"
data-iconpos
"
:
"
notext
"
,
"
data-action
"
:
"
check
"
,
"
data-reference
"
:
settings
.
base_element
.
direct
.
id
},
"
logic
"
:
{}
},
},
{
"
text
"
:
title
||
"
"
}
false
,
);
true
};
// header element
header
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
ui-header
"
+
(
config
.
widget_class
||
"
"
)
+
(
config
.
fixed
?
"
ui-header-fixed
"
:
"
"
)
+
"
slidedown ui-bar-
"
+
(
config
.
theme
||
"
inherit
"
)
},
{
"
data-role
"
:
"
header
"
,
"
data-theme
"
:
config
.
theme
,
"
data-enhanced
"
:
"
true
"
,
"
role
"
:
"
banner
"
},
{
"
id
"
:
config
.
id
||
undefined
,
"
data-position
"
:
config
.
fixed
?
"
fixed
"
:
undefined
}
);
// logo
if
(
config
.
logo
)
{
wrap
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
ui-header-logo wrap
"
+
config
.
logo
.
wrap
}
);
wrap
.
appendChild
(
factory
.
generateElement
(
"
img
"
,
{
"
src
"
:
config
.
logo
.
src
,
"
alt
"
:
config
.
logo
.
alt
},
{
"
data-i18n
"
:
"
[alt]
"
}
));
));
header
.
appendChild
(
wrap
);
row
.
appendChild
(
cell
);
}
// reverse if mergable columns
if
(
merger
)
{
target
=
util
.
reverseArray
(
target
);
}
}
// button controlgroups
// loop fields to display
if
(
config
.
controls
&&
config
.
controls
.
length
>
0
)
{
for
(
l
=
0
;
l
<
target
.
length
;
l
+=
1
)
{
for
(
i
=
0
;
i
<
config
.
controls
.
length
;
i
+=
1
)
{
field
=
target
[
l
];
direction
=
i
===
0
?
"
left
"
:
"
right
"
;
property
=
field
.
title
;
value
=
item
[
property
];
wrap
=
factory
.
generateElement
(
if
(
field
.
show
)
{
"
div
"
,
{
"
className
"
:
"
wrap
"
+
direction
}
if
(
field
.
merge
===
undefined
)
{
);
cell
=
factory
.
generateElement
(
"
td
"
,{},{},{});
group
=
factory
.
generateControlgroup
(
config
.
controls
[
i
]);
// TODO: links should reflect value but communicate key aswell
link
=
"
#
"
+
settings
.
portal_type_title
+
"
::
"
+
item
.
_id
;
// TODO: crap...refactor whole section
// fetch non portal_type values
if
(
value
===
undefined
&&
field
.
action
===
false
)
{
// TODO: bah
// fetchValue = priv.getERP5property(item._id, field.lookup);
if
(
fetchValue
.
error
)
{
value
=
"
N/A
"
;
}
}
wrap
.
appendChild
(
group
);
if
(
field
.
actions
)
{
header
.
appendChild
(
wrap
);
action_controls
=
{
"
direction
"
:
"
horizontal
"
,
"
class
"
:
""
,
"
buttons
"
:[]};
for
(
i
=
0
;
i
<
field
.
actions
.
length
;
i
+=
1
)
{
action_button
=
factory
.
map_buttons
[
field
.
actions
[
i
]];
if
(
action_button
)
{
action_controls
.
buttons
.
push
({
"
type
"
:
"
a
"
,
"
direct
"
:
{
"
href
"
:
action_button
.
href
,
"
className
"
:
action_button
.
classes
+
"
translate ui-btn ui-btn-icon-notext ui-shadow ui-corner-all ui-icon-
"
+
action_button
.
icon
},
"
attributes
"
:
{
"
data-enhanced
"
:
"
true
"
,
"
data-i18n
"
:
action_button
.
text_i18n
,
"
data-action
"
:
field
.
actions
[
i
]},
"
logic
"
:
{
"
text
"
:
action_button
.
text
}
});
}
}
action_menu
=
factory
.
generateControlgroup
(
action_controls
);
cell
.
appendChild
(
action_menu
);
}
else
if
(
field
.
status
)
{
cell
.
appendChild
(
factory
.
generateElement
(
"
a
"
,
{
"
href
"
:
link
,
"
className
"
:
"
status error ui-btn-inline ui-btn translate responsive ui-btn-icon-left ui-shadow ui-corner-all ui-icon-bolt
"
},
{
"
data-i18n
"
:
"
[title:
"
+
item
.
status
.
message_i18n
+
"
;
"
+
item
.
status
.
error_i18n
+
"
]
"
,
"
data-icon
"
:
"
bolt
"
,
"
title
"
:
item
.
status
.
message
},
{
"
text
"
:
item
.
status
.
state
}
));
}
else
{
// default
if
(
field
.
image
)
{
logic
=
{
"
img
"
:
item
.
image
}
}
else
{
// TODO: lame merge
if
(
temp
[
property
])
{
value
+=
"
"
+
temp
[
property
];
//delete temp[property];
}
logic
=
{
"
text
"
:
value
}
}
// NOTE: page title set in pagehandler, this only sets a placeholder
// TODO: a link in every cell? binding?
if
(
i
===
0
)
{
// don't touch this just for some status
header
.
appendChild
(
addTitle
(
config
.
title
,
config
.
title_i18n
));
if
(
settings
.
configuration
.
table
.
linkable_rows
)
{
cell
.
appendChild
(
factory
.
generateElement
(
"
a
"
,
{
"
className
"
:
"
table_link
"
,
"
href
"
:
link
},
{},
logic
));
}
else
{
cell
.
appendChild
(
factory
.
generateElement
(
"
span
"
,
{},
{},
logic
));
}
}
// Grrr...
if
(
merger
)
{
row
.
insertBefore
(
cell
,
(
set
===
undefined
?
undefined
:
row
.
childNodes
[
check
?
1
:
0
])
);
set
=
true
;
}
else
{
row
.
appendChild
(
cell
);
}
}
else
{
// keep the value of cells to be merged
temp
[
field
.
merge
]
=
value
;
}
}
}
}
}
else
{
header
.
appendChild
(
addTitle
(
config
.
title
,
config
.
title_i18n
));
}
}
return
row
;
return
header
;
};
};
/* ********************************************************************** */
/*
/* JQM Controlgroup */
* Generates a table body based on configuration and data provided from JIO
/* ********************************************************************** */
* @method generateTableBody
/**
* @param {object} settings Configuration for table body to create
* Generate an controlgroup = a button or action menu
* @param {object} answer from JIO
* @method generateControlgroup
* @returns {object} table_body
* @param {object} config Configuration options
* @return controlgroup
*/
*/
// TODO: refactor
factory
.
generateTableBody
=
function
(
settings
,
answer
)
{
factory
.
generateControlgroup
=
function
(
config
)
{
var
l
,
var
i
,
row
,
action_menu
,
item
,
action_controls
,
property
,
element
,
field
,
icon_string
,
error
,
direction
;
max
,
table_body
=
factory
.
generateElement
(
"
tbody
"
,{},{
"
data-update
"
:
"
true
"
});
direction
=
config
.
direction
||
"
vertical
"
;
if
(
answer
&&
answer
.
data
.
total_rows
>
0
)
{
max
=
answer
.
data
.
total_rows
;
// group
for
(
l
=
0
;
l
<
max
;
l
+=
1
)
{
action_menu
=
factory
.
generateElement
(
item
=
answer
.
data
.
rows
[
l
].
doc
;
"
div
"
,
row
=
factory
.
generateTableRow
(
settings
,
item
);
{
table_body
.
appendChild
(
row
);
"
className
"
:
"
ui-corner-all ui-controlgroup
"
+
(
config
.
widget_class
||
""
)
+
"
ui-controlgroup-
"
+
direction
},
{
"
data-role
"
:
"
controlgroup
"
,
"
data-enhanced
"
:
"
true
"
,
"
data-type
"
:
direction
}
}
);
}
else
{
// error or 0 results
row
=
factory
.
generateElement
(
"
tr
"
);
l
=
settings
.
layout
[
0
].
columns
.
length
;
// controls
if
(
answer
===
undefined
)
{
action_controls
=
factory
.
generateElement
(
error
=
"
Error retrieving Data
"
;
"
div
"
,
}
else
if
(
answer
.
data
.
total_rows
===
0
)
{
{
"
className
"
:
"
ui-controlgroup-controls
"
+
(
config
.
control_class
||
""
)}
error
=
"
No records found. Please modify your search!
"
;
);
}
else
{
error
=
"
Internal error generating gadget
"
;
}
// buttons
if
(
settings
.
configuration
.
table
.
checkbox_rows
)
{
for
(
i
=
0
;
i
<
config
.
buttons
.
length
;
i
+=
1
)
{
l
+=
1
;
element
=
config
.
buttons
[
i
];
}
switch
(
element
.
type
)
{
case
"
select
"
:
case
"
input
"
:
action_controls
.
appendChild
(
factory
.
generateFormElement
(
element
,
false
)
);
break
;
default
:
pos
=
factory
.
generateIconClassString
(
element
);
// class String
element
.
direct
.
className
+=
"
ui-btn ui-corner-all ui-shadow
"
+
pos
+
((
i
===
0
)
?
"
ui-first-child
"
:
(
i
===
(
config
.
buttons
.
length
-
1
)
?
"
ui-last-child
"
:
""
)
);
action_controls
.
appendChild
(
factory
.
generateLinkButton
(
element
));
row
.
appendChild
(
factory
.
generateElement
(
break
;
"
th
"
,
};
{
"
style
"
:
"
text-align: center; line-height: 2em;
"
},
{
"
colspan
"
:
l
},
{
"
text
"
:
error
}
));
table_body
.
appendChild
(
row
);
}
}
action_menu
.
appendChild
(
action_controls
);
return
table_body
;
return
action_menu
;
};
/* ********************************************************************** */
/* JQM Link Button */
/* ********************************************************************** */
/**
* Generate a link button ("a")
* @method generateLinkButton
* @param {object} config Configuration options
* @return button object
*/
// TODO: add chunk of text here or via JSON?
factory
.
generateLinkButton
=
function
(
config
)
{
return
button
=
factory
.
generateElement
(
config
.
type
,
config
.
direct
,
config
.
attributes
,
config
.
logic
);
};
};
/* ********************************************************************** */
/* ********************************************************************** */
/* JQM Form Element */
/* JQM Form Element */
/* ********************************************************************** */
/* ********************************************************************** */
...
@@ -1542,6 +2022,7 @@
...
@@ -1542,6 +2022,7 @@
// TODO: mini? shadow? corners?
// TODO: mini? shadow? corners?
// TODO: slider/custom-select/flip
// TODO: slider/custom-select/flip
// TODO: refactor...
// TODO: refactor...
// TODO: placeholder?
factory
.
generateFormElement
=
function
(
config
,
wrap
,
label
,
position
)
{
factory
.
generateFormElement
=
function
(
config
,
wrap
,
label
,
position
)
{
var
wrapper
,
var
wrapper
,
container
,
container
,
...
@@ -1771,71 +2252,7 @@
...
@@ -1771,71 +2252,7 @@
return
wrapper
;
return
wrapper
;
};
};
/* ********************************************************************** */
/* JQM PANEL */
/* ********************************************************************** */
/**
* Generates a JQM panel (needs enhancement!)
* @method generatePanel
* @param {object} config JSON configuration
* @return {object} HTML fragment
*/
factory
.
generatePanel
=
function
(
config
)
{
var
i
,
element
,
item
,
panel
;
panel
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
panel
"
+
config
.
widget_class
,
"
id
"
:
config
.
id
},
{
"
data-role
"
:
"
panel
"
,
"
data-theme
"
:
config
.
theme
,
"
data-position
"
:
"
left
"
,
"
data-display
"
:
"
push
"
,
"
data-position-fixed
"
:
true
}
);
for
(
i
=
0
;
i
<
config
.
elements
.
length
;
i
+=
1
)
{
element
=
config
.
elements
[
i
];
// TODO: refactor
switch
(
element
.
type
||
element
.
widget
)
{
case
"
global_search
"
:
item
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
panel_element panel_element_first panel_header
"
}
);
item
.
appendChild
(
factory
.
generateFormElement
(
element
.
element
,
false
)
);
item
.
appendChild
(
factory
.
generateLinkButton
({
"
type
"
:
"
a
"
,
"
direct
"
:
{
"
href
"
:
"
#
"
,
"
className
"
:
"
panel-close ui-icon-remove ui-btn
"
+
"
ui-btn-icon-notext ui-shadow ui-corner-all
"
},
"
attributes
"
:
{
"
data-enhanced
"
:
"
true
"
,
"
data-i18n
"
:
""
,
"
data-rel
"
:
"
close
"
},
"
logic
"
:
{
"
text
"
:
"
Close
"
}
}));
panel
.
appendChild
(
item
);
break
;
case
"
listview
"
:
item
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
panel_element
"
}
);
item
.
appendChild
(
factory
.
generateListview
(
element
));
panel
.
appendChild
(
item
);
break
;
}
}
return
panel
;
};
/* ********************************************************************** */
/* ********************************************************************** */
...
@@ -1877,6 +2294,7 @@
...
@@ -1877,6 +2294,7 @@
* @param: {object} setters Parameters requiring logic (if-else-etc)
* @param: {object} setters Parameters requiring logic (if-else-etc)
* @returns: {object} HTML object
* @returns: {object} HTML object
*/
*/
// TODO: bundle into spec!
factory
.
generateElement
=
function
(
type
,
options
,
attributes
,
setters
)
{
factory
.
generateElement
=
function
(
type
,
options
,
attributes
,
setters
)
{
var
property
,
var
property
,
attribute
,
attribute
,
...
@@ -1915,11 +2333,11 @@
...
@@ -1915,11 +2333,11 @@
break
;
break
;
case
"
id
"
:
case
"
id
"
:
case
"
rows
"
:
case
"
rows
"
:
case
"
innerHTML
"
:
case
"
cols
"
:
case
"
cols
"
:
case
"
name
"
:
case
"
name
"
:
case
"
value
"
:
case
"
value
"
:
case
"
data-
"
:
case
"
data-
"
:
case
"
role
"
:
case
"
type
"
:
case
"
type
"
:
case
"
readonly
"
:
case
"
readonly
"
:
case
"
size
"
:
case
"
size
"
:
...
@@ -2113,26 +2531,6 @@
...
@@ -2113,26 +2531,6 @@
return
array
;
return
array
;
};
};
/**
* Generate a UUID
* @method generateUuid
* @return {string} UUID
*/
util
.
generateUuid
=
function
()
{
function
S4
()
{
return
(
'
0000
'
+
Math
.
floor
(
Math
.
random
()
*
0x10000
/* 65536 */
).
toString
(
16
)).
slice
(
-
4
);
}
return
S4
()
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
"
-
"
+
S4
()
+
S4
()
+
S4
();
};
/**
/**
* Create hashes of code snippets generated
* Create hashes of code snippets generated
* @method crc32
* @method crc32
...
@@ -2878,7 +3276,8 @@
...
@@ -2878,7 +3276,8 @@
*/
*/
init
.
parsePage
=
function
(
e
,
data
)
{
init
.
parsePage
=
function
(
e
,
data
)
{
var
create
,
config
,
raw_url
,
handle
;
var
create
,
config
,
raw_url
,
handle
;
// console.log("pbc")
// TODO:maybe this is the problem???
if
(
data
)
{
if
(
data
)
{
if
(
data
.
options
.
link
)
{
if
(
data
.
options
.
link
)
{
raw_url
=
data
.
options
.
link
[
0
].
href
;
raw_url
=
data
.
options
.
link
[
0
].
href
;
...
@@ -2891,28 +3290,39 @@
...
@@ -2891,28 +3290,39 @@
if
(
typeof
raw_url
===
"
string
"
)
{
if
(
typeof
raw_url
===
"
string
"
)
{
config
=
util
.
parseLink
(
raw_url
);
config
=
util
.
parseLink
(
raw_url
);
if
(
e
)
{
if
(
e
)
{
// console.log(document.getElementById(raw_url.replace("#", "")))
// console.log(data.options.role === "popup")
// console.log(raw_url === $.mobile.getDocumentUrl())
// console.log($.mobile.getDocumentUrl())
if
(
document
.
getElementById
(
raw_url
.
replace
(
"
#
"
,
""
))
||
if
(
document
.
getElementById
(
raw_url
.
replace
(
"
#
"
,
""
))
||
raw_url
===
$
.
mobile
.
getDocumentUrl
()
||
raw_url
===
$
.
mobile
.
getDocumentUrl
()
||
data
.
options
.
role
===
"
popup
"
)
{
data
.
options
.
role
===
"
popup
"
)
{
// console.log("let JQM go")
return
;
return
;
}
}
if
(
document
.
getElementById
(
config
.
id
))
{
if
(
document
.
getElementById
(
config
.
id
))
{
// console.log("stop JQM")
e
.
preventDefault
();
e
.
preventDefault
();
return
;
return
;
}
else
{
}
else
{
// PASS!
// PASS!
// console.log("HIJACK and stop JQM")
handle
=
true
;
handle
=
true
;
e
.
preventDefault
();
e
.
preventDefault
();
}
}
}
else
{
// if ($.mobile.navigate.history.initialDst && location.hash !== "") {
// console.log("CLEANUP - set initialDst to ")
// $.mobile.navigate.history.initialDst = "";
// }
}
}
}
else
{
}
else
{
// once transition done. Update gadgets if going back to page in DOM
// once transition done. Update gadgets if going back to page in DOM
if
(
data
.
options
.
fromHashChange
)
{
if
(
data
.
options
.
fromHashChange
)
{
init
.
setPageTitle
(
data
.
toPage
[
0
],
{});
init
.
setPageTitle
(
data
.
toPage
[
0
],
{});
}
}
return
;
}
}
if
(
e
===
undefined
||
handle
)
{
if
(
e
===
undefined
||
handle
)
{
if
(
config
.
deeplink
)
{
if
(
config
.
deeplink
)
{
...
@@ -3178,7 +3588,7 @@
...
@@ -3178,7 +3588,7 @@
// JQM treatment
// JQM treatment
$
(
document
).
enhanceWithin
();
$
(
document
).
enhanceWithin
();
// console.log("CHANGING PAGE")
$
.
mobile
.
changePage
(
"
#
"
+
config
.
id
);
$
.
mobile
.
changePage
(
"
#
"
+
config
.
id
);
}
else
{
}
else
{
// populate existing page and enhance
// populate existing page and enhance
...
@@ -3342,14 +3752,14 @@
...
@@ -3342,14 +3752,14 @@
/**
/**
* Loads and runs application setters
* Loads and runs application setters
* @method load
ApplicationSetting
s
* @method load
GlobalElement
s
* @return {object} promise object
* @return {object} promise object
*/
*/
init
.
load
ApplicationSetting
s
=
function
()
{
init
.
load
GlobalElement
s
=
function
()
{
return
util
.
fetchConfiguration
({
return
util
.
fetchConfiguration
({
"
storage
"
:
"
settings
"
,
"
storage
"
:
"
settings
"
,
"
file
"
:
"
configuration
"
,
"
file
"
:
"
configuration
"
,
"
attachment
"
:
"
app
"
,
"
attachment
"
:
"
global
"
,
"
baggage
"
:
undefined
"
baggage
"
:
undefined
});
});
};
};
...
@@ -3379,25 +3789,19 @@
...
@@ -3379,25 +3789,19 @@
/**
/**
* Sets up a global application element
* Sets up a global application element
* @method setupGlobalElement
* @method setupGlobalElement
* @param {object}
config
JSON configuration
* @param {object}
spec
JSON configuration
*/
*/
init
.
setupGobalElement
=
function
(
config
)
{
init
.
setupGobalElement
=
function
(
spec
)
{
switch
(
config
.
widget
)
{
var
element
=
factory
.
util
.
forward
(
spec
);
case
"
header
"
:
document
.
body
.
appendChild
(
factory
.
generateHeader
(
config
));
switch
(
spec
.
type
)
{
break
;
case
"
Panel
"
:
case
"
footer
"
:
document
.
body
.
appendChild
(
factory
.
generateFooter
(
config
));
break
;
case
"
popup
"
:
document
.
body
.
appendChild
(
factory
.
generatePopup
(
config
));
break
;
case
"
panel
"
:
// NOTE: panel must be either before or after everything else!
// NOTE: panel must be either before or after everything else!
// WARNING: IE8- children() retrieves comments, too
// WARNING: IE8- children() retrieves comments, too
document
.
body
.
insertBefore
(
document
.
body
.
insertBefore
(
element
,
document
.
body
.
children
[
0
]);
factory
.
generatePanel
(
config
),
document
.
body
.
children
[
0
]
break
;
);
default
:
document
.
body
.
appendChild
(
element
);
break
;
break
;
}
}
};
};
...
@@ -3407,6 +3811,7 @@
...
@@ -3407,6 +3811,7 @@
* @method setGlobalBindings
* @method setGlobalBindings
*/
*/
init
.
setGlobalBindings
=
function
()
{
init
.
setGlobalBindings
=
function
()
{
$
(
document
)
$
(
document
)
.
enhanceWithin
()
.
enhanceWithin
()
...
@@ -3546,7 +3951,7 @@
...
@@ -3546,7 +3951,7 @@
// "Application Setup"
// "Application Setup"
.
runApplicationSetup
(
"
settings
"
,
"
storages
"
)
.
runApplicationSetup
(
"
settings
"
,
"
storages
"
)
.
then
(
init
.
setupStorages
)
.
then
(
init
.
setupStorages
)
.
then
(
init
.
load
ApplicationSetting
s
)
.
then
(
init
.
load
GlobalElement
s
)
.
then
(
init
.
setupGlobalElements
)
.
then
(
init
.
setupGlobalElements
)
.
then
(
init
.
setGlobalBindings
)
.
then
(
init
.
setGlobalBindings
)
// "Page Setup"
// "Page Setup"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment