Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
D
douban-api-proxy
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
captainwong
douban-api-proxy
Commits
cd0aeb28
Commit
cd0aeb28
authored
9 years ago
by
Cervinko Cera
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add Typeahead for Author input
parent
d979ed89
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
657 additions
and
10 deletions
+657
-10
typeaheadjs.css
cps/static/css/typeaheadjs.css
+93
-0
bootstrap3-typeahead.js
cps/static/js/bootstrap3-typeahead.js
+523
-0
edit_book.html
cps/templates/edit_book.html
+21
-1
layout.html
cps/templates/layout.html
+11
-9
web.py
cps/web.py
+9
-0
No files found.
cps/static/css/typeaheadjs.css
0 → 100644
View file @
cd0aeb28
span
.twitter-typeahead
.tt-menu
,
span
.twitter-typeahead
.tt-dropdown-menu
{
position
:
absolute
;
top
:
100%
;
left
:
0
;
z-index
:
1000
;
display
:
none
;
float
:
left
;
min-width
:
160px
;
padding
:
5px
0
;
margin
:
2px
0
0
;
list-style
:
none
;
font-size
:
14px
;
text-align
:
left
;
background-color
:
#ffffff
;
border
:
1px
solid
#cccccc
;
border
:
1px
solid
rgba
(
0
,
0
,
0
,
0.15
);
border-radius
:
4px
;
-webkit-box-shadow
:
0
6px
12px
rgba
(
0
,
0
,
0
,
0.175
);
box-shadow
:
0
6px
12px
rgba
(
0
,
0
,
0
,
0.175
);
background-clip
:
padding-box
;
}
span
.twitter-typeahead
.tt-suggestion
{
display
:
block
;
padding
:
3px
20px
;
clear
:
both
;
font-weight
:
normal
;
line-height
:
1.42857143
;
color
:
#333333
;
white-space
:
nowrap
;
}
span
.twitter-typeahead
.tt-suggestion.tt-cursor
,
span
.twitter-typeahead
.tt-suggestion
:hover
,
span
.twitter-typeahead
.tt-suggestion
:focus
{
color
:
#ffffff
;
text-decoration
:
none
;
outline
:
0
;
background-color
:
#337ab7
;
}
.input-group.input-group-lg
span
.twitter-typeahead
.form-control
{
height
:
46px
;
padding
:
10px
16px
;
font-size
:
18px
;
line-height
:
1.3333333
;
border-radius
:
6px
;
}
.input-group.input-group-sm
span
.twitter-typeahead
.form-control
{
height
:
30px
;
padding
:
5px
10px
;
font-size
:
12px
;
line-height
:
1.5
;
border-radius
:
3px
;
}
span
.twitter-typeahead
{
width
:
100%
;
}
.input-group
span
.twitter-typeahead
{
display
:
block
!important
;
height
:
34px
;
}
.input-group
span
.twitter-typeahead
.tt-menu
,
.input-group
span
.twitter-typeahead
.tt-dropdown-menu
{
top
:
32px
!important
;
}
.input-group
span
.twitter-typeahead
:not
(
:first-child
)
:not
(
:last-child
)
.form-control
{
border-radius
:
0
;
}
.input-group
span
.twitter-typeahead
:first-child
.form-control
{
border-top-left-radius
:
4px
;
border-bottom-left-radius
:
4px
;
border-top-right-radius
:
0
;
border-bottom-right-radius
:
0
;
}
.input-group
span
.twitter-typeahead
:last-child
.form-control
{
border-top-left-radius
:
0
;
border-bottom-left-radius
:
0
;
border-top-right-radius
:
4px
;
border-bottom-right-radius
:
4px
;
}
.input-group.input-group-sm
span
.twitter-typeahead
{
height
:
30px
;
}
.input-group.input-group-sm
span
.twitter-typeahead
.tt-menu
,
.input-group.input-group-sm
span
.twitter-typeahead
.tt-dropdown-menu
{
top
:
30px
!important
;
}
.input-group.input-group-lg
span
.twitter-typeahead
{
height
:
46px
;
}
.input-group.input-group-lg
span
.twitter-typeahead
.tt-menu
,
.input-group.input-group-lg
span
.twitter-typeahead
.tt-dropdown-menu
{
top
:
46px
!important
;
}
This diff is collapsed.
Click to expand it.
cps/static/js/bootstrap3-typeahead.js
0 → 100644
View file @
cd0aeb28
/* =============================================================
* bootstrap3-typeahead.js v3.1.0
* https://github.com/bassjobsen/Bootstrap-3-Typeahead
* =============================================================
* Original written by @mdo and @fat
* =============================================================
* Copyright 2014 Bass Jobsen @bassjobsen
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ============================================================ */
(
function
(
root
,
factory
)
{
'use strict'
;
// CommonJS module is defined
if
(
typeof
module
!==
'undefined'
&&
module
.
exports
)
{
module
.
exports
=
factory
(
require
(
'jquery'
));
}
// AMD module is defined
else
if
(
typeof
define
===
'function'
&&
define
.
amd
)
{
define
([
'jquery'
],
function
(
$
)
{
return
factory
(
$
);
});
}
else
{
factory
(
root
.
jQuery
);
}
}(
this
,
function
(
$
)
{
'use strict'
;
// jshint laxcomma: true
/* TYPEAHEAD PUBLIC CLASS DEFINITION
* ================================= */
var
Typeahead
=
function
(
element
,
options
)
{
this
.
$element
=
$
(
element
);
this
.
options
=
$
.
extend
({},
$
.
fn
.
typeahead
.
defaults
,
options
);
this
.
matcher
=
this
.
options
.
matcher
||
this
.
matcher
;
this
.
sorter
=
this
.
options
.
sorter
||
this
.
sorter
;
this
.
select
=
this
.
options
.
select
||
this
.
select
;
this
.
autoSelect
=
typeof
this
.
options
.
autoSelect
==
'boolean'
?
this
.
options
.
autoSelect
:
true
;
this
.
highlighter
=
this
.
options
.
highlighter
||
this
.
highlighter
;
this
.
render
=
this
.
options
.
render
||
this
.
render
;
this
.
updater
=
this
.
options
.
updater
||
this
.
updater
;
this
.
displayText
=
this
.
options
.
displayText
||
this
.
displayText
;
this
.
source
=
this
.
options
.
source
;
this
.
delay
=
this
.
options
.
delay
;
this
.
$menu
=
$
(
this
.
options
.
menu
);
this
.
$appendTo
=
this
.
options
.
appendTo
?
$
(
this
.
options
.
appendTo
)
:
null
;
this
.
shown
=
false
;
this
.
listen
();
this
.
showHintOnFocus
=
typeof
this
.
options
.
showHintOnFocus
==
'boolean'
?
this
.
options
.
showHintOnFocus
:
false
;
this
.
afterSelect
=
this
.
options
.
afterSelect
;
this
.
addItem
=
false
;
};
Typeahead
.
prototype
=
{
constructor
:
Typeahead
,
select
:
function
()
{
var
val
=
this
.
$menu
.
find
(
'.active'
).
data
(
'value'
);
this
.
$element
.
data
(
'active'
,
val
);
if
(
this
.
autoSelect
||
val
)
{
var
newVal
=
this
.
updater
(
val
);
// Updater can be set to any random functions via "options" parameter in constructor above.
// Add null check for cases when updater returns void or undefined.
if
(
!
newVal
)
{
newVal
=
""
;
}
this
.
$element
.
val
(
this
.
displayText
(
newVal
)
||
newVal
)
.
change
();
this
.
afterSelect
(
newVal
);
}
return
this
.
hide
();
},
updater
:
function
(
item
)
{
return
item
;
},
setSource
:
function
(
source
)
{
this
.
source
=
source
;
},
show
:
function
()
{
var
pos
=
$
.
extend
({},
this
.
$element
.
position
(),
{
height
:
this
.
$element
[
0
].
offsetHeight
}),
scrollHeight
;
scrollHeight
=
typeof
this
.
options
.
scrollHeight
==
'function'
?
this
.
options
.
scrollHeight
.
call
()
:
this
.
options
.
scrollHeight
;
var
element
;
if
(
this
.
shown
)
{
element
=
this
.
$menu
;
}
else
if
(
this
.
$appendTo
)
{
element
=
this
.
$menu
.
appendTo
(
this
.
$appendTo
);
}
else
{
element
=
this
.
$menu
.
insertAfter
(
this
.
$element
);
}
element
.
css
({
top
:
pos
.
top
+
pos
.
height
+
scrollHeight
,
left
:
pos
.
left
})
.
show
();
this
.
shown
=
true
;
return
this
;
},
hide
:
function
()
{
this
.
$menu
.
hide
();
this
.
shown
=
false
;
return
this
;
},
lookup
:
function
(
query
)
{
var
items
;
if
(
typeof
(
query
)
!=
'undefined'
&&
query
!==
null
)
{
this
.
query
=
query
;
}
else
{
this
.
query
=
this
.
$element
.
val
()
||
''
;
}
if
(
this
.
query
.
length
<
this
.
options
.
minLength
&&
!
this
.
options
.
showHintOnFocus
)
{
return
this
.
shown
?
this
.
hide
()
:
this
;
}
var
worker
=
$
.
proxy
(
function
()
{
if
(
$
.
isFunction
(
this
.
source
))
this
.
source
(
this
.
query
,
$
.
proxy
(
this
.
process
,
this
));
else
if
(
this
.
source
)
{
this
.
process
(
this
.
source
);
}
},
this
);
clearTimeout
(
this
.
lookupWorker
);
this
.
lookupWorker
=
setTimeout
(
worker
,
this
.
delay
);
},
process
:
function
(
items
)
{
var
that
=
this
;
items
=
$
.
grep
(
items
,
function
(
item
)
{
return
that
.
matcher
(
item
);
});
items
=
this
.
sorter
(
items
);
if
(
!
items
.
length
&&
!
this
.
options
.
addItem
)
{
return
this
.
shown
?
this
.
hide
()
:
this
;
}
if
(
items
.
length
>
0
)
{
this
.
$element
.
data
(
'active'
,
items
[
0
]);
}
else
{
this
.
$element
.
data
(
'active'
,
null
);
}
// Add item
if
(
this
.
options
.
addItem
){
items
.
push
(
this
.
options
.
addItem
);
}
if
(
this
.
options
.
items
==
'all'
)
{
return
this
.
render
(
items
).
show
();
}
else
{
return
this
.
render
(
items
.
slice
(
0
,
this
.
options
.
items
)).
show
();
}
},
matcher
:
function
(
item
)
{
var
it
=
this
.
displayText
(
item
);
return
~
it
.
toLowerCase
().
indexOf
(
this
.
query
.
toLowerCase
());
},
sorter
:
function
(
items
)
{
var
beginswith
=
[]
,
caseSensitive
=
[]
,
caseInsensitive
=
[]
,
item
;
while
((
item
=
items
.
shift
()))
{
var
it
=
this
.
displayText
(
item
);
if
(
!
it
.
toLowerCase
().
indexOf
(
this
.
query
.
toLowerCase
()))
beginswith
.
push
(
item
);
else
if
(
~
it
.
indexOf
(
this
.
query
))
caseSensitive
.
push
(
item
);
else
caseInsensitive
.
push
(
item
);
}
return
beginswith
.
concat
(
caseSensitive
,
caseInsensitive
);
},
highlighter
:
function
(
item
)
{
var
html
=
$
(
'<div></div>'
);
var
query
=
this
.
query
;
var
i
=
item
.
toLowerCase
().
indexOf
(
query
.
toLowerCase
());
var
len
,
leftPart
,
middlePart
,
rightPart
,
strong
;
len
=
query
.
length
;
if
(
len
===
0
){
return
html
.
text
(
item
).
html
();
}
while
(
i
>
-
1
)
{
leftPart
=
item
.
substr
(
0
,
i
);
middlePart
=
item
.
substr
(
i
,
len
);
rightPart
=
item
.
substr
(
i
+
len
);
strong
=
$
(
'<strong></strong>'
).
text
(
middlePart
);
html
.
append
(
document
.
createTextNode
(
leftPart
))
.
append
(
strong
);
item
=
rightPart
;
i
=
item
.
toLowerCase
().
indexOf
(
query
.
toLowerCase
());
}
return
html
.
append
(
document
.
createTextNode
(
item
)).
html
();
},
render
:
function
(
items
)
{
var
that
=
this
;
var
self
=
this
;
var
activeFound
=
false
;
var
data
=
[];
var
_category
=
that
.
options
.
separator
;
$
.
each
(
items
,
function
(
key
,
value
)
{
// inject separator
if
(
key
>
0
&&
value
[
_category
]
!==
items
[
key
-
1
][
_category
]){
data
.
push
({
__type
:
'divider'
});
}
// inject category header
if
(
value
[
_category
]
&&
(
key
===
0
||
value
[
_category
]
!==
items
[
key
-
1
][
_category
])){
data
.
push
({
__type
:
'category'
,
name
:
value
[
_category
]
});
}
data
.
push
(
value
);
});
items
=
$
(
data
).
map
(
function
(
i
,
item
)
{
if
((
item
.
__type
||
false
)
==
'category'
){
return
$
(
that
.
options
.
headerHtml
).
text
(
item
.
name
)[
0
];
}
if
((
item
.
__type
||
false
)
==
'divider'
){
return
$
(
that
.
options
.
headerDivider
)[
0
];
}
var
text
=
self
.
displayText
(
item
);
i
=
$
(
that
.
options
.
item
).
data
(
'value'
,
item
);
i
.
find
(
'a'
).
html
(
that
.
highlighter
(
text
,
item
));
if
(
text
==
self
.
$element
.
val
())
{
i
.
addClass
(
'active'
);
self
.
$element
.
data
(
'active'
,
item
);
activeFound
=
true
;
}
return
i
[
0
];
});
if
(
this
.
autoSelect
&&
!
activeFound
)
{
items
.
filter
(
':not(.dropdown-header)'
).
first
().
addClass
(
'active'
);
this
.
$element
.
data
(
'active'
,
items
.
first
().
data
(
'value'
));
}
this
.
$menu
.
html
(
items
);
return
this
;
},
displayText
:
function
(
item
)
{
return
typeof
item
!==
'undefined'
&&
typeof
item
.
name
!=
'undefined'
&&
item
.
name
||
item
;
},
next
:
function
(
event
)
{
var
active
=
this
.
$menu
.
find
(
'.active'
).
removeClass
(
'active'
)
,
next
=
active
.
next
();
if
(
!
next
.
length
)
{
next
=
$
(
this
.
$menu
.
find
(
'li'
)[
0
]);
}
next
.
addClass
(
'active'
);
},
prev
:
function
(
event
)
{
var
active
=
this
.
$menu
.
find
(
'.active'
).
removeClass
(
'active'
)
,
prev
=
active
.
prev
();
if
(
!
prev
.
length
)
{
prev
=
this
.
$menu
.
find
(
'li'
).
last
();
}
prev
.
addClass
(
'active'
);
},
listen
:
function
()
{
this
.
$element
.
on
(
'focus'
,
$
.
proxy
(
this
.
focus
,
this
))
.
on
(
'blur'
,
$
.
proxy
(
this
.
blur
,
this
))
.
on
(
'keypress'
,
$
.
proxy
(
this
.
keypress
,
this
))
.
on
(
'input'
,
$
.
proxy
(
this
.
input
,
this
))
.
on
(
'keyup'
,
$
.
proxy
(
this
.
keyup
,
this
));
if
(
this
.
eventSupported
(
'keydown'
))
{
this
.
$element
.
on
(
'keydown'
,
$
.
proxy
(
this
.
keydown
,
this
));
}
this
.
$menu
.
on
(
'click'
,
$
.
proxy
(
this
.
click
,
this
))
.
on
(
'mouseenter'
,
'li'
,
$
.
proxy
(
this
.
mouseenter
,
this
))
.
on
(
'mouseleave'
,
'li'
,
$
.
proxy
(
this
.
mouseleave
,
this
));
},
destroy
:
function
()
{
this
.
$element
.
data
(
'typeahead'
,
null
);
this
.
$element
.
data
(
'active'
,
null
);
this
.
$element
.
off
(
'focus'
)
.
off
(
'blur'
)
.
off
(
'keypress'
)
.
off
(
'input'
)
.
off
(
'keyup'
);
if
(
this
.
eventSupported
(
'keydown'
))
{
this
.
$element
.
off
(
'keydown'
);
}
this
.
$menu
.
remove
();
},
eventSupported
:
function
(
eventName
)
{
var
isSupported
=
eventName
in
this
.
$element
;
if
(
!
isSupported
)
{
this
.
$element
.
setAttribute
(
eventName
,
'return;'
);
isSupported
=
typeof
this
.
$element
[
eventName
]
===
'function'
;
}
return
isSupported
;
},
move
:
function
(
e
)
{
if
(
!
this
.
shown
)
return
;
switch
(
e
.
keyCode
)
{
case
9
:
// tab
case
13
:
// enter
case
27
:
// escape
e
.
preventDefault
();
break
;
case
38
:
// up arrow
// with the shiftKey (this is actually the left parenthesis)
if
(
e
.
shiftKey
)
return
;
e
.
preventDefault
();
this
.
prev
();
break
;
case
40
:
// down arrow
// with the shiftKey (this is actually the right parenthesis)
if
(
e
.
shiftKey
)
return
;
e
.
preventDefault
();
this
.
next
();
break
;
}
},
keydown
:
function
(
e
)
{
this
.
suppressKeyPressRepeat
=
~
$
.
inArray
(
e
.
keyCode
,
[
40
,
38
,
9
,
13
,
27
]);
if
(
!
this
.
shown
&&
e
.
keyCode
==
40
)
{
this
.
lookup
();
}
else
{
this
.
move
(
e
);
}
},
keypress
:
function
(
e
)
{
if
(
this
.
suppressKeyPressRepeat
)
return
;
this
.
move
(
e
);
},
input
:
function
(
e
)
{
this
.
lookup
();
e
.
preventDefault
();
},
keyup
:
function
(
e
)
{
switch
(
e
.
keyCode
)
{
case
40
:
// down arrow
case
38
:
// up arrow
case
16
:
// shift
case
17
:
// ctrl
case
18
:
// alt
break
;
case
9
:
// tab
case
13
:
// enter
if
(
!
this
.
shown
)
return
;
this
.
select
();
break
;
case
27
:
// escape
if
(
!
this
.
shown
)
return
;
this
.
hide
();
break
;
}
e
.
preventDefault
();
},
focus
:
function
(
e
)
{
if
(
!
this
.
focused
)
{
this
.
focused
=
true
;
if
(
this
.
options
.
showHintOnFocus
)
{
this
.
lookup
(
''
);
}
}
},
blur
:
function
(
e
)
{
this
.
focused
=
false
;
if
(
!
this
.
mousedover
&&
this
.
shown
)
this
.
hide
();
},
click
:
function
(
e
)
{
e
.
preventDefault
();
this
.
select
();
this
.
$element
.
focus
();
this
.
hide
();
},
mouseenter
:
function
(
e
)
{
this
.
mousedover
=
true
;
this
.
$menu
.
find
(
'.active'
).
removeClass
(
'active'
);
$
(
e
.
currentTarget
).
addClass
(
'active'
);
},
mouseleave
:
function
(
e
)
{
this
.
mousedover
=
false
;
if
(
!
this
.
focused
&&
this
.
shown
)
this
.
hide
();
}
};
/* TYPEAHEAD PLUGIN DEFINITION
* =========================== */
var
old
=
$
.
fn
.
typeahead
;
$
.
fn
.
typeahead
=
function
(
option
)
{
var
arg
=
arguments
;
if
(
typeof
option
==
'string'
&&
option
==
'getActive'
)
{
return
this
.
data
(
'active'
);
}
return
this
.
each
(
function
()
{
var
$this
=
$
(
this
)
,
data
=
$this
.
data
(
'typeahead'
)
,
options
=
typeof
option
==
'object'
&&
option
;
if
(
!
data
)
$this
.
data
(
'typeahead'
,
(
data
=
new
Typeahead
(
this
,
options
)));
if
(
typeof
option
==
'string'
&&
data
[
option
])
{
if
(
arg
.
length
>
1
)
{
data
[
option
].
apply
(
data
,
Array
.
prototype
.
slice
.
call
(
arg
,
1
));
}
else
{
data
[
option
]();
}
}
});
};
$
.
fn
.
typeahead
.
defaults
=
{
source
:
[],
items
:
8
,
menu
:
'<ul class="typeahead dropdown-menu" role="listbox"></ul>'
,
item
:
'<li><a class="dropdown-item" href="#" role="option"></a></li>'
,
minLength
:
1
,
scrollHeight
:
0
,
autoSelect
:
true
,
afterSelect
:
$
.
noop
,
addItem
:
false
,
delay
:
0
,
separator
:
'category'
,
headerHtml
:
'<li class="dropdown-header"></li>'
,
headerDivider
:
'<li class="divider" role="separator"></li>'
};
$
.
fn
.
typeahead
.
Constructor
=
Typeahead
;
/* TYPEAHEAD NO CONFLICT
* =================== */
$
.
fn
.
typeahead
.
noConflict
=
function
()
{
$
.
fn
.
typeahead
=
old
;
return
this
;
};
/* TYPEAHEAD DATA-API
* ================== */
$
(
document
).
on
(
'focus.typeahead.data-api'
,
'[data-provide="typeahead"]'
,
function
(
e
)
{
var
$this
=
$
(
this
);
if
(
$this
.
data
(
'typeahead'
))
return
;
$this
.
typeahead
(
$this
.
data
());
});
}));
This diff is collapsed.
Click to expand it.
cps/templates/edit_book.html
View file @
cd0aeb28
{% extends "layout.html" %}
{% extends "layout.html" %}
{% block body %}
{% block body %}
{% if book %}
{% if book %}
<script
type=
"text/javascript"
>
$
(
document
).
ready
(
function
(){
$
(
'input.typeahead'
).
typeahead
({
name
:
'accounts'
,
source
:
function
(
query
,
process
)
{
$
.
ajax
({
url
:
'{{ url_for('
get_authors_json
') }} '
,
type
:
'POST'
,
dataType
:
'JSON'
,
data
:
'query='
+
query
,
success
:
function
(
data
)
{
console
.
log
(
data
);
process
(
data
);
}
});
}
});
});
</script>
<div
class=
"col-sm-3 col-lg-3 col-xs-12"
>
<div
class=
"col-sm-3 col-lg-3 col-xs-12"
>
<div
class=
"cover"
>
<div
class=
"cover"
>
{% if book.has_cover is defined %}
{% if book.has_cover is defined %}
...
@@ -21,7 +41,7 @@
...
@@ -21,7 +41,7 @@
<p>
{{author.name.join("
&
")}}
</p>
<p>
{{author.name.join("
&
")}}
</p>
{% endfor %}
{% endfor %}
{% endif %}
{% endif %}
<input
type=
"text"
class=
"form-control"
name=
"author_name"
id=
"bookAuthor
"
value=
"{{book.authors[0].name}}"
>
<input
type=
"text"
data-provide=
"typeahead"
class=
"form-control typeahead"
name=
"author_name"
id=
"bookAuthor"
autocomplete=
"off
"
value=
"{{book.authors[0].name}}"
>
</div>
</div>
<div
class=
"form-group"
>
<div
class=
"form-group"
>
<label
for=
"description"
>
Description
</label>
<label
for=
"description"
>
Description
</label>
...
...
This diff is collapsed.
Click to expand it.
cps/templates/layout.html
View file @
cd0aeb28
...
@@ -18,6 +18,17 @@
...
@@ -18,6 +18,17 @@
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
<![endif]-->
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script
src=
"https://code.jquery.com/jquery.js"
></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script
src=
"{{ url_for('static', filename='js/bootstrap.min.js') }}"
></script>
<script
src=
"{{ url_for('static', filename='js/bootstrap3-typeahead.js') }}"
></script>
<script
src=
"{{ url_for('static', filename='js/underscore.min.js') }}"
></script>
<script
src=
"{{ url_for('static', filename='js/intention.js') }}"
></script>
<script
src=
"{{ url_for('static', filename='js/context.js') }}"
></script>
<script
src=
"{{ url_for('static', filename='js/plugins.js') }}"
></script>
<script
src=
"{{ url_for('static', filename='js/main.js') }}"
></script>
</head>
</head>
<body>
<body>
<!-- Static navbar -->
<!-- Static navbar -->
...
@@ -127,14 +138,5 @@
...
@@ -127,14 +138,5 @@
</div>
</div>
</div>
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script
src=
"https://code.jquery.com/jquery.js"
></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script
src=
"{{ url_for('static', filename='js/bootstrap.min.js') }}"
></script>
<script
src=
"{{ url_for('static', filename='js/underscore.min.js') }}"
></script>
<script
src=
"{{ url_for('static', filename='js/intention.js') }}"
></script>
<script
src=
"{{ url_for('static', filename='js/context.js') }}"
></script>
<script
src=
"{{ url_for('static', filename='js/plugins.js') }}"
></script>
<script
src=
"{{ url_for('static', filename='js/main.js') }}"
></script>
</body>
</body>
</html>
</html>
This diff is collapsed.
Click to expand it.
cps/web.py
View file @
cd0aeb28
...
@@ -17,6 +17,7 @@ from werkzeug.security import generate_password_hash, check_password_hash
...
@@ -17,6 +17,7 @@ from werkzeug.security import generate_password_hash, check_password_hash
from
functools
import
wraps
from
functools
import
wraps
import
base64
import
base64
from
sqlalchemy.sql
import
*
from
sqlalchemy.sql
import
*
import
json
app
=
(
Flask
(
__name__
))
app
=
(
Flask
(
__name__
))
...
@@ -222,6 +223,14 @@ def get_opds_download_link(book_id, format):
...
@@ -222,6 +223,14 @@ def get_opds_download_link(book_id, format):
)
)
return
response
return
response
@
app
.
route
(
"/get_authors_json"
,
methods
=
[
'GET'
,
'POST'
])
def
get_authors_json
():
if
request
.
method
==
"POST"
:
form
=
request
.
form
.
to_dict
()
entries
=
db
.
session
.
execute
(
"select name from authors where name like '
%
"
+
form
[
'query'
]
+
"
%
'"
)
return
json
.
dumps
([
dict
(
r
)
for
r
in
entries
])
@
app
.
route
(
"/"
,
defaults
=
{
'page'
:
1
})
@
app
.
route
(
"/"
,
defaults
=
{
'page'
:
1
})
@
app
.
route
(
'/page/<int:page>'
)
@
app
.
route
(
'/page/<int:page>'
)
def
index
(
page
):
def
index
(
page
):
...
...
This diff is collapsed.
Click to expand it.
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