$Mojolicious::Plugin::DevexpressHelpers::Helpers::VERSION
=
'0.152320'
;
our
$OUT_DECODE
=
'UTF-8'
;
our
$INDENT_BINDING
= 0;
sub
out{
my
$tag
=
shift
;
my
$bytes
= Mojo::ByteStream->new(
$tag
);
return
$bytes
->decode(
$OUT_DECODE
)
if
defined
$OUT_DECODE
;
return
$bytes
;
}
sub
new{
my
$class
=
shift
;
my
$self
=
bless
{
next_id
=> 1,
bindings
=>
''
,
},
$class
;
return
$self
;
}
sub
indent_binding{
my
$self
=
shift
;
$INDENT_BINDING
=
shift
;
}
sub
add_binding{
my
$self
=
shift
;
$self
->{bindings} .=
join
"\n"
,
@_
;
}
sub
next_id{
my
$self
=
shift
;
return
"dxctl"
.(
$self
->{next_id}++);
}
sub
new_id{
my
(
$c
,
$attrs
) =
@_
;
$c
->stash(
'dxHelper'
)->next_id;
}
sub
dxbind{
my
(
$c
,
$control
,
$id
,
$attrs
,
$extensions
,
$befores
,
$afters
) =
@_
;
$befores
//=[];
$afters
//=[];
my
$jquery_id
=
$id
;
$jquery_id
=~ s{\.}{\\\\.}g;
my
$binding
=
'$("#'
.
$jquery_id
.
'").'
.
$control
.
'('
;
my
@options
;
if
(
ref
(
$attrs
) eq
'HASH'
) {
$binding
.=
'{'
;
$binding
.=
"\n "
if
$INDENT_BINDING
;
for
my
$k
(
sort
keys
%$attrs
){
my
$v
=
$attrs
->{
$k
};
if
(
ref
(
$v
) eq
'SCALAR'
){
$v
=
$$v
;
}
elsif
(
$v
!~/^\s*(?:function\s*\()/) {
$v
= encode_json
$v
;
}
push
@options
,
"$k: $v"
;
}
}
else
{
push
@options
,
$attrs
;
}
$binding
.=
join
",\n"
.(
$INDENT_BINDING
?
' '
:
''
),
@options
;
$binding
.=
'}'
if
ref
(
$attrs
) eq
'HASH'
;
$binding
.=
');'
. (
$INDENT_BINDING
?
"\n"
:
""
);
$binding
.=
join
";\n"
.(
$INDENT_BINDING
?
' '
:
''
),
@$extensions
if
defined
$extensions
;
$c
->stash(
'dxHelper'
)->add_binding(
$binding
);
out
join
(
''
,
@$befores
).
'<div id="'
.
$id
.
'"></div>'
.
join
(
''
,
@$afters
);
}
sub
parse_attributs{
my
$c
=
shift
;
my
@implicit_args
= @{
shift
()};
my
%attrs
;
IMPLICIT_ARGUMENT:
while
(
@_
and
@implicit_args
){
my
$ref
=
ref
(
$_
[0]);
my
$implicit
=
shift
@implicit_args
||
''
;
last
unless
$ref
=~ /^(?:|SCALAR)$/
or (
substr
(
$implicit
,0,1) eq
'@'
and
$ref
eq
'ARRAY'
)
or (
substr
(
$implicit
,0,1) eq
'%'
and
$ref
eq
'HASH'
)
or (
substr
(
$implicit
,0,1) eq
'\\'
and
$ref
eq
'REF'
)
or (
substr
(
$implicit
,0,1) eq
'*'
);
$implicit
=~ s/^[\\\*\%\@]//;
$attrs
{
$implicit
} =
shift
@_
;
}
if
(
my
$args
=
shift
){
if
(
ref
(
$args
) eq
'HASH'
){
NAMED_ARGUMENT:
while
(
my
(
$k
,
$v
)=
each
%$args
){
$attrs
{
$k
} =
$v
;
}
}
}
return
\
%attrs
;
}
sub
dxmenu {
my
$c
=
shift
;
my
$attrs
= parse_attributs(
$c
, [
qw(id @items onItemClick)
],
@_
);
my
$id
=
delete
(
$attrs
->{id}) // new_id(
$c
,
$attrs
);
dxbind(
$c
,
'dxMenu'
=>
$id
=>
$attrs
);
}
sub
dxloadpanel {
my
$c
=
shift
;
my
$attrs
= parse_attributs(
$c
, [
qw(id message)
],
@_
);
my
$id
=
delete
(
$attrs
->{id}) // new_id(
$c
,
$attrs
);
dxbind(
$c
,
'dxLoadPanel'
=>
$id
=>
$attrs
);
}
sub
dxbutton {
my
$c
=
shift
;
my
$attrs
= parse_attributs(
$c
, [
qw(id text onClick type)
],
@_
);
my
$id
=
delete
(
$attrs
->{id}) // new_id(
$c
,
$attrs
);
dxbind(
$c
,
'dxButton'
=>
$id
=>
$attrs
);
}
sub
dxdatagrid{
my
$c
=
shift
;
my
$attrs
= parse_attributs(
$c
, [
qw(id dataSource)
],
@_
);
my
$id
=
delete
(
$attrs
->{id}) // new_id(
$c
,
$attrs
);
my
@extensions
;
if
(
$attrs
->{dataSource} &&
ref
(
$attrs
->{dataSource}) eq
''
) {
my
$dataSource
=
delete
$attrs
->{dataSource};
$attrs
->{dataSource} = \
"{store:{type:'odata',url:'$dataSource'}}"
;
}
if
(
exists
$attrs
->{options}) {
$attrs
=
$attrs
->{options};
}
dxbind(
$c
,
'dxDataGrid'
=>
$id
=>
$attrs
, \
@extensions
);
}
sub
dxpopup{
my
$c
=
shift
;
my
$attrs
= parse_attributs(
$c
, [
qw(id title contentTemplate)
],
@_
);
my
$id
=
delete
(
$attrs
->{id}) // new_id(
$c
,
$attrs
);
dxbind(
$c
,
'dxPopup'
=>
$id
=>
$attrs
);
}
sub
dxswitch{
my
$c
=
shift
;
my
$attrs
= parse_attributs(
$c
, [
qw(id value label)
],
@_
);
my
$id
=
delete
(
$attrs
->{id});
if
(
my
$name
=
$id
) {
$attrs
->{attr}{name}=
$name
;
}
$id
//= new_id(
$c
,
$attrs
);
$attrs
->{onText} //=
'On'
;
$attrs
->{offText} //=
'Off'
;
my
(
@before
,
@after
);
if
(
my
$label
=
delete
(
$attrs
->{label})){
push
@before
,
'<div class="dx-field">'
;
push
@before
,
'<div class="dx-field-label">'
.
$label
.
'</div>'
;
push
@before
,
'<div class="dx-field-value">'
;
push
@after
,
'</div>'
;
push
@after
,
'</div>'
;
}
dxbind(
$c
,
'dxSwitch'
=>
$id
=>
$attrs
,
undef
, \
@before
, \
@after
);
}
sub
dxtextbox{
my
$c
=
shift
;
my
$attrs
= parse_attributs(
$c
, [
qw(id value label)
],
@_
);
my
$id
=
delete
(
$attrs
->{id});
if
(
my
$name
=
$id
) {
$attrs
->{attr}{name}=
$name
;
}
$id
//= new_id(
$c
,
$attrs
);
my
(
@before
,
@after
);
if
(
my
$label
=
delete
(
$attrs
->{label})){
push
@before
,
'<div class="dx-field">'
;
push
@before
,
'<div class="dx-field-label">'
.
$label
.
'</div>'
;
push
@before
,
'<div class="dx-field-value">'
;
push
@after
,
'</div>'
;
push
@after
,
'</div>'
;
}
dxbind(
$c
,
'dxTextBox'
=>
$id
=>
$attrs
,
undef
, \
@before
, \
@after
);
}
sub
dxlookup{
my
$c
=
shift
;
my
$attrs
= parse_attributs(
$c
, [
qw(id value label)
],
@_
);
my
$id
=
delete
(
$attrs
->{id});
if
(
my
$name
=
$id
) {
$attrs
->{attr}{name}=
$name
;
}
$id
//= new_id(
$c
,
$attrs
);
my
(
@before
,
@after
);
if
(
my
$label
=
delete
(
$attrs
->{label})){
push
@before
,
'<div class="dx-field">'
;
push
@before
,
'<div class="dx-field-label">'
.
$label
.
'</div>'
;
push
@before
,
'<div class="dx-field-value">'
;
push
@after
,
'</div>'
;
push
@after
,
'</div>'
;
}
dxbind(
$c
,
'dxLookup'
=>
$id
=>
$attrs
,
undef
, \
@before
, \
@after
);
}
sub
dxselectbox{
my
$c
=
shift
;
my
$attrs
= parse_attributs(
$c
, [
qw(id value label)
],
@_
);
my
$id
=
delete
(
$attrs
->{id});
if
(
my
$name
=
$id
) {
$attrs
->{attr}{name}=
$name
;
}
$id
//= new_id(
$c
,
$attrs
);
my
(
@before
,
@after
);
if
(
my
$label
=
delete
(
$attrs
->{label})){
push
@before
,
'<div class="dx-field">'
;
push
@before
,
'<div class="dx-field-label">'
.
$label
.
'</div>'
;
push
@before
,
'<div class="dx-field-value">'
;
push
@after
,
'</div>'
;
push
@after
,
'</div>'
;
}
dxbind(
$c
,
'dxSelectBox'
=>
$id
=>
$attrs
,
undef
, \
@before
, \
@after
);
}
sub
dxbuild {
my
$c
=
shift
;
my
$dxhelper
=
$c
->stash(
'dxHelper'
) or
return
;
if
(
$dxhelper
->{bindings}){
out
'<script language="javascript">$(function(){'
.
$dxhelper
->{bindings}.
'});</script>'
;
}
}
sub
require_asset{
my
$c
=
shift
;
my
$dxhelper
=
$c
->stash(
'dxHelper'
) or
return
;
push
@{
$dxhelper
->{required_assets} },
$_
for
@_
;
return
$c
;
}
sub
required_assets{
my
$c
=
shift
;
my
$dxhelper
=
$c
->stash(
'dxHelper'
) or
return
;
my
$required_assets
=
$dxhelper
->{required_assets} // [];
my
$results
= Mojo::ByteStream->new();
ASSET:
for
my
$asset
(
@$required_assets
){
$$results
.= ${
$c
->asset(
$asset
) };
}
return
$results
;
}
my
@without_prefix
=
qw( dxbuild required_assets require_asset indent_binding )
;
my
@with_prefix
=
qw( Button DataGrid Popup TextBox TextArea Switch
Menu LoadPanel
SelectBox NumberBox List DateBox CheckBox Calendar Box Lookup )
;
sub
register {
my
(
$self
,
$app
,
$args
) =
@_
;
my
$tp
=
$args
->{tag_prefix};
SUB_NO_PREFIX:
for
my
$subname
(
@without_prefix
){
my
$lc_name
=
lc
$subname
;
my
$sub
= __PACKAGE__->can(
$lc_name
);
unless
(
$sub
){
$app
->
log
->debug(__PACKAGE__.
" helper '$lc_name' does not exists!"
);
next
SUB_NO_PREFIX;
}
$app
->helper(
$lc_name
=>
$sub
);
}
SUB_WITH_PREFIX:
for
my
$subname
(
@with_prefix
){
my
$lc_name
=
lc
$subname
;
my
$sub
= __PACKAGE__->can(
'dx'
.
$lc_name
);
unless
(
$sub
){
$app
->
log
->debug(__PACKAGE__.
" helper 'dx$lc_name' does not exists!"
);
next
SUB_WITH_PREFIX;
}
say
STDERR
"## adding helper '$tp$lc_name'"
if
DEBUG;
$app
->helper(
$tp
.
$lc_name
=>
$sub
);
say
STDERR
"## adding helper '$tp$subname'"
if
DEBUG and
$args
->{tag_camelcase};
$app
->helper(
$tp
.
$subname
=>
$sub
)
if
$args
->{tag_camelcase};
}
}
1;