How to make all or few of the choices are selected by default - sonata-admin

Sonata admin $formMapper choice: How to make all or few of the choices are selected / checked by default.
/**
* #param FormMapper $formMapper
*/
protected function configureFormFields(FormMapper $formMapper)
{
$denominationsList = array(10, 20, 30, 40);
$formMapper->add('denominations', 'choice', array(
'choices' => array($denominationsList),
'multiple' => true,
'expanded' => true
));
}

Finally, I found the answer.
/**
* #param FormMapper $formMapper
*/
protected function configureFormFields(FormMapper $formMapper)
{
$denominationsList = array(10, 20, 30, 40);
$selectedDenominations = array(0, 1, 2, 3);
$formMapper->add('denominations', 'choice', array(
'choices' => array($denominationsList),
'multiple' => true,
'expanded' => true,
'data' => $selectedDenominations
));
}
Note In 'data' we have to give the index of the selected value. Let us say if i want to only the few values to be selected then we have to pass those values indexes. From the above example if i want 10, 40 as selected the then we have to prepare $selectedDenominations is like array(0, 3).

Related

BelongsToMany retrieving and deleting correctly, not updating/saving in CakePHP 3.x

CakePHP 3.8.13 - I have a table model which CAN retrieve the related data from a table and remove it, but when updating/adding an entry, it does not change this data for some reason. So it seems like a correct setup, yet it does not update/add them. In short, it's a "Questions" table and a "Divisions" table, with a relation table called "questions_divisions". In this relation table there is a question_id and a division_id column. If I manually add or remove entries there, it all seems OK. Just when doing patchEntity and save, it does not do it. This is the post data:
'name' => string 'Some name' (length=8)
'questiontype_id' => string '1' (length=1)
'extra' => string '' (length=0)
'answer' => string '' (length=0)
'datafield' => string 'Person.firstname' (length=16)
'divisions' =>
array (size=1)
'_ids' =>
array (size=3)
0 => string '1' (length=1)
1 => string '7' (length=1)
2 => string '5' (length=1)
This is the code that is executed (so the above post data, is $this->request->getData()):
$question = $this->Questions->patchEntity($question, $this->request->getData());
if ($this->Questions->save($question)) {
All this is more or less the same that's happening elsewhere in the application for a different model, which actually DOES add/update the divisions. I also cleared the /tmp/cache just in case, didn't seem to do the trick. I'm at a loss here.
This is the whole table model:
<?php
namespace App\Model\Table;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
/**
* Questions Model
*
* #property \App\Model\Table\QuestiontypesTable|\Cake\ORM\Association\BelongsTo $Questiontypes
* #property \App\Model\Table\ActivitiesTable|\Cake\ORM\Association\BelongsToMany $Activities
* #property \App\Model\Table\BookingformsTable|\Cake\ORM\Association\BelongsToMany $Bookingforms
* #property \App\Model\Table\DivisionsTable|\Cake\ORM\Association\BelongsToMany $Divisions
*
* #method \App\Model\Entity\Question get($primaryKey, $options = [])
* #method \App\Model\Entity\Question newEntity($data = null, array $options = [])
* #method \App\Model\Entity\Question[] newEntities(array $data, array $options = [])
* #method \App\Model\Entity\Question|bool save(\Cake\Datasource\EntityInterface $entity, $options = [])
* #method \App\Model\Entity\Question|bool saveOrFail(\Cake\Datasource\EntityInterface $entity, $options = [])
* #method \App\Model\Entity\Question patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
* #method \App\Model\Entity\Question[] patchEntities($entities, array $data, array $options = [])
* #method \App\Model\Entity\Question findOrCreate($search, callable $callback = null, $options = [])
*/
class QuestionsTable extends Table {
public function beforeFind ($event, $query, $options, $primary) {
$order = $query->clause('order');
if ($order === null || !count($order)) {
$query->order([$this->getAlias() . '.name' => 'ASC']);
}
}
/**
* Initialize method
*
* #param array $config The configuration for the Table.
* #return void
*/
public function initialize(array $config) {
parent::initialize($config);
$this->setTable('questions');
$this->setDisplayField('name');
$this->setPrimaryKey('id');
$this->addBehavior('Search.Search');
$this->addBehavior('Page');
$this->hasMany('Questions_divisions', [
'foreignKey' => 'question_id'
]);
$this->belongsTo('Questiontypes', [
'foreignKey' => 'questiontype_id',
'joinType' => 'INNER'
]);
$this->belongsToMany('Activities', [
'foreignKey' => 'question_id',
'targetForeignKey' => 'activity_id',
'joinTable' => 'activities_questions'
]);
$this->belongsToMany('Bookingforms', [
'foreignKey' => 'questions_id',
'targetForeignKey' => 'bookingforms_id',
'joinTable' => 'questions_bookingforms'
]);
$this->belongsToMany('Divisions', [
'foreignKey' => 'question_id',
'targetForeignKey' => 'division_id',
'joinTable' => 'questions_divisions'
]);
//Setup searchfield
$this->behaviors()->Page->searchSetup($this->behaviors()->Search->searchManager(), $this->searchForm());
}
/**
* Default validation rules.
*
* #param \Cake\Validation\Validator $validator Validator instance.
* #return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator) {
$validator
->integer('id')
->allowEmpty('id', 'create');
$validator
->scalar('name')
->maxLength('name', 500)
->requirePresence('name', 'create')
->notEmpty('name');
$validator
->scalar('extra')
->maxLength('extra', 500)
->allowEmpty('extra');
$validator
->scalar('answer')
->maxLength('answer', 1500)
->allowEmpty('answer');
$validator
->scalar('datafield')
->maxLength('datafield', 500)
->requirePresence('datafield', 'create')
->notEmpty('datafield');
return $validator;
}
/**
* Returns a rules checker object that will be used for validating
* application integrity.
*
* #param \Cake\ORM\RulesChecker $rules The rules object to be modified.
* #return \Cake\ORM\RulesChecker
*/
public function buildRules(RulesChecker $rules) {
$rules->add($rules->existsIn(['questiontype_id'], 'Questiontypes'));
return $rules;
}
/**
* Returns an array which describes the search form
*
* #return Array with search setup
*/
public function searchForm() {
//Set up search form
$search_data = [['id' => 'name', 'label' => 'Naam', 'type' => 'textfield', 'fields' => ['name']],
['id' => 'Questiontypes_id', 'label' => 'Vraagtype', 'type' => 'multiselect', 'fields' => ['Questiontypes.id'], 'options' => $this->Questiontypes->find('list')],
['id' => 'datafield', 'label' => 'Dataveld', 'type' => 'textfield', 'fields' => ['datafield']]
];
return $search_data;
}
}
Seems like adding this column in the $_accessible array (inside the Model/Entity) does the trick... That's why it could retrieve the data, but not edit it - hence "accessible" maybe? Not sure if that's the correct name for it but hey..
protected $_accessible = [
'name' => true,
'extra' => true,
'answer' => true,
'datafield' => true,
'questiontype_id' => true,
'questiontype' => true,
'activities' => true,
'bookingforms' => true,
'divisions' => true // this did the trick!
];

How to Build Multi-step Forms with Preview data fill page in drupal 8?

many days I working on drupal 8 custom form module which is the multi-step form I have complete this using SessionManagerInterface that's work fine but I want to display all data in one page before submit how can I achieve this .here I include snapshot here
demo.routing.yml
demo.multistep_one:
path: '/demo/multistep-one'
defaults:
_form: '\Drupal\demo\Form\Multistep\MultistepOneForm'
_title: 'First form'
requirements:
_permission: 'access content'
demo.multistep_two:
path: '/demo/multistep-two'
defaults:
_form: '\Drupal\demo\Form\Multistep\MultistepTwoForm'
_title: 'Second form'
requirements:
_permission: 'access content'ent'
MultistepFormBase.php
namespace Drupal\demo\Form\Multistep;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Session\SessionManagerInterface;
use Drupal\user\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
abstract class MultistepFormBase extends FormBase {
/**
* #var \Drupal\user\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
/**
* #var \Drupal\Core\Session\SessionManagerInterface
*/
private $sessionManager;
/**
* #var \Drupal\Core\Session\AccountInterface
*/
private $currentUser;
/**
* #var \Drupal\user\PrivateTempStore
*/
protected $store;
/**
* Constructs a \Drupal\demo\Form\Multistep\MultistepFormBase.
*
* #param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
* #param \Drupal\Core\Session\SessionManagerInterface $session_manager
* #param \Drupal\Core\Session\AccountInterface $current_user
*/
public function __construct(PrivateTempStoreFactory $temp_store_factory, SessionManagerInterface $session_manager, AccountInterface $current_user) {
$this->tempStoreFactory = $temp_store_factory;
$this->sessionManager = $session_manager;
$this->currentUser = $current_user;
$this->store = $this->tempStoreFactory->get('multistep_data');
}
/**
* {#inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('user.private_tempstore'),
$container->get('session_manager'),
$container->get('current_user')
);
}
/**
* {#inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
// Start a manual session for anonymous users.
if ($this->currentUser->isAnonymous() && !isset($_SESSION['multistep_form_holds_session'])) {
$_SESSION['multistep_form_holds_session'] = true;
$this->sessionManager->start();
}
$form = array();
$form['actions']['#type'] = 'actions';
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => $this->t('Submit'),
'#button_type' => 'primary',
'#attributes' => array(
'class' => array(
'btn btn-register'
),
),
);
return $form;
}
MultistepOneForm.php which child form
namespace Drupal\demo\Form\Multistep;
use Drupal\Core\Form\FormStateInterface;
class MultistepOneForm extends MultistepFormBase {
/**
* {#inheritdoc}.
*/
public function getFormId() {
return 'multistep_form_one';
}
/**
* {#inheritdoc}.
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
$form['fname'] = array(
'#type' => 'textfield',
'#title' => $this->t('Your name'),
'#default_value' => $this->store->get('fname') ? $this->store->get('fname') : '',
'#attributes' => array(
'class' => array(
'form-control'
),
),
);
$form['lname'] = array(
'#type' => 'textfield',
'#title' => $this->t('Your Last Name'),
'#default_value' => $this->store->get('lname') ? $this->store->get('lname') : '',
'#attributes' => array(
'class' => array(
'form-control'
),
),
$form['actions']['submit']['#value'] = $this->t('Continue');
return $form;
}
/**
* {#inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->store->set('fname', $form_state->getValue('fname'));
$this->store->set('lname', $form_state->getValue('lname'));
$form_state->setRedirect('demo.multistep_two');
}
}
MultistepTwoForm.php
namespace Drupal\demo\Form\Multistep;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
class MultistepTwoForm extends MultistepFormBase {
/**
* {#inheritdoc}.
*/
public function getFormId() {
return 'multistep_form_two';
}
/**
* {#inheritdoc}.
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
$form['jfname'] = array(
'#type' => 'textfield',
'#title' => $this->t('Joint Account Holder First Name'),
'#attributes' => array(
'class' => array(
'form-control'
),
),
);
$form['jlname'] = array(
'#type' => 'textfield',
'#title' => $this->t('Joint Account Holder Last Name'),
'#attributes' => array(
'class' => array(
'form-control'
),
),
);
$form['actions']['previous'] = array(
'#type' => 'link',
'#title' => $this->t('Previous'),
'#url' => Url::fromRoute('demo.multistep_one'),
'#suffix' => '</div>',
'#attributes' => array(
'class' => array(
'btn btn-register'
),
),
);
$form['actions']['submit']['#value'] = $this->t('Continue');
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->store->set('jfname', $form_state->getValue('jfname'));
$this->store->set('jlname', $form_state->getValue('jlname'));
// $form_state->setRedirect('demo.multistep_three');
}
}
here my concern is raised How to display all data according to my snapshot.what action needs to be taken display data. one thing is that i have 3 month experience about drupal so can't take decision what i will do? this code is example of www.sitepoint.com and I take form three and session data is display in label whether it good or not i don't know give me direction appropriate
thanks in advance
In your setup, you are submitting the multiform in MultistepTwoForm.
Change this as follows:
Build one more form: MultiStepPreview. This will hold your preview.
Do Not submit the form in MultistepTwoForm but redirect the form to MultiStepPreview using $form_state->setRedirect()
In MultiStepPreview:
read the keys in the store
build a form element containing the preview (I made a html table to contain the preview)
submit the form.
class OverviewForm extends MultiStepFormBase {
public function buildForm(array $form, FormStateInterface $form_state) {
// get data from the store
$your_details = $this->store->get('your_details');
$order = $this->store->get('order_details');
// make a HTML table containing the data in store
$markup = '<table>';
// loop through $your_details and $your_order and put them in $markup
$form = parent::buildForm($form, $form_state);
$form['preview'] = [
'#markup' => $markup,
];
//in my setup all the buttons are build by MultiStepFormBase
return $form;
}
}

Tried to use TinyMce in cakephp but it is not working

I tried to use the TinyMce plugin in cakephp but the editor is not loading but the helpers are. Even after extracting the files to the plugins folder and adding the codes in bootstrap.php file its not working.
Helper:
<?php
App::uses('AppHelper', 'View/Helper');
class TinymceHelper extends AppHelper {
// Take advantage of other helpers
public $helpers = array('Js', 'Html', 'Form');
// Check if the tiny_mce.js file has been added or not
public $_script = false;
/**
* Adds the tiny_mce.js file and constructs the options
*
* #param string $fieldName Name of a field, like this "Modelname.fieldname"
* #param array $tinyoptions Array of TinyMCE attributes for this textarea
* #return string JavaScript code to initialise the TinyMCE area
*/
function _build($fieldName, $tinyoptions = array()){
if(!$this->_script){
// We don't want to add this every time, it's only needed once
$this->_script = true;
$this->Html->script('tiny_mce/tiny_mce', array('inline' => false));
}
// Ties the options to the field
$tinyoptions['mode'] = 'exact';
$tinyoptions['elements'] = $this->domId($fieldName);
// List the keys having a function
$value_arr = array();
$replace_keys = array();
foreach($tinyoptions as $key => &$value){
// Checks if the value starts with 'function ('
if(strpos($value, 'function(') === 0){
$value_arr[] = $value;
$value = '%' . $key . '%';
$replace_keys[] = '"' . $value . '"';
}
}
// Encode the array in json
$json = $this->Js->object($tinyoptions);
// Replace the functions
$json = str_replace($replace_keys, $value_arr, $json);
$this->Html->scriptStart(array('inline' => false));
echo 'tinyMCE.init(' . $json . ');';
$this->Html->scriptEnd();
}
/**
* Creates a TinyMCE textarea.
*
* #param string $fieldName Name of a field, like this "Modelname.fieldname"
* #param array $options Array of HTML attributes.
* #param array $tinyoptions Array of TinyMCE attributes for this textarea
* #param string $preset
* #return string An HTML textarea element with TinyMCE
*/
function textarea($fieldName, $options = array(), $tinyoptions = array(), $preset = null){
// If a preset is defined
if(!empty($preset)){
$preset_options = $this->preset($preset);
// If $preset_options && $tinyoptions are an array
if(is_array($preset_options) && is_array($tinyoptions)){
$tinyoptions = array_merge($preset_options, $tinyoptions);
}else{
$tinyoptions = $preset_options;
}
}
return $this->Form->textarea($fieldName, $options) . $this->_build($fieldName, $tinyoptions);
}
/**
* Creates a TinyMCE textarea.
*
* #param string $fieldName Name of a field, like this "Modelname.fieldname"
* #param array $options Array of HTML attributes.
* #param array $tinyoptions Array of TinyMCE attributes for this textarea
* #return string An HTML textarea element with TinyMCE
*/
function input($fieldName, $options = array(), $tinyoptions = array(), $preset = null){
// If a preset is defined
if(!empty($preset)){
$preset_options = $this->preset($preset);
// If $preset_options && $tinyoptions are an array
if(is_array($preset_options) && is_array($tinyoptions)){
$tinyoptions = array_merge($preset_options, $tinyoptions);
}else{
$tinyoptions = $preset_options;
}
}
$options['type'] = 'textarea';
return $this->Form->input($fieldName, $options) . $this->_build($fieldName, $tinyoptions);
}
/**
* Creates a preset for TinyOptions
*
* #param string $name
* #return array
*/
private function preset($name){
// Full Feature
if($name == 'full'){
return array(
'theme' => 'advanced',
'plugins' => 'safari,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template',
'theme_advanced_buttons1' => 'save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,fontselect,fontsizeselect',
'theme_advanced_buttons2' => 'cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor',
'theme_advanced_buttons3' => 'tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen',
'theme_advanced_buttons4' => 'insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak',
'theme_advanced_toolbar_location' => 'top',
'theme_advanced_toolbar_align' => 'left',
'theme_advanced_statusbar_location' => 'bottom',
'theme_advanced_resizing' => true,
'theme_advanced_resize_horizontal' => false,
'convert_fonts_to_spans' => true,
'file_browser_callback' => 'ckfinder_for_tiny_mce'
);
}
// Basic
if($name == 'basic'){
return array(
'theme' => 'advanced',
'plugins' => 'safari,advlink,paste',
'theme_advanced_buttons1' => 'code,|,copy,pastetext,|,bold,italic,underline,|,link,unlink,|,bullist,numlist',
'theme_advanced_buttons2' => '',
'theme_advanced_buttons3' => '',
'theme_advanced_toolbar_location' => 'top',
'theme_advanced_toolbar_align' => 'center',
'theme_advanced_statusbar_location' => 'none',
'theme_advanced_resizing' => false,
'theme_advanced_resize_horizontal' => false,
'convert_fonts_to_spans' => false
);
}
// Simple
if($name == 'simple'){
return array(
'theme' => 'simple',
);
}
// BBCode
if($name == 'bbcode'){
return array(
'theme' => 'advanced',
'plugins' => 'bbcode',
'theme_advanced_buttons1' => 'bold,italic,underline,undo,redo,link,unlink,image,forecolor,styleselect,removeformat,cleanup,code',
'theme_advanced_buttons2' => '',
'theme_advanced_buttons3' => '',
'theme_advanced_toolbar_location' => 'top',
'theme_advanced_toolbar_align' => 'left',
'theme_advanced_styles' => 'Code=codeStyle;Quote=quoteStyle',
'theme_advanced_statusbar_location' => 'bottom',
'theme_advanced_resizing' => true,
'theme_advanced_resize_horizontal' => false,
'entity_encoding' => 'raw',
'add_unload_trigger' => false,
'remove_linebreaks' => false,
'inline_styles' => false
);
}
return null;
}
}
I used the following codes in my view file:
<?php
echo $this->Html->script('/TinyMCE/js/tiny_mce/tiny_mce.js', array(
'inline' => false)); ?>
<script type="text/javascript">
tinyMCE.init({
theme : "advanced",
mode : "textareas",
convert_urls : false,
theme_advanced_buttons1 : "bold,italic,underline,blockquote,separator,strikethrough,justifyleft,justifycenter,justifyright, justifyfull,bullist,numlist,undo,redo,link,unlink",
theme_advanced_buttons2: "",
theme_advanced_buttons3: "",
theme_advanced_buttons4: "",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left"
});
</script>
I added this code in my controller:
public $helpers = array('Tinymce');
I have solved it... I just inserted it manually and the problem was in setting the path to the js file.

Why am I having trouble saving objects to the database in a typo3 extension?

Why won't my user and coupon objects get saved to the database when a new record is created?
I am using typo3 v 4.5.30 and making a little extension (my first) to manage some coupons. When I create a coupon I save the creator (a frontenduser) and it gets saved to the DB correctly. But when I do the same thing for a coupon user that user ( and the coupon ) do not get saved to the db. Consider this code frag which attempts to save the user and the coupon in a usedcoupon table. The usedcoupon table basically just has 2 columns one for the user and one for the coupon.
To get a usedcoupon object I called the objectmanagers create method. The user and coupon objects I already have and look right when I var_dump them. Even when I get them from the usedcoupon object they look ok but they don't get saved to the db even when the new record gets created. This code in in my CouponController in an action method.
$used = $this->objectManager>create('Tx_BpsCoupons_Domain_Model_UsedCoupon');
$used->setCoupon($coupon);
$used->setUser($user);
$used->setGuest("myemail#ddd.com");
$userx = $used->getUser();
$coupx = $used->getCoupon();
/// var_dumps of userx and coupx show good objects
$this->usedCouponRepository->add($used);
//after this I can examine the db and see the new record but the user and coupon fields are empty, and no errors are seen
Thanks
PS here is my TCA from Usedcoupon.php
<?php
if (!defined ('TYPO3_MODE')) {
die ('Access denied.');
}
$TCA['tx_bpscoupon_domain_model_usedcoupon'] = array(
'ctrl' => $TCA['tx_bpscoupon_domain_model_usedcoupon']['ctrl'],
'interface' => array(
'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, user, coupon, guest',
),
'types' => array(
'1' => array('showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, hidden;;1, user, coupon, guest,--div--;LLL:EXT:cms/locallang_ttc.xml:tabs.access,starttime, endtime'),
),
'palettes' => array(
'1' => array('showitem' => ''),
),
'columns' => array(
'sys_language_uid' => array(
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.language',
'config' => array(
'type' => 'select',
'foreign_table' => 'sys_language',
'foreign_table_where' => 'ORDER BY sys_language.title',
'items' => array(
array('LLL:EXT:lang/locallang_general.xml:LGL.allLanguages', -1),
array('LLL:EXT:lang/locallang_general.xml:LGL.default_value', 0)
),
),
),
'l10n_parent' => array(
'displayCond' => 'FIELD:sys_language_uid:>:0',
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.l18n_parent',
'config' => array(
'type' => 'select',
'items' => array(
array('', 0),
),
'foreign_table' => 'tx_bpscoupon_domain_model_usedcoupon',
'foreign_table_where' => 'AND tx_bpscoupon_domain_model_usedcoupon.pid=###CURRENT_PID### AND tx_bpscoupon_domain_model_usedcoupon.sys_language_uid IN (-1,0)',
),
),
'l10n_diffsource' => array(
'config' => array(
'type' => 'passthrough',
),
),
't3ver_label' => array(
'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.versionLabel',
'config' => array(
'type' => 'input',
'size' => 30,
'max' => 255,
)
),
'hidden' => array(
'exclude' => 1,
'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.hidden',
'config' => array(
'type' => 'check',
),
),
'starttime' => array(
'exclude' => 1,
'l10n_mode' => 'mergeIfNotBlank',
'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.starttime',
'config' => array(
'type' => 'input',
'size' => 13,
'max' => 20,
'eval' => 'datetime',
'checkbox' => 0,
'default' => 0,
'range' => array(
'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y'))
),
),
),
'endtime' => array(
'exclude' => 1,
'l10n_mode' => 'mergeIfNotBlank',
'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.endtime',
'config' => array(
'type' => 'input',
'size' => 13,
'max' => 20,
'eval' => 'datetime',
'checkbox' => 0,
'default' => 0,
'range' => array(
'lower' => mktime(0, 0, 0, date('m'), date('d'), date('Y'))
),
),
),
'user' => array(
'exclude' => 0,
'label' => 'LLL:EXT:bpscoupon/Resources/Private/Language/locallang_db.xml:tx_bpscoupon_domain_model_usedcoupon.user',
'config' => array(
'type' => 'select',
'foreign_table' => 'fe_users'
),
),
'coupon' => array(
'exclude' => 0,
'label' => 'LLL:EXT:bpscoupon/Resources/Private/Language/locallang_db.xml:tx_bpscoupon_domain_model_usedcoupon.coupon',
'config' => array(
'type' => 'select',
'foreign_table' => 'tx_bpscoupons_domain_model_coupon'
),
),
'guest' => array(
'exclude' => 0,
'label' => 'LLL:EXT:bpscoupon/Resources/Private/Language/locallang_db.xml:tx_bpscoupon_domain_model_usedcoupon.guest',
'config' => array(
'type' => 'input',
'size' => 30,
'eval' => 'trim'
),
),
),
);
?>
PPS adding usedcoupon model code:
<?php
/***************************************************************
* Copyright notice
*
* (c) 2013 Cory Taylor <cory#bigplayersystems.com>, Big Player Systems
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
/**
*
*
* #package bps_coupons
* #license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3 or later
*
*/
class Tx_BpsCoupons_Domain_Model_UsedCoupon extends Tx_Extbase_DomainObject_AbstractEntity {
/**
* Used By
*
* #var Tx_BpsCoupons_Domain_Model_FrontendUser
*/
protected $user;
/**
* Returns the $user
*
* #return Tx_BpsCoupons_Domain_Model_FrontendUser $user
*/
public function getUser() {
echo "<br/>" . __FUNCTION__ . __LINE__ . " <br/>";
return $this->user;
}
/**
* Sets the $user
*
* #param #param Tx_BpsCoupons_Domain_Model_FrontendUser $user
* #return void
*/
public function setUser(Tx_BpsCoupons_Domain_Model_FrontendUser $user) {
$this->user = $user;
}
/**
* the used coupon
*
* #var Tx_BpsCoupons_Domain_Model_Coupon
*/
protected $coupon;
/**
* Returns the $coupon
*
* #return Tx_BpsCoupons_Domain_Model_Coupon $coupon
*/
public function getCoupon() {
return $this->coupon;
}
/**
* Sets the $coupon
*
* #param #param Tx_BpsCoupons_Domain_Model_Coupon $coupon
* #return void
*/
public function setCoupon(Tx_BpsCoupons_Domain_Model_Coupon $coupon) {
$this->coupon = $coupon;
}
/**
* the guest email
*
* #var string
*/
protected $guest;
/**
* Returns the $guest
*
* #return string $guest
*/
public function getGuest() {
return $this->guest;
}
/**
* Sets the $guest email
*
* #param string $guest
* #return void
*/
public function setGuest( $guest) {
$this->guest = $guest;
}
}
?>
PPPS: I tried adding a basic text field for email addresses but it turns out they don't get saved either. I had thought the issue was that the user and coupon filed were references to rows in other tables but now it turns out that simpler things do not get saved either.
PP PP S: may as well look into my ext_tables file too:
<?php
if (!defined('TYPO3_MODE')) {
die ('Access denied.');
}
Tx_Extbase_Utility_Extension::registerPlugin(
$_EXTKEY,
'Bpscoupons',
'BPS_Coupons'
);
t3lib_extMgm::addStaticFile($_EXTKEY, 'Configuration/TypoScript', 'BPS_Coupons');
t3lib_extMgm::addLLrefForTCAdescr('tx_bpscoupons_domain_model_coupon', 'EXT:bps_coupons/Resources/Private/Language/locallang_csh_tx_bpscoupons_domain_model_coupon.xml');
t3lib_extMgm::allowTableOnStandardPages('tx_bpscoupons_domain_model_coupon');
$TCA['tx_bpscoupons_domain_model_coupon'] = array(
'ctrl' => array(
'title' => 'LLL:EXT:bps_coupons/Resources/Private/Language/locallang_db.xml:tx_bpscoupons_domain_model_coupon',
'label' => 'name',
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'cruser_id' => 'cruser_id',
'dividers2tabs' => TRUE,
'sortby' => 'sorting',
'versioningWS' => 2,
'versioning_followPages' => TRUE,
'origUid' => 't3_origuid',
'languageField' => 'sys_language_uid',
'transOrigPointerField' => 'l10n_parent',
'transOrigDiffSourceField' => 'l10n_diffsource',
'delete' => 'deleted',
'enablecolumns' => array(
'disabled' => 'hidden',
'starttime' => 'starttime',
'endtime' => 'endtime',
),
'searchFields' => 'name,description,expiry,hall,date_created,creator,barcode,',
'dynamicConfigFile' => t3lib_extMgm::extPath($_EXTKEY) . 'Configuration/TCA/Coupon.php',
'iconfile' => t3lib_extMgm::extRelPath($_EXTKEY) . 'Resources/Public/Icons/tx_bpscoupons_domain_model_coupon.gif'
),
);
t3lib_extMgm::addLLrefForTCAdescr('tx_bpscoupons_domain_model_usedcoupon', 'EXT:bpscoupons/Resources/Private/Language/locallang_csh_tx_bpscoupons_domain_model_usedcoupon.xml');
t3lib_extMgm::allowTableOnStandardPages('tx_bpscoupons_domain_model_usedcoupon');
$TCA['tx_bpscoupons_domain_model_usedcoupon'] = array(
'ctrl' => array(
'title' => 'LLL:EXT:bpscoupons/Resources/Private/Language/locallang_db.xml:tx_bpscoupons_domain_model_usedcoupon',
'label' => 'user',
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'cruser_id' => 'cruser_id',
'dividers2tabs' => TRUE,
'versioningWS' => 2,
'versioning_followPages' => TRUE,
'origUid' => 't3_origuid',
'languageField' => 'sys_language_uid',
'transOrigPointerField' => 'l10n_parent',
'transOrigDiffSourceField' => 'l10n_diffsource',
'delete' => 'deleted',
'enablecolumns' => array(
'disabled' => 'hidden',
'starttime' => 'starttime',
'endtime' => 'endtime',
),
'searchFields' => 'user,coupon,guest,',
'dynamicConfigFile' => t3lib_extMgm::extPath($_EXTKEY) . 'Configuration/TCA/Usedcoupon.php',
'iconfile' => t3lib_extMgm::extRelPath($_EXTKEY) . 'Resources/Public/Icons/tx_bpscoupons_domain_model_usedcoupon.gif'
),
);
?>
If that happens, most probably your objects are not persisted. Normally Extbase persists changes to objects after the end of a request. But if you e.g. return your response as JSON and then exit your action, the persistenceManager is not called.
You can persist manually by injecting the persistenceManager to your controller:
/**
* #var Tx_Extbase_Persistence_Manager
*/
protected $persistenceManager;
/**
* #param Tx_Extbase_Persistence_Manager $persistanceManager
* #return void
*/
public function injectPersistenceManager(Tx_Extbase_Persistence_Manager $persistenceManager) {
$this->persistenceManager = $persistenceManager;
}
and then call it after you added the new object:
$persistenceManager->persistAll();
In TYPO3 4.7+, you can use the #inject annotation in the doc comment of $persistenceManager to inject the persistenceManager and don't need the inject function.
If this doesn't solve the problem, maybe there's a problem with your TCA.

