I am trying to make dynamic 3 dropdown(DD) by #ajax property of drupal 7..
1st DD contains country list(coming from db)
2nd DD contains states list(coming from db)
3re DD contains city list(coming from db)
problem is as i choose country ..my states DD show states accordingly..by how to trigger my states DD so that my city DD also got updated at the same time my state updated..I have to click on states table only then my cities DD changes..
---MY CODE IN FORM_ALTER IS THIS---
$options_first = iripple_classifieds_country_list();
$selected = isset($form_state['values']['country_by_alter']) ? $form_state['values']['country_by_alter']: key($options_first);
$options_first = iripple_classifieds_country_list();
$form['country_by_alter'] = array(
'#type' => 'select',
'#title' => t('Country'),
'#validated' => TRUE,
'#options' => $options_first,
'#weight' => 5,
//'#disabled' =>TRUE,
'#ajax' => array(
'callback' => 'iripple_classifieds_country_callback',
'wrapper' => 'statereplace',
'effect' => 'fade',
// 'event' => 'onload'
),
'#attributes' => array(
// 'onload' => "jQuery('#edit-country-by-alter').trigger('click')"
)
);
$options_second = iripple_classifieds_state_list();
$selected_state = isset($form_state['values']['state_by_alter']) ? $form_state['values']['state_by_alter']: key($options_second);
$form['state_by_alter'] = array (
'#type' => 'select',
'#title' => t('State'),
'#options' => iripple_classifieds_selected_states($selected),
'#default_value' => isset($form_state['values']['state_by_alter']) ? $form_state['values']['state_by_alter']:'',
'#weight' => 7,
'#validated' => TRUE,
'#prefix' => '<div id="statereplace">',
'#suffix' => '</div>',
'#ajax' => array(
'callback' => 'iripple_classifieds_state_callback',
'wrapper' => 'cityreplace',
'event' => 'change'
)
);
$form['city_by_alter'] = array(
'#type' => 'select',
'#title' => t('City'),
'#options' => iripple_classifieds_selected_cities($selected_state),
'#default_value' => isset($form_state['values']['city_by_alter']) ? $form_state['values']['city_by_alter']:'',
'#weight' => 8,
'#validated' => TRUE,
'#prefix' => '<div id="cityreplace">',
'#suffix' => '</div>',
);
From what I have tried in the past, unless you aren't using the field module, the Hierarchial Select module with either your custom module based off the included hs_smallhierarchy or the hs_taxonomy modules/select menus would work for your three level select element.
The hs_taxonomy module has the database calls you would need, otherwise you can just pass the information and use the former. I've search a lot of different sites and this is something I've tried to accomplish for some time. Looking at their code would show you the Javascript you would have to use and process for the second and third select items because as you stated, unless it isn't stated one page load you will run into problems.
I've gotten a 6 Level Ebay Category to change the options correctly, but it won't update $form_state after a certain level.
function ajax_pra_menu() { $items['ajax_pra'] = array(enter code here
'title' => 'ajax Practice',
'page callback' => 'drupal_get_form',
'page arguments' => array('ajax_pra_dependent_dropdown'),
'access callback' => TRUE,enter code here` );
return $items;
}
function ajax_pra_dependent_dropdown($form, &$form_state) { $options_first = _ajax_pra_get_first_dropdown_options();
$options_two = _ajax_pra_get_second_dropdown_options();
$selected = isset($form_state['values']['dropdown_first']) ? $form_state['values']['dropdown_first'] : key($options_first);
$select_two = isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : key($options_two);
$form['dropdown_first'] = array(
'#title' => 'Item',
'#type' => 'select',
'#options' => $options_first,
'#default_value' => $selected,
'#ajax' => array(
'callback' => 'ajax_pra_dependent_dropdown_callback',
'wrapper' => 'dropdown-second-replace'
),
);
$form['dropdown_second'] = array(
'#title' => $options_first[$selected] . ' ' . t('type'),
'#type' => 'select',
'#prefix' => '<div id="dropdown-second-replace">',
'#suffix' => '</div>',
'#options' => _ajax_pra_get_second_dropdown_options($selected),
'#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',
'#ajax' => array(
'callback' => 'ajax_pra_two_dependent_dropdown_callback',
'wrapper' => 'dropdown-third-replace',
),
);
$form['dropdown_third'] = array(
'#title' => $options_two[$select_two] . ' ' . t('third'),
'#type' => 'select',
'#prefix' => '<div id="dropdown-third-replace">',
'#suffix' => '</div>',
'#options' => _ajax_pra_get_third_dropdown_options($select_two),
'#default_value' => isset($form_state['values']['dropdown_third']) ? $form_state['values']['dropdown_third'] : '',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('save'),
);
}
function ajax_pra_dependent_dropdown_callback($form,$form_state)
{
return $form['dropdown_second'];
}
function ajax_pra_two_dependent_dropdown_callback($form,$form_state)
{
return $form['dropdown_third'];
}
function _ajax_pra_get_first_dropdown_options()
{
return drupal_map_assoc(
array(
t('Car'),
t('Bike'),
t('Mobile'),
)
);
}
function _ajax_pra_get_second_dropdown_options($key = ' ')
{
$options = array(
t('Car') => drupal_map_assoc(
array(
t('bmw'),
t('audi'),
)
),
t('Bike') => drupal_map_assoc(
array(
t('honda'),
t('suzuki'),
)
),
t('Mobile') => drupal_map_assoc(
array(
t('nokia'),
t('micro'),
)
),
);
if (isset($options[$key]))
{
return $options[$key];
}
else{
return array();
}
}
function _ajax_pra_get_third_dropdown_options($key = '')
{
$options = array(
t('bmw') => drupal_map_assoc(
array(
t('bmw x3'),
t('bmw x6'),
)
),
t('honda') => drupal_map_assoc(
array(
t('city'),
t('accord'),
)
),
);
if(isset($options[$key]))
{
return $options[$key];
}
else
{
return array();
}
}
Related
I have a form with one field and a submit button with ajax submission option like following -
public function buildForm(array $form, FormStateInterface $form_state, $id = 0)
{
$form['fieldset']['message'] = array(
'#type' => 'textfield',
'#default_value' => "",
'#required' => true,
'#attributes' => array(
'placeholder' => t('write here'),
),
);
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => $this->t('Send'),
'#attributes' => array(
'class' => array(
),
),
'#ajax' => [
'callback' => [$this, 'Ajaxsubmit'],
'event' => 'click']
);
return $form;
}
The ajax function is following -
public function Ajaxsubmit(array $form, FormStateInterface $form_state)
{
$user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());
$db_values = [
"message" => $form_state->getValue("message"),
"date_create" => date("Y-m-d H:i:s"),
];
$save = DbStorage::Insert($db_values);
//$('#mychat_form input').val("");
//$form_state->setValue('content', NULL);
$response = new AjaxResponse();
if ($form_state->hasAnyErrors() || !$save) {
$response->addCommand(new AlertCommand('something wrong!'));
} else {
$message = DbStorage::Get(["id" => $save]);
$send_id = $message->send_id;
$build = [
'#theme' => "chat_view",
'#message' => $message,
'#sender' => $send_id,
'#current_user' => true
];
$ans_text = render($build);
$response->addCommand(new AppendCommand('#mychat', $ans_text));
}
return $response;
}
Here form data submission is working fine. But input data is not cleared after submission. I tried to clear it from my javascript using -
$('#my_form input').val("");
But the problem is my javascript file is called every 3 seconds and the form input is also cleared in every 3 seconds. this is problematic for users. Is there any other way to clear the form input after the ajax submission ? Can i do anything inside Ajaxsubmit function ?
You can use InvokeCommand for doing it.
For e.g: to clear an input value $('#my_form input').val(""); in ajax response
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Ajax\AppendCommand;
:
$form['fieldset']['message'] = array(
'#type' => 'textfield',
'#default_value' => "",
'#required' => true,
'#attributes' => array(
'placeholder' => t('write here'),
'class' => ['custom-class'],
),
);
In Ajax function
:
$build = [
'#theme' => "chat_view",
'#message' => $message,
'#sender' => $send_id,
'#current_user' => true
];
$response->addCommand(new AppendCommand('#mychat', $build));
$response->addCommand(new InvokeCommand('.custom-class', 'val', ['']));
In my symfony application, I use voters to check if users can access some features.
Now, I have a navbar where the menus are displayed or hidden according to those rights.
This navbar alone renders in about 2 seconds. That's a lot added to every page.
If I comment out the render_controller of the navbar, I gain 2 seconds. If I return true at the top of every voter is_granted method, I gain 1.5 seconds.
How can I solve this ? Using cache ? not using voters ? simplifying my voters ? Is it not a best practice to use voters? even if symfony has to check attributes against the list of all attributes?
My navbar generator:
<?php
namespace AppBundle\Menu;
use AppBundle\Application\Core\ExplorerManager;
use AppBundle\Entity\User\Associate;
use AppBundle\Entity\User\Role;
use Symfony\Component\Routing\Router;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use Symfony\Component\Translation\Translator;
class MenuBuilder
{
/**
* #var Router
*/
private $router;
/**
* #var Translator
*/
private $translator;
/**
* #var AuthorizationChecker
*/
private $authorizationChecker;
/**
* #param Router $router
* #param Translator $translator
* #param AuthorizationChecker $authorizationChecker
*/
public function __construct(Router $router, Translator $translator, AuthorizationChecker $authorizationChecker)
{
$this->router = $router;
$this->translator = $translator;
$this->authorizationChecker = $authorizationChecker;
}
public function getFrontendHeaderMenuItems($isAuthenticated)
{
$menuItems = array(
array(
'title' => 'pricing',
'route' => 'cms',
'route_parameters' => array('dir' => 'general', 'page' => 'foodmeup_premium')
),
// array(
// 'title' => 'recipes',
// 'route' => 'explore',
// 'route_parameters' => array('object' => ExplorerManager::RECETTE)
// ),
array(
'title' => 'blog',
'route' => 'explore',
'route_parameters' => array('object' => ExplorerManager::BLOG)
),
array(
'title' => 'contact',
'route' => 'message_foodmeup'
)
);
if (false == $isAuthenticated) {
$menuItems[] = array(
'title' => 'login',
'route' => 'login'
);
}
$menuItems = $this->generateMenuRoutes(
$menuItems,
'frontend_bars',
array()
);
return $menuItems;
}
public function getBackendLeftSidebarMenuItems()
{
$menuItems = array(
array(
'title' => 'dashboard',
'icon' => 'th-large',
'route' => 'dashboard'
),
array(
'title' => 'administration',
'icon' => 'star',
'is_granted' => Role::ROLE_ADMIN,
'children' => array(
array(
'title' => 'dashboard',
'route' => 'admin_dashboard',
),
array(
'title' => 'moderation',
'route' => 'moderate_posts',
),
array(
'title' => 'users',
'route' => 'switch_user',
'is_granted' => Role::ROLE_SUPERADMIN,
),
array(
'title' => 'subscriptions',
'route' => 'grant_partner_subscription',
'is_granted' => Role::ROLE_SUPERADMIN,
)
)
), array(
'title' => 'ingredients',
'icon' => 'flask',
'children' => array(
array(
'title' => 'explore_ingredients',
'route' => 'explore',
'route_parameters' => array('object' => ExplorerManager::CONSOMMABLE)
),
array(
'title' => 'my_ingredients',
'route' => 'user_ingredients_display',
'is_granted' => Associate::READ_INGREDIENT
), array(
'title' => 'create_import',
'route' => 'edit_ingredient',
'is_granted' => Associate::EDIT_INGREDIENT
), array(
'title' => 'stock',
'route' => 'set_ingredient_stock',
'is_granted' => Associate::READ_STOCK,
), array(
'title' => "buying_cost",
'route' => 'parameter_cost',
'is_granted' => Associate::READ_COST,
)
)
), array(
'title' => 'recipes',
'icon' => 'birthday-cake',
'children' => array(
array(
'title' => 'explore_recipes',
'route' => 'explore',
'route_parameters' => array('object' => ExplorerManager::RECETTE)
),
array(
'title' => 'my_recipes',
'route' => 'user_recipes_display',
'is_granted' => Associate::READ_RECIPE
), array(
'title' => 'create',
'route' => 'edit_recipe',
'is_granted' => Associate::EDIT_RECIPE
), array(
'title' => 'print',
'route' => 'print_recipes',
'is_granted' => Associate::READ_RECIPE
)
)
), array(
'title' => 'plannings',
'icon' => 'tasks',
'is_granted' => array(Associate::READ_PLANNING, Associate::EDIT_PLANNING, Associate::DELETE_PLANNING),
'children' => array(
array(
'title' => 'my_plannings',
'route' => 'display_plannings',
'is_granted' => Associate::READ_PLANNING
), array(
'title' => 'my_models',
'route' => 'display_plannings',
'route_parameters' => array('isModel' => true),
'is_granted' => Associate::READ_PLANNING
), array(
'title' => 'create_planning',
'route' => 'edit_planning',
'is_granted' => array(Associate::EDIT_PLANNING, Associate::CREATE_MODEL)
)
)
), array(
'title' => 'orders',
'icon' => 'phone',
'is_granted' => array(Associate::READ_ORDER, Associate::EDIT_ORDER, Associate::EDIT_ORDER, Associate::DELETE_ORDER),
'children' => array(
array(
'title' => 'my_orders',
'route' => 'display_planning_orders',
'is_granted' => Associate::READ_ORDER
), array(
'title' => 'automatic_order',
'route' => 'automatic_order',
'is_granted' => Associate::EDIT_ORDER
), array(
'title' => 'edit_order',
'route' => 'edit_order',
'is_granted' => Associate::EDIT_ORDER
)
)
), array(
'title' => 'suppliers',
'icon' => 'truck',
'is_granted' => array(Associate::EDIT_SUPPLIER, Associate::READ_SUPPLIER, Associate::DELETE_SUPPLIER),
'children' => array(
array(
'title' => 'my_suppliers',
'route' => 'display_suppliers',
'is_granted' => Associate::READ_SUPPLIER
), array(
'title' => 'select',
'route' => 'user_supplier_select',
'is_granted' => Associate::EDIT_SUPPLIER
), array(
'title' => 'create',
'route' => 'edit_organization',
'route_parameters' => array('category_slug' => 'fournisseur-de-consommables'),
'is_granted' => Associate::EDIT_SUPPLIER
)
)
), array(
'title' => 'teams',
'icon' => 'users',
'is_granted' => array(Associate::EDIT_TEAM, Associate::READ_TEAM, Associate::DELETE_TEAM, Associate::MANAGE_RIGHTS),
'children' => array(
array(
'title' => 'my_teams',
'route' => 'teams_display',
), array(
'title' => 'worker_parameter',
'route' => 'worker_parameter',
'is_granted' => Associate::EDIT_TEAM,
)
)
)
);
$menuItems = $this->generateMenuRoutes($menuItems, 'backend_bars', array());
return $menuItems;
}
private function generateMenuRoutes(Array $menuItems, $domain, $isGranted)
{
foreach ($menuItems as $key => $menuItem) {
if (array_key_exists('is_granted', $menuItems[$key])) {
$rights = is_array($menuItems[$key]['is_granted']) ? $menuItems[$key]['is_granted'] : array($menuItems[$key]['is_granted']);
$rights = array_map(function ($right) {
return $this->authorizationChecker->isGranted($right);
}, $rights);
if (in_array(true, $rights) == false) {
unset($menuItems[$key]);
continue;
}
}
if (array_key_exists('route', $menuItems[$key])) {
$menuItems[$key]['uri'] = $this->router->generate($menuItems[$key]['route'], array_key_exists('route_parameters', $menuItems[$key]) ? $menuItems[$key]['route_parameters'] : array());
} else {
$menuItems[$key]['uri'] = '#/';
}
$menuItems[$key]['title'] = $this->translator->trans($menuItems[$key]['title'], array(), $domain);
if (array_key_exists('children', $menuItems[$key])) {
$menuItems[$key]['children'] = $this->generateMenuRoutes($menuItems[$key]['children'], $domain, $isGranted);
}
}
return $menuItems;
}
public function extractTitles(Array $menuItems)
{
$titles = array();
foreach ($menuItems as $key => $menuItem) {
$titles[] = $menuItems[$key]['title'];
if (array_key_exists('children', $menuItems[$key])) {
$titles = array_merge($titles, $this->extractTitles($menuItems[$key]['children']));
}
}
return $titles;
}
}
Voters have performance drawbacks. So if you need a higher performance then it's better to use ACL or optimize voters loading, because symfony loops over all voters when each security check is performed.
Lets's suppose you have 30 links in a menu and there are 20 voters. When you check access to all links in 1 loop then symfony will call voters 600 times (the most of them will return Voter::ACCESS_ABSTAIN immediately, but it still takes time and in you case it takes too much time).
Update:
Symfony added voter caching for skipping call unneeded voters if new functions supportsAttribute or supportsType returned false once.
https://symfony.com/blog/new-in-symfony-5-4-faster-security-voters
http://magento.localhost.com/index.php/arithmetic/adminhtml_arithmetic/edit/id/5/key/c03c12d4c338a2e4cdbb93c3d9e511a93401d19b21a13ea77cffda20cac94577/
This is what my link looks like. I am getting all values by the ID, in the edit grid page
there is a section for multiple check boxes. How can I select all the check boxes according to the result array
$fieldset-> addField('st_user_interest', 'checkboxes', array(
'label' => Mage::helper('arithmetic')->__('Interest'),
'required' => true,
'name' => 'st_user_interest[]',
'values' => array(
array(
'label' => Mage::helper('arithmetic')->__('Education'),
'value' => 'education',
'class' => 'required-one',
),
array(
'label' => Mage::helper('arithmetic')->__('Business'),
'value' => 'business',
'class' => 'required-one',
),
array(
'label' => Mage::helper('arithmetic')->__('Marketing'),
'value' => 'marketing',
'class' => 'required-one',
),
array(
'value' => 'investment',
'label' => Mage::helper('arithmetic')->__('Investment'),
'class' => 'required-one',
)
),
));
Thanks
Hi at the time of storing array field value we are storing as string after converting array to string,
So at the time of setValues() Magento looking for that same input field value as array to check the check boxes
Trick is that convert that stored string value into array and assign to that column field that will work
Package_Arithmetic_Block_Adminhtml_Arithmetic_Edit_Tab_Form
protected function _prepareForm()
{
$id = $this->htmlEscape(Mage::registry('arithmetic_data')->getIn_user_id());
$model = Mage::getModel("arithmeti/newuser")->load($id);
/* here is the stuff witch converting the stored string to array and set in st_user_interest */
$interest = $model->getSt_user_interest();
$model->setSt_user_interest(explode(',',$interest));
$form = new Varien_Data_Form();
$this->setForm($form);
$fieldset = $form->addFieldset('arithmetic_form', array('legend'=>Mage::helper('arithmetic')->__('User information')));
$fieldset-> addField('st_user_interest', 'checkboxes', array(
'label' => Mage::helper('arithmetic')->__('Interest'),
'required' => true,
'name' => 'st_user_interest[]',
'values' => array(
array(
'label' => Mage::helper('arithmetic')->__('Education'),
'value' => 'education',
),
array(
'label' => Mage::helper('arithmetic')->__('Business'),
'value' => 'business',
),
array(
'label' => Mage::helper('arithmetic')->__('Marketing'),
'value' => 'marketing',
),
array(
'value' => 'investment',
'label' => Mage::helper('arithmetic')->__('Investment'),
)
),
));
if ( Mage::getSingleton('adminhtml/session')->getArithmeticData() )
{
$form->setValues(Mage::getSingleton('adminhtml/session')->getArithmeticData());
Mage::getSingleton('adminhtml/session')->setArithmeticData(null);
} elseif ( $model->getData() ) {
//Mage::registry('arithmetic_data')->getData(); /* removing this line and adding $model->getData() inslde the $form->setValues() */
$form->setValues($model->getData());
}
return parent::_prepareForm();
}
I have a custom form that creates a new user and fills in a number of custom fields for that user. One of these fields is a custom image (not the system avatar image).
I can get the image uploaded to the server through the form, but can't get it into the appropriate field. Here is my (custom module) code so-far.
function newacc_freebusiness_form($form, &$form_state) {
$form['bussimage'] = array(
'#title' => t('Upload an image that shows off your business.'),
'#type' => 'managed_file',
'#description' => t('Max size of 3Mb and filetype of jpg jpeg or png'),
'#upload_location' => 'public://bussimages/',
'#upload_validators' => array(
'file_validate_extensions' => array('png jpg jpeg'),
'file_validate_size' => array(3*1024*1024),
),
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
);
$form['#validate'][] = 'newacc_freebusiness_validate';
return $form;
}
function newacc_freebusiness_validate($form, &$form_state) {
$bussimage = $form_state['values']['bussimage'];
$file = file_load($bussimage);
$bussimage = image_load($file -> uri);
image_save($bussimage);
$bussimage = image_load($file -> uri);
$edit = array(
'name' => 'name',
'mail' => 'mail#mail.com',
'status' => 0,
'language' => 'en',
'init' => 'mail#mail.com',
'roles' => array(8 => 'Promoter'),
'field_business_image' => array(
'und' => array(
0 => array(
'value' => $bussimage,
),
),
),
);
user_save(NULL, $edit);
}
This is throwing the error message:
Notice: Undefined index: fid in file_field_presave() (line 219 of /var/www/drupal_site/modules/file/file.field.inc).
I have tried so many tricks now and googled so long that I can't even explain what I have and haven't tried anymore!
Any help please.
OK - solved this. The clue was in the error message and the solution was very simple! Here is the code:
function newacc_freebusiness_form($form, &$form_state) {
$form['bussimage'] = array(
'#title' => t('Upload an image that shows off your business.'),
'#type' => 'managed_file',
'#description' => t('Max size of 3Mb and filetype of jpg jpeg or png'),
'#upload_location' => 'public://bussimages/',
'#upload_validators' => array(
'file_validate_extensions' => array('png jpg jpeg'),
'file_validate_size' => array(3*1024*1024),
),
'#required' => TRUE,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
);
$form['#validate'][] = 'newacc_freebusiness_validate';
return $form;
}
function newacc_freebusiness_validate($form, &$form_state) {
$bussimage = $form_state['values']['bussimage'];
$file = file_load($bussimage);
$edit = array(
'name' => 'name',
'mail' => 'mail#mail.com',
'status' => 0,
'language' => 'en',
'init' => 'mail#mail.com',
'roles' => array(8 => 'Promoter'),
'field_business_image' => array(
'und' => array(
0 => array(
'fid' => $file -> fid,
),
),
),
);
user_save(NULL, $edit);
}
All Drupal was looking for was the file fid in the array. Don't know why I initially assumed it had to be more complicated than this.
So I have create my checkbox in my form
$form['existing_customer'] = array(
'#type' => 'checkbox',
'#title' => t('Are you an existing customer'),
'#ajax' => array(
'callback' => 'checkbox_selected',
'wrapper' => 'subject',
),);
This calls my function and changes the values in my checkbox
The problem is I cannot get it to switch back if it is unchecked
function checkbox_selected(&$form, &$form_state) {
if ($form_state['values']['existing_customer'] == 1) {
$my_options = array( 'select' => t('Select'), 'mr' => t('Mr'), 'mrs' => t('Mrs'), 'miss' => t('Miss'), 'ms' =>t('Ms'), 'sir' =>t('Sir'), 'dr' => t('Dr'), 'prof' => t('Prof') );
}
elseif ($form_state['values']['existing_customer'] == 0){
$my_options = array( 'seconfZ' => t('jimmy'), 'mr' => t('Mr'), );
}
$form['subject'] = array(
'#type' => 'select',
'#title' => t('Subject'),
'#options' => $my_options//$form['subject_options']['#value']
);
return $form['subject'];
}
I thought I could do a switch on the checkbox value or state but no joy?
Oftentimes, when you use the Form API #ajax system, the wrapper that you specify is actually replaced with another element AFTER drupal_html_id() has been called again on the element wrapper. So I would check the markup of the "subject" element in Firebug/Web Inspector after your AJAX stuff happens--I'm betting that the wrapper div is now something like "subject--1".
To fix this, you need to manually set a wrapper div on the item you are replacing--one that won't change when the form is rebuilt. For example, in your form builder:
$form['existing_customer'] = array(
'#type' => 'checkbox',
'#title' => t('Are you an existing customer'),
'#ajax' => array(
'callback' => 'checkbox_selected',
'wrapper' => 'subject-wrapper',
),
);
$form['subject'] = array(
'#prefix' => '<div id="subject-wrapper">',
...
`#suffix' => '</div>',
);
Hope that helps!