(towards CRM-19492) Improve whitespace layout
[civicrm-core.git] / templates / CRM / Contact / Form / Merge.tpl
CommitLineData
6a488035
TO
1{*
2 +--------------------------------------------------------------------+
2c4c49ca 3 | CiviCRM version 4.7 |
6a488035 4 +--------------------------------------------------------------------+
2a73d3b0 5 | Copyright CiviCRM LLC (c) 2004-2017 |
6a488035
TO
6 +--------------------------------------------------------------------+
7 | This file is a part of CiviCRM. |
8 | |
9 | CiviCRM is free software; you can copy, modify, and distribute it |
10 | under the terms of the GNU Affero General Public License |
11 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
12 | |
13 | CiviCRM is distributed in the hope that it will be useful, but |
14 | WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
16 | See the GNU Affero General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU Affero General Public |
19 | License and the CiviCRM Licensing Exception along |
20 | with this program; if not, contact CiviCRM LLC |
21 | at info[AT]civicrm[DOT]org. If you have questions about the |
22 | GNU Affero General Public License or the licensing of CiviCRM, |
23 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
24 +--------------------------------------------------------------------+
25*}
26<div class="crm-block crm-form-block crm-contact-merge-form-block">
3bb59daf
AH
27 <div class="help">
28 {ts}Click <strong>Merge</strong> to move data from the Duplicate Contact on the left into the Main Contact. In addition to the contact data (address, phone, email...), you may choose to move all or some of the related activity records (groups, contributions, memberships, etc.).{/ts} {help id="intro"}
29 </div>
ffd39a49 30
ffd39a49
J
31 <div class="message status">
32 <div class="icon inform-icon"></div>
3bb59daf 33 <strong>{ts}WARNING: The duplicate contact record WILL BE DELETED after the merge is complete.{/ts}</strong>
ffd39a49 34 </div>
ffd39a49 35
3bb59daf
AH
36 {if $user}
37 <div class="message status">
38 <div class="icon inform-icon"></div>
39 <strong>{ts 1=$config->userFramework}WARNING: There are %1 user accounts associated with both the original and duplicate contacts. Ensure that the %1 user you want to retain is on the right - if necessary use the 'Flip between original and duplicate contacts.' option at top to swap the positions of the two records before doing the merge.
40 The user record associated with the duplicate contact will not be deleted, but will be unlinked from the associated contact record (which will be deleted).
41 You will need to manually delete that user (click on the link to open the %1 user account in new screen). You may need to give thought to how you handle any content or contents associated with that user.{/ts}</strong>
42 </div>
43 {/if}
44
45 <div class="crm-submit-buttons">
46 {include file="CRM/common/formButtons.tpl" location="top"}
47 </div>
6a488035 48
3bb59daf
AH
49 <div class="action-link">
50 {if $prev}<a href="{$prev}" class="crm-hover-button action-item"><i class="crm-i fa-chevron-left"></i> {ts}Previous{/ts}</a>{/if}
51 {if $next}<a href="{$next}" class="crm-hover-button action-item">{ts}Next{/ts} <i class="crm-i fa-chevron-right"></i></a>{/if}
52 <a href="{$flip}" class="action-item crm-hover-button">
53 <i class="crm-i fa-random"></i>
54 {ts}Flip between original and duplicate contacts.{/ts}
55 </a>
56 </div>
6a488035 57
3bb59daf 58 <div class="action-link">
4e052b22 59 <a href="#" class="action-item crm-hover-button crm-notDuplicate" title={ts}Mark this pair as not a duplicate.{/ts} onClick="processDupes( {$main_cid}, {$other_cid}, 'dupe-nondupe', 'merge-contact', '{$browseUrl}' );return false;">
3bb59daf
AH
60 <i class="crm-i fa-times-circle"></i>
61 {ts}Mark this pair as not a duplicate.{/ts}
62 </a>
63 </div>
6a488035 64
3bb59daf
AH
65 <div class="action-link">
66 <a href="javascript:void(0);" class="action-item crm-hover-button toggle_equal_rows">
67 <i class="crm-i fa-eye-slash"></i>
68 {ts}Show/hide rows with the same data on each contact record.{/ts}
69 </a>
70 </div>
08ef1f91 71
3bb59daf
AH
72 <table class="row-highlight">
73 <tr class="columnheader">
74 <th>&nbsp;</th>
75 <th><a href="{crmURL p='civicrm/contact/view' q="reset=1&cid=$other_cid"}">{$other_name}</a> ({ts}duplicate{/ts})</th>
76 <th>{ts}Mark All{/ts}<br />=={$form.toggleSelect.html} ==&gt;</th>
77 <th><a href="{crmURL p='civicrm/contact/view' q="reset=1&cid=$main_cid"}">{$main_name}</a></th>
78 <th width="300">Add/overwrite?</th>
79 </tr>
eb61dc07 80
3bb59daf 81 {crmAPI var='other_result' entity='Contact' action='get' return="modified_date" id=$other_cid}
3b8dfec6 82
3bb59daf 83 {crmAPI var='main_result' entity='Contact' action='get' return="modified_date" id=$main_cid}
eb61dc07 84
3bb59daf
AH
85 <tr>
86 <td>Last modified</td>
87 <td>{$other_result.values.0.modified_date|crmDate} {if $other_result.values.0.modified_date gt $main_result.values.0.modified_date} (Most recent) {/if}</td>
88 <td></td>
89 <td>{$main_result.values.0.modified_date|crmDate} {if $main_result.values.0.modified_date gt $other_result.values.0.modified_date} (Most recent) {/if}</td>
90 <td></td>
91 </tr>
eb61dc07 92
3bb59daf 93 {foreach from=$rows item=row key=field}
6a488035 94
3bb59daf
AH
95 {if !isset($row.main) && !isset($row.other)}
96 <tr style="background-color: #fff !important; border-bottom:1px solid #ccc !important;" class="no-data">
eb61dc07 97 <td>
3bb59daf 98 <strong>{$row.title}</strong>
eb61dc07 99 </td>
3bb59daf
AH
100 {else}
101 {if $row.main eq $row.other}
102 <tr class="merge-row-equal crm-row-ok {cycle values="odd-row,even-row"}">
103 {else}
104 <tr class="crm-row-error {cycle values="odd-row,even-row"}">
105 {/if}
eb61dc07 106 <td>
3bb59daf 107 {$row.title}
eb61dc07 108 </td>
3bb59daf 109 {/if}
53e45f60 110
3bb59daf
AH
111 {assign var=position value=$field|strrpos:'_'}
112 {assign var=blockId value=$field|substr:$position+1}
113 {assign var=blockName value=$field|substr:14:$position-14}
eb61dc07
J
114
115 <td>
041d6d6b
J
116 {* @TODO check if this is ever an array or a fileName? *}
117 {* This is on one long line for address formatting *}
118 {if $row.title|substr:0:7 == "Address"}<span style="white-space: pre">{else}<span>{/if}{if !is_array($row.other)}{$row.other}{elseif $row.other.fileName}{$row.other.fileName}{else}{', '|implode:$row.other}{/if}</span>
eb61dc07
J
119 </td>
120
3bb59daf
AH
121 <td style='white-space: nowrap'>
122 {if $form.$field}=={$form.$field.html|crmAddClass:"select-row"}==&gt;{/if}
123 </td>
124
125 {* For location blocks *}
126 {if $row.title|substr:0:5 == "Email" OR
127 $row.title|substr:0:7 == "Address" OR
128 $row.title|substr:0:2 == "IM" OR
129 $row.title|substr:0:7 == "Website" OR
130 $row.title|substr:0:5 == "Phone"}
131
132 <td>
86dd5d2e 133
041d6d6b 134 {* This is on one long line for address formatting *}
86dd5d2e 135 {if $row.title|substr:0:7 == "Address"}
136 <span style="white-space: pre" id="main_{$blockName}_{$blockId}">
137 {else}
138 <span id="main_{$blockName}_{$blockId}">
139 {/if}
140
141 {* @TODO check if this is ever an array or a fileName? *}
142 {if !is_array($row.main)}
143 {$row.main}
144 {elseif $row.main.fileName}
145 {$row.main.fileName}
146 {else}
147 {', '|implode:$row.main}
148 {/if}
149
150 </span>
3bb59daf
AH
151 </td>
152
153 <td>
154 {* Display location for fields with locations *}
155 {if $blockName eq 'email' || $blockName eq 'phone' || $blockName eq 'address' || $blockName eq 'im' }
972947a7 156 {$form.location_blocks.$blockName.$blockId.locTypeId.html}&nbsp;
3bb59daf
AH
157 {/if}
158
159 {* Display other_type_id for websites, ims and phones *}
160 {if $blockName eq 'website' || $blockName eq 'im' || $blockName eq 'phone' }
972947a7 161 {$form.location_blocks.$blockName.$blockId.typeTypeId.html}&nbsp;
3bb59daf
AH
162 {/if}
163
164 {* Display the overwrite/add/add new label *}
abd0b852
J
165 <span id="main_{$blockName}_{$blockId}_overwrite" class="location_block_controls">
166
167 <span class="location_primary">
168 {if $row.main && $row.main_is_primary == "1"}Primary{/if}
169 </span>
170
171 <span class="location_block_controls_options">
172 <span class="location_operation_description">
173 {if $row.main}({ts}overwrite{/ts}){else}({ts}add{/ts}){/if}
174 </span>
175 <span style="display: block" class="location_operation_checkbox">
176 {if $row.main && ($blockName eq 'email' || $blockName eq 'phone')}
177 {$form.location_blocks.$blockName.$blockId.operation.html}
041d6d6b 178 {/if}
041d6d6b 179 </span>
abd0b852
J
180 <span style="display: block" class="location_set_other_primary">
181 {if $blockName neq 'website' && (($row.main && $row.main_is_primary != "1") || !$row.main)}
182 {$form.location_blocks.$blockName.$blockId.set_other_primary.html}
183 {/if}
184 </span>
185 </span>
3bb59daf 186 </span>
041d6d6b 187
3bb59daf
AH
188 </td>
189
190 {* For non-location blocks *}
191 {else}
192
193 <td>
3b8dfec6 194 <span>
3bb59daf
AH
195 {if !is_array($row.main)}
196 {$row.main}
197 {elseif $row.main.fileName}
198 {$row.main.fileName}
199 {else}
200 {', '|implode:$row.main}
eb61dc07 201 {/if}
08ef1f91 202 </span>
3bb59daf
AH
203 </td>
204
205 <td>
206 {if isset($row.main) || isset($row.other)}
207 <span>
208 {if $row.main == $row.other}
209 <span class="action_label">({ts}match{/ts})</span><br />
210 {elseif $row.main}
211 <span class="action_label">({ts}overwrite{/ts})</span><br />
212 {else}
213 <span class="action_label">({ts}add{/ts})</span>
214 {/if}
215 </span>
216 {/if}
217 </td>
eb61dc07 218
3bb59daf 219 {/if}
08ef1f91 220
3bb59daf
AH
221 </tr>
222 {/foreach}
6a488035 223
3bb59daf
AH
224 {foreach from=$rel_tables item=params key=paramName}
225 {if $paramName eq 'move_rel_table_users'}
226 <tr class="{cycle values="even-row,odd-row"}">
227 <td><strong>{ts}Move related...{/ts}</strong></td><td>{if $otherUfId}<a target="_blank" href="{$params.other_url}">{$otherUfName}</a></td><td style='white-space: nowrap'>=={$form.$paramName.html|crmAddClass:"select-row"}==&gt;{else}<td style='white-space: nowrap'></td>{/if}</td><td>{if $mainUfId}<a target="_blank" href="{$params.main_url}">{$mainUfName}</a>{/if}</td>
228 <td>({ts}migrate{/ts})</td>
229 </tr>
230 {else}
6a488035 231 <tr class="{cycle values="even-row,odd-row"}">
3bb59daf
AH
232 <td><strong>{ts}Move related...{/ts}</strong></td><td><a href="{$params.other_url}">{$params.title}</a></td><td style='white-space: nowrap'>=={$form.$paramName.html|crmAddClass:"select-row"}==&gt;</td><td><a href="{$params.main_url}">{$params.title}</a>{if $form.operation.$paramName.add.html}&nbsp;{$form.operation.$paramName.add.html}{/if}</td>
233 <td>({ts}migrate{/ts})</td>
234 </tr>
235 {/if}
236 {/foreach}
237 </table>
238 <div class='form-item'>
239 <!--<p>{$form.moveBelongings.html} {$form.moveBelongings.label}</p>-->
240 <!--<p>{$form.deleteOther.html} {$form.deleteOther.label}</p>-->
241 </div>
6a488035 242
3bb59daf
AH
243 <div class="crm-submit-buttons">
244 {include file="CRM/common/formButtons.tpl" location="bottom"}
245 </div>
6a488035
TO
246</div>
247
248{literal}
249<script type="text/javascript">
250
bf43eaac
J
251 var locationBlockInfo = {/literal}{$locationBlockInfo}{literal};
252 var allBlock = {/literal}{$mainLocBlock}{literal};
253
149ae679 254 /**
abd0b852
J
255 * Triggered when a 'location' or 'type' destination is changed, and when
256 * the operation or 'set primary' checkboxes are changed.
86dd5d2e 257 *
149ae679
J
258 * Check to see if the 'main' contact record has a corresponding location
259 * block when the destination of a field is changed. Allow existing location
260 * fields to be overwritten with data from the 'other' contact.
261 *
abd0b852 262 * @param blockName string
149ae679 263 * The name of the entity.
149ae679 264 * @param blockId int
ca792455
J
265 * The block ID being affected.
266 * @param event object
267 * The event that triggered the update.
149ae679 268 */
ca792455 269 function updateMainLocationBlock(blockName, blockId, event) {
06f557c5
J
270
271 // Get type of select list that's been changed (location or type)
abd0b852
J
272 var locTypeId = CRM.$('select#location_blocks_' + blockName + '_' + blockId + '_locTypeId').val();
273 var typeTypeId = CRM.$('select#location_blocks_' + blockName + '_' + blockId + '_typeTypeId').val();
06f557c5 274
34917198 275 // @todo Fix this 'special handling' for websites (no location id)
abd0b852
J
276 if (!locTypeId) {
277 locTypeId = 0;
278 }
34917198 279
bf43eaac 280 // Look for a matching block on the main contact
34917198
J
281 var mainBlockId = 0;
282 var mainBlockDisplay = '';
abd0b852
J
283 var mainBlock = findBlock(blockName, locTypeId, typeTypeId);
284 if (mainBlock != false) {
bf43eaac
J
285 mainBlockDisplay = mainBlock['display'];
286 mainBlockId = mainBlock['id'];
abd0b852
J
287 }
288
289 // Update main location display and id
290 CRM.$("input[name='location_blocks[" + blockName + "][" + blockId + "][mainContactBlockId]']").val(mainBlockId);
291 CRM.$("#main_" + blockName + "_" + blockId).html(mainBlockDisplay);
34917198 292
abd0b852 293 // Update controls area
041d6d6b 294
abd0b852
J
295 // Get the parent block once for speed
296 var this_controls = CRM.$("#main_" + blockName + "_" + blockId + "_overwrite");
297
298 // Update primary label
299 if (mainBlock != false && mainBlock['is_primary'] == '1') {
300 this_controls.find(".location_primary").text('Primary');
301 }
302 else {
303 this_controls.find(".location_primary").text('');
304 }
305
306 // Update operation description
307 var operation_description = "{/literal}{ts}add{/ts}{literal}";
308 var add_new_check_length = this_controls.find(".location_operation_checkbox input:checked").length;
309 if (mainBlock != false) {
310 if (add_new_check_length > 0) {
311 operation_description = "{/literal}{ts}add new{/ts}{literal}";
041d6d6b 312 }
abd0b852
J
313 else {
314 operation_description = "{/literal}{ts}overwrite{/ts}{literal}";
315 }
316 }
317 this_controls.find(".location_operation_description").text("(" + operation_description + ")");
318
319 // Skip if the 'add new' or 'set primary' checkboxes were clicked
320 if (event.target.id.match(/(operation|set_other_primary)/) === null) {
321 // Display 'Add new' checkbox if there is a main block, and this is an
322 // email or phone type.
323 if (mainBlock != false && (blockName == 'email' || blockName == 'phone')) {
324 var op_id = 'location_blocks[' + blockName + '][' + blockId + '][operation]';
325 this_controls.find(".location_operation_checkbox").html(
326 '<input id="' + op_id + '" name="' + op_id + '" type="checkbox" value="1" class="crm-form-checkbox"><label for="' + op_id + '">{/literal}{ts}Add new{/ts}{literal}</label>'
327 );
328 }
329 else {
330 this_controls.find(".location_operation_checkbox").html('');
331 }
332 }
041d6d6b 333
abd0b852
J
334 // Skip if 'set primary' was clicked
335 if (event.target.id.match(/(set_other_primary)/) === null) {
336 // Display 'Set primary' checkbox if applicable
337 if (blockName != 'website' && (mainBlock == false || mainBlock['is_primary'] != "1" || add_new_check_length > 0)) {
338 var prim_id = 'location_blocks[' + blockName + '][' + blockId + '][set_other_primary]';
339 this_controls.find(".location_set_other_primary").html(
340 '<input id="' + prim_id + '" name="' + prim_id + '" type="checkbox" value="1" class="crm-form-checkbox"><label for="' + prim_id + '">{/literal}{ts}Set as primary{/ts}{literal}</label>'
341 );
342 }
343 else {
344 this_controls.find(".location_set_other_primary").html('');
06f557c5 345 }
06f557c5 346 }
204ad1b2 347
06f557c5
J
348 }
349
149ae679
J
350 /**
351 * Look for a matching 'main' contact location block by entity, location and
352 * type
353 *
149ae679
J
354 * @param entName string
355 * The entity name to lookup.
356 * @param locationID int
357 * The location ID to lookup.
358 * @param typeID int
359 * The type ID to lookup.
360 *
361 * @returns boolean|object
362 * Returns false if no match, otherwise an object with the location ID and
363 * display value.
364 */
edf8e092 365 function findBlock(entName, locationID, typeID) {
bf43eaac
J
366 var entityArray = allBlock[entName];
367 var result = false;
368 for (var i = 0; i < entityArray.length; i++) {
369 // Match based on location and type ID, depending on the entity info
370 if (locationBlockInfo[entName]['hasLocation'] == false || locationID == entityArray[i]['location_type_id']) {
371 if (locationBlockInfo[entName]['hasType'] == false || typeID == entityArray[i][locationBlockInfo[entName]['hasType']]) {
372 result = {
373 display: entityArray[i][locationBlockInfo[entName]['displayField']],
041d6d6b
J
374 id: entityArray[i]['id'],
375 is_primary: entityArray[i]['is_primary']
bf43eaac
J
376 };
377 break;
378 }
379 }
380 }
381 return result;
382 }
383
e0aa05fb
J
384 /**
385 * Called when a 'set primary' checkbox is clicked in order to disable any
386 * other 'set primary' checkboxes for blocks of the same entity. So don't let
387 * users try to set two different phone numbers as primary on the form.
ca792455
J
388 *
389 * @param event object
390 * The event that triggered the update
e0aa05fb 391 */
ca792455 392 function updateSetPrimaries(event) {
e0aa05fb
J
393 var nameSplit = event.target.name.split('[');
394 var blockName = nameSplit[1].slice(0, -1);
395 var controls = CRM.$('span.location_block_controls[id^="main_' + blockName + '"]');
396
397 // Enable everything
398 controls.find('input[id$="[set_other_primary]"]:not(:checked)').removeAttr("disabled");
399
400 // If one is checked, disable the others
401 if (controls.find('input[id$="[set_other_primary]"]:checked').length > 0) {
402 controls.find('input[id$="[set_other_primary]"]:not(:checked)').attr("disabled", "disabled");
403 }
404 }
405
ae8f569f 406 CRM.$(function($) {
53e45f60 407
ae8f569f 408 $('table td input.form-checkbox').each(function() {
204ad1b2
J
409 var ele = null;
410 var element = $(this).attr('id').split('_',3);
411
412 switch ( element['1'] ) {
413 case 'addressee':
414 ele = '#' + element['0'] + '_' + element['1'];
415 break;
416
417 case 'email':
418 case 'postal':
419 ele = '#' + element['0'] + '_' + element['1'] + '_' + element['2'];
420 break;
421 }
eb61dc07 422
204ad1b2 423 if( ele ) {
eb61dc07
J
424 $(this).on('click', function() {
425 var val = $(this).prop('checked');
426 $('input' + ele + ', input' + ele + '_custom').prop('checked', val);
427 });
204ad1b2 428 }
6a488035 429 });
53e45f60 430
eb61dc07
J
431 // Show/hide matching data rows
432 $('.toggle_equal_rows').click(function() {
13919cf8 433 $('tr.merge-row-equal').toggle();
6a488035 434 });
53e45f60 435
edf8e092 436 // Call mergeBlock whenever a location type is changed
ca792455 437 $('body').on('change', 'select[id$="locTypeId"],select[id$="typeTypeId"],input[id$="[operation]"],input[id$="[set_other_primary]"]', function(event){
e0aa05fb 438
edf8e092 439 // All the information we need is held in the id, separated by underscores
abd0b852 440 var nameSplit = this.name.split('[');
e0aa05fb 441
edf8e092 442 // Lookup the main value, if any are available
abd0b852 443 if (allBlock[nameSplit[1].slice(0, -1)] != undefined) {
ca792455 444 updateMainLocationBlock(nameSplit[1].slice(0, -1), nameSplit[2].slice(0, -1), event);
edf8e092 445 }
e0aa05fb
J
446
447 // Update all 'set primary' checkboxes
ca792455 448 updateSetPrimaries(event);
e0aa05fb 449
edf8e092
J
450 });
451
ae8f569f 452 });
6a488035
TO
453
454</script>
455{/literal}
456
457{* process the dupe contacts *}
458{include file="CRM/common/dedupe.tpl"}