Second taxonomy autocomplet depend on first taxonomy autocomplet

Drupal-7
Second taxonomy autocomplet depend on first taxonomy autocomplet.
Add offer:
step 1) Country with autocomplet , City is empty
Country: U
------------USA
City:
step 2) when we select USA then we can use City with autocomplet
Country: USA
City: Be
-------Berkeley
Step 3) but we just insert new item Bexxx
Country: USA
City: Bexxx
Search offer:
Step 1) Country - select USA from the list, City is empty
Country: USA
-----------Germany
City:
Step 2) when we select USA then we have 3 items on the list
Country: USA
City: Berkeley
-------Berlin
-------Bexxxxx
I use Drupal 6, module Hierarchical select and Views. Then in Views I used field with exposed filter.
This is a simple example of dependent fields. Make a simple module named "myajx" and placed this code as it is. Now access through url ie "http://localhost/mypage". Now select a value from first field and you will see only its dependent values are listed in below field.
<?php
/**
* Implementation of hook_menu().
* Registers a form-based page that you can access at "http://localhost/mypage"
*/
function myajx_menu(){
return array(
'mypage' => array(
'title' => 'A page to test ajax',
'page callback' => 'drupal_get_form',
'page arguments' => array('myajx_page'),
'access arguments' => array('access content'),
)
);
}
/**
* A form with a dropdown whose options are dependent on a
* choice made in a previous dropdown.
*
* On changing the first dropdown, the options in the second are updated.
*/
function myajx_page($form, &$form_state) {
// Get the list of options to populate the first dropdown.
$options_first = myajx_first_dropdown_options();
$value_dropdown_first = isset($form_state['values']['dropdown_first']) ? $form_state['values']['dropdown_first'] : key($options_first);
$form['dropdown_first'] = array(
'#type' => 'select',
'#title' => 'First Dropdown',
'#options' => $options_first,
'#default_value' => $value_dropdown_first,
// Bind an ajax callback to the change event (which is the default for the
// select form type) of the first dropdown. It will replace the second
// dropdown when rebuilt
'#ajax' => array(
// When 'event' occurs, Drupal will perform an ajax request in the
// background. Usually the default value is sufficient (eg. change for
// select elements), but valid values include any jQuery event,
// most notably 'mousedown', 'blur', and 'submit'.
'event' => 'change',
'callback' => 'myajx_ajax_callback',
'wrapper' => 'dropdown_second_replace',
),
);
$form['dropdown_second'] = array(
'#type' => 'select',
'#title' => 'Second Dropdown',
'#prefix' => '<div id="dropdown_second_replace">',
'#suffix' => '</div>',
'#options' => myajx_second_dropdown_options($value_dropdown_first),
'#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',
);
return $form;
}
/**
* Selects just the second dropdown to be returned for re-rendering
*
* Since the controlling logic for populating the form is in the form builder
* function, all we do here is select the element and return it to be updated.
*
* #return renderable array (the second dropdown)
*/
function myajx_ajax_callback($form, $form_state) {
return $form['dropdown_second'];
}
/**
* Helper function to populate the first dropdown. This would normally be
* pulling data from the database.
*
* #return array of options
*/
function myajx_first_dropdown_options() {
return array(
'colors' => 'Names of colors',
'cities' => 'Names of cities',
'animals' => 'Names of animals',
);
}
function myajx_second_dropdown_options($key = '') {
$options = array(
'colors' => array(
'red' => 'Red',
'green' => 'Green',
'blue' => 'Blue'
),
'cities' => array(
'paris' => 'Paris, France',
'tokyo' => 'Tokyo, Japan',
'newyork' => 'New York, US'
),
'animals' => array(
'dog' => 'Dog',
'cat' => 'Cat',
'bird' => 'Bird'
),
);
if (isset($options[$key])) {
return $options[$key];
}
else {
return array();
}
}

Resources