Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
flask-admin
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Python-Dev
flask-admin
Commits
37ae5a07
Commit
37ae5a07
authored
Mar 20, 2012
by
Serge S. Koval
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Multi-select for many-to-one relationships, jQuery Chosen for drop downs, fixes.
parent
52131105
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
473 additions
and
22 deletions
+473
-22
TODO.txt
TODO.txt
+0
-2
simple.py
examples/sqla/simple.py
+3
-0
sqlamodel.py
flask_adminex/ext/sqlamodel.py
+32
-10
form.py
flask_adminex/form.py
+12
-0
model.py
flask_adminex/model.py
+1
-1
chosen-sprite.png
flask_adminex/static/chosen/chosen-sprite.png
+0
-0
chosen.css
flask_adminex/static/chosen/chosen.css
+392
-0
chosen.jquery.min.js
flask_adminex/static/chosen/chosen.jquery.min.js
+10
-0
master.html
flask_adminex/templates/admin/master.html
+9
-1
edit.html
flask_adminex/templates/admin/model/edit.html
+14
-8
No files found.
TODO.txt
View file @
37ae5a07
...
@@ -3,14 +3,12 @@
...
@@ -3,14 +3,12 @@
- Override base URL (/admin/)
- Override base URL (/admin/)
- Model Admin
- Model Admin
- Ability to sort by fields that are not visible?
- Ability to sort by fields that are not visible?
- Proper error display
- SQLA Model Admin
- SQLA Model Admin
- Validation of the joins in the query
- Validation of the joins in the query
- Automatic joined load for foreign keys
- Automatic joined load for foreign keys
- Automatic PK detection
- Automatic PK detection
- Filtering
- Filtering
- Many2Many editing
- Many2Many editing
- One2Many editor
- File admin
- File admin
- Documentation
- Documentation
- Examples
- Examples
...
...
examples/sqla/simple.py
View file @
37ae5a07
...
@@ -37,6 +37,9 @@ class Post(db.Model):
...
@@ -37,6 +37,9 @@ class Post(db.Model):
user_id
=
db
.
Column
(
db
.
Integer
,
db
.
ForeignKey
(
User
.
id
))
user_id
=
db
.
Column
(
db
.
Integer
,
db
.
ForeignKey
(
User
.
id
))
user
=
db
.
relationship
(
User
,
backref
=
'posts'
)
user
=
db
.
relationship
(
User
,
backref
=
'posts'
)
def
__unicode__
(
self
):
return
self
.
title
# Flask routes
# Flask routes
@
app
.
route
(
'/'
)
@
app
.
route
(
'/'
)
...
...
flask_adminex/ext/sqlamodel.py
View file @
37ae5a07
from
sqlalchemy.orm.properties
import
RelationshipProperty
,
ColumnProperty
from
sqlalchemy.orm.properties
import
RelationshipProperty
,
ColumnProperty
from
sqlalchemy.orm.interfaces
import
MANYTOONE
from
sqlalchemy.orm.interfaces
import
MANYTOONE
,
ONETOMANY
from
sqlalchemy.orm.attributes
import
InstrumentedAttribute
from
sqlalchemy.orm.attributes
import
InstrumentedAttribute
from
sqlalchemy.sql.expression
import
desc
from
sqlalchemy.sql.expression
import
desc
from
wtforms.ext.sqlalchemy.orm
import
model_form
,
ModelConverter
from
wtforms.ext.sqlalchemy.orm
import
model_form
,
ModelConverter
from
wtforms.ext.sqlalchemy.fields
import
QuerySelectField
from
wtforms.ext.sqlalchemy.fields
import
QuerySelectField
,
QuerySelectMultipleField
from
flask
import
flash
from
flask
import
flash
from
flaskext
import
wtf
from
flaskext
import
wtf
from
flask.ext.adminex.model
import
BaseModelView
from
flask.ext.adminex.model
import
BaseModelView
from
flask.ext.adminex.form
import
AdminForm
class
AdminModelConverter
(
ModelConverter
):
class
AdminModelConverter
(
ModelConverter
):
"""
"""
SQLAlchemy model to form converter
SQLAlchemy model to form converter
"""
"""
def
__init__
(
self
,
session
):
def
__init__
(
self
,
view
):
super
(
AdminModelConverter
,
self
)
.
__init__
()
super
(
AdminModelConverter
,
self
)
.
__init__
()
self
.
session
=
session
self
.
view
=
view
def
convert
(
self
,
model
,
mapper
,
prop
,
field_args
):
def
convert
(
self
,
model
,
mapper
,
prop
,
field_args
):
if
isinstance
(
prop
,
RelationshipProperty
):
if
isinstance
(
prop
,
RelationshipProperty
):
local_column
=
prop
.
local_remote_pairs
[
0
][
0
]
remote_model
=
prop
.
mapper
.
class_
kwargs
=
{
kwargs
=
{
'validators'
:
[],
'validators'
:
[],
'filters'
:
[],
'filters'
:
[],
'allow_blank'
:
local_column
.
nullable
,
'default'
:
None
'default'
:
None
}
}
if
field_args
:
if
field_args
:
kwargs
.
update
(
field_args
)
kwargs
.
update
(
field_args
)
if
prop
.
direction
is
MANYTOONE
:
def
query_factory
():
def
query_factory
():
return
self
.
view
.
session
.
query
(
remote_model
)
return
self
.
session
.
query
(
prop
.
argument
)
if
prop
.
direction
is
MANYTOONE
:
return
QuerySelectField
(
query_factory
=
query_factory
,
**
kwargs
)
return
QuerySelectField
(
query_factory
=
query_factory
,
**
kwargs
)
elif
prop
.
direction
is
ONETOMANY
:
# Skip backrefs
if
not
local_column
.
foreign_keys
and
self
.
view
.
hide_backrefs
:
return
None
return
QuerySelectMultipleField
(
query_factory
=
query_factory
,
**
kwargs
)
else
:
else
:
# Ignore pk/fk
# Ignore pk/fk
if
isinstance
(
prop
,
ColumnProperty
):
if
isinstance
(
prop
,
ColumnProperty
):
...
@@ -58,6 +69,12 @@ class ModelView(BaseModelView):
...
@@ -58,6 +69,12 @@ class ModelView(BaseModelView):
admin = ModelView(User, db.session)
admin = ModelView(User, db.session)
"""
"""
hide_backrefs
=
True
"""
Set this to False if you want to see multiselect for model backrefs.
"""
def
__init__
(
self
,
model
,
session
,
def
__init__
(
self
,
model
,
session
,
name
=
None
,
category
=
None
,
endpoint
=
None
,
url
=
None
):
name
=
None
,
category
=
None
,
endpoint
=
None
,
url
=
None
):
"""
"""
...
@@ -115,9 +132,14 @@ class ModelView(BaseModelView):
...
@@ -115,9 +132,14 @@ class ModelView(BaseModelView):
for
p
in
mapper
.
iterate_properties
:
for
p
in
mapper
.
iterate_properties
:
if
isinstance
(
p
,
ColumnProperty
):
if
isinstance
(
p
,
ColumnProperty
):
# TODO: Check for multiple columns
# Sanity check
if
len
(
p
.
columns
)
>
1
:
raise
Exception
(
'Automatic form scaffolding is not supported'
+
' for multi-column properties (
%
s.
%
s)'
%
(
self
.
model
.
__name__
,
p
.
key
))
column
=
p
.
columns
[
0
]
column
=
p
.
columns
[
0
]
# Can't sort by on primary and foreign keys by default
if
column
.
foreign_keys
or
column
.
primary_key
:
if
column
.
foreign_keys
or
column
.
primary_key
:
continue
continue
...
@@ -130,10 +152,10 @@ class ModelView(BaseModelView):
...
@@ -130,10 +152,10 @@ class ModelView(BaseModelView):
Create form from the model.
Create form from the model.
"""
"""
return
model_form
(
self
.
model
,
return
model_form
(
self
.
model
,
wtf
.
Form
,
Admin
Form
,
self
.
form_columns
,
self
.
form_columns
,
field_args
=
self
.
form_args
,
field_args
=
self
.
form_args
,
converter
=
AdminModelConverter
(
self
.
session
))
converter
=
AdminModelConverter
(
self
))
# Database-related API
# Database-related API
def
get_list
(
self
,
page
,
sort_column
,
sort_desc
,
execute
=
True
):
def
get_list
(
self
,
page
,
sort_column
,
sort_desc
,
execute
=
True
):
...
...
flask_adminex/form.py
0 → 100644
View file @
37ae5a07
from
flask.ext
import
wtf
class
AdminForm
(
wtf
.
Form
):
@
property
def
has_file_field
(
self
):
# TODO: Optimize me
for
f
in
self
:
if
isinstance
(
f
,
wtf
.
FileField
):
return
True
return
False
flask_adminex/model.py
View file @
37ae5a07
...
@@ -220,7 +220,7 @@ class BaseModelView(BaseView):
...
@@ -220,7 +220,7 @@ class BaseModelView(BaseView):
def
scaffold_form
(
self
):
def
scaffold_form
(
self
):
"""
"""
Create
WTForm
class from the model. Must be implemented in
Create
`form.AdminForm`
class from the model. Must be implemented in
the child class.
the child class.
"""
"""
raise
NotImplemented
(
'Please implement scaffold_form method'
)
raise
NotImplemented
(
'Please implement scaffold_form method'
)
...
...
flask_adminex/static/chosen/chosen-sprite.png
0 → 100644
View file @
37ae5a07
559 Bytes
flask_adminex/static/chosen/chosen.css
0 → 100644
View file @
37ae5a07
/* @group Base */
.chzn-container
{
font-size
:
13px
;
position
:
relative
;
display
:
inline-block
;
zoom
:
1
;
*
display
:
inline
;
}
.chzn-container
.chzn-drop
{
background
:
#fff
;
border
:
1px
solid
#aaa
;
border-top
:
0
;
position
:
absolute
;
top
:
29px
;
left
:
0
;
-webkit-box-shadow
:
0
4px
5px
rgba
(
0
,
0
,
0
,
.15
);
-moz-box-shadow
:
0
4px
5px
rgba
(
0
,
0
,
0
,
.15
);
-o-box-shadow
:
0
4px
5px
rgba
(
0
,
0
,
0
,
.15
);
box-shadow
:
0
4px
5px
rgba
(
0
,
0
,
0
,
.15
);
z-index
:
999
;
}
/* @end */
/* @group Single Chosen */
.chzn-container-single
.chzn-single
{
background-color
:
#ffffff
;
filter
:
progid
:
DXImageTransform
.
Microsoft
.
gradient
(
startColorstr
=
'#ffffff'
,
endColorstr
=
'#eeeeee'
,
GradientType
=
0
);
background-image
:
-webkit-gradient
(
linear
,
0%
0%
,
0%
100%
,
color-stop
(
20%
,
#ffffff
),
color-stop
(
50%
,
#f6f6f6
),
color-stop
(
52%
,
#eeeeee
),
color-stop
(
100%
,
#f4f4f4
));
background-image
:
-webkit-linear-gradient
(
top
,
#ffffff
20%
,
#f6f6f6
50%
,
#eeeeee
52%
,
#f4f4f4
100%
);
background-image
:
-moz-linear-gradient
(
top
,
#ffffff
20%
,
#f6f6f6
50%
,
#eeeeee
52%
,
#f4f4f4
100%
);
background-image
:
-o-linear-gradient
(
top
,
#ffffff
20%
,
#f6f6f6
50%
,
#eeeeee
52%
,
#f4f4f4
100%
);
background-image
:
-ms-linear-gradient
(
top
,
#ffffff
20%
,
#f6f6f6
50%
,
#eeeeee
52%
,
#f4f4f4
100%
);
background-image
:
linear-gradient
(
top
,
#ffffff
20%
,
#f6f6f6
50%
,
#eeeeee
52%
,
#f4f4f4
100%
);
-webkit-border-radius
:
5px
;
-moz-border-radius
:
5px
;
border-radius
:
5px
;
-moz-background-clip
:
padding
;
-webkit-background-clip
:
padding-box
;
background-clip
:
padding-box
;
border
:
1px
solid
#aaaaaa
;
-webkit-box-shadow
:
0
0
3px
#ffffff
inset
,
0
1px
1px
rgba
(
0
,
0
,
0
,
0.1
);
-moz-box-shadow
:
0
0
3px
#ffffff
inset
,
0
1px
1px
rgba
(
0
,
0
,
0
,
0.1
);
box-shadow
:
0
0
3px
#ffffff
inset
,
0
1px
1px
rgba
(
0
,
0
,
0
,
0.1
);
display
:
block
;
overflow
:
hidden
;
white-space
:
nowrap
;
position
:
relative
;
height
:
23px
;
line-height
:
24px
;
padding
:
0
0
0
8px
;
color
:
#444444
;
text-decoration
:
none
;
}
.chzn-container-single
.chzn-default
{
color
:
#999
;
}
.chzn-container-single
.chzn-single
span
{
margin-right
:
26px
;
display
:
block
;
overflow
:
hidden
;
white-space
:
nowrap
;
-o-text-overflow
:
ellipsis
;
-ms-text-overflow
:
ellipsis
;
text-overflow
:
ellipsis
;
}
.chzn-container-single
.chzn-single
abbr
{
display
:
block
;
position
:
absolute
;
right
:
26px
;
top
:
6px
;
width
:
12px
;
height
:
13px
;
font-size
:
1px
;
background
:
url('chosen-sprite.png')
right
top
no-repeat
;
}
.chzn-container-single
.chzn-single
abbr
:hover
{
background-position
:
right
-11px
;
}
.chzn-container-single
.chzn-single
div
{
position
:
absolute
;
right
:
0
;
top
:
0
;
display
:
block
;
height
:
100%
;
width
:
18px
;
}
.chzn-container-single
.chzn-single
div
b
{
background
:
url('chosen-sprite.png')
no-repeat
0
0
;
display
:
block
;
width
:
100%
;
height
:
100%
;
}
.chzn-container-single
.chzn-search
{
padding
:
3px
4px
;
position
:
relative
;
margin
:
0
;
white-space
:
nowrap
;
z-index
:
1010
;
}
.chzn-container-single
.chzn-search
input
{
background
:
#fff
url('chosen-sprite.png')
no-repeat
100%
-22px
;
background
:
url('chosen-sprite.png')
no-repeat
100%
-22px
,
-webkit-gradient
(
linear
,
0%
0%
,
0%
100%
,
color-stop
(
1%
,
#eeeeee
),
color-stop
(
15%
,
#ffffff
));
background
:
url('chosen-sprite.png')
no-repeat
100%
-22px
,
-webkit-linear-gradient
(
top
,
#eeeeee
1%
,
#ffffff
15%
);
background
:
url('chosen-sprite.png')
no-repeat
100%
-22px
,
-moz-linear-gradient
(
top
,
#eeeeee
1%
,
#ffffff
15%
);
background
:
url('chosen-sprite.png')
no-repeat
100%
-22px
,
-o-linear-gradient
(
top
,
#eeeeee
1%
,
#ffffff
15%
);
background
:
url('chosen-sprite.png')
no-repeat
100%
-22px
,
-ms-linear-gradient
(
top
,
#eeeeee
1%
,
#ffffff
15%
);
background
:
url('chosen-sprite.png')
no-repeat
100%
-22px
,
linear-gradient
(
top
,
#eeeeee
1%
,
#ffffff
15%
);
margin
:
1px
0
;
padding
:
4px
20px
4px
5px
;
outline
:
0
;
border
:
1px
solid
#aaa
;
font-family
:
sans-serif
;
font-size
:
1em
;
}
.chzn-container-single
.chzn-drop
{
-webkit-border-radius
:
0
0
4px
4px
;
-moz-border-radius
:
0
0
4px
4px
;
border-radius
:
0
0
4px
4px
;
-moz-background-clip
:
padding
;
-webkit-background-clip
:
padding-box
;
background-clip
:
padding-box
;
}
/* @end */
.chzn-container-single-nosearch
.chzn-search
input
{
position
:
absolute
;
left
:
-9000px
;
}
/* @group Multi Chosen */
.chzn-container-multi
.chzn-choices
{
background-color
:
#fff
;
background-image
:
-webkit-gradient
(
linear
,
0%
0%
,
0%
100%
,
color-stop
(
1%
,
#eeeeee
),
color-stop
(
15%
,
#ffffff
));
background-image
:
-webkit-linear-gradient
(
top
,
#eeeeee
1%
,
#ffffff
15%
);
background-image
:
-moz-linear-gradient
(
top
,
#eeeeee
1%
,
#ffffff
15%
);
background-image
:
-o-linear-gradient
(
top
,
#eeeeee
1%
,
#ffffff
15%
);
background-image
:
-ms-linear-gradient
(
top
,
#eeeeee
1%
,
#ffffff
15%
);
background-image
:
linear-gradient
(
top
,
#eeeeee
1%
,
#ffffff
15%
);
border
:
1px
solid
#aaa
;
margin
:
0
;
padding
:
0
;
cursor
:
text
;
overflow
:
hidden
;
height
:
auto
!important
;
height
:
1%
;
position
:
relative
;
}
.chzn-container-multi
.chzn-choices
li
{
float
:
left
;
list-style
:
none
;
}
.chzn-container-multi
.chzn-choices
.search-field
{
white-space
:
nowrap
;
margin
:
0
;
padding
:
0
;
}
.chzn-container-multi
.chzn-choices
.search-field
input
{
color
:
#666
;
background
:
transparent
!important
;
border
:
0
!important
;
font-family
:
sans-serif
;
font-size
:
100%
;
height
:
15px
;
padding
:
5px
;
margin
:
1px
0
;
outline
:
0
;
-webkit-box-shadow
:
none
;
-moz-box-shadow
:
none
;
-o-box-shadow
:
none
;
box-shadow
:
none
;
}
.chzn-container-multi
.chzn-choices
.search-field
.default
{
color
:
#999
;
}
.chzn-container-multi
.chzn-choices
.search-choice
{
-webkit-border-radius
:
3px
;
-moz-border-radius
:
3px
;
border-radius
:
3px
;
-moz-background-clip
:
padding
;
-webkit-background-clip
:
padding-box
;
background-clip
:
padding-box
;
background-color
:
#e4e4e4
;
filter
:
progid
:
DXImageTransform
.
Microsoft
.
gradient
(
startColorstr
=
'#f4f4f4'
,
endColorstr
=
'#eeeeee'
,
GradientType
=
0
);
background-image
:
-webkit-gradient
(
linear
,
0%
0%
,
0%
100%
,
color-stop
(
20%
,
#f4f4f4
),
color-stop
(
50%
,
#f0f0f0
),
color-stop
(
52%
,
#e8e8e8
),
color-stop
(
100%
,
#eeeeee
));
background-image
:
-webkit-linear-gradient
(
top
,
#f4f4f4
20%
,
#f0f0f0
50%
,
#e8e8e8
52%
,
#eeeeee
100%
);
background-image
:
-moz-linear-gradient
(
top
,
#f4f4f4
20%
,
#f0f0f0
50%
,
#e8e8e8
52%
,
#eeeeee
100%
);
background-image
:
-o-linear-gradient
(
top
,
#f4f4f4
20%
,
#f0f0f0
50%
,
#e8e8e8
52%
,
#eeeeee
100%
);
background-image
:
-ms-linear-gradient
(
top
,
#f4f4f4
20%
,
#f0f0f0
50%
,
#e8e8e8
52%
,
#eeeeee
100%
);
background-image
:
linear-gradient
(
top
,
#f4f4f4
20%
,
#f0f0f0
50%
,
#e8e8e8
52%
,
#eeeeee
100%
);
-webkit-box-shadow
:
0
0
2px
#ffffff
inset
,
0
1px
0
rgba
(
0
,
0
,
0
,
0.05
);
-moz-box-shadow
:
0
0
2px
#ffffff
inset
,
0
1px
0
rgba
(
0
,
0
,
0
,
0.05
);
box-shadow
:
0
0
2px
#ffffff
inset
,
0
1px
0
rgba
(
0
,
0
,
0
,
0.05
);
color
:
#333
;
border
:
1px
solid
#aaaaaa
;
line-height
:
13px
;
padding
:
3px
20px
3px
5px
;
margin
:
3px
0
3px
5px
;
position
:
relative
;
cursor
:
default
;
}
.chzn-container-multi
.chzn-choices
.search-choice-focus
{
background
:
#d4d4d4
;
}
.chzn-container-multi
.chzn-choices
.search-choice
.search-choice-close
{
display
:
block
;
position
:
absolute
;
right
:
3px
;
top
:
4px
;
width
:
12px
;
height
:
13px
;
font-size
:
1px
;
background
:
url('chosen-sprite.png')
right
top
no-repeat
;
}
.chzn-container-multi
.chzn-choices
.search-choice
.search-choice-close
:hover
{
background-position
:
right
-11px
;
}
.chzn-container-multi
.chzn-choices
.search-choice-focus
.search-choice-close
{
background-position
:
right
-11px
;
}
/* @end */
/* @group Results */
.chzn-container
.chzn-results
{
margin
:
0
4px
4px
0
;
max-height
:
240px
;
padding
:
0
0
0
4px
;
position
:
relative
;
overflow-x
:
hidden
;
overflow-y
:
auto
;
}
.chzn-container-multi
.chzn-results
{
margin
:
-1px
0
0
;
padding
:
0
;
}
.chzn-container
.chzn-results
li
{
display
:
none
;
line-height
:
15px
;
padding
:
5px
6px
;
margin
:
0
;
list-style
:
none
;
}
.chzn-container
.chzn-results
.active-result
{
cursor
:
pointer
;
display
:
list-item
;
}
.chzn-container
.chzn-results
.highlighted
{
background-color
:
#3875d7
;
filter
:
progid
:
DXImageTransform
.
Microsoft
.
gradient
(
startColorstr
=
'#3875d7'
,
endColorstr
=
'#2a62bc'
,
GradientType
=
0
);
background-image
:
-webkit-gradient
(
linear
,
0%
0%
,
0%
100%
,
color-stop
(
20%
,
#3875d7
),
color-stop
(
90%
,
#2a62bc
));
background-image
:
-webkit-linear-gradient
(
top
,
#3875d7
20%
,
#2a62bc
90%
);
background-image
:
-moz-linear-gradient
(
top
,
#3875d7
20%
,
#2a62bc
90%
);
background-image
:
-o-linear-gradient
(
top
,
#3875d7
20%
,
#2a62bc
90%
);
background-image
:
-ms-linear-gradient
(
top
,
#3875d7
20%
,
#2a62bc
90%
);
background-image
:
linear-gradient
(
top
,
#3875d7
20%
,
#2a62bc
90%
);
color
:
#fff
;
}
.chzn-container
.chzn-results
li
em
{
background
:
#feffde
;
font-style
:
normal
;
}
.chzn-container
.chzn-results
.highlighted
em
{
background
:
transparent
;
}
.chzn-container
.chzn-results
.no-results
{
background
:
#f4f4f4
;
display
:
list-item
;
}
.chzn-container
.chzn-results
.group-result
{
cursor
:
default
;
color
:
#999
;
font-weight
:
bold
;
}
.chzn-container
.chzn-results
.group-option
{
padding-left
:
15px
;
}
.chzn-container-multi
.chzn-drop
.result-selected
{
display
:
none
;
}
.chzn-container
.chzn-results-scroll
{
background
:
white
;
margin
:
0
4px
;
position
:
absolute
;
text-align
:
center
;
width
:
321px
;
/* This should by dynamic with js */
z-index
:
1
;
}
.chzn-container
.chzn-results-scroll
span
{
display
:
inline-block
;
height
:
17px
;
text-indent
:
-5000px
;
width
:
9px
;
}
.chzn-container
.chzn-results-scroll-down
{
bottom
:
0
;
}
.chzn-container
.chzn-results-scroll-down
span
{
background
:
url('chosen-sprite.png')
no-repeat
-4px
-3px
;
}
.chzn-container
.chzn-results-scroll-up
span
{
background
:
url('chosen-sprite.png')
no-repeat
-22px
-3px
;
}
/* @end */
/* @group Active */
.chzn-container-active
.chzn-single
{
-webkit-box-shadow
:
0
0
5px
rgba
(
0
,
0
,
0
,
.3
);
-moz-box-shadow
:
0
0
5px
rgba
(
0
,
0
,
0
,
.3
);
-o-box-shadow
:
0
0
5px
rgba
(
0
,
0
,
0
,
.3
);
box-shadow
:
0
0
5px
rgba
(
0
,
0
,
0
,
.3
);
border
:
1px
solid
#5897fb
;
}
.chzn-container-active
.chzn-single-with-drop
{
border
:
1px
solid
#aaa
;
-webkit-box-shadow
:
0
1px
0
#fff
inset
;
-moz-box-shadow
:
0
1px
0
#fff
inset
;
-o-box-shadow
:
0
1px
0
#fff
inset
;
box-shadow
:
0
1px
0
#fff
inset
;
background-color
:
#eee
;
filter
:
progid
:
DXImageTransform
.
Microsoft
.
gradient
(
startColorstr
=
'#eeeeee'
,
endColorstr
=
'#ffffff'
,
GradientType
=
0
);
background-image
:
-webkit-gradient
(
linear
,
0%
0%
,
0%
100%
,
color-stop
(
20%
,
#eeeeee
),
color-stop
(
80%
,
#ffffff
));
background-image
:
-webkit-linear-gradient
(
top
,
#eeeeee
20%
,
#ffffff
80%
);
background-image
:
-moz-linear-gradient
(
top
,
#eeeeee
20%
,
#ffffff
80%
);
background-image
:
-o-linear-gradient
(
top
,
#eeeeee
20%
,
#ffffff
80%
);
background-image
:
-ms-linear-gradient
(
top
,
#eeeeee
20%
,
#ffffff
80%
);
background-image
:
linear-gradient
(
top
,
#eeeeee
20%
,
#ffffff
80%
);
-webkit-border-bottom-left-radius
:
0
;
-webkit-border-bottom-right-radius
:
0
;
-moz-border-radius-bottomleft
:
0
;
-moz-border-radius-bottomright
:
0
;
border-bottom-left-radius
:
0
;
border-bottom-right-radius
:
0
;
}
.chzn-container-active
.chzn-single-with-drop
div
{
background
:
transparent
;
border-left
:
none
;
}
.chzn-container-active
.chzn-single-with-drop
div
b
{
background-position
:
-18px
1px
;
}
.chzn-container-active
.chzn-choices
{
-webkit-box-shadow
:
0
0
5px
rgba
(
0
,
0
,
0
,
.3
);
-moz-box-shadow
:
0
0
5px
rgba
(
0
,
0
,
0
,
.3
);
-o-box-shadow
:
0
0
5px
rgba
(
0
,
0
,
0
,
.3
);
box-shadow
:
0
0
5px
rgba
(
0
,
0
,
0
,
.3
);
border
:
1px
solid
#5897fb
;
}
.chzn-container-active
.chzn-choices
.search-field
input
{
color
:
#111
!important
;
}
/* @end */
/* @group Disabled Support */
.chzn-disabled
{
cursor
:
default
;
opacity
:
0.5
!important
;
}
.chzn-disabled
.chzn-single
{
cursor
:
default
;
}
.chzn-disabled
.chzn-choices
.search-choice
.search-choice-close
{
cursor
:
default
;
}
/* @group Right to Left */
.chzn-rtl
{
text-align
:
right
;
}
.chzn-rtl
.chzn-single
{
padding
:
0
8px
0
0
;
overflow
:
visible
;
}
.chzn-rtl
.chzn-single
span
{
margin-left
:
26px
;
margin-right
:
0
;
direction
:
rtl
;
}
.chzn-rtl
.chzn-single
div
{
left
:
3px
;
right
:
auto
;
}
.chzn-rtl
.chzn-single
abbr
{
left
:
26px
;
right
:
auto
;
}
.chzn-rtl
.chzn-choices
.search-field
input
{
direction
:
rtl
;
}
.chzn-rtl
.chzn-choices
li
{
float
:
right
;
}
.chzn-rtl
.chzn-choices
.search-choice
{
padding
:
3px
5px
3px
19px
;
margin
:
3px
5px
3px
0
;
}
.chzn-rtl
.chzn-choices
.search-choice
.search-choice-close
{
left
:
4px
;
right
:
auto
;
background-position
:
right
top
;}
.chzn-rtl.chzn-container-single
.chzn-results
{
margin
:
0
0
4px
4px
;
padding
:
0
4px
0
0
;
}
.chzn-rtl
.chzn-results
.group-option
{
padding-left
:
0
;
padding-right
:
15px
;
}
.chzn-rtl.chzn-container-active
.chzn-single-with-drop
div
{
border-right
:
none
;
}
.chzn-rtl
.chzn-search
input
{
background
:
#fff
url('chosen-sprite.png')
no-repeat
-38px
-22px
;
background
:
url('chosen-sprite.png')
no-repeat
-38px
-22px
,
-webkit-gradient
(
linear
,
0%
0%
,
0%
100%
,
color-stop
(
1%
,
#eeeeee
),
color-stop
(
15%
,
#ffffff
));
background
:
url('chosen-sprite.png')
no-repeat
-38px
-22px
,
-webkit-linear-gradient
(
top
,
#eeeeee
1%
,
#ffffff
15%
);
background
:
url('chosen-sprite.png')
no-repeat
-38px
-22px
,
-moz-linear-gradient
(
top
,
#eeeeee
1%
,
#ffffff
15%
);
background
:
url('chosen-sprite.png')
no-repeat
-38px
-22px
,
-o-linear-gradient
(
top
,
#eeeeee
1%
,
#ffffff
15%
);
background
:
url('chosen-sprite.png')
no-repeat
-38px
-22px
,
-ms-linear-gradient
(
top
,
#eeeeee
1%
,
#ffffff
15%
);
background
:
url('chosen-sprite.png')
no-repeat
-38px
-22px
,
linear-gradient
(
top
,
#eeeeee
1%
,
#ffffff
15%
);
padding
:
4px
5px
4px
20px
;
direction
:
rtl
;
}
/* @end */
flask_adminex/static/chosen/chosen.jquery.min.js
0 → 100644
View file @
37ae5a07
// Chosen, a Select Box Enhancer for jQuery and Protoype
// by Patrick Filler for Harvest, http://getharvest.com
//
// Version 0.9.8
// Full source at https://github.com/harvesthq/chosen
// Copyright (c) 2011 Harvest http://getharvest.com
// MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
// This file is generated by `cake build`, do not edit it by hand.
((
function
(){
var
a
;
a
=
function
(){
function
a
(){
this
.
options_index
=
0
,
this
.
parsed
=
[]}
return
a
.
prototype
.
add_node
=
function
(
a
){
return
a
.
nodeName
===
"OPTGROUP"
?
this
.
add_group
(
a
):
this
.
add_option
(
a
)},
a
.
prototype
.
add_group
=
function
(
a
){
var
b
,
c
,
d
,
e
,
f
,
g
;
b
=
this
.
parsed
.
length
,
this
.
parsed
.
push
({
array_index
:
b
,
group
:
!
0
,
label
:
a
.
label
,
children
:
0
,
disabled
:
a
.
disabled
}),
f
=
a
.
childNodes
,
g
=
[];
for
(
d
=
0
,
e
=
f
.
length
;
d
<
e
;
d
++
)
c
=
f
[
d
],
g
.
push
(
this
.
add_option
(
c
,
b
,
a
.
disabled
));
return
g
},
a
.
prototype
.
add_option
=
function
(
a
,
b
,
c
){
if
(
a
.
nodeName
===
"OPTION"
)
return
a
.
text
!==
""
?(
b
!=
null
&&
(
this
.
parsed
[
b
].
children
+=
1
),
this
.
parsed
.
push
({
array_index
:
this
.
parsed
.
length
,
options_index
:
this
.
options_index
,
value
:
a
.
value
,
text
:
a
.
text
,
html
:
a
.
innerHTML
,
selected
:
a
.
selected
,
disabled
:
c
===!
0
?
c
:
a
.
disabled
,
group_array_index
:
b
,
classes
:
a
.
className
,
style
:
a
.
style
.
cssText
})):
this
.
parsed
.
push
({
array_index
:
this
.
parsed
.
length
,
options_index
:
this
.
options_index
,
empty
:
!
0
}),
this
.
options_index
+=
1
},
a
}(),
a
.
select_to_array
=
function
(
b
){
var
c
,
d
,
e
,
f
,
g
;
d
=
new
a
,
g
=
b
.
childNodes
;
for
(
e
=
0
,
f
=
g
.
length
;
e
<
f
;
e
++
)
c
=
g
[
e
],
d
.
add_node
(
c
);
return
d
.
parsed
},
this
.
SelectParser
=
a
})).
call
(
this
),
function
(){
var
a
,
b
;
b
=
this
,
a
=
function
(){
function
a
(
a
,
b
){
this
.
form_field
=
a
,
this
.
options
=
b
!=
null
?
b
:{},
this
.
set_default_values
(),
this
.
is_multiple
=
this
.
form_field
.
multiple
,
this
.
default_text_default
=
this
.
is_multiple
?
"Select Some Options"
:
"Select an Option"
,
this
.
setup
(),
this
.
set_up_html
(),
this
.
register_observers
(),
this
.
finish_setup
()}
return
a
.
prototype
.
set_default_values
=
function
(){
var
a
=
this
;
return
this
.
click_test_action
=
function
(
b
){
return
a
.
test_active_click
(
b
)},
this
.
activate_action
=
function
(
b
){
return
a
.
activate_field
(
b
)},
this
.
active_field
=!
1
,
this
.
mouse_on_container
=!
1
,
this
.
results_showing
=!
1
,
this
.
result_highlighted
=
null
,
this
.
result_single_selected
=
null
,
this
.
allow_single_deselect
=
this
.
options
.
allow_single_deselect
!=
null
&&
this
.
form_field
.
options
[
0
]
!=
null
&&
this
.
form_field
.
options
[
0
].
text
===
""
?
this
.
options
.
allow_single_deselect
:
!
1
,
this
.
disable_search_threshold
=
this
.
options
.
disable_search_threshold
||
0
,
this
.
search_contains
=
this
.
options
.
search_contains
||!
1
,
this
.
choices
=
0
,
this
.
results_none_found
=
this
.
options
.
no_results_text
||
"No results match"
},
a
.
prototype
.
mouse_enter
=
function
(){
return
this
.
mouse_on_container
=!
0
},
a
.
prototype
.
mouse_leave
=
function
(){
return
this
.
mouse_on_container
=!
1
},
a
.
prototype
.
input_focus
=
function
(
a
){
var
b
=
this
;
if
(
!
this
.
active_field
)
return
setTimeout
(
function
(){
return
b
.
container_mousedown
()},
50
)},
a
.
prototype
.
input_blur
=
function
(
a
){
var
b
=
this
;
if
(
!
this
.
mouse_on_container
)
return
this
.
active_field
=!
1
,
setTimeout
(
function
(){
return
b
.
blur_test
()},
100
)},
a
.
prototype
.
result_add_option
=
function
(
a
){
var
b
,
c
;
return
a
.
disabled
?
""
:(
a
.
dom_id
=
this
.
container_id
+
"_o_"
+
a
.
array_index
,
b
=
a
.
selected
&&
this
.
is_multiple
?[]:[
"active-result"
],
a
.
selected
&&
b
.
push
(
"result-selected"
),
a
.
group_array_index
!=
null
&&
b
.
push
(
"group-option"
),
a
.
classes
!==
""
&&
b
.
push
(
a
.
classes
),
c
=
a
.
style
.
cssText
!==
""
?
' style="'
+
a
.
style
+
'"'
:
""
,
'<li id="'
+
a
.
dom_id
+
'" class="'
+
b
.
join
(
" "
)
+
'"'
+
c
+
">"
+
a
.
html
+
"</li>"
)},
a
.
prototype
.
results_update_field
=
function
(){
return
this
.
result_clear_highlight
(),
this
.
result_single_selected
=
null
,
this
.
results_build
()},
a
.
prototype
.
results_toggle
=
function
(){
return
this
.
results_showing
?
this
.
results_hide
():
this
.
results_show
()},
a
.
prototype
.
results_search
=
function
(
a
){
return
this
.
results_showing
?
this
.
winnow_results
():
this
.
results_show
()},
a
.
prototype
.
keyup_checker
=
function
(
a
){
var
b
,
c
;
b
=
(
c
=
a
.
which
)
!=
null
?
c
:
a
.
keyCode
,
this
.
search_field_scale
();
switch
(
b
){
case
8
:
if
(
this
.
is_multiple
&&
this
.
backstroke_length
<
1
&&
this
.
choices
>
0
)
return
this
.
keydown_backstroke
();
if
(
!
this
.
pending_backstroke
)
return
this
.
result_clear_highlight
(),
this
.
results_search
();
break
;
case
13
:
a
.
preventDefault
();
if
(
this
.
results_showing
)
return
this
.
result_select
(
a
);
break
;
case
27
:
return
this
.
results_showing
&&
this
.
results_hide
(),
!
0
;
case
9
:
case
38
:
case
40
:
case
16
:
case
91
:
case
17
:
break
;
default
:
return
this
.
results_search
()}},
a
.
prototype
.
generate_field_id
=
function
(){
var
a
;
return
a
=
this
.
generate_random_id
(),
this
.
form_field
.
id
=
a
,
a
},
a
.
prototype
.
generate_random_char
=
function
(){
var
a
,
b
,
c
;
return
a
=
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZ"
,
c
=
Math
.
floor
(
Math
.
random
()
*
a
.
length
),
b
=
a
.
substring
(
c
,
c
+
1
)},
a
}(),
b
.
AbstractChosen
=
a
}.
call
(
this
),
function
(){
var
a
,
b
,
c
,
d
,
e
=
Object
.
prototype
.
hasOwnProperty
,
f
=
function
(
a
,
b
){
function
d
(){
this
.
constructor
=
a
}
for
(
var
c
in
b
)
e
.
call
(
b
,
c
)
&&
(
a
[
c
]
=
b
[
c
]);
return
d
.
prototype
=
b
.
prototype
,
a
.
prototype
=
new
d
,
a
.
__super__
=
b
.
prototype
,
a
};
d
=
this
,
a
=
jQuery
,
a
.
fn
.
extend
({
chosen
:
function
(
c
){
return
!
a
.
browser
.
msie
||
a
.
browser
.
version
!==
"6.0"
&&
a
.
browser
.
version
!==
"7.0"
?
a
(
this
).
each
(
function
(
d
){
if
(
!
a
(
this
).
hasClass
(
"chzn-done"
))
return
new
b
(
this
,
c
)}):
this
}}),
b
=
function
(
b
){
function
e
(){
e
.
__super__
.
constructor
.
apply
(
this
,
arguments
)}
return
f
(
e
,
b
),
e
.
prototype
.
setup
=
function
(){
return
this
.
form_field_jq
=
a
(
this
.
form_field
),
this
.
is_rtl
=
this
.
form_field_jq
.
hasClass
(
"chzn-rtl"
)},
e
.
prototype
.
finish_setup
=
function
(){
return
this
.
form_field_jq
.
addClass
(
"chzn-done"
)},
e
.
prototype
.
set_up_html
=
function
(){
var
b
,
d
,
e
,
f
;
return
this
.
container_id
=
this
.
form_field
.
id
.
length
?
this
.
form_field
.
id
.
replace
(
/
(
:|
\.)
/g
,
"_"
):
this
.
generate_field_id
(),
this
.
container_id
+=
"_chzn"
,
this
.
f_width
=
this
.
form_field_jq
.
outerWidth
(),
this
.
default_text
=
this
.
form_field_jq
.
data
(
"placeholder"
)?
this
.
form_field_jq
.
data
(
"placeholder"
):
this
.
default_text_default
,
b
=
a
(
"<div />"
,{
id
:
this
.
container_id
,
"class"
:
"chzn-container"
+
(
this
.
is_rtl
?
" chzn-rtl"
:
""
),
style
:
"width: "
+
this
.
f_width
+
"px;"
}),
this
.
is_multiple
?
b
.
html
(
'<ul class="chzn-choices"><li class="search-field"><input type="text" value="'
+
this
.
default_text
+
'" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop" style="left:-9000px;"><ul class="chzn-results"></ul></div>'
):
b
.
html
(
'<a href="javascript:void(0)" class="chzn-single chzn-default"><span>'
+
this
.
default_text
+
'</span><div><b></b></div></a><div class="chzn-drop" style="left:-9000px;"><div class="chzn-search"><input type="text" autocomplete="off" /></div><ul class="chzn-results"></ul></div>'
),
this
.
form_field_jq
.
hide
().
after
(
b
),
this
.
container
=
a
(
"#"
+
this
.
container_id
),
this
.
container
.
addClass
(
"chzn-container-"
+
(
this
.
is_multiple
?
"multi"
:
"single"
)),
this
.
dropdown
=
this
.
container
.
find
(
"div.chzn-drop"
).
first
(),
d
=
this
.
container
.
height
(),
e
=
this
.
f_width
-
c
(
this
.
dropdown
),
this
.
dropdown
.
css
({
width
:
e
+
"px"
,
top
:
d
+
"px"
}),
this
.
search_field
=
this
.
container
.
find
(
"input"
).
first
(),
this
.
search_results
=
this
.
container
.
find
(
"ul.chzn-results"
).
first
(),
this
.
search_field_scale
(),
this
.
search_no_results
=
this
.
container
.
find
(
"li.no-results"
).
first
(),
this
.
is_multiple
?(
this
.
search_choices
=
this
.
container
.
find
(
"ul.chzn-choices"
).
first
(),
this
.
search_container
=
this
.
container
.
find
(
"li.search-field"
).
first
()):(
this
.
search_container
=
this
.
container
.
find
(
"div.chzn-search"
).
first
(),
this
.
selected_item
=
this
.
container
.
find
(
".chzn-single"
).
first
(),
f
=
e
-
c
(
this
.
search_container
)
-
c
(
this
.
search_field
),
this
.
search_field
.
css
({
width
:
f
+
"px"
})),
this
.
results_build
(),
this
.
set_tab_index
(),
this
.
form_field_jq
.
trigger
(
"liszt:ready"
,{
chosen
:
this
})},
e
.
prototype
.
register_observers
=
function
(){
var
a
=
this
;
return
this
.
container
.
mousedown
(
function
(
b
){
return
a
.
container_mousedown
(
b
)}),
this
.
container
.
mouseup
(
function
(
b
){
return
a
.
container_mouseup
(
b
)}),
this
.
container
.
mouseenter
(
function
(
b
){
return
a
.
mouse_enter
(
b
)}),
this
.
container
.
mouseleave
(
function
(
b
){
return
a
.
mouse_leave
(
b
)}),
this
.
search_results
.
mouseup
(
function
(
b
){
return
a
.
search_results_mouseup
(
b
)}),
this
.
search_results
.
mouseover
(
function
(
b
){
return
a
.
search_results_mouseover
(
b
)}),
this
.
search_results
.
mouseout
(
function
(
b
){
return
a
.
search_results_mouseout
(
b
)}),
this
.
form_field_jq
.
bind
(
"liszt:updated"
,
function
(
b
){
return
a
.
results_update_field
(
b
)}),
this
.
search_field
.
blur
(
function
(
b
){
return
a
.
input_blur
(
b
)}),
this
.
search_field
.
keyup
(
function
(
b
){
return
a
.
keyup_checker
(
b
)}),
this
.
search_field
.
keydown
(
function
(
b
){
return
a
.
keydown_checker
(
b
)}),
this
.
is_multiple
?(
this
.
search_choices
.
click
(
function
(
b
){
return
a
.
choices_click
(
b
)}),
this
.
search_field
.
focus
(
function
(
b
){
return
a
.
input_focus
(
b
)})):
this
.
container
.
click
(
function
(
a
){
return
a
.
preventDefault
()})},
e
.
prototype
.
search_field_disabled
=
function
(){
this
.
is_disabled
=
this
.
form_field_jq
[
0
].
disabled
;
if
(
this
.
is_disabled
)
return
this
.
container
.
addClass
(
"chzn-disabled"
),
this
.
search_field
[
0
].
disabled
=!
0
,
this
.
is_multiple
||
this
.
selected_item
.
unbind
(
"focus"
,
this
.
activate_action
),
this
.
close_field
();
this
.
container
.
removeClass
(
"chzn-disabled"
),
this
.
search_field
[
0
].
disabled
=!
1
;
if
(
!
this
.
is_multiple
)
return
this
.
selected_item
.
bind
(
"focus"
,
this
.
activate_action
)},
e
.
prototype
.
container_mousedown
=
function
(
b
){
var
c
;
if
(
!
this
.
is_disabled
)
return
c
=
b
!=
null
?
a
(
b
.
target
).
hasClass
(
"search-choice-close"
):
!
1
,
b
&&
b
.
type
===
"mousedown"
&&!
this
.
results_showing
&&
b
.
stopPropagation
(),
!
this
.
pending_destroy_click
&&!
c
?(
this
.
active_field
?
!
this
.
is_multiple
&&
b
&&
(
a
(
b
.
target
)[
0
]
===
this
.
selected_item
[
0
]
||
a
(
b
.
target
).
parents
(
"a.chzn-single"
).
length
)
&&
(
b
.
preventDefault
(),
this
.
results_toggle
()):(
this
.
is_multiple
&&
this
.
search_field
.
val
(
""
),
a
(
document
).
click
(
this
.
click_test_action
),
this
.
results_show
()),
this
.
activate_field
()):
this
.
pending_destroy_click
=!
1
},
e
.
prototype
.
container_mouseup
=
function
(
a
){
if
(
a
.
target
.
nodeName
===
"ABBR"
)
return
this
.
results_reset
(
a
)},
e
.
prototype
.
blur_test
=
function
(
a
){
if
(
!
this
.
active_field
&&
this
.
container
.
hasClass
(
"chzn-container-active"
))
return
this
.
close_field
()},
e
.
prototype
.
close_field
=
function
(){
return
a
(
document
).
unbind
(
"click"
,
this
.
click_test_action
),
this
.
is_multiple
||
(
this
.
selected_item
.
attr
(
"tabindex"
,
this
.
search_field
.
attr
(
"tabindex"
)),
this
.
search_field
.
attr
(
"tabindex"
,
-
1
)),
this
.
active_field
=!
1
,
this
.
results_hide
(),
this
.
container
.
removeClass
(
"chzn-container-active"
),
this
.
winnow_results_clear
(),
this
.
clear_backstroke
(),
this
.
show_search_field_default
(),
this
.
search_field_scale
()},
e
.
prototype
.
activate_field
=
function
(){
return
!
this
.
is_multiple
&&!
this
.
active_field
&&
(
this
.
search_field
.
attr
(
"tabindex"
,
this
.
selected_item
.
attr
(
"tabindex"
)),
this
.
selected_item
.
attr
(
"tabindex"
,
-
1
)),
this
.
container
.
addClass
(
"chzn-container-active"
),
this
.
active_field
=!
0
,
this
.
search_field
.
val
(
this
.
search_field
.
val
()),
this
.
search_field
.
focus
()},
e
.
prototype
.
test_active_click
=
function
(
b
){
return
a
(
b
.
target
).
parents
(
"#"
+
this
.
container_id
).
length
?
this
.
active_field
=!
0
:
this
.
close_field
()},
e
.
prototype
.
results_build
=
function
(){
var
a
,
b
,
c
,
e
,
f
;
this
.
parsing
=!
0
,
this
.
results_data
=
d
.
SelectParser
.
select_to_array
(
this
.
form_field
),
this
.
is_multiple
&&
this
.
choices
>
0
?(
this
.
search_choices
.
find
(
"li.search-choice"
).
remove
(),
this
.
choices
=
0
):
this
.
is_multiple
||
(
this
.
selected_item
.
find
(
"span"
).
text
(
this
.
default_text
),
this
.
form_field
.
options
.
length
<=
this
.
disable_search_threshold
?
this
.
container
.
addClass
(
"chzn-container-single-nosearch"
):
this
.
container
.
removeClass
(
"chzn-container-single-nosearch"
)),
a
=
""
,
f
=
this
.
results_data
;
for
(
c
=
0
,
e
=
f
.
length
;
c
<
e
;
c
++
)
b
=
f
[
c
],
b
.
group
?
a
+=
this
.
result_add_group
(
b
):
b
.
empty
||
(
a
+=
this
.
result_add_option
(
b
),
b
.
selected
&&
this
.
is_multiple
?
this
.
choice_build
(
b
):
b
.
selected
&&!
this
.
is_multiple
&&
(
this
.
selected_item
.
removeClass
(
"chzn-default"
).
find
(
"span"
).
text
(
b
.
text
),
this
.
allow_single_deselect
&&
this
.
single_deselect_control_build
()));
return
this
.
search_field_disabled
(),
this
.
show_search_field_default
(),
this
.
search_field_scale
(),
this
.
search_results
.
html
(
a
),
this
.
parsing
=!
1
},
e
.
prototype
.
result_add_group
=
function
(
b
){
return
b
.
disabled
?
""
:(
b
.
dom_id
=
this
.
container_id
+
"_g_"
+
b
.
array_index
,
'<li id="'
+
b
.
dom_id
+
'" class="group-result">'
+
a
(
"<div />"
).
text
(
b
.
label
).
html
()
+
"</li>"
)},
e
.
prototype
.
result_do_highlight
=
function
(
a
){
var
b
,
c
,
d
,
e
,
f
;
if
(
a
.
length
){
this
.
result_clear_highlight
(),
this
.
result_highlight
=
a
,
this
.
result_highlight
.
addClass
(
"highlighted"
),
d
=
parseInt
(
this
.
search_results
.
css
(
"maxHeight"
),
10
),
f
=
this
.
search_results
.
scrollTop
(),
e
=
d
+
f
,
c
=
this
.
result_highlight
.
position
().
top
+
this
.
search_results
.
scrollTop
(),
b
=
c
+
this
.
result_highlight
.
outerHeight
();
if
(
b
>=
e
)
return
this
.
search_results
.
scrollTop
(
b
-
d
>
0
?
b
-
d
:
0
);
if
(
c
<
f
)
return
this
.
search_results
.
scrollTop
(
c
)}},
e
.
prototype
.
result_clear_highlight
=
function
(){
return
this
.
result_highlight
&&
this
.
result_highlight
.
removeClass
(
"highlighted"
),
this
.
result_highlight
=
null
},
e
.
prototype
.
results_show
=
function
(){
var
a
;
return
this
.
is_multiple
||
(
this
.
selected_item
.
addClass
(
"chzn-single-with-drop"
),
this
.
result_single_selected
&&
this
.
result_do_highlight
(
this
.
result_single_selected
)),
a
=
this
.
is_multiple
?
this
.
container
.
height
():
this
.
container
.
height
()
-
1
,
this
.
dropdown
.
css
({
top
:
a
+
"px"
,
left
:
0
}),
this
.
results_showing
=!
0
,
this
.
search_field
.
focus
(),
this
.
search_field
.
val
(
this
.
search_field
.
val
()),
this
.
winnow_results
()},
e
.
prototype
.
results_hide
=
function
(){
return
this
.
is_multiple
||
this
.
selected_item
.
removeClass
(
"chzn-single-with-drop"
),
this
.
result_clear_highlight
(),
this
.
dropdown
.
css
({
left
:
"-9000px"
}),
this
.
results_showing
=!
1
},
e
.
prototype
.
set_tab_index
=
function
(
a
){
var
b
;
if
(
this
.
form_field_jq
.
attr
(
"tabindex"
))
return
b
=
this
.
form_field_jq
.
attr
(
"tabindex"
),
this
.
form_field_jq
.
attr
(
"tabindex"
,
-
1
),
this
.
is_multiple
?
this
.
search_field
.
attr
(
"tabindex"
,
b
):(
this
.
selected_item
.
attr
(
"tabindex"
,
b
),
this
.
search_field
.
attr
(
"tabindex"
,
-
1
))},
e
.
prototype
.
show_search_field_default
=
function
(){
return
this
.
is_multiple
&&
this
.
choices
<
1
&&!
this
.
active_field
?(
this
.
search_field
.
val
(
this
.
default_text
),
this
.
search_field
.
addClass
(
"default"
)):(
this
.
search_field
.
val
(
""
),
this
.
search_field
.
removeClass
(
"default"
))},
e
.
prototype
.
search_results_mouseup
=
function
(
b
){
var
c
;
c
=
a
(
b
.
target
).
hasClass
(
"active-result"
)?
a
(
b
.
target
):
a
(
b
.
target
).
parents
(
".active-result"
).
first
();
if
(
c
.
length
)
return
this
.
result_highlight
=
c
,
this
.
result_select
(
b
)},
e
.
prototype
.
search_results_mouseover
=
function
(
b
){
var
c
;
c
=
a
(
b
.
target
).
hasClass
(
"active-result"
)?
a
(
b
.
target
):
a
(
b
.
target
).
parents
(
".active-result"
).
first
();
if
(
c
)
return
this
.
result_do_highlight
(
c
)},
e
.
prototype
.
search_results_mouseout
=
function
(
b
){
if
(
a
(
b
.
target
).
hasClass
(
"active-result"
))
return
this
.
result_clear_highlight
()},
e
.
prototype
.
choices_click
=
function
(
b
){
b
.
preventDefault
();
if
(
this
.
active_field
&&!
a
(
b
.
target
).
hasClass
(
"search-choice"
)
&&!
this
.
results_showing
)
return
this
.
results_show
()},
e
.
prototype
.
choice_build
=
function
(
b
){
var
c
,
d
,
e
=
this
;
return
c
=
this
.
container_id
+
"_c_"
+
b
.
array_index
,
this
.
choices
+=
1
,
this
.
search_container
.
before
(
'<li class="search-choice" id="'
+
c
+
'"><span>'
+
b
.
html
+
'</span><a href="javascript:void(0)" class="search-choice-close" rel="'
+
b
.
array_index
+
'"></a></li>'
),
d
=
a
(
"#"
+
c
).
find
(
"a"
).
first
(),
d
.
click
(
function
(
a
){
return
e
.
choice_destroy_link_click
(
a
)})},
e
.
prototype
.
choice_destroy_link_click
=
function
(
b
){
return
b
.
preventDefault
(),
this
.
is_disabled
?
b
.
stopPropagation
:(
this
.
pending_destroy_click
=!
0
,
this
.
choice_destroy
(
a
(
b
.
target
)))},
e
.
prototype
.
choice_destroy
=
function
(
a
){
return
this
.
choices
-=
1
,
this
.
show_search_field_default
(),
this
.
is_multiple
&&
this
.
choices
>
0
&&
this
.
search_field
.
val
().
length
<
1
&&
this
.
results_hide
(),
this
.
result_deselect
(
a
.
attr
(
"rel"
)),
a
.
parents
(
"li"
).
first
().
remove
()},
e
.
prototype
.
results_reset
=
function
(
b
){
this
.
form_field
.
options
[
0
].
selected
=!
0
,
this
.
selected_item
.
find
(
"span"
).
text
(
this
.
default_text
),
this
.
is_multiple
||
this
.
selected_item
.
addClass
(
"chzn-default"
),
this
.
show_search_field_default
(),
a
(
b
.
target
).
remove
(),
this
.
form_field_jq
.
trigger
(
"change"
);
if
(
this
.
active_field
)
return
this
.
results_hide
()},
e
.
prototype
.
result_select
=
function
(
a
){
var
b
,
c
,
d
,
e
;
if
(
this
.
result_highlight
)
return
b
=
this
.
result_highlight
,
c
=
b
.
attr
(
"id"
),
this
.
result_clear_highlight
(),
this
.
is_multiple
?
this
.
result_deactivate
(
b
):(
this
.
search_results
.
find
(
".result-selected"
).
removeClass
(
"result-selected"
),
this
.
result_single_selected
=
b
,
this
.
selected_item
.
removeClass
(
"chzn-default"
)),
b
.
addClass
(
"result-selected"
),
e
=
c
.
substr
(
c
.
lastIndexOf
(
"_"
)
+
1
),
d
=
this
.
results_data
[
e
],
d
.
selected
=!
0
,
this
.
form_field
.
options
[
d
.
options_index
].
selected
=!
0
,
this
.
is_multiple
?
this
.
choice_build
(
d
):(
this
.
selected_item
.
find
(
"span"
).
first
().
text
(
d
.
text
),
this
.
allow_single_deselect
&&
this
.
single_deselect_control_build
()),(
!
a
.
metaKey
||!
this
.
is_multiple
)
&&
this
.
results_hide
(),
this
.
search_field
.
val
(
""
),
this
.
form_field_jq
.
trigger
(
"change"
),
this
.
search_field_scale
()},
e
.
prototype
.
result_activate
=
function
(
a
){
return
a
.
addClass
(
"active-result"
)},
e
.
prototype
.
result_deactivate
=
function
(
a
){
return
a
.
removeClass
(
"active-result"
)},
e
.
prototype
.
result_deselect
=
function
(
b
){
var
c
,
d
;
return
d
=
this
.
results_data
[
b
],
d
.
selected
=!
1
,
this
.
form_field
.
options
[
d
.
options_index
].
selected
=!
1
,
c
=
a
(
"#"
+
this
.
container_id
+
"_o_"
+
b
),
c
.
removeClass
(
"result-selected"
).
addClass
(
"active-result"
).
show
(),
this
.
result_clear_highlight
(),
this
.
winnow_results
(),
this
.
form_field_jq
.
trigger
(
"change"
),
this
.
search_field_scale
()},
e
.
prototype
.
single_deselect_control_build
=
function
(){
if
(
this
.
allow_single_deselect
&&
this
.
selected_item
.
find
(
"abbr"
).
length
<
1
)
return
this
.
selected_item
.
find
(
"span"
).
first
().
after
(
'<abbr class="search-choice-close"></abbr>'
)},
e
.
prototype
.
winnow_results
=
function
(){
var
b
,
c
,
d
,
e
,
f
,
g
,
h
,
i
,
j
,
k
,
l
,
m
,
n
,
o
,
p
,
q
,
r
,
s
;
this
.
no_results_clear
(),
j
=
0
,
k
=
this
.
search_field
.
val
()
===
this
.
default_text
?
""
:
a
(
"<div/>"
).
text
(
a
.
trim
(
this
.
search_field
.
val
())).
html
(),
g
=
this
.
search_contains
?
""
:
"^"
,
f
=
new
RegExp
(
g
+
k
.
replace
(
/
[
-[
\]
{}()*+?.,
\\
^$|#
\s]
/g
,
"
\\
$&"
),
"i"
),
n
=
new
RegExp
(
k
.
replace
(
/
[
-[
\]
{}()*+?.,
\\
^$|#
\s]
/g
,
"
\\
$&"
),
"i"
),
s
=
this
.
results_data
;
for
(
o
=
0
,
q
=
s
.
length
;
o
<
q
;
o
++
){
c
=
s
[
o
];
if
(
!
c
.
disabled
&&!
c
.
empty
)
if
(
c
.
group
)
a
(
"#"
+
c
.
dom_id
).
css
(
"display"
,
"none"
);
else
if
(
!
this
.
is_multiple
||!
c
.
selected
){
b
=!
1
,
i
=
c
.
dom_id
,
h
=
a
(
"#"
+
i
);
if
(
f
.
test
(
c
.
html
))
b
=!
0
,
j
+=
1
;
else
if
(
c
.
html
.
indexOf
(
" "
)
>=
0
||
c
.
html
.
indexOf
(
"["
)
===
0
){
e
=
c
.
html
.
replace
(
/
\[
|
\]
/g
,
""
).
split
(
" "
);
if
(
e
.
length
)
for
(
p
=
0
,
r
=
e
.
length
;
p
<
r
;
p
++
)
d
=
e
[
p
],
f
.
test
(
d
)
&&
(
b
=!
0
,
j
+=
1
)}
b
?(
k
.
length
?(
l
=
c
.
html
.
search
(
n
),
m
=
c
.
html
.
substr
(
0
,
l
+
k
.
length
)
+
"</em>"
+
c
.
html
.
substr
(
l
+
k
.
length
),
m
=
m
.
substr
(
0
,
l
)
+
"<em>"
+
m
.
substr
(
l
)):
m
=
c
.
html
,
h
.
html
(
m
),
this
.
result_activate
(
h
),
c
.
group_array_index
!=
null
&&
a
(
"#"
+
this
.
results_data
[
c
.
group_array_index
].
dom_id
).
css
(
"display"
,
"list-item"
)):(
this
.
result_highlight
&&
i
===
this
.
result_highlight
.
attr
(
"id"
)
&&
this
.
result_clear_highlight
(),
this
.
result_deactivate
(
h
))}}
return
j
<
1
&&
k
.
length
?
this
.
no_results
(
k
):
this
.
winnow_results_set_highlight
()},
e
.
prototype
.
winnow_results_clear
=
function
(){
var
b
,
c
,
d
,
e
,
f
;
this
.
search_field
.
val
(
""
),
c
=
this
.
search_results
.
find
(
"li"
),
f
=
[];
for
(
d
=
0
,
e
=
c
.
length
;
d
<
e
;
d
++
)
b
=
c
[
d
],
b
=
a
(
b
),
b
.
hasClass
(
"group-result"
)?
f
.
push
(
b
.
css
(
"display"
,
"auto"
)):
!
this
.
is_multiple
||!
b
.
hasClass
(
"result-selected"
)?
f
.
push
(
this
.
result_activate
(
b
)):
f
.
push
(
void
0
);
return
f
},
e
.
prototype
.
winnow_results_set_highlight
=
function
(){
var
a
,
b
;
if
(
!
this
.
result_highlight
){
b
=
this
.
is_multiple
?[]:
this
.
search_results
.
find
(
".result-selected.active-result"
),
a
=
b
.
length
?
b
.
first
():
this
.
search_results
.
find
(
".active-result"
).
first
();
if
(
a
!=
null
)
return
this
.
result_do_highlight
(
a
)}},
e
.
prototype
.
no_results
=
function
(
b
){
var
c
;
return
c
=
a
(
'<li class="no-results">'
+
this
.
results_none_found
+
' "<span></span>"</li>'
),
c
.
find
(
"span"
).
first
().
html
(
b
),
this
.
search_results
.
append
(
c
)},
e
.
prototype
.
no_results_clear
=
function
(){
return
this
.
search_results
.
find
(
".no-results"
).
remove
()},
e
.
prototype
.
keydown_arrow
=
function
(){
var
b
,
c
;
this
.
result_highlight
?
this
.
results_showing
&&
(
c
=
this
.
result_highlight
.
nextAll
(
"li.active-result"
).
first
(),
c
&&
this
.
result_do_highlight
(
c
)):(
b
=
this
.
search_results
.
find
(
"li.active-result"
).
first
(),
b
&&
this
.
result_do_highlight
(
a
(
b
)));
if
(
!
this
.
results_showing
)
return
this
.
results_show
()},
e
.
prototype
.
keyup_arrow
=
function
(){
var
a
;
if
(
!
this
.
results_showing
&&!
this
.
is_multiple
)
return
this
.
results_show
();
if
(
this
.
result_highlight
)
return
a
=
this
.
result_highlight
.
prevAll
(
"li.active-result"
),
a
.
length
?
this
.
result_do_highlight
(
a
.
first
()):(
this
.
choices
>
0
&&
this
.
results_hide
(),
this
.
result_clear_highlight
())},
e
.
prototype
.
keydown_backstroke
=
function
(){
return
this
.
pending_backstroke
?(
this
.
choice_destroy
(
this
.
pending_backstroke
.
find
(
"a"
).
first
()),
this
.
clear_backstroke
()):(
this
.
pending_backstroke
=
this
.
search_container
.
siblings
(
"li.search-choice"
).
last
(),
this
.
pending_backstroke
.
addClass
(
"search-choice-focus"
))},
e
.
prototype
.
clear_backstroke
=
function
(){
return
this
.
pending_backstroke
&&
this
.
pending_backstroke
.
removeClass
(
"search-choice-focus"
),
this
.
pending_backstroke
=
null
},
e
.
prototype
.
keydown_checker
=
function
(
a
){
var
b
,
c
;
b
=
(
c
=
a
.
which
)
!=
null
?
c
:
a
.
keyCode
,
this
.
search_field_scale
(),
b
!==
8
&&
this
.
pending_backstroke
&&
this
.
clear_backstroke
();
switch
(
b
){
case
8
:
this
.
backstroke_length
=
this
.
search_field
.
val
().
length
;
break
;
case
9
:
this
.
results_showing
&&!
this
.
is_multiple
&&
this
.
result_select
(
a
),
this
.
mouse_on_container
=!
1
;
break
;
case
13
:
a
.
preventDefault
();
break
;
case
38
:
a
.
preventDefault
(),
this
.
keyup_arrow
();
break
;
case
40
:
this
.
keydown_arrow
()}},
e
.
prototype
.
search_field_scale
=
function
(){
var
b
,
c
,
d
,
e
,
f
,
g
,
h
,
i
,
j
;
if
(
this
.
is_multiple
){
d
=
0
,
h
=
0
,
f
=
"position:absolute; left: -1000px; top: -1000px; display:none;"
,
g
=
[
"font-size"
,
"font-style"
,
"font-weight"
,
"font-family"
,
"line-height"
,
"text-transform"
,
"letter-spacing"
];
for
(
i
=
0
,
j
=
g
.
length
;
i
<
j
;
i
++
)
e
=
g
[
i
],
f
+=
e
+
":"
+
this
.
search_field
.
css
(
e
)
+
";"
;
return
c
=
a
(
"<div />"
,{
style
:
f
}),
c
.
text
(
this
.
search_field
.
val
()),
a
(
"body"
).
append
(
c
),
h
=
c
.
width
()
+
25
,
c
.
remove
(),
h
>
this
.
f_width
-
10
&&
(
h
=
this
.
f_width
-
10
),
this
.
search_field
.
css
({
width
:
h
+
"px"
}),
b
=
this
.
container
.
height
(),
this
.
dropdown
.
css
({
top
:
b
+
"px"
})}},
e
.
prototype
.
generate_random_id
=
function
(){
var
b
;
b
=
"sel"
+
this
.
generate_random_char
()
+
this
.
generate_random_char
()
+
this
.
generate_random_char
();
while
(
a
(
"#"
+
b
).
length
>
0
)
b
+=
this
.
generate_random_char
();
return
b
},
e
}(
AbstractChosen
),
c
=
function
(
a
){
var
b
;
return
b
=
a
.
outerWidth
()
-
a
.
width
()},
d
.
get_side_border_padding
=
c
}.
call
(
this
)
\ No newline at end of file
flask_adminex/templates/admin/master.html
View file @
37ae5a07
...
@@ -2,14 +2,18 @@
...
@@ -2,14 +2,18 @@
<html>
<html>
<head>
<head>
<title>
{% block title %}{% if view.category %}{{ view.category }} - {% endif %}{{ view.name }} - {{ view.admin.name }}{% endblock %}
</title>
<title>
{% block title %}{% if view.category %}{{ view.category }} - {% endif %}{{ view.name }} - {{ view.admin.name }}{% endblock %}
</title>
{% block head %}
{% block head
_meta
%}
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<meta
name=
"description"
content=
""
>
<meta
name=
"description"
content=
""
>
<meta
name=
"author"
content=
""
>
<meta
name=
"author"
content=
""
>
{% endblock %}
{% block head_css %}
<link
href=
"{{ url_for('admin.static', filename='bootstrap/css/bootstrap.css') }}"
rel=
"stylesheet"
>
<link
href=
"{{ url_for('admin.static', filename='bootstrap/css/bootstrap.css') }}"
rel=
"stylesheet"
>
<link
href=
"{{ url_for('admin.static', filename='bootstrap/css/bootstrap-responsive.css') }}"
rel=
"stylesheet"
>
<link
href=
"{{ url_for('admin.static', filename='bootstrap/css/bootstrap-responsive.css') }}"
rel=
"stylesheet"
>
<link
href=
"{{ url_for('admin.static', filename='css/admin.css') }}"
rel=
"stylesheet"
>
<link
href=
"{{ url_for('admin.static', filename='css/admin.css') }}"
rel=
"stylesheet"
>
{% endblock %}
{% endblock %}
{% block head %}
{% endblock %}
</head>
</head>
<body>
<body>
{% block page_body %}
{% block page_body %}
...
@@ -68,5 +72,9 @@
...
@@ -68,5 +72,9 @@
<script
src=
"http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"
type=
"text/javascript"
></script>
<script
src=
"http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"
type=
"text/javascript"
></script>
<script
src=
"{{ url_for('admin.static', filename='bootstrap/js/bootstrap.min.js') }}"
type=
"text/javascript"
></script>
<script
src=
"{{ url_for('admin.static', filename='bootstrap/js/bootstrap.min.js') }}"
type=
"text/javascript"
></script>
<script
src=
"{{ url_for('admin.static', filename='chosen/chosen.jquery.min.js') }}"
type=
"text/javascript"
></script>
{% block tail %}
{% endblock %}
</body>
</body>
</html>
</html>
flask_adminex/templates/admin/model/edit.html
View file @
37ae5a07
{% extends 'admin/master.html' %}
{% extends 'admin/master.html' %}
{% block head %}
<link
href=
"{{ url_for('admin.static', filename='chosen/chosen.css') }}"
rel=
"stylesheet"
>
{% endblock %}
{% block body %}
{% block body %}
<form
action=
""
method=
"POST"
class=
"form-horizontal"
>
<form
action=
""
method=
"POST"
class=
"form-horizontal"
{%
if
form
.
has_file_field
%}
enctype=
"multipart/form-data"
{%
endif
%}
>
<fieldset>
<fieldset>
{{ form.csrf }}
{{ form.csrf }}
{% for f in form if f.label.text != 'Csrf' %}
{% for f in form if f.label.text != 'Csrf' %}
{% if f.name in form.errors %}
<div
class=
"control-group{% if f.errors %} error{% endif %}"
>
<div
class=
"control-group error"
>
{% else %}
<div
class=
"control-group"
>
{% endif %}
{{ f.label(class='control-label') }}
{{ f.label(class='control-label') }}
<div
class=
"controls"
>
<div
class=
"controls"
>
<div>
<div>
{{ f }}
{{ f }}
</div>
</div>
{% if f.
name in form.
errors %}
{% if f.errors %}
<ul>
<ul>
{% for e in f
orm.errors[f.name]
%}
{% for e in f
.errors
%}
<li>
{{ e }}
</li>
<li>
{{ e }}
</li>
{% endfor %}
{% endfor %}
</ul>
</ul>
...
@@ -35,3 +35,9 @@
...
@@ -35,3 +35,9 @@
</fieldset>
</fieldset>
</form>
</form>
{% endblock %}
{% endblock %}
{% block tail %}
<script>
$
(
"select"
).
chosen
({
allow_single_deselect
:
true
});
</script>
{% endblock %}
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