Recipe - Better Duplicate Merger
Skill level: Beginner
Organization: Centre Street Church
Requires Rock: 1.12.0
{# strip images & classes from the HTML but otherwise leave structure #}
Our church finds itself using the Duplicate Finder a lot. An issue I had was scanning people's info looking for things like spelling mistakes in emails, etc. Not only did this create human error on my part, but it also took up more time.
I ended up making a simple frontend script that checks and sees if the info matches in the Duplicate Finder table. If it does match, it turns green. It's pretty simple but makes things easier and more accurate.
Installation:
All you have to do is go to your
"Duplicate Finder" > select a potential duplicate > "Person Duplicate Details" > "Block Properties" > "Advanced Settings" > "Pre-HTML" and paste this in there.
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
// Select the header row
const headerRow = document.querySelector(".grid-table.table.table-bordered.table-striped.table-hover > thead > tr:nth-child(2)");
// Find all th elements within the header row
const headerColumns = headerRow.querySelectorAll('th');
let phoneColumnIndex = -1;
let addressColumnIndex = -1; // Initialize address column index
// Iterate over each th element to find the "Phone Numbers" and "Addresses" columns
headerColumns.forEach((th, index) => {
if (th.textContent.trim() === "Phone Numbers") {
phoneColumnIndex = index;
} else if (th.textContent.trim() === "Addresses") {
addressColumnIndex = index; // Set address column index
}
});
console.log("Phone Numbers column index:", phoneColumnIndex);
console.log("Addresses column index:", addressColumnIndex); // Log address column index
// Select the first row (the header row) to compare against
const firstRow = $('.grid-table.table.table-bordered.table-striped.table-hover > tbody > tr:first-child');
// Find the | elements in the first row
const firstRowTds = firstRow.find('td');
// Get the phone numbers from the top row
const topRowPhoneNumbers = firstRowTds.eq(phoneColumnIndex).find('ul.list-unstyled li.phonenumber p').map(function() {
return $(this).text().trim();
}).get();
const topRowAddresses = firstRowTds.eq(addressColumnIndex).find('ul.list-unstyled li.address p').map(function() {
return $(this).text().trim();
}).get();
// Select all | elements except the first one (header row)
const trElements = $('.grid-table.table.table-bordered.table-striped.table-hover > tbody > tr:not(:first-child)');
// For each selected
, find and compare the | elements
trElements.each(function() {
const currentRowTds = $(this).find('td');
// Iterate through the | elements in the current row
currentRowTds.each(function(index) {
// Check if this is the phone number column
if (index === phoneColumnIndex) {
const phoneNumbers = $(this).find('ul.list-unstyled li.phonenumber p'); // Find all phone number paragraphs
// Check if there are any phone numbers in the cell
if (phoneNumbers.length > 0) {
let matchFound = false;
phoneNumbers.each(function() {
const phoneNumber = $(this).text().trim(); // Get the text of the phone number
// Check if the phone number appears anywhere in the top row's phone numbers
if (topRowPhoneNumbers.includes(phoneNumber)) {
matchFound = true;
$(this).css('color', 'green'); // Set the color of the matching phone number to green
} else {
$(this).css('color', 'black'); // Set the color of the non-matching phone number to black
}
});
if (matchFound) {
$(this).css('background-color', '#90ee905c'); // Set the background color to #90ee905c if a match is found
} else {
$(this).css('background-color', 'transparent'); // Reset background color if no match is found
}
}
}
// Check if this is the address column
else if (index === addressColumnIndex) {
const addresses = $(this).find('ul.list-unstyled li.address p'); // Find all address paragraphs
// Check if there are any addresses in the cell
if (addresses.length > 0) {
let matchFound = false;
addresses.each(function() {
const address = $(this).text().trim(); // Get the text of the address
// Check if the address appears anywhere in the top row's addresses
if (topRowAddresses.includes(address)) {
matchFound = true;
$(this).css('color', 'green'); // Set the color of the matching address to green
} else {
$(this).css('color', 'black'); // Set the color of the non-matching address to black
}
});
if (matchFound) {
$(this).css('background-color', '#90ee905c'); // Set the background color to #90ee905c if a match is found
} else {
$(this).css('background-color', 'transparent'); // Reset background color if no match is found
}
}
}
// For other columns
else {
const currentCellText = $(this).text().toLowerCase(); // Convert to lowercase
const firstRowCellText = firstRowTds.eq(index).text().toLowerCase(); // Convert to lowercase
// Check if the first row's cell is not blank and if it doesn't match the current cell
if (firstRowCellText.trim() !== '' && currentCellText !== firstRowCellText) {
$(this).css({
'color': 'red',
'background-color': 'transparent' // Reset background color
});
} else if (firstRowCellText.trim() === '') {
// If the first row's cell is blank, set the text color to black
$(this).css({
'color': 'black',
'background-color': 'transparent' // Reset background color
});
} else {
$(this).css({
'color': 'green',
'background-color': '#90ee905c' // Set background color to #90ee905c
});
}
}
});
});
});
</script>
Additionally, you can add a custom column for when the profile was created.
If you add this to the custom grid options:
{% person where:'Id == "{{ Row.PersonId }}"' %}
{{ person.CreatedDateTime }}
{% endperson %}
Screenshots
- /GetImage.ashx?guid=07f4213d-9023-444f-8729-a11900b1ebd7
|