// Make the contact ID associated with the contribution available at the Class level.
// Also make available to the session.
+ //@todo consider handling this in $this->getContactID();
$this->set('contactID', $contactID);
$this->_contactID = $contactID;
);
$this->addRule("email-{$this->_bltID}", ts('Email is not valid.'), 'email');
$pps = array();
+ $onlinePaymentProcessorEnabled = FALSE;
if (!empty($this->_paymentProcessors)) {
- $pps = $this->_paymentProcessors;
- foreach ($pps as $key => & $name) {
+ foreach ($this->_paymentProcessors as $key => $name) {
+ if($name['billing_mode'] == 1) {
+ $onlinePaymentProcessorEnabled = TRUE;
+ }
$pps[$key] = $name['name'];
}
}
$this->assign('pay_later_text', $this->_values['pay_later_text']);
}
}
+
+ $contactID = $this->getContactID();
+ if($this->getContactID() === '0') {
+ $this->addCidZeroOptions($onlinePaymentProcessorEnabled);
+ }
//build pledge block.
$this->_useForMember = 0;
//don't build membership block when pledge_id is passed
*/
function getContactID() {
$tempID = CRM_Utils_Request::retrieve('cid', 'Positive', $this);
+ if(isset($this->_params) && isset($this->_params['select_contact_id '])) {
+ $tempID = $this->_params['select_contact_id'];
+ }
// force to ignore the authenticated user
if ($tempID === '0') {
return $tempID;
}
- // check if the user is logged in and has a contact ID
- $session = CRM_Core_Session::singleton();
- $userID = $session->get('userID');
+ $userID = $this->getLoggedInUserContactID();
if ($tempID == $userID) {
return $userID;
return $userID;
}
+
+ /**
+ * Get the contact id of the logged in user
+ */
+ function getLoggedInUserContactID() {
+ // check if the user is logged in and has a contact ID
+ $session = CRM_Core_Session::singleton();
+ return $session->get('userID');
+ }
+
+ /**
+ * add autoselector field -if user has permission to view contacts
+ * If adding this to a form you also need to add to the tpl e.g
+ *
+ * {if !empty($selectable)}
+ * <div class="crm-summary-row">
+ * <div class="crm-label">{$form.select_contact.label}</div>
+ * <div class="crm-content">
+ * {$form.select_contact.html}
+ * </div>
+ * </div>
+ * {/if}
+ * @param array $profiles ids of profiles that are on the form (to be autofilled)
+ * @param array $field metadata of field to use as selector including
+ * - name_field
+ * - id_field
+ * - url (for ajax lookup)
+ *
+ * @todo add data attributes so we can deal with multiple instances on a form
+ */
+ function addAutoSelector($profiles = array(), $autoCompleteField = array()) {
+ $autoCompleteField = array_merge(array(
+ 'name_field' => 'select_contact',
+ 'id_field' => 'select_contact_id',
+ 'field_text' => ts('Select Contact'),
+ 'show_hide' => TRUE,
+ 'show_text' => ts('to select someone already in our database'),
+ 'hide_text' => ts('to clear this person and fill the form in for someone else'),
+ 'url' => array('civicrm/ajax/rest', 'className=CRM_Contact_Page_AJAX&fnName=getContactList&json=1'),
+ 'max' => civicrm_api3('setting', 'getvalue', array(
+ 'name' => 'search_autocomplete_count',
+ 'group' => 'Search Preferences',
+ ))
+ ), $autoCompleteField);
+
+ if(0 < (civicrm_api3('contact', 'getcount', array('check_permissions' => 1)))) {
+ $this->addElement('text', $autoCompleteField['name_field'] , $autoCompleteField['field_text']);
+ $this->addElement('hidden', $autoCompleteField['id_field'], '', array('id' => $autoCompleteField['id_field'])); $this->assign('selectable', $autoCompleteField['id_field']);
+
+ CRM_Core_Resources::singleton()->addScriptFile('civicrm', 'templates/CRM/common/AutoComplete.js')
+ ->addSetting(array(
+ 'form' => array('autocompletes' => $autoCompleteField),
+ 'ids' => array('profile' => $profiles),
+ ));
+ }
+ }
+
+ /**
+ * Add the options appropriate to cid = zero - ie. autocomplete
+ *
+ * @todo there is considerable code duplication between the contribution forms & event forms. It is apparent
+ * that small pieces of duplication are not being refactored into separate functions because their only shared parent
+ * is this form. Inserting a class FrontEndForm.php between the contribution & event & this class would allow functions like this
+ * and a dozen other small ones to be refactored into a shared parent with the reduction of much code duplication
+ */
+ function addCIDZeroOptions($onlinePaymentProcessorEnabled) {
+ $this->assign('nocid', TRUE);
+ $profiles = array();
+ if($this->_values['custom_pre_id']) {
+ $profiles[] = $this->_values['custom_pre_id'];
+ }
+ if($this->_values['custom_post_id']) {
+ $profiles[] = $this->_values['custom_post_id'];
+ }
+ if($onlinePaymentProcessorEnabled) {
+ $profiles[] = 'billing';
+ }
+ if(!empty($this->_values)) {
+ $this->addAutoSelector($profiles);
+ }
+ }
}
self::buildAmount($this);
}
- $pps = NULL;
+ $pps = array();
+ //@todo this processor adding fn is another one duplicated on contribute - a shared
+ // common class would make this sort of thing extractable
if (!empty($this->_paymentProcessors)) {
- $pps = $this->_paymentProcessors;
- foreach ($pps as $key => & $name) {
+ foreach ($this->_paymentProcessors as $key => $name) {
+ if($name['billing_mode'] == 1) {
+ $onlinePaymentProcessorEnabled = TRUE;
+ }
$pps[$key] = $name['name'];
}
}
-
+ if($this->getContactID() === '0') {
+ $this->addCidZeroOptions($onlinePaymentProcessorEnabled);
+ }
if (CRM_Utils_Array::value('is_pay_later', $this->_values['event']) &&
($this->_allowConfirmation || (!$this->_requireApproval && !$this->_allowWaitlist))
) {
{/if}
{/if}
-{* Main Form *}
+{* Main Form *}
{else}
{literal}
<script type="text/javascript">
<div id="intro_text" class="crm-section intro_text-section">
{$intro_text}
</div>
+ {include file="CRM/common/cidzero.tpl"}
{if $islifetime or $ispricelifetime }
<div id="help">{ts}You have a current Lifetime Membership which does not need to be renewed.{/ts}</div>
{/if}
{/if}
{include file="CRM/common/TrackingFields.tpl"}
-
{capture assign='reqMark'}<span class="marker" title="{ts}This field is required.{/ts}">*</span>{/capture}
<div class="crm-event-id-{$event.id} crm-block crm-event-register-form-block">
<p>{$event.intro_text}</p>
</div>
{/if}
-
+{include file="CRM/common/cidzero.tpl"}
{if $pcpSupporterText}
<div class="crm-section pcpSupporterText-section">
<div class="content">{$pcpSupporterText}</div>
--- /dev/null
+/**
+ * This is our closure - all of our code goes inside it
+ *
+ * This style of closure is provided by jquery and automatically
+ * waits for document.ready. It also provides us with a local
+ * alias of jQuery as $.
+ *
+ * ES5 specifies that the first line inside our closure
+ * should be 'use strict';
+ */
+/*jslint indent: 2 */
+/*global CRM, cj, ts */
+
+cj(function ($) {
+ 'use strict';
+
+ // Variables declared here will be globally available within this closure
+
+ // Behind the scenes method deals with browser for setting cursor position
+ $.caretTo = function (el, index) {
+ if (el.createTextRange) {
+ var range = el.createTextRange();
+ range.move("character", index);
+ range.select();
+ }
+ else if (el.selectionStart != null) {
+ el.focus();
+ el.setSelectionRange(index, index);
+ }
+ };
+
+ //The following methods are queued under fx for more
+ //flexibility when combining with $.fn.delay() and
+ //jQuery effects.
+
+ //Set caret to a particular index
+ $.fn.caretTo = function (index, offset) {
+ return this.queue(function (next) {
+ if (isNaN(index)) {
+ var i = $(this).val().indexOf(index);
+ if (offset === true) {
+ i += index.length;
+ }
+ else if (offset) {
+ i += offset;
+ }
+ $.caretTo(this, i);
+ }
+ else {
+ $.caretTo(this, index);
+ }
+ next();
+ });
+};
+
+ /**
+ * Display a personalized message containing the contact's name
+ * and a variable from the server
+ */
+ function assignAutoComplete(select_field, id_field, url, varmax, profileids, autocomplete) {
+ if(varmax === undefined) {varmax = 10;}
+ if(profileids === undefined) {profileids = [];}
+
+ if(url === undefined) {
+ url = CRM.url('civicrm/ajax/rest', 'className=CRM_Contact_Page_AJAX&fnName=getContactList&json=1');
+ }
+
+ var customObj = $('#' + select_field);
+ var customIdObj = $('#' + id_field);
+
+ if (!customObj.hasClass('ac_input')) {
+ customObj.autocomplete(url,
+ { width : 250, selectFirst : false, matchContains: true, max: varmax }).result(
+ function (event, data) {
+ customIdObj.val(data[1]);
+ customObj.caretTo(0);
+ var namefields = ['first_name', 'last_name', 'middle_name'];
+ CRM.api('profile', 'get', {'profile_id' : profileids, 'contact_id' : data[1]}, {
+ success: function(result) {
+ $.each(result.values, function (id, values){
+ $.each(values, function (fieldname, fieldvalue) {
+ $('#' + fieldname).val(fieldvalue);
+ });
+ });
+ }
+ });
+ }
+ );
+ customObj.click(function () {
+ customIdObj.val('');
+ });
+ }
+
+ if(autocomplete.show_hide) {
+ customObj.hide();
+ showHideAutoComplete(select_field, id_field,
+ autocomplete.show_text,
+ autocomplete.hide_text,
+ profileids
+ );
+ }
+ }
+
+ /**
+ * Show or hide the autocomplete and change the text
+ */
+ function showHideAutoComplete(name_field, id_field, hidden_text, shown_text, profileids) {
+ $('#crm-contact-toggle-' + id_field).on('click', function(event) {
+ event.preventDefault();
+ $('#' + name_field).toggle();
+ if($('#' + name_field).is(":visible")) {
+ $('#crm-contact-toggle-text-' + id_field).text(shown_text);
+ }
+ else{
+ $('#crm-contact-toggle-text-' + id_field).text(hidden_text);
+ $('#' + id_field).val('');
+ CRM.api('profile', 'get', {'profile_id' : profileids}, {
+ success: function(result) {
+ $.each(result.values, function (id, values){
+ $.each(values, function (fieldname, fieldvalue) {
+ $('#' + fieldname).val(fieldvalue);
+ });
+ });
+ }
+ });
+ }
+
+ });
+ // append(ts("Click") + " <a href='#' id= crm-contact-toggle-" + autocomplete.id_field + ("> " + ts('here') + '</a> ' + ts("to clear this and add a new contact"));
+ }
+
+ var autocompletes = CRM.form.autocompletes;
+ var url = CRM.url(autocompletes.url[0], autocompletes.url[1]);
+
+ $(autocompletes).each(function (index, autocomplete) {
+ assignAutoComplete(autocomplete.name_field, autocomplete.id_field, url, autocomplete.max, CRM.ids.profile, autocomplete);
+ }
+ );
+
+});
+
--- /dev/null
+ <div class="crm-create-relationship-row">
+ {if !empty($nocid)}
+ <span>{ts}You are entering this form on behalf of someone else. Please enter their details.</span>{/ts}
+ {/if}
+ {if !empty($selectable)}
+ {ts} <p> Click <a href=# id='crm-contact-toggle-{$selectable}'>here</a>
+ <span id='crm-contact-toggle-text-{$selectable}'> to select someone already in our database</span></p>{/ts}
+ <span id='crm-contact-toggle-hidden-text-{$selectable}'>
+ </span>
+ <div class="crm-contact-select-row">
+ <div class="crm-content">
+ {$form.select_contact.html}
+ </div>
+ </div>
+ {/if}
+ </div>