Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
O
OpnSense
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
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
Kulya
OpnSense
Commits
e472f132
Commit
e472f132
authored
May 08, 2015
by
Ad Schellevis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
proxy UI cleanups and move some functionality into the core MVC template
parent
603e91c2
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
257 additions
and
117 deletions
+257
-117
ServiceController.php
.../app/controllers/OPNsense/Proxy/Api/ServiceController.php
+8
-1
index.volt
src/opnsense/mvc/app/views/OPNsense/Proxy/index.volt
+15
-99
default.volt
src/opnsense/mvc/app/views/layouts/default.volt
+9
-10
opnsense.js
src/opnsense/www/js/opnsense.js
+38
-5
opnsense_ui.js
src/opnsense/www/js/opnsense_ui.js
+187
-2
No files found.
src/opnsense/mvc/app/controllers/OPNsense/Proxy/Api/ServiceController.php
View file @
e472f132
...
@@ -79,12 +79,19 @@ class ServiceController extends ApiControllerBase
...
@@ -79,12 +79,19 @@ class ServiceController extends ApiControllerBase
public
function
statusAction
()
public
function
statusAction
()
{
{
$backend
=
new
Backend
();
$backend
=
new
Backend
();
$mdlProxy
=
new
Proxy
();
$response
=
$backend
->
configdRun
(
"proxy status"
);
$response
=
$backend
->
configdRun
(
"proxy status"
);
if
(
strpos
(
$response
,
"not running"
)
>
0
)
{
if
(
strpos
(
$response
,
"not running"
)
>
0
)
{
if
(
$mdlProxy
->
general
->
enabled
->
__toString
()
==
1
)
{
$status
=
"stopped"
;
$status
=
"stopped"
;
}
else
{
$status
=
"disabled"
;
}
}
elseif
(
strpos
(
$response
,
"is running"
)
>
0
)
{
}
elseif
(
strpos
(
$response
,
"is running"
)
>
0
)
{
$status
=
"running"
;
$status
=
"running"
;
}
elseif
(
$mdlProxy
->
general
->
enabled
->
__toString
()
==
0
)
{
$status
=
"disabled"
;
}
else
{
}
else
{
$status
=
"unkown"
;
$status
=
"unkown"
;
}
}
...
...
src/opnsense/mvc/app/views/OPNsense/Proxy/index.volt
View file @
e472f132
...
@@ -30,23 +30,21 @@ POSSIBILITY OF SUCH DAMAGE.
...
@@ -30,23 +30,21 @@ POSSIBILITY OF SUCH DAMAGE.
$( document ).ready(function() {
$( document ).ready(function() {
data_get_map = {'frm_proxy':"/api/proxy/settings/get"};
var data_get_map = {'frm_proxy':"/api/proxy/settings/get"};
// load initial data
// load initial data
$.each(data_get_map, function(data_index, data_url) {
mapDataToFormUI(data_get_map).done(function(){
ajaxGet(url=data_url,sendData={},callback=function(data,status) {
formatTokenizersUI();
if (status == "success") {
$('.selectpicker').selectpicker('refresh');
$("form").each(function( index ) {
// request service status on load and update status box
if ( $(this).attr('id').split('-')[0] == data_index) {
ajaxCall(url="/api/proxy/service/status", sendData={}, callback=function(data,status) {
// related form found, load data
updateServiceStatusUI("proxy",data['responseText']);
setFormData($(this).attr('id'),data);
}
});
}
});
});
});
});
// form
event handler
s
// form
save event handlers for all defined form
s
$('[id*="save_"]').each(function(){
$('[id*="save_"]').each(function(){
$(this).click(function() {
$(this).click(function() {
var frm_id = $(this).closest("form").attr("id");
var frm_id = $(this).closest("form").attr("id");
...
@@ -69,100 +67,18 @@ POSSIBILITY OF SUCH DAMAGE.
...
@@ -69,100 +67,18 @@ POSSIBILITY OF SUCH DAMAGE.
message: JSON.stringify(data),
message: JSON.stringify(data),
draggable: true
draggable: true
});
});
}
});
});
});
});
// handle help messages show/hide
$('[id*="show_all_help"]').click(function() {
$('[id*="show_all_help"]').toggleClass("fa-toggle-on fa-toggle-off");
$('[id*="show_all_help"]').toggleClass("text-success text-danger");
if ($('[id*="show_all_help"]').hasClass("fa-toggle-on")) {
$('[for*="help_for"]').addClass("show");
$('[for*="help_for"]').removeClass("hidden");
} else {
$('[for*="help_for"]').addClass("hidden");
$('[for*="help_for"]').removeClass("show");
}
});
// handle advanced show/hide
$('[data-advanced*="true"]').hide(function(){
$('[data-advanced*="true"]').after("<tr data-advanced='hidden_row'></tr>"); // the table row is added to keep correct table striping
});
$('[id*="show_advanced"]').click(function() {
$('[id*="show_advanced"]').toggleClass("fa-toggle-on fa-toggle-off");
$('[id*="show_advanced"]').toggleClass("text-success text-danger");
if ($('[id*="show_advanced"]').hasClass("fa-toggle-on")) {
$('[data-advanced*="true"]').show();
$('[data-advanced*="hidden_row"]').remove(); // the table row is deleted to keep correct table striping
} else {
} else {
$('[data-advanced*="true"]').after("<tr data-advanced='hidden_row'></tr>").hide(); // the table row is added to keep correct table striping
// request service status after successful save and update status box
}
ajaxCall(url="/api/proxy/service/status", sendData={}, callback=function(data,status) {
updateServiceStatusUI("proxy",data['responseText']);
});
});
// Apply tokenizer
setTimeout(function(){
$('select[class="tokenize"]').each(function(){
if ($(this).prop("size")==0) {
maxDropdownHeight=String(36*5)+"px"; // default number of items
} else {
number_of_items = $(this).prop("size");
maxDropdownHeight=String(36*number_of_items)+"px";
}
}
hint=$(this).data("hint");
width=$(this).data("width");
allownew=$(this).data("allownew");
maxTokenContainerHeight=$(this).data("maxheight");
$(this).tokenize({
displayDropdownOnFocus: true,
newElements: allownew,
placeholder:hint
});
});
$(this).parent().find('ul[class="TokensContainer"]').parent().css("width",width);
$(this).parent().find('ul[class="Dropdown"]').css("max-height", maxDropdownHeight);
if ( maxDropdownHeight != undefined ) {
$(this).parent().find('ul[class="TokensContainer"]').css("max-height", maxTokenContainerHeight);
}
});
// TODO: fix loading order
$('.selectpicker').selectpicker('refresh');
},500);
// clear multiselect boxes, works on standard and tokenized versions
$('[id*="clear-options"]').each(function() {
$(this).click(function() {
var id = $(this).attr("for");
BootstrapDialog.confirm({
title: 'Deselect or remove all items ?',
message: 'Deselect or remove all items ?',
type: BootstrapDialog.TYPE_DANGER,
closable: true,
draggable: true,
btnCancelLabel: 'Cancel',
btnOKLabel: 'Yes',
btnOKClass: 'btn-primary',
callback: function(result) {
if(result) {
if ($('select[id="' + id + '"]').hasClass("tokenize")) {
// trigger close on all Tokens
$('select[id="' + id + '"]').parent().find('ul[class="TokensContainer"]').find('li[class="Token"]').find('a').trigger("click");
} else {
// remove options from selection
$('select[id="' + id + '"]').find('option').prop('selected',false);
}
}
}
});
});
});
});
});
});
});
});
...
...
src/opnsense/mvc/app/views/layouts/default.volt
View file @
e472f132
...
@@ -40,21 +40,21 @@
...
@@ -40,21 +40,21 @@
}
}
});
});
// handle help messages show/hide
$
(
"
a[class='showhelp']
"
).
click
(
function
()
{
$
(
"
*[for='
"
+
$
(
this
).
attr
(
'
id
'
)
+
"
']
"
).
toggleClass
(
"
hidden show
"
);
});
// hide empty menu items
// hide empty menu items
$
(
'
#mainmenu > div > .collapse
'
).
each
(
function
(){
$
(
'
#mainmenu > div > .collapse
'
).
each
(
function
(){
if
(
$
(
this
).
children
().
length
==
0
)
{
if
(
$
(
this
).
children
().
length
==
0
)
{
$
(
"
#mainmenu
"
).
find
(
'
[href="#
'
+
$
(
this
).
attr
(
'
id
'
)
+
'
"]
'
).
remove
();
$
(
"
#mainmenu
"
).
find
(
'
[href="#
'
+
$
(
this
).
attr
(
'
id
'
)
+
'
"]
'
).
remove
();
}
}
});
});
});
initFormHelpUI
();
initFormAdvancedUI
();
addMultiSelectClearUI
();
});
</script>
</script>
<!-- bootstrap dialog -->
<!-- bootstrap dialog -->
<link
href=
"/ui/themes/opnsense/build/css/bootstrap-dialog.css"
rel=
"stylesheet"
type=
"text/css"
/>
<link
href=
"/ui/themes/opnsense/build/css/bootstrap-dialog.css"
rel=
"stylesheet"
type=
"text/css"
/>
...
@@ -112,8 +112,8 @@
...
@@ -112,8 +112,8 @@
<ul
class=
"list-inline"
>
<ul
class=
"list-inline"
>
<li
class=
"__mb"
><h1>
{{title | default("")}}
</h1></li>
<li
class=
"__mb"
><h1>
{{title | default("")}}
</h1></li>
<li
class=
"btn-group-container"
>
<li
class=
"btn-group-container"
id=
"service_status_container"
>
<!-- <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal_widgets"><span class="glyphicon glyphicon-plus-sign __iconspacer"></span>Add widget</button>
-->
<!-- placeholder for service status buttons
-->
</li>
</li>
</ul>
</ul>
</div>
</div>
...
@@ -147,6 +147,5 @@
...
@@ -147,6 +147,5 @@
<script
type=
"text/javascript"
src=
"/ui/js/bootstrap-select.min.js"
></script>
<script
type=
"text/javascript"
src=
"/ui/js/bootstrap-select.min.js"
></script>
<!-- bootstrap dialog -->
<!-- bootstrap dialog -->
<script
src=
"/ui/js/bootstrap-dialog.js"
></script>
<script
src=
"/ui/js/bootstrap-dialog.js"
></script>
</body>
</body>
</html>
</html>
src/opnsense/www/js/opnsense.js
View file @
e472f132
/**
/**
* Copyright (C) 2015 Deciso B.V.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* shared components
*
*/
/**
*
* Map input fields from given parent tag to structure of named arrays.
* Map input fields from given parent tag to structure of named arrays.
*
*
* @param parent tag id in dom
* @param parent tag id in dom
...
@@ -6,14 +39,14 @@
...
@@ -6,14 +39,14 @@
*/
*/
function
getFormData
(
parent
)
{
function
getFormData
(
parent
)
{
data
=
{};
var
data
=
{};
$
(
"
#
"
+
parent
+
"
input,#
"
+
parent
+
"
select
"
).
each
(
function
(
index
)
{
$
(
"
#
"
+
parent
+
"
input,#
"
+
parent
+
"
select
"
).
each
(
function
(
index
)
{
if
(
$
(
this
).
prop
(
'
id
'
)
==
undefined
)
{
if
(
$
(
this
).
prop
(
'
id
'
)
==
undefined
)
{
// we need an id.
// we need an id.
return
;
return
;
}
}
node
=
data
;
var
node
=
data
;
keyparts
=
$
(
this
).
prop
(
'
id
'
).
split
(
'
.
'
);
var
keyparts
=
$
(
this
).
prop
(
'
id
'
).
split
(
'
.
'
);
for
(
var
i
in
keyparts
)
{
for
(
var
i
in
keyparts
)
{
if
(
!
(
keyparts
[
i
]
in
node
))
{
if
(
!
(
keyparts
[
i
]
in
node
))
{
node
[
keyparts
[
i
]]
=
{};
node
[
keyparts
[
i
]]
=
{};
...
@@ -67,8 +100,8 @@ function setFormData(parent,data) {
...
@@ -67,8 +100,8 @@ function setFormData(parent,data) {
// we need an id.
// we need an id.
return
;
return
;
}
}
node
=
data
;
var
node
=
data
;
keyparts
=
$
(
this
).
prop
(
'
id
'
).
split
(
'
.
'
);
var
keyparts
=
$
(
this
).
prop
(
'
id
'
).
split
(
'
.
'
);
for
(
var
i
in
keyparts
)
{
for
(
var
i
in
keyparts
)
{
if
(
!
(
keyparts
[
i
]
in
node
))
{
if
(
!
(
keyparts
[
i
]
in
node
))
{
break
;
break
;
...
...
src/opnsense/www/js/opnsense_ui.js
View file @
e472f132
/**
/**
* Copyright (C) 2015 Deciso B.V.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* User interface shared components, requires opnsense.js for supporting functions.
* User interface shared components, requires opnsense.js for supporting functions.
*/
*/
...
@@ -8,7 +35,7 @@
...
@@ -8,7 +35,7 @@
* @param formid parent id to grep input data from
* @param formid parent id to grep input data from
*/
*/
function
saveFormToEndpoint
(
url
,
formid
,
callback_ok
)
{
function
saveFormToEndpoint
(
url
,
formid
,
callback_ok
)
{
data
=
getFormData
(
formid
);
var
data
=
getFormData
(
formid
);
ajaxCall
(
url
=
url
,
sendData
=
data
,
callback
=
function
(
data
,
status
){
ajaxCall
(
url
=
url
,
sendData
=
data
,
callback
=
function
(
data
,
status
){
if
(
status
==
"
success
"
)
{
if
(
status
==
"
success
"
)
{
// update field validation
// update field validation
...
@@ -38,5 +65,163 @@ function saveFormToEndpoint(url,formid,callback_ok) {
...
@@ -38,5 +65,163 @@ function saveFormToEndpoint(url,formid,callback_ok) {
}
}
});
});
}
/**
* standard data mapper to map json request data to forms on this page
* @param data_get_map named array containing form names and source url's to get data from {'frm_example':"/api/example/settings/get"};
* @return promise object, resolves when all are loaded
*/
function
mapDataToFormUI
(
data_get_map
)
{
var
dfObj
=
new
$
.
Deferred
();
// calculate number of items for deferred object to resolve
var
data_map_seq
=
1
;
var
data_map_count
=
0
;
$
.
each
(
data_get_map
,
function
(){
data_map_count
+=
1
;
});
$
.
each
(
data_get_map
,
function
(
data_index
,
data_url
)
{
ajaxGet
(
url
=
data_url
,
sendData
=
{},
callback
=
function
(
data
,
status
)
{
if
(
status
==
"
success
"
)
{
$
(
"
form
"
).
each
(
function
(
index
)
{
if
(
$
(
this
).
attr
(
'
id
'
).
split
(
'
-
'
)[
0
]
==
data_index
)
{
// related form found, load data
setFormData
(
$
(
this
).
attr
(
'
id
'
),
data
);
}
});
}
if
(
data_map_seq
==
data_map_count
)
{
dfObj
.
resolve
(
data_map_seq
);
}
data_map_seq
+=
1
;
});
});
return
dfObj
;
}
/**
* update service status buttons in user interface
*/
function
updateServiceStatusUI
(
service
,
status
)
{
var
status_html
=
''
;
if
(
status
==
"
running
"
)
{
status_html
+=
'
<span class="btn btn-success">
'
;
}
else
if
(
status
==
"
stopped
"
)
{
status_html
+=
'
<span class="btn btn-danger">
'
;
}
else
{
status_html
+=
'
<span class="btn">
'
;
}
status_html
+=
'
<span class="glyphicon glyphicon-play" data-placement="bottom"></span> </span>
'
;
$
(
'
#service_status_container
'
).
html
(
status_html
);
}
/**
* reformat all tokenizers on this document
*/
function
formatTokenizersUI
(){
$
(
'
select[class="tokenize"]
'
).
each
(
function
(){
if
(
$
(
this
).
prop
(
"
size
"
)
==
0
)
{
maxDropdownHeight
=
String
(
36
*
5
)
+
"
px
"
;
// default number of items
}
else
{
number_of_items
=
$
(
this
).
prop
(
"
size
"
);
maxDropdownHeight
=
String
(
36
*
number_of_items
)
+
"
px
"
;
}
hint
=
$
(
this
).
data
(
"
hint
"
);
width
=
$
(
this
).
data
(
"
width
"
);
allownew
=
$
(
this
).
data
(
"
allownew
"
);
maxTokenContainerHeight
=
$
(
this
).
data
(
"
maxheight
"
);
$
(
this
).
tokenize
({
displayDropdownOnFocus
:
true
,
newElements
:
allownew
,
placeholder
:
hint
});
$
(
this
).
parent
().
find
(
'
ul[class="TokensContainer"]
'
).
parent
().
css
(
"
width
"
,
width
);
$
(
this
).
parent
().
find
(
'
ul[class="Dropdown"]
'
).
css
(
"
max-height
"
,
maxDropdownHeight
);
if
(
maxDropdownHeight
!=
undefined
)
{
$
(
this
).
parent
().
find
(
'
ul[class="TokensContainer"]
'
).
css
(
"
max-height
"
,
maxTokenContainerHeight
);
}
});
}
/**
* clear multiselect boxes on click event, works on standard and tokenized versions
*/
function
addMultiSelectClearUI
()
{
$
(
'
[id*="clear-options"]
'
).
each
(
function
()
{
$
(
this
).
click
(
function
()
{
var
id
=
$
(
this
).
attr
(
"
for
"
);
BootstrapDialog
.
confirm
({
title
:
'
Deselect or remove all items ?
'
,
message
:
'
Deselect or remove all items ?
'
,
type
:
BootstrapDialog
.
TYPE_DANGER
,
closable
:
true
,
draggable
:
true
,
btnCancelLabel
:
'
Cancel
'
,
btnOKLabel
:
'
Yes
'
,
btnOKClass
:
'
btn-primary
'
,
callback
:
function
(
result
)
{
if
(
result
)
{
if
(
$
(
'
select[id="
'
+
id
+
'
"]
'
).
hasClass
(
"
tokenize
"
))
{
// trigger close on all Tokens
$
(
'
select[id="
'
+
id
+
'
"]
'
).
parent
().
find
(
'
ul[class="TokensContainer"]
'
).
find
(
'
li[class="Token"]
'
).
find
(
'
a
'
).
trigger
(
"
click
"
);
}
else
{
// remove options from selection
$
(
'
select[id="
'
+
id
+
'
"]
'
).
find
(
'
option
'
).
prop
(
'
selected
'
,
false
);
}
}
}
});
});
});
}
/**
* setup form help buttons
*/
function
initFormHelpUI
()
{
// handle help messages show/hide
$
(
"
a[class='showhelp']
"
).
click
(
function
()
{
$
(
"
*[for='
"
+
$
(
this
).
attr
(
'
id
'
)
+
"
']
"
).
toggleClass
(
"
hidden show
"
);
});
// handle all help messages show/hide
$
(
'
[id*="show_all_help"]
'
).
click
(
function
()
{
$
(
'
[id*="show_all_help"]
'
).
toggleClass
(
"
fa-toggle-on fa-toggle-off
"
);
$
(
'
[id*="show_all_help"]
'
).
toggleClass
(
"
text-success text-danger
"
);
if
(
$
(
'
[id*="show_all_help"]
'
).
hasClass
(
"
fa-toggle-on
"
))
{
$
(
'
[for*="help_for"]
'
).
addClass
(
"
show
"
);
$
(
'
[for*="help_for"]
'
).
removeClass
(
"
hidden
"
);
}
else
{
$
(
'
[for*="help_for"]
'
).
addClass
(
"
hidden
"
);
$
(
'
[for*="help_for"]
'
).
removeClass
(
"
show
"
);
}
});
}
/**
* handle advanced show/hide
*/
function
initFormAdvancedUI
()
{
$
(
'
[data-advanced*="true"]
'
).
hide
(
function
(){
$
(
'
[data-advanced*="true"]
'
).
after
(
"
<tr data-advanced='hidden_row'></tr>
"
);
// the table row is added to keep correct table striping
});
$
(
'
[id*="show_advanced"]
'
).
click
(
function
()
{
$
(
'
[id*="show_advanced"]
'
).
toggleClass
(
"
fa-toggle-on fa-toggle-off
"
);
$
(
'
[id*="show_advanced"]
'
).
toggleClass
(
"
text-success text-danger
"
);
if
(
$
(
'
[id*="show_advanced"]
'
).
hasClass
(
"
fa-toggle-on
"
))
{
$
(
'
[data-advanced*="true"]
'
).
show
();
$
(
'
[data-advanced*="hidden_row"]
'
).
remove
();
// the table row is deleted to keep correct table striping
}
else
{
$
(
'
[data-advanced*="true"]
'
).
after
(
"
<tr data-advanced='hidden_row'></tr>
"
).
hide
();
// the table row is added to keep correct table striping
}
});
}
}
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