Lists: Search in custom fields and status filter.
This commit is contained in:
parent
3bc1596839
commit
8a412562f2
4 changed files with 72 additions and 9 deletions
|
@ -204,6 +204,9 @@ statuscolored=false
|
||||||
# Alternative directory containing the files geoip-country.dat and geoip-country6.dat
|
# Alternative directory containing the files geoip-country.dat and geoip-country6.dat
|
||||||
datadirectory=false
|
datadirectory=false
|
||||||
|
|
||||||
|
[search]
|
||||||
|
inhiddenfields=true
|
||||||
|
|
||||||
[reports]
|
[reports]
|
||||||
# The whole reporting functionality can be disabled below if the they are not needed and the DB cannot be
|
# The whole reporting functionality can be disabled below if the they are not needed and the DB cannot be
|
||||||
# properly protected.
|
# properly protected.
|
||||||
|
|
|
@ -71,7 +71,7 @@ module.exports.listTestUsers = (listId, callback) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.filter = (listId, request, columns, segmentId, callback) => {
|
module.exports.filter = (listId, request, columns, segmentId, searchFields, callback) => {
|
||||||
listId = Number(listId) || 0;
|
listId = Number(listId) || 0;
|
||||||
segmentId = Number(segmentId) || 0;
|
segmentId = Number(segmentId) || 0;
|
||||||
|
|
||||||
|
@ -85,10 +85,10 @@ module.exports.filter = (listId, request, columns, segmentId, callback) => {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
tableHelpers.filter('subscription__' + listId, ['*'], request, columns, ['email', 'first_name', 'last_name'], 'email ASC', queryData, callback);
|
tableHelpers.filter('subscription__' + listId, ['*'], request, columns, searchFields, 'email ASC', queryData, callback);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
tableHelpers.filter('subscription__' + listId, ['*'], request, columns, ['email', 'first_name', 'last_name'], 'email ASC', null, callback);
|
tableHelpers.filter('subscription__' + listId, ['*'], request, columns, searchFields, 'email ASC', null, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -190,8 +190,25 @@ router.post('/ajax/:id', (req, res) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
let columns = ['#', 'email', 'first_name', 'last_name'].concat(fieldList.filter(field => field.visible).map(field => field.column)).concat(['status', 'created']);
|
let columns = ['#', 'email', 'first_name', 'last_name'].concat(fieldList.filter(field => field.visible).map(field => field.column)).concat(['status', 'created']);
|
||||||
|
let searchFields = ['email', 'first_name', 'last_name'];
|
||||||
|
|
||||||
subscriptions.filter(list.id, req.body, columns, req.query.segment, (err, data, total, filteredTotal) => {
|
if (('search' in req.body) && req.body.search.value) {
|
||||||
|
const search = req.body.search.value.toLowerCase();
|
||||||
|
const statusTypes = ['subscribed', 'unsubscribed', 'bounced', 'complained'];
|
||||||
|
|
||||||
|
if (statusTypes.includes(search)) {
|
||||||
|
searchFields = ['status'];
|
||||||
|
req.body.search.value = String(statusTypes.indexOf(search) + 1);
|
||||||
|
} else if (fieldList.length) {
|
||||||
|
const searcheableTypes = ['text', 'longtext', 'website'].concat(/^[0-9]+$/.test(search) ? ['number'] : []);
|
||||||
|
let additionalSearchFields = fieldList.filter(field => {
|
||||||
|
return ((searcheableTypes.indexOf(field.type) > -1) && (config.search.inhiddenfields ? true : field.visible));
|
||||||
|
}).map(field => field.column);
|
||||||
|
searchFields = searchFields.concat(additionalSearchFields);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subscriptions.filter(list.id, req.body, columns, req.query.segment, searchFields, (err, data, total, filteredTotal) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return res.json({
|
return res.json({
|
||||||
error: err.message || err,
|
error: err.message || err,
|
||||||
|
|
|
@ -205,9 +205,9 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{#if statusColored }}
|
|
||||||
<script>
|
<script>
|
||||||
(function(){
|
(function(){
|
||||||
|
{{#if statusColored }}
|
||||||
function updateSubscribersRows () {
|
function updateSubscribersRows () {
|
||||||
$('.dataTable thead tr').removeClass('highlight');
|
$('.dataTable thead tr').removeClass('highlight');
|
||||||
if ($(document).scrollTop() > 400) {
|
if ($(document).scrollTop() > 400) {
|
||||||
|
@ -219,8 +219,8 @@
|
||||||
for (i = 0; i < 5; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
$('.dataTable tr:has(span.subscriber-status-' + i + ')').addClass('subscriber-status-' + i);
|
$('.dataTable tr:has(span.subscriber-status-' + i + ')').addClass('subscriber-status-' + i);
|
||||||
}
|
}
|
||||||
$(window).trigger('resize');
|
|
||||||
}
|
}
|
||||||
|
{{/if}}
|
||||||
function updateTableWidth () {
|
function updateTableWidth () {
|
||||||
var container = $('.container');
|
var container = $('.container');
|
||||||
var containerWidth = container.width();
|
var containerWidth = container.width();
|
||||||
|
@ -230,13 +230,56 @@
|
||||||
container.css({ width: 'auto', 'max-width': tableWidth + 100 + 'px' });
|
container.css({ width: 'auto', 'max-width': tableWidth + 100 + 'px' });
|
||||||
$(window).off('resize', updateTableWidth);
|
$(window).off('resize', updateTableWidth);
|
||||||
}
|
}
|
||||||
|
$(window).trigger('resize');
|
||||||
|
}
|
||||||
|
|
||||||
|
function StatusSelector () {
|
||||||
|
var slt = document.createElement('select');
|
||||||
|
slt.name = 'status';
|
||||||
|
slt.classList = 'form-control input-sm';
|
||||||
|
['', 'Subscribed', 'Unsubscribed', 'Bounced', 'Complained'].forEach(function(s) {
|
||||||
|
var opt = document.createElement('option');
|
||||||
|
opt.value = s.toLowerCase();
|
||||||
|
opt.textContent = s || '{{#translate}}All Status{{/translate}}';
|
||||||
|
slt.appendChild(opt);
|
||||||
|
});
|
||||||
|
return slt;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function (event) {
|
document.addEventListener("DOMContentLoaded", function (event) {
|
||||||
|
var dataTable = $('.data-table-ajax').dataTable();
|
||||||
|
dataTable.on('init.dt', function() {
|
||||||
|
var statusSelect = new StatusSelector();
|
||||||
|
$('.dataTables_filter').append(' ').append(statusSelect);
|
||||||
|
$(statusSelect).on('change', function () {
|
||||||
|
dataTable.api().search($(this).val()).draw();
|
||||||
|
});
|
||||||
|
$('input[type=search]', '.dataTables_filter').on('focus', function(){
|
||||||
|
if ($(statusSelect).val().length) {
|
||||||
|
$(this).val('');
|
||||||
|
$(statusSelect).val('').change();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
updateTableWidth();
|
||||||
|
});
|
||||||
|
|
||||||
|
{{#if statusColored }}
|
||||||
|
dataTable.on('draw.dt', updateSubscribersRows);
|
||||||
updateSubscribersRows();
|
updateSubscribersRows();
|
||||||
$('body').on('DOMSubtreeModified', '.dataTables_info', updateSubscribersRows);
|
{{/if}}
|
||||||
$(window).resize(updateTableWidth);
|
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
|
{{!-- <form id="statusFilters" class="form-inline">
|
||||||
|
<div class="form-group">
|
||||||
|
<select name="status" class="form-control input-sm">
|
||||||
|
<option value="">{{#translate}}Status{{/translate}}</option>
|
||||||
|
<option value="subscribed">{{#translate}}Subscribed{{/translate}}</option>
|
||||||
|
<option value="unsubscribed">{{#translate}}Unsubscribed{{/translate}}</option>
|
||||||
|
<option value="bounced">{{#translate}}Bounced{{/translate}}</option>
|
||||||
|
<option value="complained">{{#translate}}Complained{{/translate}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</form> --}}
|
Loading…
Add table
Add a link
Reference in a new issue