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 @@
// ERP5 custom methods
var
erp5
=
{};
// JQM content
gen
erator
// JQM content
erate
erator
var
factory
=
{};
/* ====================================================================== */
...
...
@@ -272,8 +272,8 @@
// NOTE: method must be present or added to validation handler
if
(
prevail
.
properties
.
external_validator
||
spec
.
properties
.
external_validator
)
{
validation_list
+=
prevail
.
properties
.
external_validator
||
spec
.
properties
.
external_validator
;
validation_list
+=
(
prevail
.
properties
.
external_validator
||
spec
.
properties
.
external_validator
)
;
}
// required
...
...
@@ -600,7 +600,7 @@
/* ====================================================================== */
/* ********************************************************************** */
/*
"mapping to erp5"
*/
/*
Factory Mappings (to ERP5)
*/
/* ********************************************************************** */
factory
.
map_buttons
=
erp5
.
map_buttons
;
factory
.
map_actions
=
erp5
.
map_actions
;
...
...
@@ -608,923 +608,1403 @@
factory
.
map_utils
=
erp5
.
map_utils
;
/* ********************************************************************** */
/*
JQM "Bar"
*/
/*
Factory Utils
*/
/* ********************************************************************** */
factory
.
util
=
{};
/*
* 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
* Forward to factory generator depending on "generate". This method will
* handle generation of elements, widgets (and gadgets?)
* @method forward
* @param {object} spec Configuration object for the element to be created
* @return {object} HTML object containing generated elements
*/
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
();
factory
.
util
.
forward
=
function
(
spec
)
{
switch
(
spec
.
generate
)
{
// widget generator
case
"
widget
"
:
return
factory
[
"
generate
"
+
spec
.
type
](
spec
);
break
;
// gadget generator
case
"
gadget
"
:
if
(
slot
)
{
wrapped_in_slot
=
true
;
break
;
// 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
)
{
element
=
elements
[
m
];
if
(
wrapped_in_slot
)
{
target
=
factory
.
generateElement
(
"
div
"
,
{},
{
"
data-slot
"
:
true
,
"
data-slot-id
"
:
element
.
slot
}
);
}
else
{
target
=
container
;
}
/*
* Loop over a selection of elements and generate the respective content
* @method generateFromArray
* @param {array} spec Array containing the elements to generate
* @param {string} type Requesting widget
* @param {object} hack
* @return {object} fragment HTML object containing the elements
*/
// 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
;
// TODO: don't set in every case (because of controlgroup);
for
(
i
=
0
;
i
<
spec
.
length
;
i
+=
1
)
{
element
=
spec
[
i
];
target
=
undefined
;
switch
(
trigger_element
.
type
)
{
case
"
input
"
:
case
"
select
"
:
trigger_element
.
attributes
[
"
data-reference
"
]
=
reference
;
target
.
appendChild
(
factory
.
generateFormElement
(
trigger_element
,
false
)
// class string
if
(
element
.
direct
)
{
order
=
i
===
0
?
"
ui-first-child
"
:
(
i
===
(
spec
.
length
-
1
)
?
"
ui-last-child
"
:
"
"
);
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
;
case
"
controlgroup
"
:
for
(
o
=
0
;
o
<
element
.
children
.
length
;
o
+=
1
)
{
element
.
children
[
o
].
attributes
[
"
data-reference
"
]
=
reference
;
// HACK: this adds the panel close button, don't do this here!
if
(
i
===
0
&&
hack
)
{
target
.
appendChild
(
hack
);
}
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
)
));
case
"
navbar
"
:
target
=
factory
.
generateElement
(
"
li
"
,
{
"
className
"
:
"
ui-block-
"
+
util
.
toLetters
(
i
+
1
).
toLowerCase
()}
);
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
"
)
}
);
}
};
// 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
);
// generate with/without wrapper
if
(
target
)
{
target
.
appendChild
(
factory
.
util
.
forward
(
element
));
fragment
.
appendChild
(
target
);
}
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
* @method generatePage
* @param {object} config Config object based on parsed link
* @param {object} layout Layout for the page to generate
* @return {object} HTML fragment
*/
// NOTE: we are defaulting to fixed toolbars!
factory
.
generatePage
=
function
(
config
,
layout
)
{
var
page
=
factory
.
generateElement
(
"
div
"
,
{
"
id
"
:
config
.
id
,
"
className
"
:
"
ui-page
"
+
(
"
ui-page-theme-
"
+
layout
.
theme
||
""
)
+
"
"
+
((
layout
.
fix
&&
layout
.
fix
===
false
)
?
""
:
"
ui-page-header-fixed ui-page-footer-fixed
"
)
},
{
"
data-module
"
:
config
.
id
,
"
data-role
"
:
"
page
"
,
"
data-url
"
:
config
.
url
,
"
data-external-page
"
:
true
,
"
tabindex
"
:
0
,
"
data-enhanced
"
:
true
* Generate a pre-enhanced popup and necessary elements
* Full options (with defaults)
* {
* "generate": "widget",
* "type":"popup",
* "class_list": "",
* "theme": "",
* "id": null,
* "property_dict": {
* "overlay-theme": null,
* "transition": "fade",
* "position-to": "window",
* "tolerance": "30,30,30,30",
* "shadow": true
* },
* "form": null,
* "children": [],
* }
* @method generatePopup
* @param {object} spec JSON configuration for popup to be generated
* @param {string} scope id of page to append popup
* @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
* @method generateTableHeader
* @param {object} settings Configuration for table to create
* @param {object} fields Field configurations for this portal Type
/**
* Generates JQM header. Header buttons are wrapped in controlgroups!
* Full options (with defaults)
* {
* "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
factory
.
generateTableHeader
=
function
(
settings
,
fields
)
{
var
k
,
l
,
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
"
;
// NOTE: Logos should be added as children of the header!
// NOTE: page title set in pagehandler, this only sets a placeholder
factory
.
generateHeader
=
function
(
spec
,
scope
)
{
var
config
,
id
,
title
,
wrap
,
position
,
children
,
header
,
target
;
cell
=
factory
.
generateElement
(
"
th
"
,{},{},{});
config
=
{
"
type
"
:
"
input
"
,
"
direct
"
:
{
"
id
"
:
settings
.
portal_type_title
+
"
_check_all
"
,
"
className
"
:
"
action
"
},
if
(
spec
===
undefined
)
{
util
.
errorHandler
({
"
error
"
:
"
Generate Header: Missing configuration
"
});
}
else
{
config
=
spec
.
property_dict
||
{};
id
=
spec
.
id
||
(
scope
?
(
scope
+
"
-header
"
)
:
"
global_header
"
);
children
=
spec
.
children
.
length
position
=
children
===
2
?
1
:
(
children
===
0
?
0
:
1
);
// title
title
=
{
"
type
"
:
"
h1
"
,
"
direct
"
:
{
"
className
"
:
"
translate ui-title
"
},
"
attributes
"
:
{
"
type
"
:
"
checkbox
"
,
"
value
"
:
"
Select All/Unselect All
"
,
"
data-iconpos
"
:
"
notext
"
,
"
data-reference
"
:
settings
.
base_element
.
direct
.
id
,
"
data-action
"
:
action
"
data-i18n
"
:
config
.
title_i18n
||
""
,
"
role
"
:
"
heading
"
,
"
aria-level
"
:
"
1
"
},
"
logic
"
:
{}
"
logic
"
:
{
"
text
"
:
config
.
title
||
"
\
u00A0
"
}
}
cell
.
appendChild
(
factory
.
generateFormElement
(
config
,
false
,
true
));
row
.
appendChild
(
cell
);
}
spec
.
children
.
splice
(
position
,
0
,
title
);
// reverse columns so they are mergeable :-)
if
(
merger
)
{
target
=
util
.
reverseArray
(
target
);
}
// header
header
=
factory
.
generateElement
(
"
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
)
{
link
=
undefined
;
field
=
target
[
l
];
config
=
{};
property
=
field
.
title
;
field_config
=
{};
// form
target
=
factory
.
util
.
wrapInForm
(
spec
.
form
);
if
(
field
.
show
)
{
// TODO: good mapping?
field_config
=
fields
[
field
.
title
];
// children/action buttons (wrap first/last)
if
(
spec
.
children
)
{
target
.
appendChild
(
factory
.
util
.
generateFromArray
(
spec
.
children
,
"
header
"
)
);
}
if
(
field
.
merge
===
undefined
)
{
if
(
field_config
)
{
config
[
"
data-i18n
"
]
=
field_config
.
widget
.
title_i18n
;
}
if
(
field
.
persist
===
undefined
)
{
config
[
"
data-priority
"
]
=
field
.
priority
||
6
;
}
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
;
}
// assemble
header
.
appendChild
(
target
);
// add to DOM if scoped
if
(
scope
)
{
document
.
getElementById
(
scope
).
appendChild
(
header
);
return
undefined
;
}
}
table_header
.
appendChild
(
row
);
return
table_header
;
return
header
;
}
};
/*
* Generate table rows based on configuration and data provided. Needed
* to switch between editable and readonly table rows
* @method generateTableRow
* @param {object} settings Configuration for table row to create
* @param {object} item Data for this table row
* @returns table_row
/* ********************************************************************** */
/* JQM PANEL */
/* ********************************************************************** */
/**
* Generates a JQM panel (needs enhancement!)
* Full spec example (with defaults):
* {
* "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
)
{
var
k
,
l
,
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
;
// TODO: Needs pre-enhancement!
factory
.
generatePanel
=
function
(
spec
,
scope
)
{
var
config
,
id
,
panel
,
closer
;
if
(
check
)
{
cell
=
factory
.
generateElement
(
"
th
"
,{},{},{});
cell
.
appendChild
(
factory
.
generateFormElement
(
if
(
spec
===
undefined
)
{
util
.
errorHandler
({
"
error
"
:
"
Generate Panel: Missing configuration
"
});
}
else
{
config
=
spec
.
property_dict
||
{};
id
=
spec
.
id
||
(
scope
?
(
scope
+
"
-panel
"
)
:
"
global_panel
"
);
// panel
panel
=
factory
.
generateElement
(
"
div
"
,
{
"
type
"
:
"
input
"
,
"
direct
"
:
{
"
id
"
:
"
select_
"
+
item
.
_id
,
"
name
"
:
"
select_
"
+
item
.
_id
,
"
className
"
:
"
action
"
"
id
"
:
id
,
"
className
"
:
"
panel
"
+
(
spec
.
class_list
||
""
)
},
{
"
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
"
,
"
value
"
:
"
Select item
"
,
"
data-iconpos
"
:
"
notext
"
,
"
data-action
"
:
"
check
"
,
"
data-reference
"
:
settings
.
base_element
.
direct
.
id
{
"
data-enhanced
"
:
true
,
"
data-i18n
"
:
""
,
"
data-rel
"
:
"
close
"
},
"
logic
"
:
{}
},
false
,
true
));
row
.
appendChild
(
cell
);
}
{
"
text
"
:
"
Close
"
}
);
}
// reverse if mergable columns
if
(
merger
)
{
target
=
util
.
reverseArray
(
target
);
// form
target
=
factory
.
util
.
wrapInForm
(
spec
.
form
);
// 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
)
{
field
=
target
[
l
];
property
=
field
.
title
;
value
=
item
[
property
];
/* ********************************************************************** */
/* JQM Footer */
/* ********************************************************************** */
/**
* 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
(
field
.
merge
===
undefined
)
{
cell
=
factory
.
generateElement
(
"
td
"
,{},{},{});
// TODO: links should reflect value but communicate key aswell
link
=
"
#
"
+
settings
.
portal_type_title
+
"
::
"
+
item
.
_id
;
if
(
spec
===
undefined
)
{
util
.
errorHandler
({
"
error
"
:
"
Generate Footer: Missing config
"
});
}
else
{
config
=
spec
.
property_dict
||
{};
id
=
spec
.
id
||
(
scope
?
(
scope
+
"
-footer
"
)
:
"
global_footer
"
)
;
// 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
"
;
}
}
// footer
footer
=
factory
.
generateElement
(
"
div
"
,
{
"
id
"
:
id
,
"
className
"
:
"
ui-footer
"
+
(
spec
.
class_list
||
"
"
)
+
(
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
)
{
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
.
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
}
}
// form
target
=
factory
.
util
.
wrapInForm
(
spec
.
form
);
// TODO: a link in every cell? binding?
// don't touch this just for some status
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
;
}
// children
if
(
spec
.
children
)
{
target
.
appendChild
(
factory
.
util
.
generateFromArray
(
spec
.
children
,
"
footer
"
)
);
}
// assemble
footer
.
appendChild
(
target
);
return
footer
;
}
return
row
;
};
/*
* Generates a table body based on configuration and data provided from JIO
* @method generateTableBody
* @param {object} settings Configuration for table body to create
* @param {object} answer from JIO
* @returns {object} table_body
/* ********************************************************************** */
/* JQM Controlgroup */
/* ********************************************************************** */
/**
* Generate an controlgroup = a button or action menu
* {
* "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
)
{
var
l
,
row
,
item
,
property
,
field
,
error
,
max
,
table_body
=
factory
.
generateElement
(
"
tbody
"
,{},{
"
data-update
"
:
"
true
"
});
factory
.
generateControlgroup
=
function
(
spec
)
{
var
config
,
group
,
direction
,
controls
,
target
;
if
(
answer
&&
answer
.
data
.
total_rows
>
0
)
{
max
=
answer
.
data
.
total_rows
;
if
(
spec
===
undefined
)
{
util
.
errorHandler
({
"
error
"
:
"
Generate Controlgroup: Missing config
"
});
}
else
{
config
=
spec
.
property_dict
||
{};
direction
=
config
.
direction
||
"
vertical
"
;
for
(
l
=
0
;
l
<
max
;
l
+=
1
)
{
item
=
answer
.
data
.
rows
[
l
].
doc
;
row
=
factory
.
generateTableRow
(
settings
,
item
);
table_body
.
appendChild
(
row
);
// group
group
=
factory
.
generateElement
(
"
div
"
,
{
"
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
{
// error or 0 results
row
=
factory
.
generateElement
(
"
tr
"
);
l
=
settings
.
layout
[
0
].
columns
.
length
;
config
=
spec
.
property_dict
||
{};
if
(
answer
===
undefined
)
{
error
=
"
Error retrieving Data
"
;
}
else
if
(
answer
.
data
.
total_rows
===
0
)
{
error
=
"
No records found. Please modify your search!
"
;
}
else
{
error
=
"
Internal error generating gadget
"
;
}
// navbar
navbar
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
navbar ui-navbar
"
+
(
spec
.
class_list
||
""
)},
{
"
data-role
"
:
"
navbar
"
,
"
role
"
:
"
navigation
"
,
"
data-enhanced
"
:
"
true
"
}
);
if
(
settings
.
configuration
.
table
.
checkbox_rows
)
{
l
+=
1
;
// controls
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
(
"
th
"
,
{
"
style
"
:
"
text-align: center; line-height: 2em;
"
},
{
"
colspan
"
:
l
},
{
"
text
"
:
error
}
));
table_body
.
appendChild
(
row
);
// form
target
=
factory
.
util
.
wrapInForm
(
spec
.
form
);
// assemble
navbar
.
appendChild
(
controls
);
target
.
appendChild
(
navbar
);
return
target
;
}
return
table_body
;
};
/* ********************************************************************** */
/* ********************************************************************** */
/* 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
* @param {object}
config
JSON configuration
* @param {object}
spec
JSON configuration
* @return HTML object
*/
// TODO: refactor
factory
.
generateListview
=
function
(
config
)
{
var
i
,
item_config
,
item
,
list
,
target
,
skip
;
list
=
factory
.
generateElement
(
config
.
element
.
type
,
config
.
element
.
direct
,
config
.
element
.
attributes
,
config
.
element
.
logic
||
{}
);
// TODO: this is crap! redo item API!
for
(
i
=
0
;
i
<
config
.
items
.
length
;
i
+=
1
)
{
item_config
=
config
.
items
[
i
];
if
(
item_config
.
type
===
"
divider
"
)
{
// TODO: add to form support via children
// TODO: add collapsible support if needed
// TODO: mesh with live data!
// TODO: redo like the above and handle the array creation in arrayHandler
// WARNING: JQM does not support enhanced on listview - update JQM!
factory
.
generateListview
=
function
(
spec
)
{
var
fragment
,
config
,
list
,
i
,
item
,
props
,
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
(
"
li
"
,
{
"
className
"
:
"
ui-li-divider ui-bar-
"
+
config
.
theme
+
(
i
===
0
?
"
ui-first-child
"
:
""
)
"
className
"
:
divider
?
(
"
ui-li-divider ui-bar-
"
+
theme
)
:
""
+
(
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
"
,
"
role
"
:
"
heading
"
,
"
data-i18n
"
:
item_config
.
text_i18n
},
{
"
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
"
:
""
)
"
data-role
"
:
divider
?
"
divider
"
:
null
,
"
role
"
:
divider
?
"
heading
"
:
null
,
"
data-icon
"
:
icon
===
null
?
false
:
(
icon
===
undefined
?
null
:
icon
)
}
);
// 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
)
{
target
.
appendChild
(
factory
.
generateElement
(
"
span
"
,
if
(
static
||
divider
)
{
target
=
item
;
}
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
"
,
"
innerHTML
"
:
"
"
"
data-external
"
:
props
.
external
?
true
:
null
}
)
)
;
);
}
if
(
item_config
.
middle
.
title
)
{
target
.
appendChild
(
factory
.
generateElement
(
"
h3
"
,
{},
{
"
data-i18n
"
:
item_config
.
middle
.
title_i18n
},
{
"
text
"
:
item_config
.
middle
.
title
}
));
// image
if
(
props
.
left
)
{
if
(
props
.
left
.
img
)
{
target
.
appendChild
(
factory
.
generateElement
(
"
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
)
{
target
.
appendChild
(
factory
.
generateElement
(
"
p
"
,
{},
{
"
data-i18n
"
:
item_config
.
middle
.
subtitle_i18n
},
{
"
text
"
:
item_config
.
middle
.
subtitle
}
));
// text elements/aside elements
for
(
j
=
0
;
j
<
props
.
center
.
text
.
length
;
j
+=
1
)
{
block
=
props
.
center
.
text
[
j
];
target
.
appendChild
(
factory
.
generateElement
(
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
(
"
span
"
,
{
"
className
"
:
"
ui-li-count ui-body-
"
+
(
config
.
count_theme
||
spec
.
theme
)
},
{},
{
"
data-i18n
"
:
item_config
.
middle
.
info_i18n
},
{
"
text
"
:
item_config
.
middle
.
info
}
{
"
text
"
:
props
.
center
.
count
}
));
}
// 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
)
));
}
if
(
skip
===
undefined
)
{
item
.
appendChild
(
target
);
}
break
;
};
// 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
list
;
return
[
container
,
flag
];
};
/* ********************************************************************** */
/*
JQM POPUP
*/
/*
JQM Page
*/
/* ********************************************************************** */
/**
* Generate a pre-enhanced popup and necessary elements (without content!)
* @method generatePopup
* @param {object} config JSON configuration for popup to be generated
* @param {string} scope id of page to append popup
* @return {object} documentFragment
*/
// TODO: make sure popups work inside the page, too
factory
.
generatePopup
=
function
(
config
,
scope
)
{
var
popup
,
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
(
* Generate an empty JQM page
* @method generatePage
* @param {object} config Config object based on parsed link
* @param {object} layout Layout for the page to generate
* @return {object} HTML fragment
*/
// NOTE: we are defaulting to fixed toolbars!
factory
.
generatePage
=
function
(
config
,
layout
)
{
var
page
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
ui-popup ui-body-
"
+
config
.
theme
+
(
config
.
shadow
?
"
ui-overlay-shadow
"
:
"
"
)
+
"
ui-corner-all
"
+
config
.
widget_class
,
"
id
"
:
popup_id
},
{
"
data-transition
"
:
config
.
transition
||
"
fade
"
,
"
data-role
"
:
"
popup
"
,
"
data-enhanced
"
:
"
true
"
,
"
data-position-to
"
:
config
.
position
||
"
window
"
},
{
"
data-theme
"
:
config
.
theme
||
null
,
"
data-overlay-theme
"
:
config
.
overlay_theme
||
null
,
"
data-tolerance
"
:
config
.
tolerance
||
"
30,30,30,30
"
"
id
"
:
config
.
id
,
"
className
"
:
"
ui-page
"
+
(
"
ui-page-theme-
"
+
layout
.
theme
||
""
)
+
"
"
+
((
layout
.
fix
&&
layout
.
fix
===
false
)
?
""
:
"
ui-page-header-fixed ui-page-footer-fixed
"
)
},
{
"
data-module
"
:
config
.
id
,
"
data-role
"
:
"
page
"
,
"
data-url
"
:
config
.
url
,
"
data-external-page
"
:
true
,
"
tabindex
"
:
0
,
"
data-enhanced
"
:
true
}
);
popup_wrap
.
appendChild
(
popup
);
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
));
// set state
return
container
;
return
page
;
};
/* ********************************************************************** */
/*
JQM Navbar
*/
/*
JQM Table
*/
/* ********************************************************************** */
/* Generate a navbar
* @method generateNavbar
* @param {object} config Configuration options
* @returns navbar HTML fragment
/*
* Generates a table header based on configuration and portal_type
* @method generateTableHeader
* @param {object} settings Configuration for table to create
* @param {object} fields Field configurations for this portal Type
*/
factory
.
generateNavbar
=
function
(
config
)
{
var
i
,
navbar
,
controls
;
navbar
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
navbar ui-navbar
"
+
(
config
.
type_class
||
""
)},
{
"
data-role
"
:
"
navbar
"
,
"
role
"
:
"
navigation
"
,
"
data-enhanced
"
:
"
true
"
}
);
controls
=
factory
.
generateElement
(
"
ul
"
,
{
"
className
"
:
"
ui-grid-
"
+
util
.
toLetters
(
config
.
buttons
.
length
-
1
).
toLowerCase
()
}
);
// TODO: single row ok. multi row to make
factory
.
generateTableHeader
=
function
(
settings
,
fields
)
{
var
k
,
l
,
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
"
);
for
(
i
=
0
;
i
<
config
.
buttons
.
length
;
i
+=
1
)
{
button
=
config
.
buttons
[
i
];
button
.
direct
[
"
className
"
]
+=
"
ui-btn ui-shadow
"
+
factory
.
generateIconClassString
(
button
);
// tickbox - all
if
(
check
)
{
// allow to select all records (not only visible)
action
=
settings
.
configuration
.
table
.
select_all
?
"
check_all
"
:
"
check_all_visible
"
;
item
=
factory
.
generateElement
(
"
li
"
,
{
"
className
"
:
"
ui-block-
"
+
util
.
toLetters
(
i
+
1
).
toLowerCase
()}
);
item
.
appendChild
(
factory
.
generateLinkButton
(
button
));
cell
=
factory
.
generateElement
(
"
th
"
,{},{},{});
config
=
{
"
type
"
:
"
input
"
,
"
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
=
{};
/* ********************************************************************** */
/* JQM Footer */
/* ********************************************************************** */
/**
* 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
;
if
(
field
.
show
)
{
// TODO: good mapping?
field_config
=
fields
[
field
.
title
];
footer
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
ui-footer
"
+
(
config
.
widget_class
||
"
"
)
+
(
config
.
fixed
?
"
ui-footer-fixed
"
:
"
"
)
+
"
slideup ui-bar-
"
+
(
config
.
theme
||
"
inherit
"
),
},
{
"
data-role
"
:
"
footer
"
,
"
data-theme
"
:
config
.
theme
,
"
data-enhanced
"
:
"
true
"
,
"
role
"
:
"
contentinfo
"
},
{
"
id
"
:
config
.
id
||
undefined
,
"
data-position
"
:
config
.
fixed
?
"
fixed
"
:
undefined
if
(
field
.
merge
===
undefined
)
{
if
(
field_config
)
{
config
[
"
data-i18n
"
]
=
field_config
.
widget
.
title_i18n
;
}
if
(
field
.
persist
===
undefined
)
{
config
[
"
data-priority
"
]
=
field
.
priority
||
6
;
}
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
;
}
}
);
// 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 */
/* ********************************************************************** */
/**
* Generates JQM header. Header buttons are wrapped in controlgroups!
* @method generateHeader
* @param {object} config JSON configuration
* @return {object} HTML fragment
/*
* Generate table rows based on configuration and data provided. Needed
* to switch between editable and readonly table rows
* @method generateTableRow
* @param {object} settings Configuration for table row to create
* @param {object} item Data for this table row
* @returns table_row
*/
// TODO: logo instead of header
factory
.
generateHeader
=
function
(
config
)
{
var
header
,
group
,
wrap
,
factory
.
generateTableRow
=
function
(
settings
,
item
)
{
var
k
,
l
,
i
,
direction
,
addTitle
;
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
;
// title
addTitle
=
function
(
title
,
i18n
)
{
return
factory
.
generateElement
(
"
h1
"
,
{
"
className
"
:
"
translate ui-title
"
},
if
(
check
)
{
cell
=
factory
.
generateElement
(
"
th
"
,{},{},{});
cell
.
appendChild
(
factory
.
generateFormElement
(
{
"
data-i18n
"
:
i18n
||
""
,
"
role
"
:
"
heading
"
,
"
aria-level
"
:
"
1
"
"
type
"
:
"
input
"
,
"
direct
"
:
{
"
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
||
"
"
}
);
};
// 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]
"
}
false
,
true
));
header
.
appendChild
(
wrap
);
row
.
appendChild
(
cell
);
}
// reverse if mergable columns
if
(
merger
)
{
target
=
util
.
reverseArray
(
target
);
}
// button controlgroups
if
(
config
.
controls
&&
config
.
controls
.
length
>
0
)
{
for
(
i
=
0
;
i
<
config
.
controls
.
length
;
i
+=
1
)
{
direction
=
i
===
0
?
"
left
"
:
"
right
"
;
// loop fields to display
for
(
l
=
0
;
l
<
target
.
length
;
l
+=
1
)
{
field
=
target
[
l
];
property
=
field
.
title
;
value
=
item
[
property
];
wrap
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
wrap
"
+
direction
}
);
group
=
factory
.
generateControlgroup
(
config
.
controls
[
i
]);
if
(
field
.
show
)
{
if
(
field
.
merge
===
undefined
)
{
cell
=
factory
.
generateElement
(
"
td
"
,{},{},{});
// 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
);
header
.
appendChild
(
wrap
);
if
(
field
.
actions
)
{
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
if
(
i
===
0
)
{
header
.
appendChild
(
addTitle
(
config
.
title
,
config
.
title_i18n
));
// TODO: a link in every cell? binding?
// don't touch this just for some status
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
header
;
return
row
;
};
/* ********************************************************************** */
/* JQM Controlgroup */
/* ********************************************************************** */
/**
* Generate an controlgroup = a button or action menu
* @method generateControlgroup
* @param {object} config Configuration options
* @return controlgroup
/*
* Generates a table body based on configuration and data provided from JIO
* @method generateTableBody
* @param {object} settings Configuration for table body to create
* @param {object} answer from JIO
* @returns {object} table_body
*/
// TODO: refactor
factory
.
generateControlgroup
=
function
(
config
)
{
var
i
,
action_menu
,
action_controls
,
element
,
icon_string
,
direction
;
factory
.
generateTableBody
=
function
(
settings
,
answer
)
{
var
l
,
row
,
item
,
property
,
field
,
error
,
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
action_menu
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
ui-corner-all ui-controlgroup
"
+
(
config
.
widget_class
||
""
)
+
"
ui-controlgroup-
"
+
direction
},
{
"
data-role
"
:
"
controlgroup
"
,
"
data-enhanced
"
:
"
true
"
,
"
data-type
"
:
direction
for
(
l
=
0
;
l
<
max
;
l
+=
1
)
{
item
=
answer
.
data
.
rows
[
l
].
doc
;
row
=
factory
.
generateTableRow
(
settings
,
item
);
table_body
.
appendChild
(
row
);
}
);
}
else
{
// error or 0 results
row
=
factory
.
generateElement
(
"
tr
"
);
l
=
settings
.
layout
[
0
].
columns
.
length
;
// controls
action_controls
=
factory
.
generateElement
(
"
div
"
,
{
"
className
"
:
"
ui-controlgroup-controls
"
+
(
config
.
control_class
||
""
)}
);
if
(
answer
===
undefined
)
{
error
=
"
Error retrieving Data
"
;
}
else
if
(
answer
.
data
.
total_rows
===
0
)
{
error
=
"
No records found. Please modify your search!
"
;
}
else
{
error
=
"
Internal error generating gadget
"
;
}
// buttons
for
(
i
=
0
;
i
<
config
.
buttons
.
length
;
i
+=
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
"
:
""
)
);
if
(
settings
.
configuration
.
table
.
checkbox_rows
)
{
l
+=
1
;
}
action_controls
.
appendChild
(
factory
.
generateLinkButton
(
element
));
break
;
};
row
.
appendChild
(
factory
.
generateElement
(
"
th
"
,
{
"
style
"
:
"
text-align: center; line-height: 2em;
"
},
{
"
colspan
"
:
l
},
{
"
text
"
:
error
}
));
table_body
.
appendChild
(
row
);
}
action_menu
.
appendChild
(
action_controls
);
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
);
return
table_body
;
};
/* ********************************************************************** */
/* JQM Form Element */
/* ********************************************************************** */
...
...
@@ -1542,6 +2022,7 @@
// TODO: mini? shadow? corners?
// TODO: slider/custom-select/flip
// TODO: refactor...
// TODO: placeholder?
factory
.
generateFormElement
=
function
(
config
,
wrap
,
label
,
position
)
{
var
wrapper
,
container
,
...
...
@@ -1771,71 +2252,7 @@
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 @@
* @param: {object} setters Parameters requiring logic (if-else-etc)
* @returns: {object} HTML object
*/
// TODO: bundle into spec!
factory
.
generateElement
=
function
(
type
,
options
,
attributes
,
setters
)
{
var
property
,
attribute
,
...
...
@@ -1915,11 +2333,11 @@
break
;
case
"
id
"
:
case
"
rows
"
:
case
"
innerHTML
"
:
case
"
cols
"
:
case
"
name
"
:
case
"
value
"
:
case
"
data-
"
:
case
"
role
"
:
case
"
type
"
:
case
"
readonly
"
:
case
"
size
"
:
...
...
@@ -2113,26 +2531,6 @@
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
* @method crc32
...
...
@@ -2878,7 +3276,8 @@
*/
init
.
parsePage
=
function
(
e
,
data
)
{
var
create
,
config
,
raw_url
,
handle
;
// console.log("pbc")
// TODO:maybe this is the problem???
if
(
data
)
{
if
(
data
.
options
.
link
)
{
raw_url
=
data
.
options
.
link
[
0
].
href
;
...
...
@@ -2891,28 +3290,39 @@
if
(
typeof
raw_url
===
"
string
"
)
{
config
=
util
.
parseLink
(
raw_url
);
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
(
"
#
"
,
""
))
||
raw_url
===
$
.
mobile
.
getDocumentUrl
()
||
data
.
options
.
role
===
"
popup
"
)
{
// console.log("let JQM go")
return
;
}
if
(
document
.
getElementById
(
config
.
id
))
{
// console.log("stop JQM")
e
.
preventDefault
();
return
;
}
else
{
// PASS!
// console.log("HIJACK and stop JQM")
handle
=
true
;
e
.
preventDefault
();
}
}
else
{
// if ($.mobile.navigate.history.initialDst && location.hash !== "") {
// console.log("CLEANUP - set initialDst to ")
// $.mobile.navigate.history.initialDst = "";
// }
}
}
else
{
// once transition done. Update gadgets if going back to page in DOM
if
(
data
.
options
.
fromHashChange
)
{
init
.
setPageTitle
(
data
.
toPage
[
0
],
{});
}
return
;
}
if
(
e
===
undefined
||
handle
)
{
if
(
config
.
deeplink
)
{
...
...
@@ -3178,7 +3588,7 @@
// JQM treatment
$
(
document
).
enhanceWithin
();
// console.log("CHANGING PAGE")
$
.
mobile
.
changePage
(
"
#
"
+
config
.
id
);
}
else
{
// populate existing page and enhance
...
...
@@ -3342,14 +3752,14 @@
/**
* Loads and runs application setters
* @method load
ApplicationSetting
s
* @method load
GlobalElement
s
* @return {object} promise object
*/
init
.
load
ApplicationSetting
s
=
function
()
{
init
.
load
GlobalElement
s
=
function
()
{
return
util
.
fetchConfiguration
({
"
storage
"
:
"
settings
"
,
"
file
"
:
"
configuration
"
,
"
attachment
"
:
"
app
"
,
"
attachment
"
:
"
global
"
,
"
baggage
"
:
undefined
});
};
...
...
@@ -3379,25 +3789,19 @@
/**
* Sets up a global application element
* @method setupGlobalElement
* @param {object}
config
JSON configuration
* @param {object}
spec
JSON configuration
*/
init
.
setupGobalElement
=
function
(
config
)
{
switch
(
config
.
widget
)
{
case
"
header
"
:
document
.
body
.
appendChild
(
factory
.
generateHeader
(
config
));
break
;
case
"
footer
"
:
document
.
body
.
appendChild
(
factory
.
generateFooter
(
config
));
break
;
case
"
popup
"
:
document
.
body
.
appendChild
(
factory
.
generatePopup
(
config
));
break
;
case
"
panel
"
:
init
.
setupGobalElement
=
function
(
spec
)
{
var
element
=
factory
.
util
.
forward
(
spec
);
switch
(
spec
.
type
)
{
case
"
Panel
"
:
// NOTE: panel must be either before or after everything else!
// WARNING: IE8- children() retrieves comments, too
document
.
body
.
insertBefore
(
factory
.
generatePanel
(
config
),
document
.
body
.
children
[
0
]
);
document
.
body
.
insertBefore
(
element
,
document
.
body
.
children
[
0
]);
break
;
default
:
document
.
body
.
appendChild
(
element
);
break
;
}
};
...
...
@@ -3407,6 +3811,7 @@
* @method setGlobalBindings
*/
init
.
setGlobalBindings
=
function
()
{
$
(
document
)
.
enhanceWithin
()
...
...
@@ -3546,7 +3951,7 @@
// "Application Setup"
.
runApplicationSetup
(
"
settings
"
,
"
storages
"
)
.
then
(
init
.
setupStorages
)
.
then
(
init
.
load
ApplicationSetting
s
)
.
then
(
init
.
load
GlobalElement
s
)
.
then
(
init
.
setupGlobalElements
)
.
then
(
init
.
setGlobalBindings
)
// "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