Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
Asistencia
Overview
Overview
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
Billy Larru
Asistencia
Commits
c018db65
Commit
c018db65
authored
Jun 27, 2018
by
Billy Larru
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
configurando datatatable y datepicker
parent
3edc4df7
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
4323 additions
and
6 deletions
+4323
-6
general.css
src/main/webapp/css/general.css
+1
-2
bootstrap-select.min.css
.../webapp/css/lib/bootstrap-select/bootstrap-select.min.css
+303
-0
general.js
src/main/webapp/js/general.js
+81
-3
bootstrap-select.min.js
...in/webapp/js/lib/bootstrap-select/bootstrap-select.min.js
+1872
-0
underscore.js
src/main/webapp/js/lib/underscore.js
+1693
-0
controlAsistenciaDocentes.js
src/main/webapp/js/pages/controlAsistenciaDocentes.js
+146
-0
controlAsistenciaDocentes.jsp
src/main/webapp/vistas/controlAsistenciaDocentes.jsp
+226
-0
footer-body.jsp
src/main/webapp/vistas/templates/footer-body.jsp
+1
-1
No files found.
src/main/webapp/css/general.css
View file @
c018db65
btn-green
{
background-color
:
#26A69A
;
}
\ No newline at end of file
}
src/main/webapp/css/lib/bootstrap-select/bootstrap-select.min.css
0 → 100644
View file @
c018db65
/*!
* Bootstrap-select v1.12.4 (http://silviomoreto.github.io/bootstrap-select)
*
* Copyright 2013-2017 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
*/
select
.bs-select-hidden
,
select
.selectpicker
{
display
:
none
!important
;
height
:
32px
;
}
.bootstrap-select
{
width
:
220px
\
0
;
/*IE9 and below*/
}
.bootstrap-select
>
.dropdown-toggle
{
width
:
100%
;
padding-right
:
25px
;
z-index
:
1
;
height
:
32px
;
}
.bootstrap-select
>
.dropdown-toggle.bs-placeholder
,
.bootstrap-select
>
.dropdown-toggle.bs-placeholder
:hover
,
.bootstrap-select
>
.dropdown-toggle.bs-placeholder
:focus
,
.bootstrap-select
>
.dropdown-toggle.bs-placeholder
:active
{
/*color: #999;*/
}
.bootstrap-select
>
select
{
position
:
absolute
!important
;
bottom
:
0
;
left
:
50%
;
display
:
block
!important
;
width
:
0.5px
!important
;
height
:
100%
!important
;
padding
:
0
!important
;
opacity
:
0
!important
;
border
:
none
;
}
.bootstrap-select
>
select
.mobile-device
{
top
:
0
;
left
:
0
;
display
:
block
!important
;
width
:
100%
!important
;
z-index
:
2
;
}
.has-error
.bootstrap-select
.dropdown-toggle
,
.error
.bootstrap-select
.dropdown-toggle
{
border-color
:
#b94a48
;
}
.bootstrap-select.fit-width
{
width
:
auto
!important
;
}
.bootstrap-select
:not
([
class
*=
"col-"
])
:not
([
class
*=
"form-control"
])
:not
(
.input-group-btn
)
{
width
:
220px
;
}
.bootstrap-select
.dropdown-toggle
:focus
{
outline
:
thin
dotted
#333333
!important
;
outline
:
5px
auto
-webkit-focus-ring-color
!important
;
outline-offset
:
-2px
;
}
.bootstrap-select.form-control
{
margin-bottom
:
0
;
padding
:
0
;
border
:
none
;
}
.bootstrap-select.form-control
:not
([
class
*=
"col-"
])
{
width
:
100%
;
}
.bootstrap-select.form-control.input-group-btn
{
z-index
:
auto
;
}
.bootstrap-select.form-control.input-group-btn
:not
(
:first-child
)
:not
(
:last-child
)
>
.btn
{
border-radius
:
0
;
}
.bootstrap-select.btn-group
:not
(
.input-group-btn
),
.bootstrap-select.btn-group
[
class
*=
"col-"
]
{
float
:
none
;
display
:
inline-block
;
margin-left
:
0
;
}
.bootstrap-select.btn-group.dropdown-menu-right
,
.bootstrap-select.btn-group
[
class
*=
"col-"
]
.dropdown-menu-right
,
.row
.bootstrap-select.btn-group
[
class
*=
"col-"
]
.dropdown-menu-right
{
float
:
right
;
}
.form-inline
.bootstrap-select.btn-group
,
.form-horizontal
.bootstrap-select.btn-group
,
.form-group
.bootstrap-select.btn-group
{
margin-bottom
:
0
;
}
.form-group-lg
.bootstrap-select.btn-group.form-control
,
.form-group-sm
.bootstrap-select.btn-group.form-control
{
padding
:
0
;
}
.form-group-lg
.bootstrap-select.btn-group.form-control
.dropdown-toggle
,
.form-group-sm
.bootstrap-select.btn-group.form-control
.dropdown-toggle
{
height
:
100%
;
font-size
:
inherit
;
line-height
:
inherit
;
border-radius
:
inherit
;
}
.form-inline
.bootstrap-select.btn-group
.form-control
{
width
:
100%
;
}
.bootstrap-select.btn-group.disabled
,
.bootstrap-select.btn-group
>
.disabled
{
cursor
:
not-allowed
;
}
.bootstrap-select.btn-group.disabled
:focus
,
.bootstrap-select.btn-group
>
.disabled
:focus
{
outline
:
none
!important
;
}
.bootstrap-select.btn-group.bs-container
{
position
:
absolute
;
height
:
0
!important
;
padding
:
0
!important
;
}
.bootstrap-select.btn-group.bs-container
.dropdown-menu
{
z-index
:
1060
;
}
.bootstrap-select.btn-group
.dropdown-toggle
.filter-option
{
display
:
inline-block
;
overflow
:
hidden
;
width
:
100%
;
text-align
:
left
;
}
.bootstrap-select.btn-group
.dropdown-toggle
.caret
{
position
:
absolute
;
top
:
50%
;
right
:
12px
;
margin-top
:
-2px
;
vertical-align
:
middle
;
}
.bootstrap-select.btn-group
[
class
*=
"col-"
]
.dropdown-toggle
{
width
:
100%
;
}
.bootstrap-select.btn-group
.dropdown-menu
{
min-width
:
100%
;
-webkit-box-sizing
:
border-box
;
-moz-box-sizing
:
border-box
;
box-sizing
:
border-box
;
}
.bootstrap-select.btn-group
.dropdown-menu.inner
{
position
:
static
;
float
:
none
;
border
:
0
;
padding
:
0
;
margin
:
0
;
border-radius
:
0
;
-webkit-box-shadow
:
none
;
box-shadow
:
none
;
}
.bootstrap-select.btn-group
.dropdown-menu
li
{
position
:
relative
;
}
.bootstrap-select.btn-group
.dropdown-menu
li
.active
small
{
color
:
#fff
;
}
.bootstrap-select.btn-group
.dropdown-menu
li
.disabled
a
{
cursor
:
not-allowed
;
}
.bootstrap-select.btn-group
.dropdown-menu
li
a
{
cursor
:
pointer
;
-webkit-user-select
:
none
;
-moz-user-select
:
none
;
-ms-user-select
:
none
;
user-select
:
none
;
}
.bootstrap-select.btn-group
.dropdown-menu
li
a
.opt
{
position
:
relative
;
padding-left
:
2.25em
;
}
.bootstrap-select.btn-group
.dropdown-menu
li
a
span
.check-mark
{
display
:
none
;
}
.bootstrap-select.btn-group
.dropdown-menu
li
a
span
.text
{
display
:
inline-block
;
}
.bootstrap-select.btn-group
.dropdown-menu
li
small
{
padding-left
:
0.5em
;
}
.bootstrap-select.btn-group
.dropdown-menu
.notify
{
position
:
absolute
;
bottom
:
5px
;
width
:
96%
;
margin
:
0
2%
;
min-height
:
26px
;
padding
:
3px
5px
;
background
:
#f5f5f5
;
border
:
1px
solid
#e3e3e3
;
-webkit-box-shadow
:
inset
0
1px
1px
rgba
(
0
,
0
,
0
,
0.05
);
box-shadow
:
inset
0
1px
1px
rgba
(
0
,
0
,
0
,
0.05
);
pointer-events
:
none
;
opacity
:
0.9
;
-webkit-box-sizing
:
border-box
;
-moz-box-sizing
:
border-box
;
box-sizing
:
border-box
;
}
.bootstrap-select.btn-group
.no-results
{
padding
:
3px
;
background
:
#f5f5f5
;
margin
:
0
5px
;
white-space
:
nowrap
;
}
.bootstrap-select.btn-group.fit-width
.dropdown-toggle
.filter-option
{
position
:
static
;
}
.bootstrap-select.btn-group.fit-width
.dropdown-toggle
.caret
{
position
:
static
;
top
:
auto
;
margin-top
:
-1px
;
}
.bootstrap-select.btn-group.show-tick
.dropdown-menu
li
.selected
a
span
.check-mark
{
position
:
absolute
;
display
:
inline-block
;
right
:
15px
;
margin-top
:
5px
;
}
.bootstrap-select.btn-group.show-tick
.dropdown-menu
li
a
span
.text
{
margin-right
:
34px
;
}
.bootstrap-select.show-menu-arrow.open
>
.dropdown-toggle
{
z-index
:
1061
;
}
.bootstrap-select.show-menu-arrow
.dropdown-toggle
:before
{
content
:
''
;
border-left
:
7px
solid
transparent
;
border-right
:
7px
solid
transparent
;
border-bottom
:
7px
solid
rgba
(
204
,
204
,
204
,
0.2
);
position
:
absolute
;
bottom
:
-4px
;
left
:
9px
;
display
:
none
;
}
.bootstrap-select.show-menu-arrow
.dropdown-toggle
:after
{
content
:
''
;
border-left
:
6px
solid
transparent
;
border-right
:
6px
solid
transparent
;
border-bottom
:
6px
solid
white
;
position
:
absolute
;
bottom
:
-4px
;
left
:
10px
;
display
:
none
;
}
.bootstrap-select.show-menu-arrow.dropup
.dropdown-toggle
:before
{
bottom
:
auto
;
top
:
-3px
;
border-top
:
7px
solid
rgba
(
204
,
204
,
204
,
0.2
);
border-bottom
:
0
;
}
.bootstrap-select.show-menu-arrow.dropup
.dropdown-toggle
:after
{
bottom
:
auto
;
top
:
-3px
;
border-top
:
6px
solid
white
;
border-bottom
:
0
;
}
.bootstrap-select.show-menu-arrow.pull-right
.dropdown-toggle
:before
{
right
:
12px
;
left
:
auto
;
}
.bootstrap-select.show-menu-arrow.pull-right
.dropdown-toggle
:after
{
right
:
13px
;
left
:
auto
;
}
.bootstrap-select.show-menu-arrow.open
>
.dropdown-toggle
:before
,
.bootstrap-select.show-menu-arrow.open
>
.dropdown-toggle
:after
{
display
:
block
;
}
.bs-searchbox
,
.bs-actionsbox
,
.bs-donebutton
{
padding
:
4px
8px
;
}
.bs-actionsbox
{
width
:
100%
;
-webkit-box-sizing
:
border-box
;
-moz-box-sizing
:
border-box
;
box-sizing
:
border-box
;
}
.bs-actionsbox
.btn-group
button
{
width
:
50%
;
}
.bs-donebutton
{
float
:
left
;
width
:
100%
;
-webkit-box-sizing
:
border-box
;
-moz-box-sizing
:
border-box
;
box-sizing
:
border-box
;
}
.bs-donebutton
.btn-group
button
{
width
:
100%
;
}
.bs-searchbox
+
.bs-actionsbox
{
padding
:
0
8px
4px
;
}
.bs-searchbox
.form-control
{
margin-bottom
:
0
;
width
:
100%
;
float
:
none
;
}
/*# sourceMappingURL=bootstrap-select.css.map */
\ No newline at end of file
src/main/webapp/js/general.js
View file @
c018db65
...
...
@@ -4,7 +4,8 @@ const PATH_IP = 'http://172.16.2.102:7070/Asistencia/';
//PRODUCCION
const
PATH_DOMAIN
=
''
;
const
CODIGO_PROYECTO_ASISTENCIA
=
'7'
;
const
PATH_SERVICIO_REST
=
'http://172.16.2.53:8080/security-rest/api/'
//'http://app8.sacooliveros.edu.pe:8080/security-rest/api/';
//const PATH_SERVICIO_REST = 'http://172.16.2.53:8080/security-rest/api/'//'http://app8.sacooliveros.edu.pe:8080/security-rest/api/';
const
PATH_SERVICIO_REST
=
'http://app9.sacooliveros.edu.pe:8080/security-rest/api/'
;
/*Ajax genral*/
const
ajaxRequestSendBody
=
obj
=>
{
...
...
@@ -149,4 +150,81 @@ let logOut = () => {
document
.
querySelector
(
'#logOut'
).
addEventListener
(
'click'
,
(
e
)
=>
{
window
.
location
.
href
=
'../vistas/logout'
;
});
};
\ No newline at end of file
};
function
defaultConfigDataTable
()
{
$
.
extend
(
$
.
fn
.
dataTable
.
defaults
,
{
autoWidth
:
false
,
searching
:
false
,
lengthChange
:
false
,
responsive
:
true
,
bSort
:
false
,
dom
:
'<"datatable-header"fl><"datatable-scroll"t><"datatable-footer"ip>'
,
language
:
{
"paginate"
:
{
'first'
:
'First'
,
'last'
:
'Last'
,
'next'
:
'→'
,
'previous'
:
'←'
},
"sProcessing"
:
"Procesando..."
,
"sLengthMenu"
:
"Mostrar _MENU_ registros"
,
"sZeroRecords"
:
"No se encontraron resultados"
,
"sEmptyTable"
:
"Ningún dato disponible en esta tabla"
,
"sInfo"
:
"Mostrando registros del _START_ al _END_ de un total de _TOTAL_ registros"
,
"sInfoEmpty"
:
"Mostrando registros del 0 al 0 de un total de 0 registros"
,
"sInfoFiltered"
:
"(filtrado de un total de _MAX_ registros)"
,
"sInfoPostFix"
:
""
,
"sSearch"
:
"Buscar:"
,
"sUrl"
:
""
,
"sInfoThousands"
:
","
,
"sLoadingRecords"
:
"Cargando..."
,
"oPaginate"
:
{
"sFirst"
:
"Primero"
,
"sLast"
:
"Último"
,
"sNext"
:
"Siguiente"
,
"sPrevious"
:
"Anterior"
},
"oAria"
:
{
"sSortAscending"
:
": Activar para ordenar la columna de manera ascendente"
,
"sSortDescending"
:
": Activar para ordenar la columna de manera descendente"
}
},
drawCallback
:
function
()
{
$
(
this
).
find
(
'tbody tr'
).
slice
(
-
3
).
find
(
'.dropdown, .btn-group'
).
addClass
(
'dropup'
);
},
preDrawCallback
:
function
()
{
$
(
this
).
find
(
'tbody tr'
).
slice
(
-
3
).
find
(
'.dropdown, .btn-group'
).
removeClass
(
'dropup'
);
},
rowCallback
:
function
(
row
,
data
,
index
)
{
if
(
$
(
row
).
hasClass
(
'odd'
))
{
$
(
row
).
css
(
'background-color'
,
'#e8f4f4'
);
}
}
});
}
function
defaultConfigDatePicker
()
{
$
.
datepicker
.
regional
[
'es'
]
=
{
closeText
:
'Cerrar'
,
prevText
:
'<Ant'
,
nextText
:
'Sig>'
,
currentText
:
'Hoy'
,
monthNames
:
[
'Enero'
,
'Febrero'
,
'Marzo'
,
'Abril'
,
'Mayo'
,
'Junio'
,
'Julio'
,
'Agosto'
,
'Septiembre'
,
'Octubre'
,
'Noviembre'
,
'Diciembre'
],
monthNamesShort
:
[
'Ene'
,
'Feb'
,
'Mar'
,
'Abr'
,
'May'
,
'Jun'
,
'Jul'
,
'Ago'
,
'Sep'
,
'Oct'
,
'Nov'
,
'Dic'
],
dayNames
:
[
'Domingo'
,
'Lunes'
,
'Martes'
,
'Miércoles'
,
'Jueves'
,
'Viernes'
,
'Sábado'
],
dayNamesShort
:
[
'Dom'
,
'Lun'
,
'Mar'
,
'Mié'
,
'Jue'
,
'Vie'
,
'Sáb'
],
dayNamesMin
:
[
'Do'
,
'Lu'
,
'Ma'
,
'Mi'
,
'Ju'
,
'Vi'
,
'Sá'
],
weekHeader
:
'Sm'
,
dateFormat
:
'dd/mm/yy'
,
firstDay
:
1
,
isRTL
:
false
,
showMonthAfterYear
:
false
,
yearSuffix
:
''
};
$
.
datepicker
.
setDefaults
(
$
.
datepicker
.
regional
[
'es'
]);
}
\ No newline at end of file
src/main/webapp/js/lib/bootstrap-select/bootstrap-select.min.js
0 → 100644
View file @
c018db65
/*!
* Bootstrap-select v1.12.4 (http://silviomoreto.github.io/bootstrap-select)
*
* Copyright 2013-2017 bootstrap-select
* Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)
*/
(
function
(
root
,
factory
)
{
if
(
typeof
define
===
'function'
&&
define
.
amd
)
{
// AMD. Register as an anonymous module unless amdModuleId is set
define
([
"jquery"
],
function
(
a0
)
{
return
(
factory
(
a0
));
});
}
else
if
(
typeof
module
===
'object'
&&
module
.
exports
)
{
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module
.
exports
=
factory
(
require
(
"jquery"
));
}
else
{
factory
(
root
[
"jQuery"
]);
}
}(
this
,
function
(
jQuery
)
{
(
function
(
$
)
{
'use strict'
;
//<editor-fold desc="Shims">
if
(
!
String
.
prototype
.
includes
)
{
(
function
()
{
'use strict'
;
// needed to support `apply`/`call` with `undefined`/`null`
var
toString
=
{}.
toString
;
var
defineProperty
=
(
function
()
{
// IE 8 only supports `Object.defineProperty` on DOM elements
try
{
var
object
=
{};
var
$defineProperty
=
Object
.
defineProperty
;
var
result
=
$defineProperty
(
object
,
object
,
object
)
&&
$defineProperty
;
}
catch
(
error
)
{
}
return
result
;
}());
var
indexOf
=
''
.
indexOf
;
var
includes
=
function
(
search
)
{
if
(
this
==
null
)
{
throw
new
TypeError
();
}
var
string
=
String
(
this
);
if
(
search
&&
toString
.
call
(
search
)
==
'[object RegExp]'
)
{
throw
new
TypeError
();
}
var
stringLength
=
string
.
length
;
var
searchString
=
String
(
search
);
var
searchLength
=
searchString
.
length
;
var
position
=
arguments
.
length
>
1
?
arguments
[
1
]
:
undefined
;
// `ToInteger`
var
pos
=
position
?
Number
(
position
)
:
0
;
if
(
pos
!=
pos
)
{
// better `isNaN`
pos
=
0
;
}
var
start
=
Math
.
min
(
Math
.
max
(
pos
,
0
),
stringLength
);
// Avoid the `indexOf` call if no match is possible
if
(
searchLength
+
start
>
stringLength
)
{
return
false
;
}
return
indexOf
.
call
(
string
,
searchString
,
pos
)
!=
-
1
;
};
if
(
defineProperty
)
{
defineProperty
(
String
.
prototype
,
'includes'
,
{
'value'
:
includes
,
'configurable'
:
true
,
'writable'
:
true
});
}
else
{
String
.
prototype
.
includes
=
includes
;
}
}());
}
if
(
!
String
.
prototype
.
startsWith
)
{
(
function
()
{
'use strict'
;
// needed to support `apply`/`call` with `undefined`/`null`
var
defineProperty
=
(
function
()
{
// IE 8 only supports `Object.defineProperty` on DOM elements
try
{
var
object
=
{};
var
$defineProperty
=
Object
.
defineProperty
;
var
result
=
$defineProperty
(
object
,
object
,
object
)
&&
$defineProperty
;
}
catch
(
error
)
{
}
return
result
;
}());
var
toString
=
{}.
toString
;
var
startsWith
=
function
(
search
)
{
if
(
this
==
null
)
{
throw
new
TypeError
();
}
var
string
=
String
(
this
);
if
(
search
&&
toString
.
call
(
search
)
==
'[object RegExp]'
)
{
throw
new
TypeError
();
}
var
stringLength
=
string
.
length
;
var
searchString
=
String
(
search
);
var
searchLength
=
searchString
.
length
;
var
position
=
arguments
.
length
>
1
?
arguments
[
1
]
:
undefined
;
// `ToInteger`
var
pos
=
position
?
Number
(
position
)
:
0
;
if
(
pos
!=
pos
)
{
// better `isNaN`
pos
=
0
;
}
var
start
=
Math
.
min
(
Math
.
max
(
pos
,
0
),
stringLength
);
// Avoid the `indexOf` call if no match is possible
if
(
searchLength
+
start
>
stringLength
)
{
return
false
;
}
var
index
=
-
1
;
while
(
++
index
<
searchLength
)
{
if
(
string
.
charCodeAt
(
start
+
index
)
!=
searchString
.
charCodeAt
(
index
))
{
return
false
;
}
}
return
true
;
};
if
(
defineProperty
)
{
defineProperty
(
String
.
prototype
,
'startsWith'
,
{
'value'
:
startsWith
,
'configurable'
:
true
,
'writable'
:
true
});
}
else
{
String
.
prototype
.
startsWith
=
startsWith
;
}
}());
}
if
(
!
Object
.
keys
)
{
Object
.
keys
=
function
(
o
,
// object
k
,
// key
r
// result array
){
// initialize object and result
r
=
[];
// iterate over object keys
for
(
k
in
o
)
// fill result array with non-prototypical keys
r
.
hasOwnProperty
.
call
(
o
,
k
)
&&
r
.
push
(
k
);
// return result
return
r
;
};
}
// set data-selected on select element if the value has been programmatically selected
// prior to initialization of bootstrap-select
// * consider removing or replacing an alternative method *
var
valHooks
=
{
useDefault
:
false
,
_set
:
$
.
valHooks
.
select
.
set
};
$
.
valHooks
.
select
.
set
=
function
(
elem
,
value
)
{
if
(
value
&&
!
valHooks
.
useDefault
)
$
(
elem
).
data
(
'selected'
,
true
);
return
valHooks
.
_set
.
apply
(
this
,
arguments
);
};
var
changed_arguments
=
null
;
var
EventIsSupported
=
(
function
()
{
try
{
new
Event
(
'change'
);
return
true
;
}
catch
(
e
)
{
return
false
;
}
})();
$
.
fn
.
triggerNative
=
function
(
eventName
)
{
var
el
=
this
[
0
],
event
;
if
(
el
.
dispatchEvent
)
{
// for modern browsers & IE9+
if
(
EventIsSupported
)
{
// For modern browsers
event
=
new
Event
(
eventName
,
{
bubbles
:
true
});
}
else
{
// For IE since it doesn't support Event constructor
event
=
document
.
createEvent
(
'Event'
);
event
.
initEvent
(
eventName
,
true
,
false
);
}
el
.
dispatchEvent
(
event
);
}
else
if
(
el
.
fireEvent
)
{
// for IE8
event
=
document
.
createEventObject
();
event
.
eventType
=
eventName
;
el
.
fireEvent
(
'on'
+
eventName
,
event
);
}
else
{
// fall back to jQuery.trigger
this
.
trigger
(
eventName
);
}
};
//</editor-fold>
// Case insensitive contains search
$
.
expr
.
pseudos
.
icontains
=
function
(
obj
,
index
,
meta
)
{
var
$obj
=
$
(
obj
).
find
(
'a'
);
var
haystack
=
(
$obj
.
data
(
'tokens'
)
||
$obj
.
text
()).
toString
().
toUpperCase
();
return
haystack
.
includes
(
meta
[
3
].
toUpperCase
());
};
// Case insensitive begins search
$
.
expr
.
pseudos
.
ibegins
=
function
(
obj
,
index
,
meta
)
{
var
$obj
=
$
(
obj
).
find
(
'a'
);
var
haystack
=
(
$obj
.
data
(
'tokens'
)
||
$obj
.
text
()).
toString
().
toUpperCase
();
return
haystack
.
startsWith
(
meta
[
3
].
toUpperCase
());
};
// Case and accent insensitive contains search
$
.
expr
.
pseudos
.
aicontains
=
function
(
obj
,
index
,
meta
)
{
var
$obj
=
$
(
obj
).
find
(
'a'
);
var
haystack
=
(
$obj
.
data
(
'tokens'
)
||
$obj
.
data
(
'normalizedText'
)
||
$obj
.
text
()).
toString
().
toUpperCase
();
return
haystack
.
includes
(
meta
[
3
].
toUpperCase
());
};
// Case and accent insensitive begins search
$
.
expr
.
pseudos
.
aibegins
=
function
(
obj
,
index
,
meta
)
{
var
$obj
=
$
(
obj
).
find
(
'a'
);
var
haystack
=
(
$obj
.
data
(
'tokens'
)
||
$obj
.
data
(
'normalizedText'
)
||
$obj
.
text
()).
toString
().
toUpperCase
();
return
haystack
.
startsWith
(
meta
[
3
].
toUpperCase
());
};
/**
* Remove all diatrics from the given text.
* @access private
* @param {String} text
* @returns {String}
*/
function
normalizeToBase
(
text
)
{
var
rExps
=
[
{
re
:
/
[\x
C0-
\x
C6
]
/g
,
ch
:
"A"
},
{
re
:
/
[\x
E0-
\x
E6
]
/g
,
ch
:
"a"
},
{
re
:
/
[\x
C8-
\x
CB
]
/g
,
ch
:
"E"
},
{
re
:
/
[\x
E8-
\x
EB
]
/g
,
ch
:
"e"
},
{
re
:
/
[\x
CC-
\x
CF
]
/g
,
ch
:
"I"
},
{
re
:
/
[\x
EC-
\x
EF
]
/g
,
ch
:
"i"
},
{
re
:
/
[\x
D2-
\x
D6
]
/g
,
ch
:
"O"
},
{
re
:
/
[\x
F2-
\x
F6
]
/g
,
ch
:
"o"
},
{
re
:
/
[\x
D9-
\x
DC
]
/g
,
ch
:
"U"
},
{
re
:
/
[\x
F9-
\x
FC
]
/g
,
ch
:
"u"
},
{
re
:
/
[\x
C7-
\x
E7
]
/g
,
ch
:
"c"
},
{
re
:
/
[\x
D1
]
/g
,
ch
:
"N"
},
{
re
:
/
[\x
F1
]
/g
,
ch
:
"n"
}
];
$
.
each
(
rExps
,
function
()
{
text
=
text
?
text
.
replace
(
this
.
re
,
this
.
ch
)
:
''
;
});
return
text
;
}
// List of HTML entities for escaping.
var
escapeMap
=
{
'&'
:
'&'
,
'<'
:
'<'
,
'>'
:
'>'
,
'"'
:
'"'
,
"'"
:
'''
,
'`'
:
'`'
};
var
unescapeMap
=
{
'&'
:
'&'
,
'<'
:
'<'
,
'>'
:
'>'
,
'"'
:
'"'
,
'''
:
"'"
,
'`'
:
'`'
};
// Functions for escaping and unescaping strings to/from HTML interpolation.
var
createEscaper
=
function
(
map
)
{
var
escaper
=
function
(
match
)
{
return
map
[
match
];
};
// Regexes for identifying a key that needs to be escaped.
var
source
=
'(?:'
+
Object
.
keys
(
map
).
join
(
'|'
)
+
')'
;
var
testRegexp
=
RegExp
(
source
);
var
replaceRegexp
=
RegExp
(
source
,
'g'
);
return
function
(
string
)
{
string
=
string
==
null
?
''
:
''
+
string
;
return
testRegexp
.
test
(
string
)
?
string
.
replace
(
replaceRegexp
,
escaper
)
:
string
;
};
};
var
htmlEscape
=
createEscaper
(
escapeMap
);
var
htmlUnescape
=
createEscaper
(
unescapeMap
);
var
Selectpicker
=
function
(
element
,
options
)
{
// bootstrap-select has been initialized - revert valHooks.select.set back to its original function
if
(
!
valHooks
.
useDefault
)
{
$
.
valHooks
.
select
.
set
=
valHooks
.
_set
;
valHooks
.
useDefault
=
true
;
}
this
.
$element
=
$
(
element
);
this
.
$newElement
=
null
;
this
.
$button
=
null
;
this
.
$menu
=
null
;
this
.
$lis
=
null
;
this
.
options
=
options
;
// If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a
// data-attribute)
if
(
this
.
options
.
title
===
null
)
{
this
.
options
.
title
=
this
.
$element
.
attr
(
'title'
);
}
// Format window padding
var
winPad
=
this
.
options
.
windowPadding
;
if
(
typeof
winPad
===
'number'
)
{
this
.
options
.
windowPadding
=
[
winPad
,
winPad
,
winPad
,
winPad
];
}
//Expose public methods
this
.
val
=
Selectpicker
.
prototype
.
val
;
this
.
render
=
Selectpicker
.
prototype
.
render
;
this
.
refresh
=
Selectpicker
.
prototype
.
refresh
;
this
.
setStyle
=
Selectpicker
.
prototype
.
setStyle
;
this
.
selectAll
=
Selectpicker
.
prototype
.
selectAll
;
this
.
deselectAll
=
Selectpicker
.
prototype
.
deselectAll
;
this
.
destroy
=
Selectpicker
.
prototype
.
destroy
;
this
.
remove
=
Selectpicker
.
prototype
.
remove
;
this
.
show
=
Selectpicker
.
prototype
.
show
;
this
.
hide
=
Selectpicker
.
prototype
.
hide
;
this
.
init
();
};
Selectpicker
.
VERSION
=
'1.12.4'
;
// part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.
Selectpicker
.
DEFAULTS
=
{
noneSelectedText
:
'[SELECCIONE]'
,
noneResultsText
:
'Sin resultados {0}'
,
countSelectedText
:
function
(
numSelected
,
numTotal
)
{
return
(
numSelected
==
1
)
?
"{0} item selected"
:
"{0} items selected"
;
},
maxOptionsText
:
function
(
numAll
,
numGroup
)
{
return
[
(
numAll
==
1
)
?
'Limit reached ({n} item max)'
:
'Limit reached ({n} items max)'
,
(
numGroup
==
1
)
?
'Group limit reached ({n} item max)'
:
'Group limit reached ({n} items max)'
];
},
selectAllText
:
'Todos'
,
deselectAllText
:
'Deseleccionar'
,
doneButton
:
false
,
doneButtonText
:
'Close'
,
multipleSeparator
:
', '
,
styleBase
:
'btn'
,
style
:
'btn-default'
,
size
:
'auto'
,
title
:
null
,
selectedTextFormat
:
'values'
,
width
:
false
,
container
:
false
,
hideDisabled
:
false
,
showSubtext
:
false
,
showIcon
:
true
,
showContent
:
true
,
dropupAuto
:
false
,
header
:
false
,
liveSearch
:
true
,
liveSearchPlaceholder
:
null
,
liveSearchNormalize
:
false
,
liveSearchStyle
:
'contains'
,
actionsBox
:
true
,
iconBase
:
'glyphicon'
,
tickIcon
:
'glyphicon-ok'
,
showTick
:
false
,
template
:
{
caret
:
'<span class="caret"></span>'
},
maxOptions
:
false
,
mobile
:
false
,
selectOnTab
:
false
,
dropdownAlignRight
:
false
,
windowPadding
:
0
};
Selectpicker
.
prototype
=
{
constructor
:
Selectpicker
,
init
:
function
()
{
var
that
=
this
,
id
=
this
.
$element
.
attr
(
'id'
);
this
.
$element
.
addClass
(
'bs-select-hidden'
);
// store originalIndex (key) and newIndex (value) in this.liObj for fast accessibility
// allows us to do this.$lis.eq(that.liObj[index]) instead of this.$lis.filter('[data-original-index="' + index + '"]')
this
.
liObj
=
{};
this
.
multiple
=
this
.
$element
.
prop
(
'multiple'
);
this
.
autofocus
=
this
.
$element
.
prop
(
'autofocus'
);
this
.
$newElement
=
this
.
createView
();
this
.
$element
.
after
(
this
.
$newElement
)
.
appendTo
(
this
.
$newElement
);
this
.
$button
=
this
.
$newElement
.
children
(
'button'
);
this
.
$menu
=
this
.
$newElement
.
children
(
'.dropdown-menu'
);
this
.
$menuInner
=
this
.
$menu
.
children
(
'.inner'
);
this
.
$searchbox
=
this
.
$menu
.
find
(
'input'
);
this
.
$element
.
removeClass
(
'bs-select-hidden'
);
if
(
this
.
options
.
dropdownAlignRight
===
true
)
this
.
$menu
.
addClass
(
'dropdown-menu-right'
);
if
(
typeof
id
!==
'undefined'
)
{
this
.
$button
.
attr
(
'data-id'
,
id
);
$
(
'label[for="'
+
id
+
'"]'
).
click
(
function
(
e
)
{
e
.
preventDefault
();
that
.
$button
.
focus
();
});
}
this
.
checkDisabled
();
this
.
clickListener
();
if
(
this
.
options
.
liveSearch
)
this
.
liveSearchListener
();
this
.
render
();
this
.
setStyle
();
this
.
setWidth
();
if
(
this
.
options
.
container
)
this
.
selectPosition
();
this
.
$menu
.
data
(
'this'
,
this
);
this
.
$newElement
.
data
(
'this'
,
this
);
if
(
this
.
options
.
mobile
)
this
.
mobile
();
this
.
$newElement
.
on
({
'hide.bs.dropdown'
:
function
(
e
)
{
that
.
$menuInner
.
attr
(
'aria-expanded'
,
false
);
that
.
$element
.
trigger
(
'hide.bs.select'
,
e
);
},
'hidden.bs.dropdown'
:
function
(
e
)
{
that
.
$element
.
trigger
(
'hidden.bs.select'
,
e
);
},
'show.bs.dropdown'
:
function
(
e
)
{
that
.
$menuInner
.
attr
(
'aria-expanded'
,
true
);
that
.
$element
.
trigger
(
'show.bs.select'
,
e
);
},
'shown.bs.dropdown'
:
function
(
e
)
{
that
.
$element
.
trigger
(
'shown.bs.select'
,
e
);
}
});
if
(
that
.
$element
[
0
].
hasAttribute
(
'required'
))
{
this
.
$element
.
on
(
'invalid'
,
function
()
{
that
.
$button
.
addClass
(
'bs-invalid'
);
that
.
$element
.
on
({
'focus.bs.select'
:
function
()
{
that
.
$button
.
focus
();
that
.
$element
.
off
(
'focus.bs.select'
);
},
'shown.bs.select'
:
function
()
{
that
.
$element
.
val
(
that
.
$element
.
val
())
// set the value to hide the validation message in Chrome when menu is opened
.
off
(
'shown.bs.select'
);
},
'rendered.bs.select'
:
function
()
{
// if select is no longer invalid, remove the bs-invalid class
if
(
this
.
validity
.
valid
)
that
.
$button
.
removeClass
(
'bs-invalid'
);
that
.
$element
.
off
(
'rendered.bs.select'
);
}
});
that
.
$button
.
on
(
'blur.bs.select'
,
function
()
{
that
.
$element
.
focus
().
blur
();
that
.
$button
.
off
(
'blur.bs.select'
);
});
});
}
setTimeout
(
function
()
{
that
.
$element
.
trigger
(
'loaded.bs.select'
);
});
},
createDropdown
:
function
()
{
// Options
// If we are multiple or showTick option is set, then add the show-tick class
var
showTick
=
(
this
.
multiple
||
this
.
options
.
showTick
)
?
' show-tick'
:
''
,
inputGroup
=
this
.
$element
.
parent
().
hasClass
(
'input-group'
)
?
' input-group-btn'
:
''
,
autofocus
=
this
.
autofocus
?
' autofocus'
:
''
;
// Elements
var
header
=
this
.
options
.
header
?
'<div class="popover-title"><button type="button" class="close" aria-hidden="true">×</button>'
+
this
.
options
.
header
+
'</div>'
:
''
;
var
searchbox
=
this
.
options
.
liveSearch
?
'<div class="bs-searchbox">'
+
'<input type="text" class="form-control" autocomplete="off"'
+
(
null
===
this
.
options
.
liveSearchPlaceholder
?
''
:
' placeholder="'
+
htmlEscape
(
this
.
options
.
liveSearchPlaceholder
)
+
'"'
)
+
' role="textbox" aria-label="Search">'
+
'</div>'
:
''
;
var
actionsbox
=
this
.
multiple
&&
this
.
options
.
actionsBox
?
'<div class="bs-actionsbox">'
+
'<div class="btn-group btn-group-sm btn-block">'
+
'<button type="button" class="actions-btn bs-select-all btn btn-default">'
+
this
.
options
.
selectAllText
+
'</button>'
+
'<button type="button" class="actions-btn bs-deselect-all btn btn-default">'
+
this
.
options
.
deselectAllText
+
'</button>'
+
'</div>'
+
'</div>'
:
''
;
var
donebutton
=
this
.
multiple
&&
this
.
options
.
doneButton
?
'<div class="bs-donebutton">'
+
'<div class="btn-group btn-block">'
+
'<button type="button" class="btn btn-sm btn-default">'
+
this
.
options
.
doneButtonText
+
'</button>'
+
'</div>'
+
'</div>'
:
''
;
var
drop
=
'<div class="btn-group bootstrap-select'
+
showTick
+
inputGroup
+
'">'
+
'<button type="button" class="'
+
this
.
options
.
styleBase
+
' dropdown-toggle" data-toggle="dropdown"'
+
autofocus
+
' role="button">'
+
'<span class="filter-option pull-left"></span> '
+
'<span class="bs-caret">'
+
this
.
options
.
template
.
caret
+
'</span>'
+
'</button>'
+
'<div class="dropdown-menu open" role="combobox">'
+
header
+
searchbox
+
actionsbox
+
'<ul class="dropdown-menu inner" role="listbox" aria-expanded="false">'
+
'</ul>'
+
donebutton
+
'</div>'
+
'</div>'
;
return
$
(
drop
);
},
createView
:
function
()
{
var
$drop
=
this
.
createDropdown
(),
li
=
this
.
createLi
();
$drop
.
find
(
'ul'
)[
0
].
innerHTML
=
li
;
return
$drop
;
},
reloadLi
:
function
()
{
// rebuild
var
li
=
this
.
createLi
();
this
.
$menuInner
[
0
].
innerHTML
=
li
;
},
createLi
:
function
()
{
var
that
=
this
,
_li
=
[],
optID
=
0
,
titleOption
=
document
.
createElement
(
'option'
),
liIndex
=
-
1
;
// increment liIndex whenever a new <li> element is created to ensure liObj is correct
// Helper functions
/**
* @param content
* @param [index]
* @param [classes]
* @param [optgroup]
* @returns {string}
*/
var
generateLI
=
function
(
content
,
index
,
classes
,
optgroup
)
{
return
'<li'
+
((
typeof
classes
!==
'undefined'
&&
''
!==
classes
)
?
' class="'
+
classes
+
'"'
:
''
)
+
((
typeof
index
!==
'undefined'
&&
null
!==
index
)
?
' data-original-index="'
+
index
+
'"'
:
''
)
+
((
typeof
optgroup
!==
'undefined'
&&
null
!==
optgroup
)
?
'data-optgroup="'
+
optgroup
+
'"'
:
''
)
+
'>'
+
content
+
'</li>'
;
};
/**
* @param text
* @param [classes]
* @param [inline]
* @param [tokens]
* @returns {string}
*/
var
generateA
=
function
(
text
,
classes
,
inline
,
tokens
)
{
return
'<a tabindex="0"'
+
(
typeof
classes
!==
'undefined'
?
' class="'
+
classes
+
'"'
:
''
)
+
(
inline
?
' style="'
+
inline
+
'"'
:
''
)
+
(
that
.
options
.
liveSearchNormalize
?
' data-normalized-text="'
+
normalizeToBase
(
htmlEscape
(
$
(
text
).
html
()))
+
'"'
:
''
)
+
(
typeof
tokens
!==
'undefined'
||
tokens
!==
null
?
' data-tokens="'
+
tokens
+
'"'
:
''
)
+
' role="option">'
+
text
+
'<span class="'
+
that
.
options
.
iconBase
+
' '
+
that
.
options
.
tickIcon
+
' check-mark"></span>'
+
'</a>'
;
};
if
(
this
.
options
.
title
&&
!
this
.
multiple
)
{
// this option doesn't create a new <li> element, but does add a new option, so liIndex is decreased
// since liObj is recalculated on every refresh, liIndex needs to be decreased even if the titleOption is already appended
liIndex
--
;
if
(
!
this
.
$element
.
find
(
'.bs-title-option'
).
length
)
{
// Use native JS to prepend option (faster)
var
element
=
this
.
$element
[
0
];
titleOption
.
className
=
'bs-title-option'
;
titleOption
.
innerHTML
=
this
.
options
.
title
;
titleOption
.
value
=
''
;
element
.
insertBefore
(
titleOption
,
element
.
firstChild
);
// Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option.
// the selected item may have been changed by user or programmatically before the bootstrap select plugin runs,
// if so, the select will have the data-selected attribute
var
$opt
=
$
(
element
.
options
[
element
.
selectedIndex
]);
if
(
$opt
.
attr
(
'selected'
)
===
undefined
&&
this
.
$element
.
data
(
'selected'
)
===
undefined
)
{
titleOption
.
selected
=
true
;
}
}
}
var
$selectOptions
=
this
.
$element
.
find
(
'option'
);
$selectOptions
.
each
(
function
(
index
)
{
var
$this
=
$
(
this
);
liIndex
++
;
if
(
$this
.
hasClass
(
'bs-title-option'
))
return
;
// Get the class and text for the option
var
optionClass
=
this
.
className
||
''
,
inline
=
htmlEscape
(
this
.
style
.
cssText
),
text
=
$this
.
data
(
'content'
)
?
$this
.
data
(
'content'
)
:
$this
.
html
(),
tokens
=
$this
.
data
(
'tokens'
)
?
$this
.
data
(
'tokens'
)
:
null
,
subtext
=
typeof
$this
.
data
(
'subtext'
)
!==
'undefined'
?
'<small class="text-muted">'
+
$this
.
data
(
'subtext'
)
+
'</small>'
:
''
,
icon
=
typeof
$this
.
data
(
'icon'
)
!==
'undefined'
?
'<span class="'
+
that
.
options
.
iconBase
+
' '
+
$this
.
data
(
'icon'
)
+
'"></span> '
:
''
,
$parent
=
$this
.
parent
(),
isOptgroup
=
$parent
[
0
].
tagName
===
'OPTGROUP'
,
isOptgroupDisabled
=
isOptgroup
&&
$parent
[
0
].
disabled
,
isDisabled
=
this
.
disabled
||
isOptgroupDisabled
,
prevHiddenIndex
;
if
(
icon
!==
''
&&
isDisabled
)
{
icon
=
'<span>'
+
icon
+
'</span>'
;
}
if
(
that
.
options
.
hideDisabled
&&
(
isDisabled
&&
!
isOptgroup
||
isOptgroupDisabled
))
{
// set prevHiddenIndex - the index of the first hidden option in a group of hidden options
// used to determine whether or not a divider should be placed after an optgroup if there are
// hidden options between the optgroup and the first visible option
prevHiddenIndex
=
$this
.
data
(
'prevHiddenIndex'
);
$this
.
next
().
data
(
'prevHiddenIndex'
,
(
prevHiddenIndex
!==
undefined
?
prevHiddenIndex
:
index
));
liIndex
--
;
return
;
}
if
(
!
$this
.
data
(
'content'
))
{
// Prepend any icon and append any subtext to the main text.
text
=
icon
+
'<span class="text">'
+
text
+
subtext
+
'</span>'
;
}
if
(
isOptgroup
&&
$this
.
data
(
'divider'
)
!==
true
)
{
if
(
that
.
options
.
hideDisabled
&&
isDisabled
)
{
if
(
$parent
.
data
(
'allOptionsDisabled'
)
===
undefined
)
{
var
$options
=
$parent
.
children
();
$parent
.
data
(
'allOptionsDisabled'
,
$options
.
filter
(
':disabled'
).
length
===
$options
.
length
);
}
if
(
$parent
.
data
(
'allOptionsDisabled'
))
{
liIndex
--
;
return
;
}
}
var
optGroupClass
=
' '
+
$parent
[
0
].
className
||
''
;
if
(
$this
.
index
()
===
0
)
{
// Is it the first option of the optgroup?
optID
+=
1
;
// Get the opt group label
var
label
=
$parent
[
0
].
label
,
labelSubtext
=
typeof
$parent
.
data
(
'subtext'
)
!==
'undefined'
?
'<small class="text-muted">'
+
$parent
.
data
(
'subtext'
)
+
'</small>'
:
''
,
labelIcon
=
$parent
.
data
(
'icon'
)
?
'<span class="'
+
that
.
options
.
iconBase
+
' '
+
$parent
.
data
(
'icon'
)
+
'"></span> '
:
''
;
label
=
labelIcon
+
'<span class="text">'
+
htmlEscape
(
label
)
+
labelSubtext
+
'</span>'
;
if
(
index
!==
0
&&
_li
.
length
>
0
)
{
// Is it NOT the first option of the select && are there elements in the dropdown?
liIndex
++
;
_li
.
push
(
generateLI
(
''
,
null
,
'divider'
,
optID
+
'div'
));
}
liIndex
++
;
_li
.
push
(
generateLI
(
label
,
null
,
'dropdown-header'
+
optGroupClass
,
optID
));
}
if
(
that
.
options
.
hideDisabled
&&
isDisabled
)
{
liIndex
--
;
return
;
}
_li
.
push
(
generateLI
(
generateA
(
text
,
'opt '
+
optionClass
+
optGroupClass
,
inline
,
tokens
),
index
,
''
,
optID
));
}
else
if
(
$this
.
data
(
'divider'
)
===
true
)
{
_li
.
push
(
generateLI
(
''
,
index
,
'divider'
));
}
else
if
(
$this
.
data
(
'hidden'
)
===
true
)
{
// set prevHiddenIndex - the index of the first hidden option in a group of hidden options
// used to determine whether or not a divider should be placed after an optgroup if there are
// hidden options between the optgroup and the first visible option
prevHiddenIndex
=
$this
.
data
(
'prevHiddenIndex'
);
$this
.
next
().
data
(
'prevHiddenIndex'
,
(
prevHiddenIndex
!==
undefined
?
prevHiddenIndex
:
index
));
_li
.
push
(
generateLI
(
generateA
(
text
,
optionClass
,
inline
,
tokens
),
index
,
'hidden is-hidden'
));
}
else
{
var
showDivider
=
this
.
previousElementSibling
&&
this
.
previousElementSibling
.
tagName
===
'OPTGROUP'
;
// if previous element is not an optgroup and hideDisabled is true
if
(
!
showDivider
&&
that
.
options
.
hideDisabled
)
{
prevHiddenIndex
=
$this
.
data
(
'prevHiddenIndex'
);
if
(
prevHiddenIndex
!==
undefined
)
{
// select the element **before** the first hidden element in the group
var
prevHidden
=
$selectOptions
.
eq
(
prevHiddenIndex
)[
0
].
previousElementSibling
;
if
(
prevHidden
&&
prevHidden
.
tagName
===
'OPTGROUP'
&&
!
prevHidden
.
disabled
)
{
showDivider
=
true
;
}
}
}
if
(
showDivider
)
{
liIndex
++
;
_li
.
push
(
generateLI
(
''
,
null
,
'divider'
,
optID
+
'div'
));
}
_li
.
push
(
generateLI
(
generateA
(
text
,
optionClass
,
inline
,
tokens
),
index
));
}
that
.
liObj
[
index
]
=
liIndex
;
});
//If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button
if
(
!
this
.
multiple
&&
this
.
$element
.
find
(
'option:selected'
).
length
===
0
&&
!
this
.
options
.
title
)
{
this
.
$element
.
find
(
'option'
).
eq
(
0
).
prop
(
'selected'
,
true
).
attr
(
'selected'
,
'selected'
);
}
return
_li
.
join
(
''
);
},
findLis
:
function
()
{
if
(
this
.
$lis
==
null
)
this
.
$lis
=
this
.
$menu
.
find
(
'li'
);
return
this
.
$lis
;
},
/**
* @param [updateLi] defaults to true
*/
render
:
function
(
updateLi
)
{
var
that
=
this
,
notDisabled
,
$selectOptions
=
this
.
$element
.
find
(
'option'
);
//Update the LI to match the SELECT
if
(
updateLi
!==
false
)
{
$selectOptions
.
each
(
function
(
index
)
{
var
$lis
=
that
.
findLis
().
eq
(
that
.
liObj
[
index
]);
that
.
setDisabled
(
index
,
this
.
disabled
||
this
.
parentNode
.
tagName
===
'OPTGROUP'
&&
this
.
parentNode
.
disabled
,
$lis
);
that
.
setSelected
(
index
,
this
.
selected
,
$lis
);
});
}
this
.
togglePlaceholder
();
this
.
tabIndex
();
var
selectedItems
=
$selectOptions
.
map
(
function
()
{
if
(
this
.
selected
)
{
if
(
that
.
options
.
hideDisabled
&&
(
this
.
disabled
||
this
.
parentNode
.
tagName
===
'OPTGROUP'
&&
this
.
parentNode
.
disabled
))
return
;
var
$this
=
$
(
this
),
icon
=
$this
.
data
(
'icon'
)
&&
that
.
options
.
showIcon
?
'<i class="'
+
that
.
options
.
iconBase
+
' '
+
$this
.
data
(
'icon'
)
+
'"></i> '
:
''
,
subtext
;
if
(
that
.
options
.
showSubtext
&&
$this
.
data
(
'subtext'
)
&&
!
that
.
multiple
)
{
subtext
=
' <small class="text-muted">'
+
$this
.
data
(
'subtext'
)
+
'</small>'
;
}
else
{
subtext
=
''
;
}
if
(
typeof
$this
.
attr
(
'title'
)
!==
'undefined'
)
{
return
$this
.
attr
(
'title'
);
}
else
if
(
$this
.
data
(
'content'
)
&&
that
.
options
.
showContent
)
{
return
$this
.
data
(
'content'
).
toString
();
}
else
{
return
icon
+
$this
.
html
()
+
subtext
;
}
}
}).
toArray
();
//Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled
//Convert all the values into a comma delimited string
var
title
=
!
this
.
multiple
?
selectedItems
[
0
]
:
selectedItems
.
join
(
this
.
options
.
multipleSeparator
);
//If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..
if
(
this
.
multiple
&&
this
.
options
.
selectedTextFormat
.
indexOf
(
'count'
)
>
-
1
)
{
var
max
=
this
.
options
.
selectedTextFormat
.
split
(
'>'
);
if
((
max
.
length
>
1
&&
selectedItems
.
length
>
max
[
1
])
||
(
max
.
length
==
1
&&
selectedItems
.
length
>=
2
))
{
notDisabled
=
this
.
options
.
hideDisabled
?
', [disabled]'
:
''
;
var
totalCount
=
$selectOptions
.
not
(
'[data-divider="true"], [data-hidden="true"]'
+
notDisabled
).
length
,
tr8nText
=
(
typeof
this
.
options
.
countSelectedText
===
'function'
)
?
this
.
options
.
countSelectedText
(
selectedItems
.
length
,
totalCount
)
:
this
.
options
.
countSelectedText
;
title
=
tr8nText
.
replace
(
'{0}'
,
selectedItems
.
length
.
toString
()).
replace
(
'{1}'
,
totalCount
.
toString
());
}
}
if
(
this
.
options
.
title
==
undefined
)
{
this
.
options
.
title
=
this
.
$element
.
attr
(
'title'
);
}
if
(
this
.
options
.
selectedTextFormat
==
'static'
)
{
title
=
this
.
options
.
title
;
}
//If we dont have a title, then use the default, or if nothing is set at all, use the not selected text
if
(
!
title
)
{
title
=
typeof
this
.
options
.
title
!==
'undefined'
?
this
.
options
.
title
:
this
.
options
.
noneSelectedText
;
}
//strip all HTML tags and trim the result, then unescape any escaped tags
this
.
$button
.
attr
(
'title'
,
htmlUnescape
(
$
.
trim
(
title
.
replace
(
/<
[^
>
]
*>
?
/g
,
''
))));
this
.
$button
.
children
(
'.filter-option'
).
html
(
title
);
this
.
$element
.
trigger
(
'rendered.bs.select'
);
},
/**
* @param [style]
* @param [status]
*/
setStyle
:
function
(
style
,
status
)
{
if
(
this
.
$element
.
attr
(
'class'
))
{
this
.
$newElement
.
addClass
(
this
.
$element
.
attr
(
'class'
).
replace
(
/selectpicker|mobile-device|bs-select-hidden|validate
\[
.*
\]
/gi
,
''
));
}
var
buttonClass
=
style
?
style
:
this
.
options
.
style
;
if
(
status
==
'add'
)
{
this
.
$button
.
addClass
(
buttonClass
);
}
else
if
(
status
==
'remove'
)
{
this
.
$button
.
removeClass
(
buttonClass
);
}
else
{
this
.
$button
.
removeClass
(
this
.
options
.
style
);
this
.
$button
.
addClass
(
buttonClass
);
}
},
liHeight
:
function
(
refresh
)
{
if
(
!
refresh
&&
(
this
.
options
.
size
===
false
||
this
.
sizeInfo
))
return
;
var
newElement
=
document
.
createElement
(
'div'
),
menu
=
document
.
createElement
(
'div'
),
menuInner
=
document
.
createElement
(
'ul'
),
divider
=
document
.
createElement
(
'li'
),
li
=
document
.
createElement
(
'li'
),
a
=
document
.
createElement
(
'a'
),
text
=
document
.
createElement
(
'span'
),
header
=
this
.
options
.
header
&&
this
.
$menu
.
find
(
'.popover-title'
).
length
>
0
?
this
.
$menu
.
find
(
'.popover-title'
)[
0
].
cloneNode
(
true
)
:
null
,
search
=
this
.
options
.
liveSearch
?
document
.
createElement
(
'div'
)
:
null
,
actions
=
this
.
options
.
actionsBox
&&
this
.
multiple
&&
this
.
$menu
.
find
(
'.bs-actionsbox'
).
length
>
0
?
this
.
$menu
.
find
(
'.bs-actionsbox'
)[
0
].
cloneNode
(
true
)
:
null
,
doneButton
=
this
.
options
.
doneButton
&&
this
.
multiple
&&
this
.
$menu
.
find
(
'.bs-donebutton'
).
length
>
0
?
this
.
$menu
.
find
(
'.bs-donebutton'
)[
0
].
cloneNode
(
true
)
:
null
;
text
.
className
=
'text'
;
newElement
.
className
=
this
.
$menu
[
0
].
parentNode
.
className
+
' open'
;
menu
.
className
=
'dropdown-menu open'
;
menuInner
.
className
=
'dropdown-menu inner'
;
divider
.
className
=
'divider'
;
text
.
appendChild
(
document
.
createTextNode
(
'Inner text'
));
a
.
appendChild
(
text
);
li
.
appendChild
(
a
);
menuInner
.
appendChild
(
li
);
menuInner
.
appendChild
(
divider
);
if
(
header
)
menu
.
appendChild
(
header
);
if
(
search
)
{
var
input
=
document
.
createElement
(
'input'
);
search
.
className
=
'bs-searchbox'
;
input
.
className
=
'form-control'
;
search
.
appendChild
(
input
);
menu
.
appendChild
(
search
);
}
if
(
actions
)
menu
.
appendChild
(
actions
);
menu
.
appendChild
(
menuInner
);
if
(
doneButton
)
menu
.
appendChild
(
doneButton
);
newElement
.
appendChild
(
menu
);
document
.
body
.
appendChild
(
newElement
);
var
liHeight
=
a
.
offsetHeight
,
headerHeight
=
header
?
header
.
offsetHeight
:
0
,
searchHeight
=
search
?
search
.
offsetHeight
:
0
,
actionsHeight
=
actions
?
actions
.
offsetHeight
:
0
,
doneButtonHeight
=
doneButton
?
doneButton
.
offsetHeight
:
0
,
dividerHeight
=
$
(
divider
).
outerHeight
(
true
),
// fall back to jQuery if getComputedStyle is not supported
menuStyle
=
typeof
getComputedStyle
===
'function'
?
getComputedStyle
(
menu
)
:
false
,
$menu
=
menuStyle
?
null
:
$
(
menu
),
menuPadding
=
{
vert
:
parseInt
(
menuStyle
?
menuStyle
.
paddingTop
:
$menu
.
css
(
'paddingTop'
))
+
parseInt
(
menuStyle
?
menuStyle
.
paddingBottom
:
$menu
.
css
(
'paddingBottom'
))
+
parseInt
(
menuStyle
?
menuStyle
.
borderTopWidth
:
$menu
.
css
(
'borderTopWidth'
))
+
parseInt
(
menuStyle
?
menuStyle
.
borderBottomWidth
:
$menu
.
css
(
'borderBottomWidth'
)),
horiz
:
parseInt
(
menuStyle
?
menuStyle
.
paddingLeft
:
$menu
.
css
(
'paddingLeft'
))
+
parseInt
(
menuStyle
?
menuStyle
.
paddingRight
:
$menu
.
css
(
'paddingRight'
))
+
parseInt
(
menuStyle
?
menuStyle
.
borderLeftWidth
:
$menu
.
css
(
'borderLeftWidth'
))
+
parseInt
(
menuStyle
?
menuStyle
.
borderRightWidth
:
$menu
.
css
(
'borderRightWidth'
))
},
menuExtras
=
{
vert
:
menuPadding
.
vert
+
parseInt
(
menuStyle
?
menuStyle
.
marginTop
:
$menu
.
css
(
'marginTop'
))
+
parseInt
(
menuStyle
?
menuStyle
.
marginBottom
:
$menu
.
css
(
'marginBottom'
))
+
2
,
horiz
:
menuPadding
.
horiz
+
parseInt
(
menuStyle
?
menuStyle
.
marginLeft
:
$menu
.
css
(
'marginLeft'
))
+
parseInt
(
menuStyle
?
menuStyle
.
marginRight
:
$menu
.
css
(
'marginRight'
))
+
2
}
document
.
body
.
removeChild
(
newElement
);
this
.
sizeInfo
=
{
liHeight
:
liHeight
,
headerHeight
:
headerHeight
,
searchHeight
:
searchHeight
,
actionsHeight
:
actionsHeight
,
doneButtonHeight
:
doneButtonHeight
,
dividerHeight
:
dividerHeight
,
menuPadding
:
menuPadding
,
menuExtras
:
menuExtras
};
},
setSize
:
function
()
{
this
.
findLis
();
this
.
liHeight
();
if
(
this
.
options
.
header
)
this
.
$menu
.
css
(
'padding-top'
,
0
);
if
(
this
.
options
.
size
===
false
)
return
;
var
that
=
this
,
$menu
=
this
.
$menu
,
$menuInner
=
this
.
$menuInner
,
$window
=
$
(
window
),
selectHeight
=
this
.
$newElement
[
0
].
offsetHeight
,
selectWidth
=
this
.
$newElement
[
0
].
offsetWidth
,
liHeight
=
this
.
sizeInfo
[
'liHeight'
],
headerHeight
=
this
.
sizeInfo
[
'headerHeight'
],
searchHeight
=
this
.
sizeInfo
[
'searchHeight'
],
actionsHeight
=
this
.
sizeInfo
[
'actionsHeight'
],
doneButtonHeight
=
this
.
sizeInfo
[
'doneButtonHeight'
],
divHeight
=
this
.
sizeInfo
[
'dividerHeight'
],
menuPadding
=
this
.
sizeInfo
[
'menuPadding'
],
menuExtras
=
this
.
sizeInfo
[
'menuExtras'
],
notDisabled
=
this
.
options
.
hideDisabled
?
'.disabled'
:
''
,
menuHeight
,
menuWidth
,
getHeight
,
getWidth
,
selectOffsetTop
,
selectOffsetBot
,
selectOffsetLeft
,
selectOffsetRight
,
getPos
=
function
()
{
var
pos
=
that
.
$newElement
.
offset
(),
$container
=
$
(
that
.
options
.
container
),
containerPos
;
if
(
that
.
options
.
container
&&
!
$container
.
is
(
'body'
))
{
containerPos
=
$container
.
offset
();
containerPos
.
top
+=
parseInt
(
$container
.
css
(
'borderTopWidth'
));
containerPos
.
left
+=
parseInt
(
$container
.
css
(
'borderLeftWidth'
));
}
else
{
containerPos
=
{
top
:
0
,
left
:
0
};
}
var
winPad
=
that
.
options
.
windowPadding
;
selectOffsetTop
=
pos
.
top
-
containerPos
.
top
-
$window
.
scrollTop
();
selectOffsetBot
=
$window
.
height
()
-
selectOffsetTop
-
selectHeight
-
containerPos
.
top
-
winPad
[
2
];
selectOffsetLeft
=
pos
.
left
-
containerPos
.
left
-
$window
.
scrollLeft
();
selectOffsetRight
=
$window
.
width
()
-
selectOffsetLeft
-
selectWidth
-
containerPos
.
left
-
winPad
[
1
];
selectOffsetTop
-=
winPad
[
0
];
selectOffsetLeft
-=
winPad
[
3
];
};
getPos
();
if
(
this
.
options
.
size
===
'auto'
)
{
var
getSize
=
function
()
{
var
minHeight
,
hasClass
=
function
(
className
,
include
)
{
return
function
(
element
)
{
if
(
include
)
{
return
(
element
.
classList
?
element
.
classList
.
contains
(
className
)
:
$
(
element
).
hasClass
(
className
));
}
else
{
return
!
(
element
.
classList
?
element
.
classList
.
contains
(
className
)
:
$
(
element
).
hasClass
(
className
));
}
};
},
lis
=
that
.
$menuInner
[
0
].
getElementsByTagName
(
'li'
),
lisVisible
=
Array
.
prototype
.
filter
?
Array
.
prototype
.
filter
.
call
(
lis
,
hasClass
(
'hidden'
,
false
))
:
that
.
$lis
.
not
(
'.hidden'
),
optGroup
=
Array
.
prototype
.
filter
?
Array
.
prototype
.
filter
.
call
(
lisVisible
,
hasClass
(
'dropdown-header'
,
true
))
:
lisVisible
.
filter
(
'.dropdown-header'
);
getPos
();
menuHeight
=
selectOffsetBot
-
menuExtras
.
vert
;
menuWidth
=
selectOffsetRight
-
menuExtras
.
horiz
;
if
(
that
.
options
.
container
)
{
if
(
!
$menu
.
data
(
'height'
))
$menu
.
data
(
'height'
,
$menu
.
height
());
getHeight
=
$menu
.
data
(
'height'
);
if
(
!
$menu
.
data
(
'width'
))
$menu
.
data
(
'width'
,
$menu
.
width
());
getWidth
=
$menu
.
data
(
'width'
);
}
else
{
getHeight
=
$menu
.
height
();
getWidth
=
$menu
.
width
();
}
if
(
that
.
options
.
dropupAuto
)
{
that
.
$newElement
.
toggleClass
(
'dropup'
,
selectOffsetTop
>
selectOffsetBot
&&
(
menuHeight
-
menuExtras
.
vert
)
<
getHeight
);
}
if
(
that
.
$newElement
.
hasClass
(
'dropup'
))
{
menuHeight
=
selectOffsetTop
-
menuExtras
.
vert
;
}
if
(
that
.
options
.
dropdownAlignRight
===
'auto'
)
{
$menu
.
toggleClass
(
'dropdown-menu-right'
,
selectOffsetLeft
>
selectOffsetRight
&&
(
menuWidth
-
menuExtras
.
horiz
)
<
(
getWidth
-
selectWidth
));
}
if
((
lisVisible
.
length
+
optGroup
.
length
)
>
3
)
{
minHeight
=
liHeight
*
3
+
menuExtras
.
vert
-
2
;
}
else
{
minHeight
=
0
;
}
$menu
.
css
({
'max-height'
:
menuHeight
+
'px'
,
'overflow'
:
'hidden'
,
'min-height'
:
minHeight
+
headerHeight
+
searchHeight
+
actionsHeight
+
doneButtonHeight
+
'px'
});
$menuInner
.
css
({
'max-height'
:
menuHeight
-
headerHeight
-
searchHeight
-
actionsHeight
-
doneButtonHeight
-
menuPadding
.
vert
+
'px'
,
'overflow-y'
:
'auto'
,
'min-height'
:
Math
.
max
(
minHeight
-
menuPadding
.
vert
,
0
)
+
'px'
});
};
getSize
();
this
.
$searchbox
.
off
(
'input.getSize propertychange.getSize'
).
on
(
'input.getSize propertychange.getSize'
,
getSize
);
$window
.
off
(
'resize.getSize scroll.getSize'
).
on
(
'resize.getSize scroll.getSize'
,
getSize
);
}
else
if
(
this
.
options
.
size
&&
this
.
options
.
size
!=
'auto'
&&
this
.
$lis
.
not
(
notDisabled
).
length
>
this
.
options
.
size
)
{
var
optIndex
=
this
.
$lis
.
not
(
'.divider'
).
not
(
notDisabled
).
children
().
slice
(
0
,
this
.
options
.
size
).
last
().
parent
().
index
(),
divLength
=
this
.
$lis
.
slice
(
0
,
optIndex
+
1
).
filter
(
'.divider'
).
length
;
menuHeight
=
liHeight
*
this
.
options
.
size
+
divLength
*
divHeight
+
menuPadding
.
vert
;
if
(
that
.
options
.
container
)
{
if
(
!
$menu
.
data
(
'height'
))
$menu
.
data
(
'height'
,
$menu
.
height
());
getHeight
=
$menu
.
data
(
'height'
);
}
else
{
getHeight
=
$menu
.
height
();
}
if
(
that
.
options
.
dropupAuto
)
{
//noinspection JSUnusedAssignment
this
.
$newElement
.
toggleClass
(
'dropup'
,
selectOffsetTop
>
selectOffsetBot
&&
(
menuHeight
-
menuExtras
.
vert
)
<
getHeight
);
}
$menu
.
css
({
'max-height'
:
menuHeight
+
headerHeight
+
searchHeight
+
actionsHeight
+
doneButtonHeight
+
'px'
,
'overflow'
:
'hidden'
,
'min-height'
:
''
});
$menuInner
.
css
({
'max-height'
:
menuHeight
-
menuPadding
.
vert
+
'px'
,
'overflow-y'
:
'auto'
,
'min-height'
:
''
});
}
},
setWidth
:
function
()
{
if
(
this
.
options
.
width
===
'auto'
)
{
this
.
$menu
.
css
(
'min-width'
,
'0'
);
// Get correct width if element is hidden
var
$selectClone
=
this
.
$menu
.
parent
().
clone
().
appendTo
(
'body'
),
$selectClone2
=
this
.
options
.
container
?
this
.
$newElement
.
clone
().
appendTo
(
'body'
)
:
$selectClone
,
ulWidth
=
$selectClone
.
children
(
'.dropdown-menu'
).
outerWidth
(),
btnWidth
=
$selectClone2
.
css
(
'width'
,
'auto'
).
children
(
'button'
).
outerWidth
();
$selectClone
.
remove
();
$selectClone2
.
remove
();
// Set width to whatever's larger, button title or longest option
this
.
$newElement
.
css
(
'width'
,
Math
.
max
(
ulWidth
,
btnWidth
)
+
'px'
);
}
else
if
(
this
.
options
.
width
===
'fit'
)
{
// Remove inline min-width so width can be changed from 'auto'
this
.
$menu
.
css
(
'min-width'
,
''
);
this
.
$newElement
.
css
(
'width'
,
''
).
addClass
(
'fit-width'
);
}
else
if
(
this
.
options
.
width
)
{
// Remove inline min-width so width can be changed from 'auto'
this
.
$menu
.
css
(
'min-width'
,
''
);
this
.
$newElement
.
css
(
'width'
,
this
.
options
.
width
);
}
else
{
// Remove inline min-width/width so width can be changed
this
.
$menu
.
css
(
'min-width'
,
''
);
this
.
$newElement
.
css
(
'width'
,
''
);
}
// Remove fit-width class if width is changed programmatically
if
(
this
.
$newElement
.
hasClass
(
'fit-width'
)
&&
this
.
options
.
width
!==
'fit'
)
{
this
.
$newElement
.
removeClass
(
'fit-width'
);
}
},
selectPosition
:
function
()
{
this
.
$bsContainer
=
$
(
'<div class="bs-container" />'
);
var
that
=
this
,
$container
=
$
(
this
.
options
.
container
),
pos
,
containerPos
,
actualHeight
,
getPlacement
=
function
(
$element
)
{
that
.
$bsContainer
.
addClass
(
$element
.
attr
(
'class'
).
replace
(
/form-control|fit-width/gi
,
''
)).
toggleClass
(
'dropup'
,
$element
.
hasClass
(
'dropup'
));
pos
=
$element
.
offset
();
if
(
!
$container
.
is
(
'body'
))
{
containerPos
=
$container
.
offset
();
containerPos
.
top
+=
parseInt
(
$container
.
css
(
'borderTopWidth'
))
-
$container
.
scrollTop
();
containerPos
.
left
+=
parseInt
(
$container
.
css
(
'borderLeftWidth'
))
-
$container
.
scrollLeft
();
}
else
{
containerPos
=
{
top
:
0
,
left
:
0
};
}
actualHeight
=
$element
.
hasClass
(
'dropup'
)
?
0
:
$element
[
0
].
offsetHeight
;
that
.
$bsContainer
.
css
({
'top'
:
pos
.
top
-
containerPos
.
top
+
actualHeight
,
'left'
:
pos
.
left
-
containerPos
.
left
,
'width'
:
$element
[
0
].
offsetWidth
});
};
this
.
$button
.
on
(
'click'
,
function
()
{
var
$this
=
$
(
this
);
if
(
that
.
isDisabled
())
{
return
;
}
getPlacement
(
that
.
$newElement
);
that
.
$bsContainer
.
appendTo
(
that
.
options
.
container
)
.
toggleClass
(
'open'
,
!
$this
.
hasClass
(
'open'
))
.
append
(
that
.
$menu
);
});
$
(
window
).
on
(
'resize scroll'
,
function
()
{
getPlacement
(
that
.
$newElement
);
});
this
.
$element
.
on
(
'hide.bs.select'
,
function
()
{
that
.
$menu
.
data
(
'height'
,
that
.
$menu
.
height
());
that
.
$bsContainer
.
detach
();
});
},
/**
* @param {number} index - the index of the option that is being changed
* @param {boolean} selected - true if the option is being selected, false if being deselected
* @param {JQuery} $lis - the 'li' element that is being modified
*/
setSelected
:
function
(
index
,
selected
,
$lis
)
{
if
(
!
$lis
)
{
this
.
togglePlaceholder
();
// check if setSelected is being called by changing the value of the select
$lis
=
this
.
findLis
().
eq
(
this
.
liObj
[
index
]);
}
$lis
.
toggleClass
(
'selected'
,
selected
).
find
(
'a'
).
attr
(
'aria-selected'
,
selected
);
},
/**
* @param {number} index - the index of the option that is being disabled
* @param {boolean} disabled - true if the option is being disabled, false if being enabled
* @param {JQuery} $lis - the 'li' element that is being modified
*/
setDisabled
:
function
(
index
,
disabled
,
$lis
)
{
if
(
!
$lis
)
{
$lis
=
this
.
findLis
().
eq
(
this
.
liObj
[
index
]);
}
if
(
disabled
)
{
$lis
.
addClass
(
'disabled'
).
children
(
'a'
).
attr
(
'href'
,
'#'
).
attr
(
'tabindex'
,
-
1
).
attr
(
'aria-disabled'
,
true
);
}
else
{
$lis
.
removeClass
(
'disabled'
).
children
(
'a'
).
removeAttr
(
'href'
).
attr
(
'tabindex'
,
0
).
attr
(
'aria-disabled'
,
false
);
}
},
isDisabled
:
function
()
{
return
this
.
$element
[
0
].
disabled
;
},
checkDisabled
:
function
()
{
var
that
=
this
;
if
(
this
.
isDisabled
())
{
this
.
$newElement
.
addClass
(
'disabled'
);
this
.
$button
.
addClass
(
'disabled'
).
attr
(
'tabindex'
,
-
1
).
attr
(
'aria-disabled'
,
true
);
}
else
{
if
(
this
.
$button
.
hasClass
(
'disabled'
))
{
this
.
$newElement
.
removeClass
(
'disabled'
);
this
.
$button
.
removeClass
(
'disabled'
).
attr
(
'aria-disabled'
,
false
);
}
if
(
this
.
$button
.
attr
(
'tabindex'
)
==
-
1
&&
!
this
.
$element
.
data
(
'tabindex'
))
{
this
.
$button
.
removeAttr
(
'tabindex'
);
}
}
this
.
$button
.
click
(
function
()
{
return
!
that
.
isDisabled
();
});
},
togglePlaceholder
:
function
()
{
var
value
=
this
.
$element
.
val
();
this
.
$button
.
toggleClass
(
'bs-placeholder'
,
value
===
null
||
value
===
''
||
(
value
.
constructor
===
Array
&&
value
.
length
===
0
));
},
tabIndex
:
function
()
{
if
(
this
.
$element
.
data
(
'tabindex'
)
!==
this
.
$element
.
attr
(
'tabindex'
)
&&
(
this
.
$element
.
attr
(
'tabindex'
)
!==
-
98
&&
this
.
$element
.
attr
(
'tabindex'
)
!==
'-98'
))
{
this
.
$element
.
data
(
'tabindex'
,
this
.
$element
.
attr
(
'tabindex'
));
this
.
$button
.
attr
(
'tabindex'
,
this
.
$element
.
data
(
'tabindex'
));
}
this
.
$element
.
attr
(
'tabindex'
,
-
98
);
},
clickListener
:
function
()
{
var
that
=
this
,
$document
=
$
(
document
);
$document
.
data
(
'spaceSelect'
,
false
);
this
.
$button
.
on
(
'keyup'
,
function
(
e
)
{
if
(
/
(
32
)
/
.
test
(
e
.
keyCode
.
toString
(
10
))
&&
$document
.
data
(
'spaceSelect'
))
{
e
.
preventDefault
();
$document
.
data
(
'spaceSelect'
,
false
);
}
});
this
.
$button
.
on
(
'click'
,
function
()
{
that
.
setSize
();
});
this
.
$element
.
on
(
'shown.bs.select'
,
function
()
{
if
(
!
that
.
options
.
liveSearch
&&
!
that
.
multiple
)
{
that
.
$menuInner
.
find
(
'.selected a'
).
focus
();
}
else
if
(
!
that
.
multiple
)
{
var
selectedIndex
=
that
.
liObj
[
that
.
$element
[
0
].
selectedIndex
];
if
(
typeof
selectedIndex
!==
'number'
||
that
.
options
.
size
===
false
)
return
;
// scroll to selected option
var
offset
=
that
.
$lis
.
eq
(
selectedIndex
)[
0
].
offsetTop
-
that
.
$menuInner
[
0
].
offsetTop
;
offset
=
offset
-
that
.
$menuInner
[
0
].
offsetHeight
/
2
+
that
.
sizeInfo
.
liHeight
/
2
;
that
.
$menuInner
[
0
].
scrollTop
=
offset
;
}
});
this
.
$menuInner
.
on
(
'click'
,
'li a'
,
function
(
e
)
{
var
$this
=
$
(
this
),
clickedIndex
=
$this
.
parent
().
data
(
'originalIndex'
),
prevValue
=
that
.
$element
.
val
(),
prevIndex
=
that
.
$element
.
prop
(
'selectedIndex'
),
triggerChange
=
true
;
// Don't close on multi choice menu
if
(
that
.
multiple
&&
that
.
options
.
maxOptions
!==
1
)
{
e
.
stopPropagation
();
}
e
.
preventDefault
();
//Don't run if we have been disabled
if
(
!
that
.
isDisabled
()
&&
!
$this
.
parent
().
hasClass
(
'disabled'
))
{
var
$options
=
that
.
$element
.
find
(
'option'
),
$option
=
$options
.
eq
(
clickedIndex
),
state
=
$option
.
prop
(
'selected'
),
$optgroup
=
$option
.
parent
(
'optgroup'
),
maxOptions
=
that
.
options
.
maxOptions
,
maxOptionsGrp
=
$optgroup
.
data
(
'maxOptions'
)
||
false
;
if
(
!
that
.
multiple
)
{
// Deselect all others if not multi select box
$options
.
prop
(
'selected'
,
false
);
$option
.
prop
(
'selected'
,
true
);
that
.
$menuInner
.
find
(
'.selected'
).
removeClass
(
'selected'
).
find
(
'a'
).
attr
(
'aria-selected'
,
false
);
that
.
setSelected
(
clickedIndex
,
true
);
}
else
{
// Toggle the one we have chosen if we are multi select.
$option
.
prop
(
'selected'
,
!
state
);
that
.
setSelected
(
clickedIndex
,
!
state
);
$this
.
blur
();
if
(
maxOptions
!==
false
||
maxOptionsGrp
!==
false
)
{
var
maxReached
=
maxOptions
<
$options
.
filter
(
':selected'
).
length
,
maxReachedGrp
=
maxOptionsGrp
<
$optgroup
.
find
(
'option:selected'
).
length
;
if
((
maxOptions
&&
maxReached
)
||
(
maxOptionsGrp
&&
maxReachedGrp
))
{
if
(
maxOptions
&&
maxOptions
==
1
)
{
$options
.
prop
(
'selected'
,
false
);
$option
.
prop
(
'selected'
,
true
);
that
.
$menuInner
.
find
(
'.selected'
).
removeClass
(
'selected'
);
that
.
setSelected
(
clickedIndex
,
true
);
}
else
if
(
maxOptionsGrp
&&
maxOptionsGrp
==
1
)
{
$optgroup
.
find
(
'option:selected'
).
prop
(
'selected'
,
false
);
$option
.
prop
(
'selected'
,
true
);
var
optgroupID
=
$this
.
parent
().
data
(
'optgroup'
);
that
.
$menuInner
.
find
(
'[data-optgroup="'
+
optgroupID
+
'"]'
).
removeClass
(
'selected'
);
that
.
setSelected
(
clickedIndex
,
true
);
}
else
{
var
maxOptionsText
=
typeof
that
.
options
.
maxOptionsText
===
'string'
?
[
that
.
options
.
maxOptionsText
,
that
.
options
.
maxOptionsText
]
:
that
.
options
.
maxOptionsText
,
maxOptionsArr
=
typeof
maxOptionsText
===
'function'
?
maxOptionsText
(
maxOptions
,
maxOptionsGrp
)
:
maxOptionsText
,
maxTxt
=
maxOptionsArr
[
0
].
replace
(
'{n}'
,
maxOptions
),
maxTxtGrp
=
maxOptionsArr
[
1
].
replace
(
'{n}'
,
maxOptionsGrp
),
$notify
=
$
(
'<div class="notify"></div>'
);
// If {var} is set in array, replace it
/** @deprecated */
if
(
maxOptionsArr
[
2
])
{
maxTxt
=
maxTxt
.
replace
(
'{var}'
,
maxOptionsArr
[
2
][
maxOptions
>
1
?
0
:
1
]);
maxTxtGrp
=
maxTxtGrp
.
replace
(
'{var}'
,
maxOptionsArr
[
2
][
maxOptionsGrp
>
1
?
0
:
1
]);
}
$option
.
prop
(
'selected'
,
false
);
that
.
$menu
.
append
(
$notify
);
if
(
maxOptions
&&
maxReached
)
{
$notify
.
append
(
$
(
'<div>'
+
maxTxt
+
'</div>'
));
triggerChange
=
false
;
that
.
$element
.
trigger
(
'maxReached.bs.select'
);
}
if
(
maxOptionsGrp
&&
maxReachedGrp
)
{
$notify
.
append
(
$
(
'<div>'
+
maxTxtGrp
+
'</div>'
));
triggerChange
=
false
;
that
.
$element
.
trigger
(
'maxReachedGrp.bs.select'
);
}
setTimeout
(
function
()
{
that
.
setSelected
(
clickedIndex
,
false
);
},
10
);
$notify
.
delay
(
750
).
fadeOut
(
300
,
function
()
{
$
(
this
).
remove
();
});
}
}
}
}
if
(
!
that
.
multiple
||
(
that
.
multiple
&&
that
.
options
.
maxOptions
===
1
))
{
that
.
$button
.
focus
();
}
else
if
(
that
.
options
.
liveSearch
)
{
that
.
$searchbox
.
focus
();
}
// Trigger select 'change'
if
(
triggerChange
)
{
if
((
prevValue
!=
that
.
$element
.
val
()
&&
that
.
multiple
)
||
(
prevIndex
!=
that
.
$element
.
prop
(
'selectedIndex'
)
&&
!
that
.
multiple
))
{
// $option.prop('selected') is current option state (selected/unselected). state is previous option state.
changed_arguments
=
[
clickedIndex
,
$option
.
prop
(
'selected'
),
state
];
that
.
$element
.
triggerNative
(
'change'
);
}
}
}
});
this
.
$menu
.
on
(
'click'
,
'li.disabled a, .popover-title, .popover-title :not(.close)'
,
function
(
e
)
{
if
(
e
.
currentTarget
==
this
)
{
e
.
preventDefault
();
e
.
stopPropagation
();
if
(
that
.
options
.
liveSearch
&&
!
$
(
e
.
target
).
hasClass
(
'close'
))
{
that
.
$searchbox
.
focus
();
}
else
{
that
.
$button
.
focus
();
}
}
});
this
.
$menuInner
.
on
(
'click'
,
'.divider, .dropdown-header'
,
function
(
e
)
{
e
.
preventDefault
();
e
.
stopPropagation
();
if
(
that
.
options
.
liveSearch
)
{
that
.
$searchbox
.
focus
();
}
else
{
that
.
$button
.
focus
();
}
});
this
.
$menu
.
on
(
'click'
,
'.popover-title .close'
,
function
()
{
that
.
$button
.
click
();
});
this
.
$searchbox
.
on
(
'click'
,
function
(
e
)
{
e
.
stopPropagation
();
});
this
.
$menu
.
on
(
'click'
,
'.actions-btn'
,
function
(
e
)
{
if
(
that
.
options
.
liveSearch
)
{
that
.
$searchbox
.
focus
();
}
else
{
that
.
$button
.
focus
();
}
e
.
preventDefault
();
e
.
stopPropagation
();
if
(
$
(
this
).
hasClass
(
'bs-select-all'
))
{
that
.
selectAll
();
}
else
{
that
.
deselectAll
();
}
});
this
.
$element
.
change
(
function
()
{
that
.
render
(
false
);
that
.
$element
.
trigger
(
'changed.bs.select'
,
changed_arguments
);
changed_arguments
=
null
;
});
},
liveSearchListener
:
function
()
{
var
that
=
this
,
$no_results
=
$
(
'<li class="no-results"></li>'
);
this
.
$button
.
on
(
'click.dropdown.data-api'
,
function
()
{
that
.
$menuInner
.
find
(
'.active'
).
removeClass
(
'active'
);
if
(
!!
that
.
$searchbox
.
val
())
{
that
.
$searchbox
.
val
(
''
);
that
.
$lis
.
not
(
'.is-hidden'
).
removeClass
(
'hidden'
);
if
(
!!
$no_results
.
parent
().
length
)
$no_results
.
remove
();
}
if
(
!
that
.
multiple
)
that
.
$menuInner
.
find
(
'.selected'
).
addClass
(
'active'
);
setTimeout
(
function
()
{
that
.
$searchbox
.
focus
();
},
10
);
});
this
.
$searchbox
.
on
(
'click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api'
,
function
(
e
)
{
e
.
stopPropagation
();
});
this
.
$searchbox
.
on
(
'input propertychange'
,
function
()
{
that
.
$lis
.
not
(
'.is-hidden'
).
removeClass
(
'hidden'
);
that
.
$lis
.
filter
(
'.active'
).
removeClass
(
'active'
);
$no_results
.
remove
();
if
(
that
.
$searchbox
.
val
())
{
var
$searchBase
=
that
.
$lis
.
not
(
'.is-hidden, .divider, .dropdown-header'
),
$hideItems
;
if
(
that
.
options
.
liveSearchNormalize
)
{
$hideItems
=
$searchBase
.
not
(
':a'
+
that
.
_searchStyle
()
+
'("'
+
normalizeToBase
(
that
.
$searchbox
.
val
())
+
'")'
);
}
else
{
$hideItems
=
$searchBase
.
not
(
':'
+
that
.
_searchStyle
()
+
'("'
+
that
.
$searchbox
.
val
()
+
'")'
);
}
if
(
$hideItems
.
length
===
$searchBase
.
length
)
{
$no_results
.
html
(
that
.
options
.
noneResultsText
.
replace
(
'{0}'
,
'"'
+
htmlEscape
(
that
.
$searchbox
.
val
())
+
'"'
));
that
.
$menuInner
.
append
(
$no_results
);
that
.
$lis
.
addClass
(
'hidden'
);
}
else
{
$hideItems
.
addClass
(
'hidden'
);
var
$lisVisible
=
that
.
$lis
.
not
(
'.hidden'
),
$foundDiv
;
// hide divider if first or last visible, or if followed by another divider
$lisVisible
.
each
(
function
(
index
)
{
var
$this
=
$
(
this
);
if
(
$this
.
hasClass
(
'divider'
))
{
if
(
$foundDiv
===
undefined
)
{
$this
.
addClass
(
'hidden'
);
}
else
{
if
(
$foundDiv
)
$foundDiv
.
addClass
(
'hidden'
);
$foundDiv
=
$this
;
}
}
else
if
(
$this
.
hasClass
(
'dropdown-header'
)
&&
$lisVisible
.
eq
(
index
+
1
).
data
(
'optgroup'
)
!==
$this
.
data
(
'optgroup'
))
{
$this
.
addClass
(
'hidden'
);
}
else
{
$foundDiv
=
null
;
}
});
if
(
$foundDiv
)
$foundDiv
.
addClass
(
'hidden'
);
$searchBase
.
not
(
'.hidden'
).
first
().
addClass
(
'active'
);
that
.
$menuInner
.
scrollTop
(
0
);
}
}
});
},
_searchStyle
:
function
()
{
var
styles
=
{
begins
:
'ibegins'
,
startsWith
:
'ibegins'
};
return
styles
[
this
.
options
.
liveSearchStyle
]
||
'icontains'
;
},
val
:
function
(
value
)
{
if
(
typeof
value
!==
'undefined'
)
{
this
.
$element
.
val
(
value
);
this
.
render
();
return
this
.
$element
;
}
else
{
return
this
.
$element
.
val
();
}
},
changeAll
:
function
(
status
)
{
if
(
!
this
.
multiple
)
return
;
if
(
typeof
status
===
'undefined'
)
status
=
true
;
this
.
findLis
();
var
$options
=
this
.
$element
.
find
(
'option'
),
$lisVisible
=
this
.
$lis
.
not
(
'.divider, .dropdown-header, .disabled, .hidden'
),
lisVisLen
=
$lisVisible
.
length
,
selectedOptions
=
[];
if
(
status
)
{
if
(
$lisVisible
.
filter
(
'.selected'
).
length
===
$lisVisible
.
length
)
return
;
}
else
{
if
(
$lisVisible
.
filter
(
'.selected'
).
length
===
0
)
return
;
}
$lisVisible
.
toggleClass
(
'selected'
,
status
);
for
(
var
i
=
0
;
i
<
lisVisLen
;
i
++
)
{
var
origIndex
=
$lisVisible
[
i
].
getAttribute
(
'data-original-index'
);
selectedOptions
[
selectedOptions
.
length
]
=
$options
.
eq
(
origIndex
)[
0
];
}
$
(
selectedOptions
).
prop
(
'selected'
,
status
);
this
.
render
(
false
);
this
.
togglePlaceholder
();
this
.
$element
.
triggerNative
(
'change'
);
},
selectAll
:
function
()
{
return
this
.
changeAll
(
true
);
},
deselectAll
:
function
()
{
return
this
.
changeAll
(
false
);
},
toggle
:
function
(
e
)
{
e
=
e
||
window
.
event
;
if
(
e
)
e
.
stopPropagation
();
this
.
$button
.
trigger
(
'click'
);
},
keydown
:
function
(
e
)
{
var
$this
=
$
(
this
),
$parent
=
$this
.
is
(
'input'
)
?
$this
.
parent
().
parent
()
:
$this
.
parent
(),
$items
,
that
=
$parent
.
data
(
'this'
),
index
,
prevIndex
,
isActive
,
selector
=
':not(.disabled, .hidden, .dropdown-header, .divider)'
,
keyCodeMap
=
{
32
:
' '
,
48
:
'0'
,
49
:
'1'
,
50
:
'2'
,
51
:
'3'
,
52
:
'4'
,
53
:
'5'
,
54
:
'6'
,
55
:
'7'
,
56
:
'8'
,
57
:
'9'
,
59
:
';'
,
65
:
'a'
,
66
:
'b'
,
67
:
'c'
,
68
:
'd'
,
69
:
'e'
,
70
:
'f'
,
71
:
'g'
,
72
:
'h'
,
73
:
'i'
,
74
:
'j'
,
75
:
'k'
,
76
:
'l'
,
77
:
'm'
,
78
:
'n'
,
79
:
'o'
,
80
:
'p'
,
81
:
'q'
,
82
:
'r'
,
83
:
's'
,
84
:
't'
,
85
:
'u'
,
86
:
'v'
,
87
:
'w'
,
88
:
'x'
,
89
:
'y'
,
90
:
'z'
,
96
:
'0'
,
97
:
'1'
,
98
:
'2'
,
99
:
'3'
,
100
:
'4'
,
101
:
'5'
,
102
:
'6'
,
103
:
'7'
,
104
:
'8'
,
105
:
'9'
};
isActive
=
that
.
$newElement
.
hasClass
(
'open'
);
if
(
!
isActive
&&
(
e
.
keyCode
>=
48
&&
e
.
keyCode
<=
57
||
e
.
keyCode
>=
96
&&
e
.
keyCode
<=
105
||
e
.
keyCode
>=
65
&&
e
.
keyCode
<=
90
))
{
if
(
!
that
.
options
.
container
)
{
that
.
setSize
();
that
.
$menu
.
parent
().
addClass
(
'open'
);
isActive
=
true
;
}
else
{
that
.
$button
.
trigger
(
'click'
);
}
that
.
$searchbox
.
focus
();
return
;
}
if
(
that
.
options
.
liveSearch
)
{
if
(
/
(
^9$|27
)
/
.
test
(
e
.
keyCode
.
toString
(
10
))
&&
isActive
)
{
e
.
preventDefault
();
e
.
stopPropagation
();
that
.
$menuInner
.
click
();
that
.
$button
.
focus
();
}
}
if
(
/
(
38|40
)
/
.
test
(
e
.
keyCode
.
toString
(
10
)))
{
$items
=
that
.
$lis
.
filter
(
selector
);
if
(
!
$items
.
length
)
return
;
if
(
!
that
.
options
.
liveSearch
)
{
index
=
$items
.
index
(
$items
.
find
(
'a'
).
filter
(
':focus'
).
parent
());
}
else
{
index
=
$items
.
index
(
$items
.
filter
(
'.active'
));
}
prevIndex
=
that
.
$menuInner
.
data
(
'prevIndex'
);
if
(
e
.
keyCode
==
38
)
{
if
((
that
.
options
.
liveSearch
||
index
==
prevIndex
)
&&
index
!=
-
1
)
index
--
;
if
(
index
<
0
)
index
+=
$items
.
length
;
}
else
if
(
e
.
keyCode
==
40
)
{
if
(
that
.
options
.
liveSearch
||
index
==
prevIndex
)
index
++
;
index
=
index
%
$items
.
length
;
}
that
.
$menuInner
.
data
(
'prevIndex'
,
index
);
if
(
!
that
.
options
.
liveSearch
)
{
$items
.
eq
(
index
).
children
(
'a'
).
focus
();
}
else
{
e
.
preventDefault
();
if
(
!
$this
.
hasClass
(
'dropdown-toggle'
))
{
$items
.
removeClass
(
'active'
).
eq
(
index
).
addClass
(
'active'
).
children
(
'a'
).
focus
();
$this
.
focus
();
}
}
}
else
if
(
!
$this
.
is
(
'input'
))
{
var
keyIndex
=
[],
count
,
prevKey
;
$items
=
that
.
$lis
.
filter
(
selector
);
$items
.
each
(
function
(
i
)
{
if
(
$
.
trim
(
$
(
this
).
children
(
'a'
).
text
().
toLowerCase
()).
substring
(
0
,
1
)
==
keyCodeMap
[
e
.
keyCode
])
{
keyIndex
.
push
(
i
);
}
});
count
=
$
(
document
).
data
(
'keycount'
);
count
++
;
$
(
document
).
data
(
'keycount'
,
count
);
prevKey
=
$
.
trim
(
$
(
':focus'
).
text
().
toLowerCase
()).
substring
(
0
,
1
);
if
(
prevKey
!=
keyCodeMap
[
e
.
keyCode
])
{
count
=
1
;
$
(
document
).
data
(
'keycount'
,
count
);
}
else
if
(
count
>=
keyIndex
.
length
)
{
$
(
document
).
data
(
'keycount'
,
0
);
if
(
count
>
keyIndex
.
length
)
count
=
1
;
}
$items
.
eq
(
keyIndex
[
count
-
1
]).
children
(
'a'
).
focus
();
}
// Select focused option if "Enter", "Spacebar" or "Tab" (when selectOnTab is true) are pressed inside the menu.
if
((
/
(
13|32
)
/
.
test
(
e
.
keyCode
.
toString
(
10
))
||
(
/
(
^9$
)
/
.
test
(
e
.
keyCode
.
toString
(
10
))
&&
that
.
options
.
selectOnTab
))
&&
isActive
)
{
if
(
!
/
(
32
)
/
.
test
(
e
.
keyCode
.
toString
(
10
)))
e
.
preventDefault
();
if
(
!
that
.
options
.
liveSearch
)
{
var
elem
=
$
(
':focus'
);
elem
.
click
();
// Bring back focus for multiselects
elem
.
focus
();
// Prevent screen from scrolling if the user hit the spacebar
e
.
preventDefault
();
// Fixes spacebar selection of dropdown items in FF & IE
$
(
document
).
data
(
'spaceSelect'
,
true
);
}
else
if
(
!
/
(
32
)
/
.
test
(
e
.
keyCode
.
toString
(
10
)))
{
that
.
$menuInner
.
find
(
'.active a'
).
click
();
$this
.
focus
();
}
$
(
document
).
data
(
'keycount'
,
0
);
}
if
((
/
(
^9$|27
)
/
.
test
(
e
.
keyCode
.
toString
(
10
))
&&
isActive
&&
(
that
.
multiple
||
that
.
options
.
liveSearch
))
||
(
/
(
27
)
/
.
test
(
e
.
keyCode
.
toString
(
10
))
&&
!
isActive
))
{
that
.
$menu
.
parent
().
removeClass
(
'open'
);
if
(
that
.
options
.
container
)
that
.
$newElement
.
removeClass
(
'open'
);
that
.
$button
.
focus
();
}
},
mobile
:
function
()
{
this
.
$element
.
addClass
(
'mobile-device'
);
},
refresh
:
function
()
{
this
.
$lis
=
null
;
this
.
liObj
=
{};
this
.
reloadLi
();
this
.
render
();
this
.
checkDisabled
();
this
.
liHeight
(
true
);
this
.
setStyle
();
this
.
setWidth
();
if
(
this
.
$lis
)
this
.
$searchbox
.
trigger
(
'propertychange'
);
this
.
$element
.
trigger
(
'refreshed.bs.select'
);
},
hide
:
function
()
{
this
.
$newElement
.
hide
();
},
show
:
function
()
{
this
.
$newElement
.
show
();
},
remove
:
function
()
{
this
.
$newElement
.
remove
();
this
.
$element
.
remove
();
},
destroy
:
function
()
{
this
.
$newElement
.
before
(
this
.
$element
).
remove
();
if
(
this
.
$bsContainer
)
{
this
.
$bsContainer
.
remove
();
}
else
{
this
.
$menu
.
remove
();
}
this
.
$element
.
off
(
'.bs.select'
)
.
removeData
(
'selectpicker'
)
.
removeClass
(
'bs-select-hidden selectpicker'
);
}
};
// SELECTPICKER PLUGIN DEFINITION
// ==============================
function
Plugin
(
option
)
{
// get the args of the outer function..
var
args
=
arguments
;
// The arguments of the function are explicitly re-defined from the argument list, because the shift causes them
// to get lost/corrupted in android 2.3 and IE9 #715 #775
var
_option
=
option
;
[].
shift
.
apply
(
args
);
var
value
;
var
chain
=
this
.
each
(
function
()
{
var
$this
=
$
(
this
);
if
(
$this
.
is
(
'select'
))
{
var
data
=
$this
.
data
(
'selectpicker'
),
options
=
typeof
_option
==
'object'
&&
_option
;
if
(
!
data
)
{
var
config
=
$
.
extend
({},
Selectpicker
.
DEFAULTS
,
$
.
fn
.
selectpicker
.
defaults
||
{},
$this
.
data
(),
options
);
config
.
template
=
$
.
extend
({},
Selectpicker
.
DEFAULTS
.
template
,
(
$
.
fn
.
selectpicker
.
defaults
?
$
.
fn
.
selectpicker
.
defaults
.
template
:
{}),
$this
.
data
().
template
,
options
.
template
);
$this
.
data
(
'selectpicker'
,
(
data
=
new
Selectpicker
(
this
,
config
)));
}
else
if
(
options
)
{
for
(
var
i
in
options
)
{
if
(
options
.
hasOwnProperty
(
i
))
{
data
.
options
[
i
]
=
options
[
i
];
}
}
}
if
(
typeof
_option
==
'string'
)
{
if
(
data
[
_option
]
instanceof
Function
)
{
value
=
data
[
_option
].
apply
(
data
,
args
);
}
else
{
value
=
data
.
options
[
_option
];
}
}
}
});
if
(
typeof
value
!==
'undefined'
)
{
//noinspection JSUnusedAssignment
return
value
;
}
else
{
return
chain
;
}
}
var
old
=
$
.
fn
.
selectpicker
;
$
.
fn
.
selectpicker
=
Plugin
;
$
.
fn
.
selectpicker
.
Constructor
=
Selectpicker
;
// SELECTPICKER NO CONFLICT
// ========================
$
.
fn
.
selectpicker
.
noConflict
=
function
()
{
$
.
fn
.
selectpicker
=
old
;
return
this
;
};
$
(
document
)
.
data
(
'keycount'
,
0
)
.
on
(
'keydown.bs.select'
,
'.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role="listbox"], .bs-searchbox input'
,
Selectpicker
.
prototype
.
keydown
)
.
on
(
'focusin.modal'
,
'.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role="listbox"], .bs-searchbox input'
,
function
(
e
)
{
e
.
stopPropagation
();
});
// SELECTPICKER DATA-API
// =====================
$
(
window
).
on
(
'load.bs.select.data-api'
,
function
()
{
$
(
'.selectpicker'
).
each
(
function
()
{
var
$selectpicker
=
$
(
this
);
Plugin
.
call
(
$selectpicker
,
$selectpicker
.
data
());
})
});
})(
jQuery
);
}));
src/main/webapp/js/lib/underscore.js
0 → 100644
View file @
c018db65
// Underscore.js 1.9.1
// http://underscorejs.org
// (c) 2009-2018 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Underscore may be freely distributed under the MIT license.
(
function
()
{
// Baseline setup
// --------------
// Establish the root object, `window` (`self`) in the browser, `global`
// on the server, or `this` in some virtual machines. We use `self`
// instead of `window` for `WebWorker` support.
var
root
=
typeof
self
==
'object'
&&
self
.
self
===
self
&&
self
||
typeof
global
==
'object'
&&
global
.
global
===
global
&&
global
||
this
||
{};
// Save the previous value of the `_` variable.
var
previousUnderscore
=
root
.
_
;
// Save bytes in the minified (but not gzipped) version:
var
ArrayProto
=
Array
.
prototype
,
ObjProto
=
Object
.
prototype
;
var
SymbolProto
=
typeof
Symbol
!==
'undefined'
?
Symbol
.
prototype
:
null
;
// Create quick reference variables for speed access to core prototypes.
var
push
=
ArrayProto
.
push
,
slice
=
ArrayProto
.
slice
,
toString
=
ObjProto
.
toString
,
hasOwnProperty
=
ObjProto
.
hasOwnProperty
;
// All **ECMAScript 5** native function implementations that we hope to use
// are declared here.
var
nativeIsArray
=
Array
.
isArray
,
nativeKeys
=
Object
.
keys
,
nativeCreate
=
Object
.
create
;
// Naked function reference for surrogate-prototype-swapping.
var
Ctor
=
function
(){};
// Create a safe reference to the Underscore object for use below.
var
_
=
function
(
obj
)
{
if
(
obj
instanceof
_
)
return
obj
;
if
(
!
(
this
instanceof
_
))
return
new
_
(
obj
);
this
.
_wrapped
=
obj
;
};
// Export the Underscore object for **Node.js**, with
// backwards-compatibility for their old module API. If we're in
// the browser, add `_` as a global object.
// (`nodeType` is checked to ensure that `module`
// and `exports` are not HTML elements.)
if
(
typeof
exports
!=
'undefined'
&&
!
exports
.
nodeType
)
{
if
(
typeof
module
!=
'undefined'
&&
!
module
.
nodeType
&&
module
.
exports
)
{
exports
=
module
.
exports
=
_
;
}
exports
.
_
=
_
;
}
else
{
root
.
_
=
_
;
}
// Current version.
_
.
VERSION
=
'1.9.1'
;
// Internal function that returns an efficient (for current engines) version
// of the passed-in callback, to be repeatedly applied in other Underscore
// functions.
var
optimizeCb
=
function
(
func
,
context
,
argCount
)
{
if
(
context
===
void
0
)
return
func
;
switch
(
argCount
==
null
?
3
:
argCount
)
{
case
1
:
return
function
(
value
)
{
return
func
.
call
(
context
,
value
);
};
// The 2-argument case is omitted because we’re not using it.
case
3
:
return
function
(
value
,
index
,
collection
)
{
return
func
.
call
(
context
,
value
,
index
,
collection
);
};
case
4
:
return
function
(
accumulator
,
value
,
index
,
collection
)
{
return
func
.
call
(
context
,
accumulator
,
value
,
index
,
collection
);
};
}
return
function
()
{
return
func
.
apply
(
context
,
arguments
);
};
};
var
builtinIteratee
;
// An internal function to generate callbacks that can be applied to each
// element in a collection, returning the desired result — either `identity`,
// an arbitrary callback, a property matcher, or a property accessor.
var
cb
=
function
(
value
,
context
,
argCount
)
{
if
(
_
.
iteratee
!==
builtinIteratee
)
return
_
.
iteratee
(
value
,
context
);
if
(
value
==
null
)
return
_
.
identity
;
if
(
_
.
isFunction
(
value
))
return
optimizeCb
(
value
,
context
,
argCount
);
if
(
_
.
isObject
(
value
)
&&
!
_
.
isArray
(
value
))
return
_
.
matcher
(
value
);
return
_
.
property
(
value
);
};
// External wrapper for our callback generator. Users may customize
// `_.iteratee` if they want additional predicate/iteratee shorthand styles.
// This abstraction hides the internal-only argCount argument.
_
.
iteratee
=
builtinIteratee
=
function
(
value
,
context
)
{
return
cb
(
value
,
context
,
Infinity
);
};
// Some functions take a variable number of arguments, or a few expected
// arguments at the beginning and then a variable number of values to operate
// on. This helper accumulates all remaining arguments past the function’s
// argument length (or an explicit `startIndex`), into an array that becomes
// the last argument. Similar to ES6’s "rest parameter".
var
restArguments
=
function
(
func
,
startIndex
)
{
startIndex
=
startIndex
==
null
?
func
.
length
-
1
:
+
startIndex
;
return
function
()
{
var
length
=
Math
.
max
(
arguments
.
length
-
startIndex
,
0
),
rest
=
Array
(
length
),
index
=
0
;
for
(;
index
<
length
;
index
++
)
{
rest
[
index
]
=
arguments
[
index
+
startIndex
];
}
switch
(
startIndex
)
{
case
0
:
return
func
.
call
(
this
,
rest
);
case
1
:
return
func
.
call
(
this
,
arguments
[
0
],
rest
);
case
2
:
return
func
.
call
(
this
,
arguments
[
0
],
arguments
[
1
],
rest
);
}
var
args
=
Array
(
startIndex
+
1
);
for
(
index
=
0
;
index
<
startIndex
;
index
++
)
{
args
[
index
]
=
arguments
[
index
];
}
args
[
startIndex
]
=
rest
;
return
func
.
apply
(
this
,
args
);
};
};
// An internal function for creating a new object that inherits from another.
var
baseCreate
=
function
(
prototype
)
{
if
(
!
_
.
isObject
(
prototype
))
return
{};
if
(
nativeCreate
)
return
nativeCreate
(
prototype
);
Ctor
.
prototype
=
prototype
;
var
result
=
new
Ctor
;
Ctor
.
prototype
=
null
;
return
result
;
};
var
shallowProperty
=
function
(
key
)
{
return
function
(
obj
)
{
return
obj
==
null
?
void
0
:
obj
[
key
];
};
};
var
has
=
function
(
obj
,
path
)
{
return
obj
!=
null
&&
hasOwnProperty
.
call
(
obj
,
path
);
}
var
deepGet
=
function
(
obj
,
path
)
{
var
length
=
path
.
length
;
for
(
var
i
=
0
;
i
<
length
;
i
++
)
{
if
(
obj
==
null
)
return
void
0
;
obj
=
obj
[
path
[
i
]];
}
return
length
?
obj
:
void
0
;
};
// Helper for collection methods to determine whether a collection
// should be iterated as an array or as an object.
// Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
// Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
var
MAX_ARRAY_INDEX
=
Math
.
pow
(
2
,
53
)
-
1
;
var
getLength
=
shallowProperty
(
'length'
);
var
isArrayLike
=
function
(
collection
)
{
var
length
=
getLength
(
collection
);
return
typeof
length
==
'number'
&&
length
>=
0
&&
length
<=
MAX_ARRAY_INDEX
;
};
// Collection Functions
// --------------------
// The cornerstone, an `each` implementation, aka `forEach`.
// Handles raw objects in addition to array-likes. Treats all
// sparse array-likes as if they were dense.
_
.
each
=
_
.
forEach
=
function
(
obj
,
iteratee
,
context
)
{
iteratee
=
optimizeCb
(
iteratee
,
context
);
var
i
,
length
;
if
(
isArrayLike
(
obj
))
{
for
(
i
=
0
,
length
=
obj
.
length
;
i
<
length
;
i
++
)
{
iteratee
(
obj
[
i
],
i
,
obj
);
}
}
else
{
var
keys
=
_
.
keys
(
obj
);
for
(
i
=
0
,
length
=
keys
.
length
;
i
<
length
;
i
++
)
{
iteratee
(
obj
[
keys
[
i
]],
keys
[
i
],
obj
);
}
}
return
obj
;
};
// Return the results of applying the iteratee to each element.
_
.
map
=
_
.
collect
=
function
(
obj
,
iteratee
,
context
)
{
iteratee
=
cb
(
iteratee
,
context
);
var
keys
=
!
isArrayLike
(
obj
)
&&
_
.
keys
(
obj
),
length
=
(
keys
||
obj
).
length
,
results
=
Array
(
length
);
for
(
var
index
=
0
;
index
<
length
;
index
++
)
{
var
currentKey
=
keys
?
keys
[
index
]
:
index
;
results
[
index
]
=
iteratee
(
obj
[
currentKey
],
currentKey
,
obj
);
}
return
results
;
};
// Create a reducing function iterating left or right.
var
createReduce
=
function
(
dir
)
{
// Wrap code that reassigns argument variables in a separate function than
// the one that accesses `arguments.length` to avoid a perf hit. (#1991)
var
reducer
=
function
(
obj
,
iteratee
,
memo
,
initial
)
{
var
keys
=
!
isArrayLike
(
obj
)
&&
_
.
keys
(
obj
),
length
=
(
keys
||
obj
).
length
,
index
=
dir
>
0
?
0
:
length
-
1
;
if
(
!
initial
)
{
memo
=
obj
[
keys
?
keys
[
index
]
:
index
];
index
+=
dir
;
}
for
(;
index
>=
0
&&
index
<
length
;
index
+=
dir
)
{
var
currentKey
=
keys
?
keys
[
index
]
:
index
;
memo
=
iteratee
(
memo
,
obj
[
currentKey
],
currentKey
,
obj
);
}
return
memo
;
};
return
function
(
obj
,
iteratee
,
memo
,
context
)
{
var
initial
=
arguments
.
length
>=
3
;
return
reducer
(
obj
,
optimizeCb
(
iteratee
,
context
,
4
),
memo
,
initial
);
};
};
// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`.
_
.
reduce
=
_
.
foldl
=
_
.
inject
=
createReduce
(
1
);
// The right-associative version of reduce, also known as `foldr`.
_
.
reduceRight
=
_
.
foldr
=
createReduce
(
-
1
);
// Return the first value which passes a truth test. Aliased as `detect`.
_
.
find
=
_
.
detect
=
function
(
obj
,
predicate
,
context
)
{
var
keyFinder
=
isArrayLike
(
obj
)
?
_
.
findIndex
:
_
.
findKey
;
var
key
=
keyFinder
(
obj
,
predicate
,
context
);
if
(
key
!==
void
0
&&
key
!==
-
1
)
return
obj
[
key
];
};
// Return all the elements that pass a truth test.
// Aliased as `select`.
_
.
filter
=
_
.
select
=
function
(
obj
,
predicate
,
context
)
{
var
results
=
[];
predicate
=
cb
(
predicate
,
context
);
_
.
each
(
obj
,
function
(
value
,
index
,
list
)
{
if
(
predicate
(
value
,
index
,
list
))
results
.
push
(
value
);
});
return
results
;
};
// Return all the elements for which a truth test fails.
_
.
reject
=
function
(
obj
,
predicate
,
context
)
{
return
_
.
filter
(
obj
,
_
.
negate
(
cb
(
predicate
)),
context
);
};
// Determine whether all of the elements match a truth test.
// Aliased as `all`.
_
.
every
=
_
.
all
=
function
(
obj
,
predicate
,
context
)
{
predicate
=
cb
(
predicate
,
context
);
var
keys
=
!
isArrayLike
(
obj
)
&&
_
.
keys
(
obj
),
length
=
(
keys
||
obj
).
length
;
for
(
var
index
=
0
;
index
<
length
;
index
++
)
{
var
currentKey
=
keys
?
keys
[
index
]
:
index
;
if
(
!
predicate
(
obj
[
currentKey
],
currentKey
,
obj
))
return
false
;
}
return
true
;
};
// Determine if at least one element in the object matches a truth test.
// Aliased as `any`.
_
.
some
=
_
.
any
=
function
(
obj
,
predicate
,
context
)
{
predicate
=
cb
(
predicate
,
context
);
var
keys
=
!
isArrayLike
(
obj
)
&&
_
.
keys
(
obj
),
length
=
(
keys
||
obj
).
length
;
for
(
var
index
=
0
;
index
<
length
;
index
++
)
{
var
currentKey
=
keys
?
keys
[
index
]
:
index
;
if
(
predicate
(
obj
[
currentKey
],
currentKey
,
obj
))
return
true
;
}
return
false
;
};
// Determine if the array or object contains a given item (using `===`).
// Aliased as `includes` and `include`.
_
.
contains
=
_
.
includes
=
_
.
include
=
function
(
obj
,
item
,
fromIndex
,
guard
)
{
if
(
!
isArrayLike
(
obj
))
obj
=
_
.
values
(
obj
);
if
(
typeof
fromIndex
!=
'number'
||
guard
)
fromIndex
=
0
;
return
_
.
indexOf
(
obj
,
item
,
fromIndex
)
>=
0
;
};
// Invoke a method (with arguments) on every item in a collection.
_
.
invoke
=
restArguments
(
function
(
obj
,
path
,
args
)
{
var
contextPath
,
func
;
if
(
_
.
isFunction
(
path
))
{
func
=
path
;
}
else
if
(
_
.
isArray
(
path
))
{
contextPath
=
path
.
slice
(
0
,
-
1
);
path
=
path
[
path
.
length
-
1
];
}
return
_
.
map
(
obj
,
function
(
context
)
{
var
method
=
func
;
if
(
!
method
)
{
if
(
contextPath
&&
contextPath
.
length
)
{
context
=
deepGet
(
context
,
contextPath
);
}
if
(
context
==
null
)
return
void
0
;
method
=
context
[
path
];
}
return
method
==
null
?
method
:
method
.
apply
(
context
,
args
);
});
});
// Convenience version of a common use case of `map`: fetching a property.
_
.
pluck
=
function
(
obj
,
key
)
{
return
_
.
map
(
obj
,
_
.
property
(
key
));
};
// Convenience version of a common use case of `filter`: selecting only objects
// containing specific `key:value` pairs.
_
.
where
=
function
(
obj
,
attrs
)
{
return
_
.
filter
(
obj
,
_
.
matcher
(
attrs
));
};
// Convenience version of a common use case of `find`: getting the first object
// containing specific `key:value` pairs.
_
.
findWhere
=
function
(
obj
,
attrs
)
{
return
_
.
find
(
obj
,
_
.
matcher
(
attrs
));
};
// Return the maximum element (or element-based computation).
_
.
max
=
function
(
obj
,
iteratee
,
context
)
{
var
result
=
-
Infinity
,
lastComputed
=
-
Infinity
,
value
,
computed
;
if
(
iteratee
==
null
||
typeof
iteratee
==
'number'
&&
typeof
obj
[
0
]
!=
'object'
&&
obj
!=
null
)
{
obj
=
isArrayLike
(
obj
)
?
obj
:
_
.
values
(
obj
);
for
(
var
i
=
0
,
length
=
obj
.
length
;
i
<
length
;
i
++
)
{
value
=
obj
[
i
];
if
(
value
!=
null
&&
value
>
result
)
{
result
=
value
;
}
}
}
else
{
iteratee
=
cb
(
iteratee
,
context
);
_
.
each
(
obj
,
function
(
v
,
index
,
list
)
{
computed
=
iteratee
(
v
,
index
,
list
);
if
(
computed
>
lastComputed
||
computed
===
-
Infinity
&&
result
===
-
Infinity
)
{
result
=
v
;
lastComputed
=
computed
;
}
});
}
return
result
;
};
// Return the minimum element (or element-based computation).
_
.
min
=
function
(
obj
,
iteratee
,
context
)
{
var
result
=
Infinity
,
lastComputed
=
Infinity
,
value
,
computed
;
if
(
iteratee
==
null
||
typeof
iteratee
==
'number'
&&
typeof
obj
[
0
]
!=
'object'
&&
obj
!=
null
)
{
obj
=
isArrayLike
(
obj
)
?
obj
:
_
.
values
(
obj
);
for
(
var
i
=
0
,
length
=
obj
.
length
;
i
<
length
;
i
++
)
{
value
=
obj
[
i
];
if
(
value
!=
null
&&
value
<
result
)
{
result
=
value
;
}
}
}
else
{
iteratee
=
cb
(
iteratee
,
context
);
_
.
each
(
obj
,
function
(
v
,
index
,
list
)
{
computed
=
iteratee
(
v
,
index
,
list
);
if
(
computed
<
lastComputed
||
computed
===
Infinity
&&
result
===
Infinity
)
{
result
=
v
;
lastComputed
=
computed
;
}
});
}
return
result
;
};
// Shuffle a collection.
_
.
shuffle
=
function
(
obj
)
{
return
_
.
sample
(
obj
,
Infinity
);
};
// Sample **n** random values from a collection using the modern version of the
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
// If **n** is not specified, returns a single random element.
// The internal `guard` argument allows it to work with `map`.
_
.
sample
=
function
(
obj
,
n
,
guard
)
{
if
(
n
==
null
||
guard
)
{
if
(
!
isArrayLike
(
obj
))
obj
=
_
.
values
(
obj
);
return
obj
[
_
.
random
(
obj
.
length
-
1
)];
}
var
sample
=
isArrayLike
(
obj
)
?
_
.
clone
(
obj
)
:
_
.
values
(
obj
);
var
length
=
getLength
(
sample
);
n
=
Math
.
max
(
Math
.
min
(
n
,
length
),
0
);
var
last
=
length
-
1
;
for
(
var
index
=
0
;
index
<
n
;
index
++
)
{
var
rand
=
_
.
random
(
index
,
last
);
var
temp
=
sample
[
index
];
sample
[
index
]
=
sample
[
rand
];
sample
[
rand
]
=
temp
;
}
return
sample
.
slice
(
0
,
n
);
};
// Sort the object's values by a criterion produced by an iteratee.
_
.
sortBy
=
function
(
obj
,
iteratee
,
context
)
{
var
index
=
0
;
iteratee
=
cb
(
iteratee
,
context
);
return
_
.
pluck
(
_
.
map
(
obj
,
function
(
value
,
key
,
list
)
{
return
{
value
:
value
,
index
:
index
++
,
criteria
:
iteratee
(
value
,
key
,
list
)
};
}).
sort
(
function
(
left
,
right
)
{
var
a
=
left
.
criteria
;
var
b
=
right
.
criteria
;
if
(
a
!==
b
)
{
if
(
a
>
b
||
a
===
void
0
)
return
1
;
if
(
a
<
b
||
b
===
void
0
)
return
-
1
;
}
return
left
.
index
-
right
.
index
;
}),
'value'
);
};
// An internal function used for aggregate "group by" operations.
var
group
=
function
(
behavior
,
partition
)
{
return
function
(
obj
,
iteratee
,
context
)
{
var
result
=
partition
?
[[],
[]]
:
{};
iteratee
=
cb
(
iteratee
,
context
);
_
.
each
(
obj
,
function
(
value
,
index
)
{
var
key
=
iteratee
(
value
,
index
,
obj
);
behavior
(
result
,
value
,
key
);
});
return
result
;
};
};
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
_
.
groupBy
=
group
(
function
(
result
,
value
,
key
)
{
if
(
has
(
result
,
key
))
result
[
key
].
push
(
value
);
else
result
[
key
]
=
[
value
];
});
// Indexes the object's values by a criterion, similar to `groupBy`, but for
// when you know that your index values will be unique.
_
.
indexBy
=
group
(
function
(
result
,
value
,
key
)
{
result
[
key
]
=
value
;
});
// Counts instances of an object that group by a certain criterion. Pass
// either a string attribute to count by, or a function that returns the
// criterion.
_
.
countBy
=
group
(
function
(
result
,
value
,
key
)
{
if
(
has
(
result
,
key
))
result
[
key
]
++
;
else
result
[
key
]
=
1
;
});
var
reStrSymbol
=
/
[^\u
d800-
\u
dfff
]
|
[\u
d800-
\u
dbff
][\u
dc00-
\u
dfff
]
|
[\u
d800-
\u
dfff
]
/g
;
// Safely create a real, live array from anything iterable.
_
.
toArray
=
function
(
obj
)
{
if
(
!
obj
)
return
[];
if
(
_
.
isArray
(
obj
))
return
slice
.
call
(
obj
);
if
(
_
.
isString
(
obj
))
{
// Keep surrogate pair characters together
return
obj
.
match
(
reStrSymbol
);
}
if
(
isArrayLike
(
obj
))
return
_
.
map
(
obj
,
_
.
identity
);
return
_
.
values
(
obj
);
};
// Return the number of elements in an object.
_
.
size
=
function
(
obj
)
{
if
(
obj
==
null
)
return
0
;
return
isArrayLike
(
obj
)
?
obj
.
length
:
_
.
keys
(
obj
).
length
;
};
// Split a collection into two arrays: one whose elements all satisfy the given
// predicate, and one whose elements all do not satisfy the predicate.
_
.
partition
=
group
(
function
(
result
,
value
,
pass
)
{
result
[
pass
?
0
:
1
].
push
(
value
);
},
true
);
// Array Functions
// ---------------
// Get the first element of an array. Passing **n** will return the first N
// values in the array. Aliased as `head` and `take`. The **guard** check
// allows it to work with `_.map`.
_
.
first
=
_
.
head
=
_
.
take
=
function
(
array
,
n
,
guard
)
{
if
(
array
==
null
||
array
.
length
<
1
)
return
n
==
null
?
void
0
:
[];
if
(
n
==
null
||
guard
)
return
array
[
0
];
return
_
.
initial
(
array
,
array
.
length
-
n
);
};
// Returns everything but the last entry of the array. Especially useful on
// the arguments object. Passing **n** will return all the values in
// the array, excluding the last N.
_
.
initial
=
function
(
array
,
n
,
guard
)
{
return
slice
.
call
(
array
,
0
,
Math
.
max
(
0
,
array
.
length
-
(
n
==
null
||
guard
?
1
:
n
)));
};
// Get the last element of an array. Passing **n** will return the last N
// values in the array.
_
.
last
=
function
(
array
,
n
,
guard
)
{
if
(
array
==
null
||
array
.
length
<
1
)
return
n
==
null
?
void
0
:
[];
if
(
n
==
null
||
guard
)
return
array
[
array
.
length
-
1
];
return
_
.
rest
(
array
,
Math
.
max
(
0
,
array
.
length
-
n
));
};
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
// Especially useful on the arguments object. Passing an **n** will return
// the rest N values in the array.
_
.
rest
=
_
.
tail
=
_
.
drop
=
function
(
array
,
n
,
guard
)
{
return
slice
.
call
(
array
,
n
==
null
||
guard
?
1
:
n
);
};
// Trim out all falsy values from an array.
_
.
compact
=
function
(
array
)
{
return
_
.
filter
(
array
,
Boolean
);
};
// Internal implementation of a recursive `flatten` function.
var
flatten
=
function
(
input
,
shallow
,
strict
,
output
)
{
output
=
output
||
[];
var
idx
=
output
.
length
;
for
(
var
i
=
0
,
length
=
getLength
(
input
);
i
<
length
;
i
++
)
{
var
value
=
input
[
i
];
if
(
isArrayLike
(
value
)
&&
(
_
.
isArray
(
value
)
||
_
.
isArguments
(
value
)))
{
// Flatten current level of array or arguments object.
if
(
shallow
)
{
var
j
=
0
,
len
=
value
.
length
;
while
(
j
<
len
)
output
[
idx
++
]
=
value
[
j
++
];
}
else
{
flatten
(
value
,
shallow
,
strict
,
output
);
idx
=
output
.
length
;
}
}
else
if
(
!
strict
)
{
output
[
idx
++
]
=
value
;
}
}
return
output
;
};
// Flatten out an array, either recursively (by default), or just one level.
_
.
flatten
=
function
(
array
,
shallow
)
{
return
flatten
(
array
,
shallow
,
false
);
};
// Return a version of the array that does not contain the specified value(s).
_
.
without
=
restArguments
(
function
(
array
,
otherArrays
)
{
return
_
.
difference
(
array
,
otherArrays
);
});
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
// The faster algorithm will not work with an iteratee if the iteratee
// is not a one-to-one function, so providing an iteratee will disable
// the faster algorithm.
// Aliased as `unique`.
_
.
uniq
=
_
.
unique
=
function
(
array
,
isSorted
,
iteratee
,
context
)
{
if
(
!
_
.
isBoolean
(
isSorted
))
{
context
=
iteratee
;
iteratee
=
isSorted
;
isSorted
=
false
;
}
if
(
iteratee
!=
null
)
iteratee
=
cb
(
iteratee
,
context
);
var
result
=
[];
var
seen
=
[];
for
(
var
i
=
0
,
length
=
getLength
(
array
);
i
<
length
;
i
++
)
{
var
value
=
array
[
i
],
computed
=
iteratee
?
iteratee
(
value
,
i
,
array
)
:
value
;
if
(
isSorted
&&
!
iteratee
)
{
if
(
!
i
||
seen
!==
computed
)
result
.
push
(
value
);
seen
=
computed
;
}
else
if
(
iteratee
)
{
if
(
!
_
.
contains
(
seen
,
computed
))
{
seen
.
push
(
computed
);
result
.
push
(
value
);
}
}
else
if
(
!
_
.
contains
(
result
,
value
))
{
result
.
push
(
value
);
}
}
return
result
;
};
// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
_
.
union
=
restArguments
(
function
(
arrays
)
{
return
_
.
uniq
(
flatten
(
arrays
,
true
,
true
));
});
// Produce an array that contains every item shared between all the
// passed-in arrays.
_
.
intersection
=
function
(
array
)
{
var
result
=
[];
var
argsLength
=
arguments
.
length
;
for
(
var
i
=
0
,
length
=
getLength
(
array
);
i
<
length
;
i
++
)
{
var
item
=
array
[
i
];
if
(
_
.
contains
(
result
,
item
))
continue
;
var
j
;
for
(
j
=
1
;
j
<
argsLength
;
j
++
)
{
if
(
!
_
.
contains
(
arguments
[
j
],
item
))
break
;
}
if
(
j
===
argsLength
)
result
.
push
(
item
);
}
return
result
;
};
// Take the difference between one array and a number of other arrays.
// Only the elements present in just the first array will remain.
_
.
difference
=
restArguments
(
function
(
array
,
rest
)
{
rest
=
flatten
(
rest
,
true
,
true
);
return
_
.
filter
(
array
,
function
(
value
){
return
!
_
.
contains
(
rest
,
value
);
});
});
// Complement of _.zip. Unzip accepts an array of arrays and groups
// each array's elements on shared indices.
_
.
unzip
=
function
(
array
)
{
var
length
=
array
&&
_
.
max
(
array
,
getLength
).
length
||
0
;
var
result
=
Array
(
length
);
for
(
var
index
=
0
;
index
<
length
;
index
++
)
{
result
[
index
]
=
_
.
pluck
(
array
,
index
);
}
return
result
;
};
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_
.
zip
=
restArguments
(
_
.
unzip
);
// Converts lists into objects. Pass either a single array of `[key, value]`
// pairs, or two parallel arrays of the same length -- one of keys, and one of
// the corresponding values. Passing by pairs is the reverse of _.pairs.
_
.
object
=
function
(
list
,
values
)
{
var
result
=
{};
for
(
var
i
=
0
,
length
=
getLength
(
list
);
i
<
length
;
i
++
)
{
if
(
values
)
{
result
[
list
[
i
]]
=
values
[
i
];
}
else
{
result
[
list
[
i
][
0
]]
=
list
[
i
][
1
];
}
}
return
result
;
};
// Generator function to create the findIndex and findLastIndex functions.
var
createPredicateIndexFinder
=
function
(
dir
)
{
return
function
(
array
,
predicate
,
context
)
{
predicate
=
cb
(
predicate
,
context
);
var
length
=
getLength
(
array
);
var
index
=
dir
>
0
?
0
:
length
-
1
;
for
(;
index
>=
0
&&
index
<
length
;
index
+=
dir
)
{
if
(
predicate
(
array
[
index
],
index
,
array
))
return
index
;
}
return
-
1
;
};
};
// Returns the first index on an array-like that passes a predicate test.
_
.
findIndex
=
createPredicateIndexFinder
(
1
);
_
.
findLastIndex
=
createPredicateIndexFinder
(
-
1
);
// Use a comparator function to figure out the smallest index at which
// an object should be inserted so as to maintain order. Uses binary search.
_
.
sortedIndex
=
function
(
array
,
obj
,
iteratee
,
context
)
{
iteratee
=
cb
(
iteratee
,
context
,
1
);
var
value
=
iteratee
(
obj
);
var
low
=
0
,
high
=
getLength
(
array
);
while
(
low
<
high
)
{
var
mid
=
Math
.
floor
((
low
+
high
)
/
2
);
if
(
iteratee
(
array
[
mid
])
<
value
)
low
=
mid
+
1
;
else
high
=
mid
;
}
return
low
;
};
// Generator function to create the indexOf and lastIndexOf functions.
var
createIndexFinder
=
function
(
dir
,
predicateFind
,
sortedIndex
)
{
return
function
(
array
,
item
,
idx
)
{
var
i
=
0
,
length
=
getLength
(
array
);
if
(
typeof
idx
==
'number'
)
{
if
(
dir
>
0
)
{
i
=
idx
>=
0
?
idx
:
Math
.
max
(
idx
+
length
,
i
);
}
else
{
length
=
idx
>=
0
?
Math
.
min
(
idx
+
1
,
length
)
:
idx
+
length
+
1
;
}
}
else
if
(
sortedIndex
&&
idx
&&
length
)
{
idx
=
sortedIndex
(
array
,
item
);
return
array
[
idx
]
===
item
?
idx
:
-
1
;
}
if
(
item
!==
item
)
{
idx
=
predicateFind
(
slice
.
call
(
array
,
i
,
length
),
_
.
isNaN
);
return
idx
>=
0
?
idx
+
i
:
-
1
;
}
for
(
idx
=
dir
>
0
?
i
:
length
-
1
;
idx
>=
0
&&
idx
<
length
;
idx
+=
dir
)
{
if
(
array
[
idx
]
===
item
)
return
idx
;
}
return
-
1
;
};
};
// Return the position of the first occurrence of an item in an array,
// or -1 if the item is not included in the array.
// If the array is large and already in sort order, pass `true`
// for **isSorted** to use binary search.
_
.
indexOf
=
createIndexFinder
(
1
,
_
.
findIndex
,
_
.
sortedIndex
);
_
.
lastIndexOf
=
createIndexFinder
(
-
1
,
_
.
findLastIndex
);
// Generate an integer Array containing an arithmetic progression. A port of
// the native Python `range()` function. See
// [the Python documentation](http://docs.python.org/library/functions.html#range).
_
.
range
=
function
(
start
,
stop
,
step
)
{
if
(
stop
==
null
)
{
stop
=
start
||
0
;
start
=
0
;
}
if
(
!
step
)
{
step
=
stop
<
start
?
-
1
:
1
;
}
var
length
=
Math
.
max
(
Math
.
ceil
((
stop
-
start
)
/
step
),
0
);
var
range
=
Array
(
length
);
for
(
var
idx
=
0
;
idx
<
length
;
idx
++
,
start
+=
step
)
{
range
[
idx
]
=
start
;
}
return
range
;
};
// Chunk a single array into multiple arrays, each containing `count` or fewer
// items.
_
.
chunk
=
function
(
array
,
count
)
{
if
(
count
==
null
||
count
<
1
)
return
[];
var
result
=
[];
var
i
=
0
,
length
=
array
.
length
;
while
(
i
<
length
)
{
result
.
push
(
slice
.
call
(
array
,
i
,
i
+=
count
));
}
return
result
;
};
// Function (ahem) Functions
// ------------------
// Determines whether to execute a function as a constructor
// or a normal function with the provided arguments.
var
executeBound
=
function
(
sourceFunc
,
boundFunc
,
context
,
callingContext
,
args
)
{
if
(
!
(
callingContext
instanceof
boundFunc
))
return
sourceFunc
.
apply
(
context
,
args
);
var
self
=
baseCreate
(
sourceFunc
.
prototype
);
var
result
=
sourceFunc
.
apply
(
self
,
args
);
if
(
_
.
isObject
(
result
))
return
result
;
return
self
;
};
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
// available.
_
.
bind
=
restArguments
(
function
(
func
,
context
,
args
)
{
if
(
!
_
.
isFunction
(
func
))
throw
new
TypeError
(
'Bind must be called on a function'
);
var
bound
=
restArguments
(
function
(
callArgs
)
{
return
executeBound
(
func
,
bound
,
context
,
this
,
args
.
concat
(
callArgs
));
});
return
bound
;
});
// Partially apply a function by creating a version that has had some of its
// arguments pre-filled, without changing its dynamic `this` context. _ acts
// as a placeholder by default, allowing any combination of arguments to be
// pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.
_
.
partial
=
restArguments
(
function
(
func
,
boundArgs
)
{
var
placeholder
=
_
.
partial
.
placeholder
;
var
bound
=
function
()
{
var
position
=
0
,
length
=
boundArgs
.
length
;
var
args
=
Array
(
length
);
for
(
var
i
=
0
;
i
<
length
;
i
++
)
{
args
[
i
]
=
boundArgs
[
i
]
===
placeholder
?
arguments
[
position
++
]
:
boundArgs
[
i
];
}
while
(
position
<
arguments
.
length
)
args
.
push
(
arguments
[
position
++
]);
return
executeBound
(
func
,
bound
,
this
,
this
,
args
);
};
return
bound
;
});
_
.
partial
.
placeholder
=
_
;
// Bind a number of an object's methods to that object. Remaining arguments
// are the method names to be bound. Useful for ensuring that all callbacks
// defined on an object belong to it.
_
.
bindAll
=
restArguments
(
function
(
obj
,
keys
)
{
keys
=
flatten
(
keys
,
false
,
false
);
var
index
=
keys
.
length
;
if
(
index
<
1
)
throw
new
Error
(
'bindAll must be passed function names'
);
while
(
index
--
)
{
var
key
=
keys
[
index
];
obj
[
key
]
=
_
.
bind
(
obj
[
key
],
obj
);
}
});
// Memoize an expensive function by storing its results.
_
.
memoize
=
function
(
func
,
hasher
)
{
var
memoize
=
function
(
key
)
{
var
cache
=
memoize
.
cache
;
var
address
=
''
+
(
hasher
?
hasher
.
apply
(
this
,
arguments
)
:
key
);
if
(
!
has
(
cache
,
address
))
cache
[
address
]
=
func
.
apply
(
this
,
arguments
);
return
cache
[
address
];
};
memoize
.
cache
=
{};
return
memoize
;
};
// Delays a function for the given number of milliseconds, and then calls
// it with the arguments supplied.
_
.
delay
=
restArguments
(
function
(
func
,
wait
,
args
)
{
return
setTimeout
(
function
()
{
return
func
.
apply
(
null
,
args
);
},
wait
);
});
// Defers a function, scheduling it to run after the current call stack has
// cleared.
_
.
defer
=
_
.
partial
(
_
.
delay
,
_
,
1
);
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time. Normally, the throttled function will run
// as much as it can, without ever going more than once per `wait` duration;
// but if you'd like to disable the execution on the leading edge, pass
// `{leading: false}`. To disable execution on the trailing edge, ditto.
_
.
throttle
=
function
(
func
,
wait
,
options
)
{
var
timeout
,
context
,
args
,
result
;
var
previous
=
0
;
if
(
!
options
)
options
=
{};
var
later
=
function
()
{
previous
=
options
.
leading
===
false
?
0
:
_
.
now
();
timeout
=
null
;
result
=
func
.
apply
(
context
,
args
);
if
(
!
timeout
)
context
=
args
=
null
;
};
var
throttled
=
function
()
{
var
now
=
_
.
now
();
if
(
!
previous
&&
options
.
leading
===
false
)
previous
=
now
;
var
remaining
=
wait
-
(
now
-
previous
);
context
=
this
;
args
=
arguments
;
if
(
remaining
<=
0
||
remaining
>
wait
)
{
if
(
timeout
)
{
clearTimeout
(
timeout
);
timeout
=
null
;
}
previous
=
now
;
result
=
func
.
apply
(
context
,
args
);
if
(
!
timeout
)
context
=
args
=
null
;
}
else
if
(
!
timeout
&&
options
.
trailing
!==
false
)
{
timeout
=
setTimeout
(
later
,
remaining
);
}
return
result
;
};
throttled
.
cancel
=
function
()
{
clearTimeout
(
timeout
);
previous
=
0
;
timeout
=
context
=
args
=
null
;
};
return
throttled
;
};
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_
.
debounce
=
function
(
func
,
wait
,
immediate
)
{
var
timeout
,
result
;
var
later
=
function
(
context
,
args
)
{
timeout
=
null
;
if
(
args
)
result
=
func
.
apply
(
context
,
args
);
};
var
debounced
=
restArguments
(
function
(
args
)
{
if
(
timeout
)
clearTimeout
(
timeout
);
if
(
immediate
)
{
var
callNow
=
!
timeout
;
timeout
=
setTimeout
(
later
,
wait
);
if
(
callNow
)
result
=
func
.
apply
(
this
,
args
);
}
else
{
timeout
=
_
.
delay
(
later
,
wait
,
this
,
args
);
}
return
result
;
});
debounced
.
cancel
=
function
()
{
clearTimeout
(
timeout
);
timeout
=
null
;
};
return
debounced
;
};
// Returns the first function passed as an argument to the second,
// allowing you to adjust arguments, run code before and after, and
// conditionally execute the original function.
_
.
wrap
=
function
(
func
,
wrapper
)
{
return
_
.
partial
(
wrapper
,
func
);
};
// Returns a negated version of the passed-in predicate.
_
.
negate
=
function
(
predicate
)
{
return
function
()
{
return
!
predicate
.
apply
(
this
,
arguments
);
};
};
// Returns a function that is the composition of a list of functions, each
// consuming the return value of the function that follows.
_
.
compose
=
function
()
{
var
args
=
arguments
;
var
start
=
args
.
length
-
1
;
return
function
()
{
var
i
=
start
;
var
result
=
args
[
start
].
apply
(
this
,
arguments
);
while
(
i
--
)
result
=
args
[
i
].
call
(
this
,
result
);
return
result
;
};
};
// Returns a function that will only be executed on and after the Nth call.
_
.
after
=
function
(
times
,
func
)
{
return
function
()
{
if
(
--
times
<
1
)
{
return
func
.
apply
(
this
,
arguments
);
}
};
};
// Returns a function that will only be executed up to (but not including) the Nth call.
_
.
before
=
function
(
times
,
func
)
{
var
memo
;
return
function
()
{
if
(
--
times
>
0
)
{
memo
=
func
.
apply
(
this
,
arguments
);
}
if
(
times
<=
1
)
func
=
null
;
return
memo
;
};
};
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_
.
once
=
_
.
partial
(
_
.
before
,
2
);
_
.
restArguments
=
restArguments
;
// Object Functions
// ----------------
// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
var
hasEnumBug
=
!
{
toString
:
null
}.
propertyIsEnumerable
(
'toString'
);
var
nonEnumerableProps
=
[
'valueOf'
,
'isPrototypeOf'
,
'toString'
,
'propertyIsEnumerable'
,
'hasOwnProperty'
,
'toLocaleString'
];
var
collectNonEnumProps
=
function
(
obj
,
keys
)
{
var
nonEnumIdx
=
nonEnumerableProps
.
length
;
var
constructor
=
obj
.
constructor
;
var
proto
=
_
.
isFunction
(
constructor
)
&&
constructor
.
prototype
||
ObjProto
;
// Constructor is a special case.
var
prop
=
'constructor'
;
if
(
has
(
obj
,
prop
)
&&
!
_
.
contains
(
keys
,
prop
))
keys
.
push
(
prop
);
while
(
nonEnumIdx
--
)
{
prop
=
nonEnumerableProps
[
nonEnumIdx
];
if
(
prop
in
obj
&&
obj
[
prop
]
!==
proto
[
prop
]
&&
!
_
.
contains
(
keys
,
prop
))
{
keys
.
push
(
prop
);
}
}
};
// Retrieve the names of an object's own properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`.
_
.
keys
=
function
(
obj
)
{
if
(
!
_
.
isObject
(
obj
))
return
[];
if
(
nativeKeys
)
return
nativeKeys
(
obj
);
var
keys
=
[];
for
(
var
key
in
obj
)
if
(
has
(
obj
,
key
))
keys
.
push
(
key
);
// Ahem, IE < 9.
if
(
hasEnumBug
)
collectNonEnumProps
(
obj
,
keys
);
return
keys
;
};
// Retrieve all the property names of an object.
_
.
allKeys
=
function
(
obj
)
{
if
(
!
_
.
isObject
(
obj
))
return
[];
var
keys
=
[];
for
(
var
key
in
obj
)
keys
.
push
(
key
);
// Ahem, IE < 9.
if
(
hasEnumBug
)
collectNonEnumProps
(
obj
,
keys
);
return
keys
;
};
// Retrieve the values of an object's properties.
_
.
values
=
function
(
obj
)
{
var
keys
=
_
.
keys
(
obj
);
var
length
=
keys
.
length
;
var
values
=
Array
(
length
);
for
(
var
i
=
0
;
i
<
length
;
i
++
)
{
values
[
i
]
=
obj
[
keys
[
i
]];
}
return
values
;
};
// Returns the results of applying the iteratee to each element of the object.
// In contrast to _.map it returns an object.
_
.
mapObject
=
function
(
obj
,
iteratee
,
context
)
{
iteratee
=
cb
(
iteratee
,
context
);
var
keys
=
_
.
keys
(
obj
),
length
=
keys
.
length
,
results
=
{};
for
(
var
index
=
0
;
index
<
length
;
index
++
)
{
var
currentKey
=
keys
[
index
];
results
[
currentKey
]
=
iteratee
(
obj
[
currentKey
],
currentKey
,
obj
);
}
return
results
;
};
// Convert an object into a list of `[key, value]` pairs.
// The opposite of _.object.
_
.
pairs
=
function
(
obj
)
{
var
keys
=
_
.
keys
(
obj
);
var
length
=
keys
.
length
;
var
pairs
=
Array
(
length
);
for
(
var
i
=
0
;
i
<
length
;
i
++
)
{
pairs
[
i
]
=
[
keys
[
i
],
obj
[
keys
[
i
]]];
}
return
pairs
;
};
// Invert the keys and values of an object. The values must be serializable.
_
.
invert
=
function
(
obj
)
{
var
result
=
{};
var
keys
=
_
.
keys
(
obj
);
for
(
var
i
=
0
,
length
=
keys
.
length
;
i
<
length
;
i
++
)
{
result
[
obj
[
keys
[
i
]]]
=
keys
[
i
];
}
return
result
;
};
// Return a sorted list of the function names available on the object.
// Aliased as `methods`.
_
.
functions
=
_
.
methods
=
function
(
obj
)
{
var
names
=
[];
for
(
var
key
in
obj
)
{
if
(
_
.
isFunction
(
obj
[
key
]))
names
.
push
(
key
);
}
return
names
.
sort
();
};
// An internal function for creating assigner functions.
var
createAssigner
=
function
(
keysFunc
,
defaults
)
{
return
function
(
obj
)
{
var
length
=
arguments
.
length
;
if
(
defaults
)
obj
=
Object
(
obj
);
if
(
length
<
2
||
obj
==
null
)
return
obj
;
for
(
var
index
=
1
;
index
<
length
;
index
++
)
{
var
source
=
arguments
[
index
],
keys
=
keysFunc
(
source
),
l
=
keys
.
length
;
for
(
var
i
=
0
;
i
<
l
;
i
++
)
{
var
key
=
keys
[
i
];
if
(
!
defaults
||
obj
[
key
]
===
void
0
)
obj
[
key
]
=
source
[
key
];
}
}
return
obj
;
};
};
// Extend a given object with all the properties in passed-in object(s).
_
.
extend
=
createAssigner
(
_
.
allKeys
);
// Assigns a given object with all the own properties in the passed-in object(s).
// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
_
.
extendOwn
=
_
.
assign
=
createAssigner
(
_
.
keys
);
// Returns the first key on an object that passes a predicate test.
_
.
findKey
=
function
(
obj
,
predicate
,
context
)
{
predicate
=
cb
(
predicate
,
context
);
var
keys
=
_
.
keys
(
obj
),
key
;
for
(
var
i
=
0
,
length
=
keys
.
length
;
i
<
length
;
i
++
)
{
key
=
keys
[
i
];
if
(
predicate
(
obj
[
key
],
key
,
obj
))
return
key
;
}
};
// Internal pick helper function to determine if `obj` has key `key`.
var
keyInObj
=
function
(
value
,
key
,
obj
)
{
return
key
in
obj
;
};
// Return a copy of the object only containing the whitelisted properties.
_
.
pick
=
restArguments
(
function
(
obj
,
keys
)
{
var
result
=
{},
iteratee
=
keys
[
0
];
if
(
obj
==
null
)
return
result
;
if
(
_
.
isFunction
(
iteratee
))
{
if
(
keys
.
length
>
1
)
iteratee
=
optimizeCb
(
iteratee
,
keys
[
1
]);
keys
=
_
.
allKeys
(
obj
);
}
else
{
iteratee
=
keyInObj
;
keys
=
flatten
(
keys
,
false
,
false
);
obj
=
Object
(
obj
);
}
for
(
var
i
=
0
,
length
=
keys
.
length
;
i
<
length
;
i
++
)
{
var
key
=
keys
[
i
];
var
value
=
obj
[
key
];
if
(
iteratee
(
value
,
key
,
obj
))
result
[
key
]
=
value
;
}
return
result
;
});
// Return a copy of the object without the blacklisted properties.
_
.
omit
=
restArguments
(
function
(
obj
,
keys
)
{
var
iteratee
=
keys
[
0
],
context
;
if
(
_
.
isFunction
(
iteratee
))
{
iteratee
=
_
.
negate
(
iteratee
);
if
(
keys
.
length
>
1
)
context
=
keys
[
1
];
}
else
{
keys
=
_
.
map
(
flatten
(
keys
,
false
,
false
),
String
);
iteratee
=
function
(
value
,
key
)
{
return
!
_
.
contains
(
keys
,
key
);
};
}
return
_
.
pick
(
obj
,
iteratee
,
context
);
});
// Fill in a given object with default properties.
_
.
defaults
=
createAssigner
(
_
.
allKeys
,
true
);
// Creates an object that inherits from the given prototype object.
// If additional properties are provided then they will be added to the
// created object.
_
.
create
=
function
(
prototype
,
props
)
{
var
result
=
baseCreate
(
prototype
);
if
(
props
)
_
.
extendOwn
(
result
,
props
);
return
result
;
};
// Create a (shallow-cloned) duplicate of an object.
_
.
clone
=
function
(
obj
)
{
if
(
!
_
.
isObject
(
obj
))
return
obj
;
return
_
.
isArray
(
obj
)
?
obj
.
slice
()
:
_
.
extend
({},
obj
);
};
// Invokes interceptor with the obj, and then returns obj.
// The primary purpose of this method is to "tap into" a method chain, in
// order to perform operations on intermediate results within the chain.
_
.
tap
=
function
(
obj
,
interceptor
)
{
interceptor
(
obj
);
return
obj
;
};
// Returns whether an object has a given set of `key:value` pairs.
_
.
isMatch
=
function
(
object
,
attrs
)
{
var
keys
=
_
.
keys
(
attrs
),
length
=
keys
.
length
;
if
(
object
==
null
)
return
!
length
;
var
obj
=
Object
(
object
);
for
(
var
i
=
0
;
i
<
length
;
i
++
)
{
var
key
=
keys
[
i
];
if
(
attrs
[
key
]
!==
obj
[
key
]
||
!
(
key
in
obj
))
return
false
;
}
return
true
;
};
// Internal recursive comparison function for `isEqual`.
var
eq
,
deepEq
;
eq
=
function
(
a
,
b
,
aStack
,
bStack
)
{
// Identical objects are equal. `0 === -0`, but they aren't identical.
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
if
(
a
===
b
)
return
a
!==
0
||
1
/
a
===
1
/
b
;
// `null` or `undefined` only equal to itself (strict comparison).
if
(
a
==
null
||
b
==
null
)
return
false
;
// `NaN`s are equivalent, but non-reflexive.
if
(
a
!==
a
)
return
b
!==
b
;
// Exhaust primitive checks
var
type
=
typeof
a
;
if
(
type
!==
'function'
&&
type
!==
'object'
&&
typeof
b
!=
'object'
)
return
false
;
return
deepEq
(
a
,
b
,
aStack
,
bStack
);
};
// Internal recursive comparison function for `isEqual`.
deepEq
=
function
(
a
,
b
,
aStack
,
bStack
)
{
// Unwrap any wrapped objects.
if
(
a
instanceof
_
)
a
=
a
.
_wrapped
;
if
(
b
instanceof
_
)
b
=
b
.
_wrapped
;
// Compare `[[Class]]` names.
var
className
=
toString
.
call
(
a
);
if
(
className
!==
toString
.
call
(
b
))
return
false
;
switch
(
className
)
{
// Strings, numbers, regular expressions, dates, and booleans are compared by value.
case
'[object RegExp]'
:
// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
case
'[object String]'
:
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
// equivalent to `new String("5")`.
return
''
+
a
===
''
+
b
;
case
'[object Number]'
:
// `NaN`s are equivalent, but non-reflexive.
// Object(NaN) is equivalent to NaN.
if
(
+
a
!==
+
a
)
return
+
b
!==
+
b
;
// An `egal` comparison is performed for other numeric values.
return
+
a
===
0
?
1
/
+
a
===
1
/
b
:
+
a
===
+
b
;
case
'[object Date]'
:
case
'[object Boolean]'
:
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
// millisecond representations. Note that invalid dates with millisecond representations
// of `NaN` are not equivalent.
return
+
a
===
+
b
;
case
'[object Symbol]'
:
return
SymbolProto
.
valueOf
.
call
(
a
)
===
SymbolProto
.
valueOf
.
call
(
b
);
}
var
areArrays
=
className
===
'[object Array]'
;
if
(
!
areArrays
)
{
if
(
typeof
a
!=
'object'
||
typeof
b
!=
'object'
)
return
false
;
// Objects with different constructors are not equivalent, but `Object`s or `Array`s
// from different frames are.
var
aCtor
=
a
.
constructor
,
bCtor
=
b
.
constructor
;
if
(
aCtor
!==
bCtor
&&
!
(
_
.
isFunction
(
aCtor
)
&&
aCtor
instanceof
aCtor
&&
_
.
isFunction
(
bCtor
)
&&
bCtor
instanceof
bCtor
)
&&
(
'constructor'
in
a
&&
'constructor'
in
b
))
{
return
false
;
}
}
// Assume equality for cyclic structures. The algorithm for detecting cyclic
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
// Initializing stack of traversed objects.
// It's done here since we only need them for objects and arrays comparison.
aStack
=
aStack
||
[];
bStack
=
bStack
||
[];
var
length
=
aStack
.
length
;
while
(
length
--
)
{
// Linear search. Performance is inversely proportional to the number of
// unique nested structures.
if
(
aStack
[
length
]
===
a
)
return
bStack
[
length
]
===
b
;
}
// Add the first object to the stack of traversed objects.
aStack
.
push
(
a
);
bStack
.
push
(
b
);
// Recursively compare objects and arrays.
if
(
areArrays
)
{
// Compare array lengths to determine if a deep comparison is necessary.
length
=
a
.
length
;
if
(
length
!==
b
.
length
)
return
false
;
// Deep compare the contents, ignoring non-numeric properties.
while
(
length
--
)
{
if
(
!
eq
(
a
[
length
],
b
[
length
],
aStack
,
bStack
))
return
false
;
}
}
else
{
// Deep compare objects.
var
keys
=
_
.
keys
(
a
),
key
;
length
=
keys
.
length
;
// Ensure that both objects contain the same number of properties before comparing deep equality.
if
(
_
.
keys
(
b
).
length
!==
length
)
return
false
;
while
(
length
--
)
{
// Deep compare each member
key
=
keys
[
length
];
if
(
!
(
has
(
b
,
key
)
&&
eq
(
a
[
key
],
b
[
key
],
aStack
,
bStack
)))
return
false
;
}
}
// Remove the first object from the stack of traversed objects.
aStack
.
pop
();
bStack
.
pop
();
return
true
;
};
// Perform a deep comparison to check if two objects are equal.
_
.
isEqual
=
function
(
a
,
b
)
{
return
eq
(
a
,
b
);
};
// Is a given array, string, or object empty?
// An "empty" object has no enumerable own-properties.
_
.
isEmpty
=
function
(
obj
)
{
if
(
obj
==
null
)
return
true
;
if
(
isArrayLike
(
obj
)
&&
(
_
.
isArray
(
obj
)
||
_
.
isString
(
obj
)
||
_
.
isArguments
(
obj
)))
return
obj
.
length
===
0
;
return
_
.
keys
(
obj
).
length
===
0
;
};
// Is a given value a DOM element?
_
.
isElement
=
function
(
obj
)
{
return
!!
(
obj
&&
obj
.
nodeType
===
1
);
};
// Is a given value an array?
// Delegates to ECMA5's native Array.isArray
_
.
isArray
=
nativeIsArray
||
function
(
obj
)
{
return
toString
.
call
(
obj
)
===
'[object Array]'
;
};
// Is a given variable an object?
_
.
isObject
=
function
(
obj
)
{
var
type
=
typeof
obj
;
return
type
===
'function'
||
type
===
'object'
&&
!!
obj
;
};
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError, isMap, isWeakMap, isSet, isWeakSet.
_
.
each
([
'Arguments'
,
'Function'
,
'String'
,
'Number'
,
'Date'
,
'RegExp'
,
'Error'
,
'Symbol'
,
'Map'
,
'WeakMap'
,
'Set'
,
'WeakSet'
],
function
(
name
)
{
_
[
'is'
+
name
]
=
function
(
obj
)
{
return
toString
.
call
(
obj
)
===
'[object '
+
name
+
']'
;
};
});
// Define a fallback version of the method in browsers (ahem, IE < 9), where
// there isn't any inspectable "Arguments" type.
if
(
!
_
.
isArguments
(
arguments
))
{
_
.
isArguments
=
function
(
obj
)
{
return
has
(
obj
,
'callee'
);
};
}
// Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
// IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).
var
nodelist
=
root
.
document
&&
root
.
document
.
childNodes
;
if
(
typeof
/./
!=
'function'
&&
typeof
Int8Array
!=
'object'
&&
typeof
nodelist
!=
'function'
)
{
_
.
isFunction
=
function
(
obj
)
{
return
typeof
obj
==
'function'
||
false
;
};
}
// Is a given object a finite number?
_
.
isFinite
=
function
(
obj
)
{
return
!
_
.
isSymbol
(
obj
)
&&
isFinite
(
obj
)
&&
!
isNaN
(
parseFloat
(
obj
));
};
// Is the given value `NaN`?
_
.
isNaN
=
function
(
obj
)
{
return
_
.
isNumber
(
obj
)
&&
isNaN
(
obj
);
};
// Is a given value a boolean?
_
.
isBoolean
=
function
(
obj
)
{
return
obj
===
true
||
obj
===
false
||
toString
.
call
(
obj
)
===
'[object Boolean]'
;
};
// Is a given value equal to null?
_
.
isNull
=
function
(
obj
)
{
return
obj
===
null
;
};
// Is a given variable undefined?
_
.
isUndefined
=
function
(
obj
)
{
return
obj
===
void
0
;
};
// Shortcut function for checking if an object has a given property directly
// on itself (in other words, not on a prototype).
_
.
has
=
function
(
obj
,
path
)
{
if
(
!
_
.
isArray
(
path
))
{
return
has
(
obj
,
path
);
}
var
length
=
path
.
length
;
for
(
var
i
=
0
;
i
<
length
;
i
++
)
{
var
key
=
path
[
i
];
if
(
obj
==
null
||
!
hasOwnProperty
.
call
(
obj
,
key
))
{
return
false
;
}
obj
=
obj
[
key
];
}
return
!!
length
;
};
// Utility Functions
// -----------------
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
// previous owner. Returns a reference to the Underscore object.
_
.
noConflict
=
function
()
{
root
.
_
=
previousUnderscore
;
return
this
;
};
// Keep the identity function around for default iteratees.
_
.
identity
=
function
(
value
)
{
return
value
;
};
// Predicate-generating functions. Often useful outside of Underscore.
_
.
constant
=
function
(
value
)
{
return
function
()
{
return
value
;
};
};
_
.
noop
=
function
(){};
// Creates a function that, when passed an object, will traverse that object’s
// properties down the given `path`, specified as an array of keys or indexes.
_
.
property
=
function
(
path
)
{
if
(
!
_
.
isArray
(
path
))
{
return
shallowProperty
(
path
);
}
return
function
(
obj
)
{
return
deepGet
(
obj
,
path
);
};
};
// Generates a function for a given object that returns a given property.
_
.
propertyOf
=
function
(
obj
)
{
if
(
obj
==
null
)
{
return
function
(){};
}
return
function
(
path
)
{
return
!
_
.
isArray
(
path
)
?
obj
[
path
]
:
deepGet
(
obj
,
path
);
};
};
// Returns a predicate for checking whether an object has a given set of
// `key:value` pairs.
_
.
matcher
=
_
.
matches
=
function
(
attrs
)
{
attrs
=
_
.
extendOwn
({},
attrs
);
return
function
(
obj
)
{
return
_
.
isMatch
(
obj
,
attrs
);
};
};
// Run a function **n** times.
_
.
times
=
function
(
n
,
iteratee
,
context
)
{
var
accum
=
Array
(
Math
.
max
(
0
,
n
));
iteratee
=
optimizeCb
(
iteratee
,
context
,
1
);
for
(
var
i
=
0
;
i
<
n
;
i
++
)
accum
[
i
]
=
iteratee
(
i
);
return
accum
;
};
// Return a random integer between min and max (inclusive).
_
.
random
=
function
(
min
,
max
)
{
if
(
max
==
null
)
{
max
=
min
;
min
=
0
;
}
return
min
+
Math
.
floor
(
Math
.
random
()
*
(
max
-
min
+
1
));
};
// A (possibly faster) way to get the current timestamp as an integer.
_
.
now
=
Date
.
now
||
function
()
{
return
new
Date
().
getTime
();
};
// List of HTML entities for escaping.
var
escapeMap
=
{
'&'
:
'&'
,
'<'
:
'<'
,
'>'
:
'>'
,
'"'
:
'"'
,
"'"
:
'''
,
'`'
:
'`'
};
var
unescapeMap
=
_
.
invert
(
escapeMap
);
// Functions for escaping and unescaping strings to/from HTML interpolation.
var
createEscaper
=
function
(
map
)
{
var
escaper
=
function
(
match
)
{
return
map
[
match
];
};
// Regexes for identifying a key that needs to be escaped.
var
source
=
'(?:'
+
_
.
keys
(
map
).
join
(
'|'
)
+
')'
;
var
testRegexp
=
RegExp
(
source
);
var
replaceRegexp
=
RegExp
(
source
,
'g'
);
return
function
(
string
)
{
string
=
string
==
null
?
''
:
''
+
string
;
return
testRegexp
.
test
(
string
)
?
string
.
replace
(
replaceRegexp
,
escaper
)
:
string
;
};
};
_
.
escape
=
createEscaper
(
escapeMap
);
_
.
unescape
=
createEscaper
(
unescapeMap
);
// Traverses the children of `obj` along `path`. If a child is a function, it
// is invoked with its parent as context. Returns the value of the final
// child, or `fallback` if any child is undefined.
_
.
result
=
function
(
obj
,
path
,
fallback
)
{
if
(
!
_
.
isArray
(
path
))
path
=
[
path
];
var
length
=
path
.
length
;
if
(
!
length
)
{
return
_
.
isFunction
(
fallback
)
?
fallback
.
call
(
obj
)
:
fallback
;
}
for
(
var
i
=
0
;
i
<
length
;
i
++
)
{
var
prop
=
obj
==
null
?
void
0
:
obj
[
path
[
i
]];
if
(
prop
===
void
0
)
{
prop
=
fallback
;
i
=
length
;
// Ensure we don't continue iterating.
}
obj
=
_
.
isFunction
(
prop
)
?
prop
.
call
(
obj
)
:
prop
;
}
return
obj
;
};
// Generate a unique integer id (unique within the entire client session).
// Useful for temporary DOM ids.
var
idCounter
=
0
;
_
.
uniqueId
=
function
(
prefix
)
{
var
id
=
++
idCounter
+
''
;
return
prefix
?
prefix
+
id
:
id
;
};
// By default, Underscore uses ERB-style template delimiters, change the
// following template settings to use alternative delimiters.
_
.
templateSettings
=
{
evaluate
:
/<%
([\s\S]
+
?)
%>/g
,
interpolate
:
/<%=
([\s\S]
+
?)
%>/g
,
escape
:
/<%-
([\s\S]
+
?)
%>/g
};
// When customizing `templateSettings`, if you don't want to define an
// interpolation, evaluation or escaping regex, we need one that is
// guaranteed not to match.
var
noMatch
=
/
(
.
)
^/
;
// Certain characters need to be escaped so that they can be put into a
// string literal.
var
escapes
=
{
"'"
:
"'"
,
'
\
\'
: '
\\
',
'
\
r
': '
r
',
'
\
n
': '
n
',
'
\
u2028
': '
u2028
',
'
\
u2029
': '
u2029
'
};
var escapeRegExp = /
\\
|'
|
\
r
|
\
n
|
\
u2028
|
\
u2029
/
g
;
var
escapeChar
=
function
(
match
)
{
return
'
\
\'
+ escapes[match];
};
// JavaScript micro-templating, similar to John Resig'
s
implementation
.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
// NB: `oldSettings` only exists for backwards compatibility.
_
.
template
=
function
(
text
,
settings
,
oldSettings
)
{
if
(
!
settings
&&
oldSettings
)
settings
=
oldSettings
;
settings
=
_
.
defaults
({},
settings
,
_
.
templateSettings
);
// Combine delimiters into one regular expression via alternation.
var
matcher
=
RegExp
([
(
settings
.
escape
||
noMatch
).
source
,
(
settings
.
interpolate
||
noMatch
).
source
,
(
settings
.
evaluate
||
noMatch
).
source
].
join
(
'|'
)
+
'|$'
,
'g'
);
// Compile the template source, escaping string literals appropriately.
var
index
=
0
;
var
source
=
"__p+='"
;
text
.
replace
(
matcher
,
function
(
match
,
escape
,
interpolate
,
evaluate
,
offset
)
{
source
+=
text
.
slice
(
index
,
offset
).
replace
(
escapeRegExp
,
escapeChar
);
index
=
offset
+
match
.
length
;
if
(
escape
)
{
source
+=
"'+
\
n((__t=("
+
escape
+
"))==null?'':_.escape(__t))+
\
n'"
;
}
else
if
(
interpolate
)
{
source
+=
"'+
\
n((__t=("
+
interpolate
+
"))==null?'':__t)+
\
n'"
;
}
else
if
(
evaluate
)
{
source
+=
"';
\
n"
+
evaluate
+
"
\
n__p+='"
;
}
// Adobe VMs need the match returned to produce the correct offset.
return
match
;
});
source
+=
"';
\
n"
;
// If a variable is not specified, place data values in local scope.
if
(
!
settings
.
variable
)
source
=
'with(obj||{}){
\
n'
+
source
+
'}
\
n'
;
source
=
"var __t,__p='',__j=Array.prototype.join,"
+
"print=function(){__p+=__j.call(arguments,'');};
\
n"
+
source
+
'return __p;
\
n'
;
var
render
;
try
{
render
=
new
Function
(
settings
.
variable
||
'obj'
,
'_'
,
source
);
}
catch
(
e
)
{
e
.
source
=
source
;
throw
e
;
}
var
template
=
function
(
data
)
{
return
render
.
call
(
this
,
data
,
_
);
};
// Provide the compiled source as a convenience for precompilation.
var
argument
=
settings
.
variable
||
'obj'
;
template
.
source
=
'function('
+
argument
+
'){
\
n'
+
source
+
'}'
;
return
template
;
};
// Add a "chain" function. Start chaining a wrapped Underscore object.
_
.
chain
=
function
(
obj
)
{
var
instance
=
_
(
obj
);
instance
.
_chain
=
true
;
return
instance
;
};
// OOP
// ---------------
// If Underscore is called as a function, it returns a wrapped object that
// can be used OO-style. This wrapper holds altered versions of all the
// underscore functions. Wrapped objects may be chained.
// Helper function to continue chaining intermediate results.
var
chainResult
=
function
(
instance
,
obj
)
{
return
instance
.
_chain
?
_
(
obj
).
chain
()
:
obj
;
};
// Add your own custom functions to the Underscore object.
_
.
mixin
=
function
(
obj
)
{
_
.
each
(
_
.
functions
(
obj
),
function
(
name
)
{
var
func
=
_
[
name
]
=
obj
[
name
];
_
.
prototype
[
name
]
=
function
()
{
var
args
=
[
this
.
_wrapped
];
push
.
apply
(
args
,
arguments
);
return
chainResult
(
this
,
func
.
apply
(
_
,
args
));
};
});
return
_
;
};
// Add all of the Underscore functions to the wrapper object.
_
.
mixin
(
_
);
// Add all mutator Array functions to the wrapper.
_
.
each
([
'pop'
,
'push'
,
'reverse'
,
'shift'
,
'sort'
,
'splice'
,
'unshift'
],
function
(
name
)
{
var
method
=
ArrayProto
[
name
];
_
.
prototype
[
name
]
=
function
()
{
var
obj
=
this
.
_wrapped
;
method
.
apply
(
obj
,
arguments
);
if
((
name
===
'shift'
||
name
===
'splice'
)
&&
obj
.
length
===
0
)
delete
obj
[
0
];
return
chainResult
(
this
,
obj
);
};
});
// Add all accessor Array functions to the wrapper.
_
.
each
([
'concat'
,
'join'
,
'slice'
],
function
(
name
)
{
var
method
=
ArrayProto
[
name
];
_
.
prototype
[
name
]
=
function
()
{
return
chainResult
(
this
,
method
.
apply
(
this
.
_wrapped
,
arguments
));
};
});
// Extracts the result from a wrapped and chained object.
_
.
prototype
.
value
=
function
()
{
return
this
.
_wrapped
;
};
// Provide unwrapping proxy for some methods used in engine operations
// such as arithmetic and JSON stringification.
_
.
prototype
.
valueOf
=
_
.
prototype
.
toJSON
=
_
.
prototype
.
value
;
_
.
prototype
.
toString
=
function
()
{
return
String
(
this
.
_wrapped
);
};
// AMD registration happens at the end for compatibility with AMD loaders
// that may not enforce next-turn semantics on modules. Even though general
// practice for AMD registration is to be anonymous, underscore registers
// as a named module because, like jQuery, it is a base library that is
// popular enough to be bundled in a third party lib, but not be part of
// an AMD load request. Those cases could generate an error when an
// anonymous define() is called outside of a loader request.
if
(
typeof
define
==
'function'
&&
define
.
amd
)
{
define
(
'underscore'
,
[],
function
()
{
return
_
;
});
}
}());
\ No newline at end of file
src/main/webapp/js/pages/controlAsistenciaDocentes.js
0 → 100644
View file @
c018db65
let
asistencias
=
[];
function
buscar
()
{
let
busqueda
=
""
;
$
(
"#tblAsistenciaDocentes"
).
DataTable
().
destroy
();
$
(
"#tblAsistenciaDocentes"
).
DataTable
({
iDisplayLength
:
50
,
bStateSave
:
false
,
autoWidth
:
false
,
responsive
:
true
,
stateSave
:
true
,
columnDefs
:
[{
orderable
:
false
,
width
:
'100px'
,
targets
:
[
8
]
}],
dom
:
'<"datatable-header"fl><"datatable-scroll-wrap"t><"datatable-footer"ip>'
,
"processing"
:
true
,
"serverSide"
:
false
,
"data"
:
asistencias
,
"columns"
:
[{
"data"
:
"fila"
},
{
"data"
:
"nombres"
},
{
"data"
:
"dni"
},
// {"data": "sede"},
{
"data"
:
"area"
},
{
"data"
:
"cargo"
},
{
"data"
:
"fecha_asistencia"
,
"className"
:
'text-center'
},
{
"data"
:
"hora_ingreso"
,
"className"
:
'text-center'
},
{
"data"
:
"hora_salida"
,
"className"
:
'text-center'
},
{
"data"
:
"observacion"
,
"className"
:
'text-center'
,
render
:
function
(
data
)
{
let
label
=
''
;
let
obs
=
[
''
,
'Asistió'
,
'No marcó'
,
'Falta con aviso'
,
'Falta sin aviso'
,
'Tardanza'
,
'Vacaciones'
,
'Feriado'
,
'LSGH'
,
'LCGH'
];
debugger
switch
(
data
)
{
case
"1"
:
//Asistió
label
=
"label label-success"
;
break
;
case
"2"
:
//No marco
label
=
'label label-info'
;
break
;
case
"3"
:
//'Falta con aviso'
case
"4"
:
//'Falta sin aviso'
label
=
'label label-danger'
;
break
;
case
"5"
:
//'Tardanza'
label
=
'label label-warning'
;
break
;
case
"6"
:
//'Vacaciones'
case
"7"
:
//'Feriado'
case
"8"
:
//'LSGH'
case
"9"
:
//'LCGH'
label
=
'label label-primary'
;
break
;
default
:
label
=
'label label-default'
;
}
debugger
console
.
log
(
label
);
return
`<span class="
${
label
}
" style="font-size: 12px">
${
obs
[
data
]}
</span>`
;
}
}
],
fnInitComplete
:
function
(
settings
,
data
)
{
console
.
log
(
data
);
}
});
}
//$("#dp").datepicker({
// minDate: new Date(1900, 1 - 1, 1), maxDate: '-18Y',
// dateFormat: 'dd/mm/yy',
// defaultDate: new Date(1970, 1 - 1, 1),
// changeMonth: true,
// changeYear: true,
// yearRange: '-110:-18',
// onSelect: function () {
// $(this).valid();
// }
//});
//$("#dtpFechaInicio").datepicker('setDate', 'now');
$
().
ready
(
function
()
{
console
.
log
(
"awsdfasdf"
);
defaultConfigDataTable
();
$
(
'.selectpicker'
).
selectpicker
({
style
:
'btn-info'
,
size
:
4
});
$
(
".btn.dropdown-toggle.bs-placeholder"
).
removeClass
(
"btn-info"
);
$
(
".btn.dropdown-toggle.bs-placeholder"
).
css
({
border
:
"1px solid #ddd"
,
backgroundColor
:
"#fff"
});
$
(
"#dpFechaInicio"
).
datepicker
({
minDate
:
new
Date
(
2000
,
1
-
1
,
1
),
maxDate
:
new
Date
(),
dateFormat
:
'dd/mm/yy'
,
defaultDate
:
new
Date
(),
changeMonth
:
true
,
changeYear
:
true
,
yearRange
:
'-18:+0'
,
onSelect
:
function
()
{
// $(this).valid();
}
});
$
(
"#dpFechaInicio"
).
datepicker
(
'setDate'
,
'now'
);
$
(
"#dpFechaFin"
).
datepicker
({
minDate
:
new
Date
(
2000
,
1
-
1
,
1
),
maxDate
:
new
Date
(),
dateFormat
:
'dd/mm/yy'
,
defaultDate
:
new
Date
(),
changeMonth
:
true
,
changeYear
:
true
,
yearRange
:
'-18:+0'
,
onSelect
:
function
()
{
// $(this).valid();
}
});
$
(
"#dpFechaFin"
).
datepicker
(
'setDate'
,
'now'
);
defaultConfigDatePicker
();
});
\ No newline at end of file
src/main/webapp/vistas/controlAsistenciaDocentes.jsp
0 → 100644
View file @
c018db65
<
%@
include
file=
"templates/validar.jsp"
%
>
<
%@
page
contentType=
"text/html"
pageEncoding=
"UTF-8"
%
>
<!DOCTYPE html>
<html>
<head>
<
%@
include
file=
"templates/header.jsp"
%
>
<!--template-core-->
<!--css de la pagina-->
<!--<link href="../css/lib/bootstrap-select/bootstrap-select.min.css" rel="stylesheet" type="text/css"/>-->
<!--css-->
</head>
<body>
<
%@
include
file=
"templates/header-body.jsp"
%
>
<!-- content -->
<div
class=
"col-md-6 col-md-offset-3"
>
<div
class=
"panel panel-primary"
>
<div
class=
"panel-heading"
>
<h5
class=
"panel-title"
>
Control de Asistencia de Docentes
</h5>
</div>
<form
id=
"frmAsistenciaDocentes"
onsubmit=
"return false;"
autocomplete=
"off"
>
<div
class=
"panel-body"
>
<div
class=
"row"
>
<div
class=
"col-md-6 form-group"
>
<label>
Fecha Inicio
</label>
<div
class=
"input-group"
>
<span
class=
"input-group-addon"
><i
class=
"icon-calendar"
></i></span>
<input
type=
"text"
class=
"form-control"
id=
"dpFechaInicio"
name=
"dpFechaInicio"
placeholder=
"Fecha inicio …"
>
</div>
</div>
<div
class=
"col-md-6 form-group"
>
<label>
Fecha Fin
</label>
<div
class=
"input-group"
>
<span
class=
"input-group-addon"
><i
class=
"icon-calendar"
></i></span>
<input
type=
"text"
class=
"form-control"
id=
"dpFechaFin"
name=
"dpFechaFin"
placeholder=
"Fecha fin …"
>
</div>
</div>
</div>
<div
class=
"row"
>
<div
class=
"col-md-3 form-group"
>
<label>
Criterio
</label>
<select
class=
"form-control"
>
<option>
SEDE
</option>
<option>
APELLIDOS
</option>
<option>
DNI
</option>
</select>
</div>
<div
class=
"col-md-9 form-group"
>
<label>
Busqueda
</label>
<input
type=
"text"
class=
"form-control"
/>
</div>
</div>
<div
class=
"row"
>
<div
class=
"col-md-10 form-group"
>
<label>
Estado
</label>
<select
class=
"selectpicker form-control"
name=
"cboSedes"
id=
"cboSedes"
multiple
>
<option>
PENDIENTE
</option>
<option>
FCA
</option>
<option>
FSA
</option>
<option>
TEMPRANO
</option>
<option>
TARDANZA
</option>
<option>
NO MARCÓ
</option>
</select>
</div>
</div>
</div>
<div
class=
"panel-footer"
>
<div
class=
"text-center"
>
<button
class=
"btn btn-primary"
id=
"btnBuscar"
><i
class=
"fa fa-search"
></i>
Buscar
</button>
<button
class=
"btn btn-warning"
id=
"btnLimpiar"
><i
class=
"fa fa-eraser"
></i>
Limpiar
</button>
</div>
</div>
</form>
</div>
</div>
<div
class=
"col-md-10 col-md-offset-1"
>
<div
class=
"panel panel-primary card-3"
style=
"margin-top: 30px"
>
<div
class=
"panel-heading"
style=
"padding: 8px 15px"
>
<h6
class=
"panel-title"
style=
"font-size: 15px; font-family: inherit"
><i
class=
"icon icon-search4"
></i>
LISTADO DE ASISTENCIAS
</h6>
</div>
<div>
<table
class=
"table dataTable table-striped table-hover table-sm table-bordered"
id=
"tblAsistenciaDocentes"
>
<thead>
<tr>
<th>
Nº
</th>
<!--<th>SEDE</th>-->
<th>
APELLIDOS Y NOMBRES
</th>
<th>
FECHA
</th>
<th>
HORARIO
</th>
<th>
HORA MARCACIÓN
</th>
<th>
AULAS
</th>
<th>
ESTADO
</th>
<th>
ACCIONES
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
1
</td>
<td>
HUAMANI TAIPE, FRANCISCO
</td>
<td>
26/06/2018
</td>
<td>
07:50 - 14:30
</td>
<td>
07:35
</td>
<td>
1A-2A-3A-4A
</td>
<td><span
class=
"label label-success"
>
TEMPRANO
</span></td>
<td></td>
</tr>
<tr>
<td>
2
</td>
<td>
LEON GOMEZ, MARIO JOSIMAR
</td>
<td>
26/06/2018
</td>
<td>
07:50 - 09:35
</td>
<td>
07:56
</td>
<td>
1A
</td>
<td><span
class=
"label label-warning"
>
TARDANZA
</span></td>
<td></td>
</tr>
<tr>
<td>
3
</td>
<td>
ALVITES MARIN, VICTOR MANUEL
</td>
<td>
26/06/2018
</td>
<td>
07:50 - 14:30
</td>
<td>
-
</td>
<td>
1A
</td>
<td><span
class=
"label label-danger"
>
FCA
</span></td>
<td></td>
</tr>
<tr>
<td>
3
</td>
<td>
ALVITES MARIN, VICTOR MANUEL
</td>
<td>
26/06/2018
</td>
<td>
07:50 - 14:30
</td>
<td>
-
</td>
<td>
1A
</td>
<td><span
class=
"label label-danger"
>
FSA
</span></td>
<td></td>
</tr>
<tr>
<td>
4
</td>
<td>
ALVITES MARIN, VICTOR MANUEL
</td>
<td>
26/06/2018
</td>
<td>
07:50 - 14:30
</td>
<td>
-
</td>
<td>
1A
</td>
<td><span
class=
"label label-default"
>
NO MARCÓ
</span></td>
<td></td>
</tr>
<tr>
<td>
4
</td>
<td>
ALVITES MARIN, VICTOR MANUEL
</td>
<td>
26/06/2018
</td>
<td>
07:50 - 14:30
</td>
<td>
-
</td>
<td>
1A
</td>
<td><span
class=
"label label-info"
>
VAC
</span></td>
<td></td>
</tr>
<tr>
<td>
4
</td>
<td>
ALVITES MARIN, VICTOR MANUEL
</td>
<td>
26/06/2018
</td>
<td>
07:50 - 14:30
</td>
<td>
-
</td>
<td>
1A
</td>
<td><span
class=
"label label-info"
>
FER
</span></td>
<td></td>
</tr>
<tr>
<td>
4
</td>
<td>
ALVITES MARIN, VICTOR MANUEL
</td>
<td>
26/06/2018
</td>
<td>
07:50 - 14:30
</td>
<td>
-
</td>
<td>
1A
</td>
<td><span
class=
"label label-info"
>
LCGH
</span></td>
<td></td>
</tr>
<tr>
<td>
4
</td>
<td>
ALVITES MARIN, VICTOR MANUEL
</td>
<td>
26/06/2018
</td>
<td>
07:50 - 14:30
</td>
<td></td>
<td>
1A
</td>
<td><span
class=
"label bg-purple"
>
PENDIENTE
</span></td>
<td>
<span
data-toggle=
"tooltip"
data-placement=
"left"
title=
"Editar"
style=
"cursor: pointer"
>
<i
class=
'registrar icon-plus-circle2 text-success-700'
></i>
</span>
<span
data-toggle=
"tooltip"
data-placement=
"left"
title=
"Editar"
style=
"cursor: pointer"
>
<i
class=
'editar icon-pencil text-slate-800'
></i>
</span>
<span
data-toggle=
"tooltip"
data-placement=
"left"
title=
"Aprobar"
style=
"cursor: pointer"
>
<i
class=
'aprobar icon-checkmark-circle text-success-700'
></i>
</span>
<span
data-toggle=
"tooltip"
data-placement=
"left"
title=
"Anular"
style=
"cursor: pointer"
>
<i
class=
'anular icon-cancel-circle2 text-danger-700'
></i>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!-- / content -->
<
%@
include
file=
"templates/footer-body.jsp"
%
>
<!--js de la pagina-->
<script
type=
"text/javascript"
src=
"https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"
></script>
<script
type=
"text/javascript"
src=
"https://cdn.datatables.net/1.10.16/js/dataTables.bootstrap.min.js"
></script>
<script
src=
"../js/lib/bootstrap-select/bootstrap-select.min.js"
type=
"text/javascript"
></script>
<script
type=
"text/javascript"
src=
"../plantilla/assets/js/core/libraries/jquery_ui/widgets.min.js"
></script>
<script
src=
"../js/pages/controlAsistenciaDocentes.js"
type=
"text/javascript"
></script>
<!--js-->
</body>
</html>
\ No newline at end of file
src/main/webapp/vistas/templates/footer-body.jsp
View file @
c018db65
...
...
@@ -25,7 +25,7 @@
<script type="text/javascript" src="../plantilla/assets/js/plugins/forms/styling/switchery.min.js"></script>
<script type="text/javascript" src="../plantilla/assets/js/plugins/forms/styling/uniform.min.js"></script>
<
script type="text/javascript" src="../plantilla/assets/js/plugins/forms/selects/bootstrap_multiselect.js"></script
>
<
!--<script type="text/javascript" src="../plantilla/assets/js/plugins/forms/selects/bootstrap_multiselect.js"></script>--
>
<script type="text/javascript" src="../plantilla/assets/js/core/app.js"></script>
<!-- /core JS files -->
...
...
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