How to show a tx_news tag title by id? - typo3

How can I display the title of a tx_news tag in any fluid template if only the id and the pid of the tag is given?

The best option is to use a ViewHelper
<?php
declare(strict_types=1);
namespace Vendor\Package\ViewHelpers;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
class DbViewHelper extends AbstractViewHelper
{
use CompileWithRenderStatic;
/**
* #var bool
*/
protected $escapeOutput = false;
/**
* Initialize arguments
*/
public function initializeArguments(): void
{
$this->registerArgument(
'table',
'string',
'Table (Foreign table)',
true
);
$this->registerArgument(
'id',
'int',
'ID ',
true
);
$this->registerArgument(
'as',
'string',
'This parameter specifies the name of the variable that will be used for the returned ' .
'ViewHelper result.',
true
);
}
/**
* #param array $arguments
* #param \Closure $renderChildrenClosure
* #param RenderingContextInterface $renderingContext
* #return mixed
*/
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
$templateVariableContainer = $renderingContext->getVariableProvider();
$row = BackendUtility::getRecord($arguments['table'], $arguments['id']);
$templateVariableContainer->add($arguments['as'], $row);
$content = $renderChildrenClosure();
$templateVariableContainer->remove($arguments['as']);
return $content;
}
}
And then you can use
<vendor:db table="tx_news_domain_model_tag" id="123" as="tag">
<strong>{tag.title}</strong>
</vendor:db>
Don't forget to register the namespace in the template

You can do something like,
# Add news title if on single view
lib.articleTitle = RECORDS
lib.articleTitle {
if.isTrue.data = 251 # News PID. You can use GP:tx_news_pi1|news if you want
dontCheckPid = 1
tables = tx_news_domain_model_news
source.data = 251 # News PID. You can use GP:tx_news_pi1|news if you want
source.intval = 1
conf.tx_news_domain_model_news = TEXT
conf.tx_news_domain_model_news {
field = title
htmlSpecialChars = 1
}
wrap = |
}
And call lib object from fluid,
<f:cObject typoscriptObjectPath="lib.articleTitle" />
That's it!

Related

TYPO3 typoscript set includeCSS trough userFunc

I have a site that has a dark theme and light theme set in function of the daylight ...
in my constants i define sunset and sunrise and I have a Class that I reach through userFunc, my class:
<?php
namespace Vendor\Extension\Utility;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
/**
* will return theme class in various instances of the page
*/
class ThemeClass extends ContentObjectRenderer
{
/**
* #var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
*/
public $cObj;
/**
* Returns theme class according to daylight
*
* #var string $content
* #var array $config
* #return string
**/
protected function class($content, array $config = null)
{
// init
$sunRise = $this->cObj->stdWrapValue('sunRise', $config, null);
$sunSet = $this->cObj->stdWrapValue('sunSet', $config, null);
$format = 'h:i a';
$now = date_create_from_format($format, Date($format));
$open = date_create_from_format($format, $sunRise);
$close = date_create_from_format($format, $sunSet);
return $theme = ($now > $open && $now < $close) ? 'light' : 'dark' ;
}
/**
* Returns body tag according to theme
*
* #var string $content
* #var array $config
* #return string
**/
public function bodyTag($content, array $config = null)
{
$theme = $this->class($content, $config);
return '<body class="'.$theme.'">';
}
/**
* Returns css according to theme
*
* #var string $content
* #var array $config
* #return string
**/
public function themeCss($content, array $config = null)
{
$theme = $this->class($content, $config);
return 'EXT:extension/Resources/Public/Css/_'.$theme.'.css">';
}
}
I use the theme overrideing the bodytag like this:
page.bodyTag >
page.bodyTagCObject = USER
page.bodyTagCObject {
userFunc = Vendor\Extension\Utility\ThemeClass->bodyTag
sunRise = {$extension.config.daylight.sunrise}
sunSet = {$extension.config.daylight.sunset}
}
I expected that something similar would work here :
page.includeCSS {
theme.cObject = USER
theme.cObject {
userFunc = Vendor\Extension\Utility\ThemeClass->themeCss
sunRise = {$extension.config.daylight.sunrise}
sunSet = {$extension.config.daylight.sunset}
}
}
but it doesn't work within includeCSS ... I tried a few 'side-steps' of this but cannot get anything to work ...
You could register a USER or USER_INT somewhere in the page object and in you user function get the AssetCollector to register CSS.

TYPO3 set title of fluid page object from extension

I want to set the the page title within my extension, so the current {page} object in the Fluid Templates will also show the set title.
$GLOBALS['TSFE']->altPageTitle = $pageTitle; will only set the <title> tag and has no impact to the {page.title}
My Primary Goal: To show the 'correct' title of a detail page within a breadcrumb.
Any ideas how to manipulate that?
I don't know anything about a {page} object in fluid, so I did it with a ViewHelper similar to the one from here
/**
* A view helper for setting the document title in the <title> tag.
*
* = Examples =
*
* <page.title mode="prepend" glue=" - ">{blog.name}</page.title>
*
* <page.title mode="replace">Something here</page.title>
*
* <h1><page.title mode="append" glue=" | " display="render">Title</page.title></h1>
*
* #license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
*/
class PageTitleViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* #var bool
*/
protected $escapeOutput = false;
/**
* #param string $mode Method for adding the new title to the existing one.
* #param string $glue Glue the new title to the old title with this string.
* #param string $display If render, this tag displays it's children. By default it doesn't display anything.
* #return string Rendered content or blank depending on display mode.
* #author Nathan Lenz <nathan.lenz#organicvalley.coop>
*/
public function render($mode = 'replace', $glue = ' - ', $display = 'none') {
$renderedContent = $this->renderChildren();
$existingTitle = $GLOBALS['TSFE']->page['title'];
if ($mode === 'prepend' && !empty($existingTitle)) {
$newTitle = $renderedContent.$glue.$existingTitle;
} else if ($mode === 'append' && !empty($existingTitle)) {
$newTitle = $existingTitle.$glue.$renderedContent;
} else {
$newTitle = $renderedContent;
}
$GLOBALS['TSFE']->page['title'] = $newTitle;
$GLOBALS['TSFE']->indexedDocTitle = $newTitle;
if ($display === 'render') {
return $renderedContent;
} else {
return '';
}
}
}
For cached pages and plugins this should work:
$GLOBALS['TSFE']->page['title'] = $pageTitle;

news linkhandler (TYPO 8) and detailpage from category

When using the new linkhandler in TYPO3 like the link below:
https://usetypo3.com/linkhandler.html
i only have one parameter for the detail page:
config.recordLinks.tx_news {
typolink {
parameter = {$myConstants.newsDetailPid}
}
}
How can ich change the linkhandler (hook etc.) in order to get the detail page from the news Category (sys category)?
Use the following code:
config.recordLinks.tx_news {
typolink {
parameter.stdWrap.cObject = CONTENT
parameter.stdWrap.cObject {
table = sys_category
select {
pidInList = 100
# pid of category records
max = 1
selectFields = sys_category.single_pid AS detailPid
join = sys_category_record_mm ON sys_category_record_mm.uid_local = sys_category.uid
where = sys_category_record_mm.uid_foreign = { field: uid }
where.insertData = 1
andWhere.stdWrap.intVal = 1
andWhere.stdWrap.stripHtml = 1
}
renderObj = TEXT
renderObj.field = detailPid
renderObj.wrap = |
}
additionalParams.data = field:uid
additionalParams.wrap = &tx_news_pi1[news]=|
useCacheHash = 1
}
}
https://www.clickstorm.de/blog/linkhandler-typo3/
You find the documentation of the linkhandler integration here:
https://docs.typo3.org/typo3cms/extensions/core/8.7/Changelog/8.6/Feature-79626-IntegrateRecordLinkHandler.html
There you can see that you can specify an own class for the handling. No hooks are provided as far as I can see.
This is possible with the next upcoming version of ext:news, see this change for details.
By using the following TypoScript
config.recordLinks.tx_news {
typolink {
# Detail page
parameter.cObject = USER
parameter.cObject {
userFunc = GeorgRinger\News\Service\LinkHandlerTargetPageService->process
news.data = field:uid
# Page used if no detail page is set in the category
fallback = 123
}
additionalParams.data = field:uid
additionalParams.wrap = &tx_news_pi1[controller]=News&tx_news_pi1[action]=detail&tx_news_pi1[news]=|
}
}
and the according userfunc
<?php
declare(strict_types=1);
namespace GeorgRinger\News\Service;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
/**
* This file is part of the "news" Extension for TYPO3 CMS.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*/
class LinkHandlerTargetPageService
{
/** #var ContentObjectRenderer */
public $cObj;
public function process(string $content = '', array $configuration = []): int
{
$fallbackPageId = (int)($configuration['fallback'] ?? 0);
$newsId = (int)$this->cObj->stdWrapValue('news', $configuration, null);
if ($newsId === 0) {
return $fallbackPageId;
}
$singlePid = $this->getSinglePidFromCategory($newsId);
return $singlePid ?: $fallbackPageId;
}
/**
* Obtains a pid for the single view from the category.
*
* #param int $newsId
* #return int
*/
protected function getSinglePidFromCategory(int $newsId): int
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('sys_category');
$categoryRecord = $queryBuilder
->select('title', 'single_pid')
->from('sys_category')
->leftJoin(
'sys_category',
'sys_category_record_mm',
'sys_category_record_mm',
$queryBuilder->expr()->eq('sys_category_record_mm.uid_local', $queryBuilder->quoteIdentifier('sys_category.uid'))
)
->where(
$queryBuilder->expr()->eq('sys_category_record_mm.tablenames', $queryBuilder->createNamedParameter('tx_news_domain_model_news', \PDO::PARAM_STR)),
$queryBuilder->expr()->gt('sys_category.single_pid', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)),
$queryBuilder->expr()->eq('sys_category_record_mm.uid_foreign', $queryBuilder->createNamedParameter($newsId, \PDO::PARAM_INT))
)
->orderBy('sys_category_record_mm.sorting')
->setMaxResults(1)
->execute()->fetch();
return (int)$categoryRecord['single_pid'];
}
}
Of course you can copy the PHP Class to your site package and adopt the namespaces in the TS as well to have it working in your installation

how to add "target lists" to my custom module

i have create a module and named: Custom_module by Developer Tools --> Module Builder
I trired to add "target lists" to Custom_module like module Campaign, but i can not find the way the do that
everyone can help you to find the best way to add "target lists" to my module.
thanks
You Just need to create a custom sub panel in your custom module.
target list is ProspectLists module.
Follow this link to create custom module.
http://shanedowling.com/sugarcrm-7-custom-subpanels
https://developer.sugarcrm.com/2015/05/18/creating-subpanels-with-custom-results-in-sugar-7-5/
1. Create a new link class
This should go into custom/modules//YourNewLink.php and this class will act as the custom functionality that will build your link between the two records.
<?php
/**
* Custom filtered link
*/
class YourNewLink extends Link2
{
/**
* DB
*
* #var DBManager
*/
protected $db;
public function __construct($linkName, $bean, $linkDef = false)
{
$this->focus = $bean;
$this->name = $linkName;
$this->db = DBManagerFactory::getInstance();
if (empty($linkDef)) {
$this->def = $bean->field_defs[$linkName];
} else {
$this->def = $linkDef;
}
}
/**
* Returns false if no relationship was found for this link
*
* #return bool
*/
public function loadedSuccesfully()
{
// this link always loads successfully
return true;
}
/**
* #see Link2::getRelatedModuleName()
*/
public function getRelatedModuleName()
{
return '<Your_Module>';
}
/**
*
* #see Link2::buildJoinSugarQuery()
*/
public function buildJoinSugarQuery($sugar_query, $options = array())
{
$joinParams = array('joinType' => isset($options['joinType']) ? $options['joinType'] : 'INNER');
$jta = 'active_other_invites';
if (!empty($options['joinTableAlias'])) {
$jta = $joinParams['alias'] = $options['joinTableAlias'];
}
$sugar_query->joinRaw($this->getCustomJoin($options), $joinParams);
return $sugar_query->join[$jta];
}
/**
* Builds main join subpanel
* #param string $params
* #return string JOIN clause
*/
protected function getCustomJoin($params = array())
{
$bean_id = $this->db->quoted($this->focus->id);
$sql = " INNER JOIN(";
$sql .= "SELECT id FROM accounts WHERE id={$bean_id}"; // This is essentially a select statement that will return a set of ids that you can match with the existing sugar_query
$sql .= ") accounts_result ON accounts_result.id = sugar_query_table.id";
return $sql;
}
2. Add a new vardef entry for the link field.
For this example, I'm going to create the custom link on the contacts module. So this code goes in custom/Extension/modules/Contacts/Ext/Vardefs/your_field_name.php
<?php
$dictionary["Contact"]["fields"]["your_field_name"] = array(
'name' => 'active_other_invites',
'type' => 'link',
'link_file' => 'custom/modules/<YourModule>/YourNewLink.php',
'link_class' => 'YourNewLink',
'source' => 'non-db',
'vname' => 'LBL_NEW_LINK',
'module' => '<YourModule>',
'link_type' => 'many',
'relationship' => '',
);
3. Add the new link as a subpanel
This goes under custom/Extension/modules/Contacts/Ext/clients/base/layouts/subpanels/your_subpanel_name.php
<?php
$viewdefs['Contacts']['base']['layout']['subpanels']['components'][] = array (
'layout' => 'subpanel',
'label' => 'LBL_NEW_LINK',
'context' =>
array (
'link' => 'your_field_name',
),
);
4. Add the label
Under custom/Extension/modules/Contacts/Ext/Language/en_us.new_link.php
<?php
$mod_strings['LBL_ACTIVE_OTHER_INVITES'] = 'Your New Link';
5. Quick Repair and Rebuild

Ejuicombobox Throwing Undefined Offset Error On Specific Model Attributes

I downloaded the Editable combo box control with Auto-complete and added the extension. I am having problem with patient_id and problem_definition_id attributes of the model. Works fine for problem_duration_id and some other attributes. When I use them for the combo box I receive the following error:
Following is the code that i have used in my view:
$this->widget('ext.combobox.EJuiComboBox', array(
'model' => $PatientProblem,
'attribute' => 'problem_definition_id',
'id'=>'eeed',
'data'=>Yii::app()->cache->get('PATIENT_PROBLEM'),
// options passed to plugin
'assoc'=>true,
'options' => array(
'allowText' => false,),
// Options passed to the text input
'htmlOptions' => array('size' => 6),
));
Following is the my model:
<?php
/**
* This is the model class for table "patient_problem".
*
* The followings are the available columns in table 'patient_problem':
* #property integer $problem_id
* #property integer $problem_definition_id
* #property integer $patient_id
* #property integer $curr_or_history
* #property integer $patient_visit_id
* #property string $problem_notes
* #property string $chronic
* #property string $alert_on_dashboard
* #property integer $problem_duration_id
* #property integer $create_acc_id
* #property integer $create_user_id
* #property string $create_date
* #property integer $create_acc_assign_id
* #property integer $update_acc_id
* #property integer $update_user_id
* #property string $update_date
* #property integer $update_acc_assign_id
*
* The followings are the available model relations:
* #property Patient $patient
* #property ListOfValues $currOrHistory
* #property PatientVisit $patientVisit
* #property ListOfValues $problemDefinition
* #property ListOfValues $problemDuration
*/
class PatientProblem extends CActiveRecord
{
/**
* Returns the static model of the specified AR class.
* #param string $className active record class name.
* #return PatientProblem the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* #return string the associated database table name
*/
public function tableName()
{
return 'patient_problem';
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('problem_definition_id, patient_id, curr_or_history, patient_visit_id, problem_duration_id, create_acc_id, create_user_id, create_acc_assign_id, update_acc_id, update_user_id, update_acc_assign_id', 'numerical', 'integerOnly'=>true),
array('chronic, alert_on_dashboard', 'length', 'max'=>1),
array('problem_notes, problem_reported_date, create_date, update_date', 'safe'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('problem_id, problem_definition_id, patient_id, curr_or_history, patient_visit_id, problem_notes, problem_reported_date, chronic, alert_on_dashboard, problem_duration_id, create_acc_id, create_user_id, create_date, create_acc_assign_id, update_acc_id, update_user_id, update_date, update_acc_assign_id', 'safe', 'on'=>'search'),
);
}
/**
* #return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'patient' => array(self::BELONGS_TO, 'Patient', 'patient_id'),
'currOrHistory' => array(self::BELONGS_TO, 'ListOfValues', 'curr_or_history'),
'patientVisit' => array(self::BELONGS_TO, 'PatientVisit', 'patient_visit_id'),
'problemDefinition' => array(self::BELONGS_TO, 'ListOfValues', 'problem_definition_id'),
'problemDuration' => array(self::BELONGS_TO, 'ListOfValues', 'problem_duration_id'),
);
}
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'problem_id' => 'Problem',
'problem_definition_id' => 'Problem Definition',
'patient_id' => 'Patient',
'curr_or_history' => 'Curr Or History',
'patient_visit_id' => 'Patient Visit',
'problem_notes' => 'Problem Notes',
'problem_reported_date'=>'Report Date',
'chronic' => 'Chronic',
'alert_on_dashboard' => 'Alert On Dashboard',
'problem_duration_id' => 'Problem Duration',
'create_acc_id' => 'Create Acc',
'create_user_id' => 'Create User',
'create_date' => 'Create Date',
'create_acc_assign_id' => 'Create Acc Assign',
'update_acc_id' => 'Update Acc',
'update_user_id' => 'Update User',
'update_date' => 'Update Date',
'update_acc_assign_id' => 'Update Acc Assign',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* #return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('problem_id',$this->problem_id);
$criteria->compare('problem_definition_id',$this->problem_definition_id);
$criteria->compare('patient_id',$this->patient_id);
$criteria->compare('curr_or_history',$this->curr_or_history);
$criteria->compare('patient_visit_id',$this->patient_visit_id);
$criteria->compare('problem_notes',$this->problem_notes,true);
$criteria->compare('problem_reported_date',$this->problem_reported_date,true);
$criteria->compare('chronic',$this->chronic,true);
$criteria->compare('alert_on_dashboard',$this->alert_on_dashboard,true);
$criteria->compare('problem_duration_id',$this->problem_duration_id);
$criteria->compare('create_acc_id',$this->create_acc_id);
$criteria->compare('create_user_id',$this->create_user_id);
$criteria->compare('create_date',$this->create_date,true);
$criteria->compare('create_acc_assign_id',$this->create_acc_assign_id);
$criteria->compare('update_acc_id',$this->update_acc_id);
$criteria->compare('update_user_id',$this->update_user_id);
$criteria->compare('update_date',$this->update_date,true);
$criteria->compare('update_acc_assign_id',$this->update_acc_assign_id);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
/* The code till this line is Gii generated. All the code beyond this point is cutom code. */
public function beforeSave(){
$retval=false;
if ($this->isNewRecord){
//Handling duplicate Entries for Problem in one visit.
$criteria = new CDbCriteria;
$criteria->compare('problem_definition_id', $this->problem_definition_id);
$criteria->compare('patient_id', $this->patient_id);
$criteria->compare('patient_visit_id', $this->patient_visit_id);
$PatientProblem = $this->model()->findAll($criteria);
if (count($PatientProblem)==0){
$retval=true;
$this->setAttribute('create_date',date("Y-m-d H:i:s"));
$this->setAttribute('create_user_id',Yii::app()->user->id);
$this->setAttribute('create_acc_id',Yii::app()->user->assigner_account_id);
$this->setAttribute('create_acc_assign_id',Yii::app()->user->acc_assign_id);
}
else{
$errorMsg='';
$criteria = new CDbCriteria;
$criteria->compare('mCode','VISIT_PROBLEM_EXISTS');
$criteria->compare('mLang',Yii::app()->user->account_lang);
$SysMsgs=SystemMessages::model()->findAll($criteria);
if (count($SysMsgs)>0){
$errorMsg='"'.$this->problemDefinition->group_display_val.'"'.$SysMsgs[0]->mDesc.' Code['.$SysMsgs[0]->mId.']';
}
else{
$errorMsg=$this->problemDefinition->group_display_val.' already recorded.';
}
throw new Exception($errorMsg);
$retval=false;
}
}
else{
$this->setAttribute('update_date',date("Y-m-d H:i:s"));
$this->setAttribute('update_user_id',Yii::app()->user->id);
$this->setAttribute('update_acc_id',Yii::app()->user->assigner_account_id);
$this->setAttribute('update_acc_assign_id',Yii::app()->user->acc_assign_id);
$retval=true;
}
return $retval;
}
public function getProb_def_id(){
return $this->problem_definition_id;
}
public function setProb_def_id($val){
$this->problem_definition_id=$val;
}
public function getProblemFlaged(){
return $this->alert_on_dashboard=='1' ? CHtml::image(Yii::app()->baseUrl .'/images/Flagredicon.png') : '';
}
public function getProblemFlagSrc(){
return $this->alert_on_dashboard=='1' ? Yii::app()->baseUrl .'/images/Flagredicon.png' :'';
}
public function getProblemChronic(){
return $this->chronic=='1' ? CHtml::image(Yii::app()->baseUrl .'/images/tickedS.jpg') : '';
}
public function getProblemDel(){
return '&nbsp<a class="delete" title="Delete" onclick="DeletePatProblem('.$this->problem_id.'); return false; " href="#"><img src="/webapp/assets/50005a14/gridview/delete.png" alt="Delete" /></a>&nbsp<a class="delete" title="Update" onclick="UpdatePatProblem(this,'.$this->problem_id.','.$this->problem_definition_id.','.$this->curr_or_history.',\''.$this->problem_notes.'\','.$this->problem_duration_id.','.$this->chronic.','.$this->alert_on_dashboard.'); return false; " href="#"><img src="/webapp/assets/50005a14/gridview/update.png" alt="Update" /></a>';
}
}
Following is the code of EJuiComboBox.php
<?php
/**
* jQuery combobox Yii extension
*
* Allows selecting a value from a dropdown list or entering in text.
* Also works as an autocomplete for items in the select.
*
* #copyright © Digitick <www.digitick.net> 2011
* #license GNU Lesser General Public License v3.0
* #author Ianaré Sévi
* #author Jacques Basseck
*
*/
Yii::import('zii.widgets.jui.CJuiInputWidget');
/**
* Base class.
*/
class EJuiComboBox extends CJuiInputWidget
{
/**
* #var array the entries that the autocomplete should choose from.
*/
public $data = array();
public $assoc;
/**
* #var string A jQuery selector used to apply the widget to the element(s).
* Use this to have the elements keep their binding when the DOM is manipulated
* by Javascript, ie ajax calls or cloning.
* Can also be useful when there are several elements that share the same settings,
* to cut down on the amount of JS injected into the HTML.
*/
public $scriptSelector;
public $defaultOptions = array('allowText' => true);
protected function setSelector($id, $script, $event=null)
{
if ($this->scriptSelector) {
if (!$event)
$event = 'focusin';
$js = "jQuery('body').delegate('{$this->scriptSelector}','{$event}',function(e){\$(this).{$script}});";
$id = $this->scriptSelector;
}
else
$js = "jQuery('#{$id}').{$script}";
return array($id, $js);
}
public function init()
{
$cs = Yii::app()->getClientScript();
$assets = Yii::app()->getAssetManager()->publish(dirname(__FILE__) . '/assets');
$cs->registerScriptFile($assets . '/jquery.ui.widget.min.js');
$cs->registerScriptFile($assets . '/jquery.ui.combobox.js');
parent::init();
}
/**
* Run this widget.
* This method registers necessary javascript and renders the needed HTML code.
*/
/*
public function run()
{
list($name, $id) = $this->resolveNameID();
if (is_array($this->data) && !empty($this->data)){
$data = array_combine($this->data, $this->data);
array_unshift($data, null);
}
else
$data = array();
echo CHtml::dropDownList(null, null, $data, array('id' => $id . '_select'));
if ($this->hasModel())
echo CHtml::activeTextField($this->model, $this->attribute, $this->htmlOptions);
else
echo CHtml::textField($name, $this->value, $this->htmlOptions);
$this->options = array_merge($this->defaultOptions, $this->options);
$options = CJavaScript::encode($this->options);
$cs = Yii::app()->getClientScript();
$js = "combobox({$options});";
list($id, $js) = $this->setSelector($id, $js);
$cs->registerScript(__CLASS__ . '#' . $id, $js);
}
*/
public function run()
{
list($name, $id) = $this->resolveNameID();
if (is_array($this->data) && !empty($this->data)){
//if $data is not an assoc array make each value its key
if($this->assoc){
$data=$this->data;
}
else{
$data=array_combine($this->data, $this->data);
}
//does the same as array_unshift($data,null) but does not break assoc arrays
$data=array(""=>"")+$data;
}
else
$data = array();
if ($this->hasModel())
echo CHtml::activeDropDownList($this->model,$this->attribute,$data);
else
echo CHtml::dropDownList($name, $this->value, $data);
echo CHtml::textField(null,($this->hasModel()?($data[$this->model->{$this->attribute}]):$data[$this->value]),array('id'=>$id.'_combobox'));
$this->options = array_merge($this->defaultOptions, $this->options);
$options = CJavaScript::encode($this->options);
$cs = Yii::app()->getClientScript();
$js = "combobox({$options});";
list($id, $js) = $this->setSelector($id.'_combobox', $js);
$cs->registerScript(__CLASS__ . '#' . $id, $js);
}
}
Any help would greatly appreciated.
I used to have the same error for EJuiComboBox, too. It happens whenever NO DATA is found to feed the Textfield in the combobox, it is a PHP Error.. I made the following change to the run method of EJuiComboBox to stop it from throwing this PHP error when no data is found
public function run()
{
list($name, $id) = $this->resolveNameID();
if (is_array($this->data) && !empty($this->data)){
//if $data is not an assoc array make each value its key
$data=($this->assoc)?$this->data:array_combine($this->data, $this->data);
//does the same as array_unshift($data,null) but does not break assoc arrays
$data=array(""=>"")+$data;
}
else
$data = array();
if ($data == array()) {
echo "No hay registros";
return;
}
if ($this->hasModel())
echo CHtml::activeDropDownList($this->model,$this->attribute,$data,$this->selectHtmlOptions);
else
echo CHtml::dropDownList($name, $this->value, $data,$this->selectHtmlOptions);
echo CHtml::textField(null,($this->hasModel()?($data[$this->model->{$this->attribute}]):$data[$this->value]),array('id'=>$id.'_combobox'));
$this->options = array_merge($this->defaultOptions, $this->options);
$options = CJavaScript::encode($this->options);
$cs = Yii::app()->getClientScript();
$js = "combobox({$options});";
list($id, $js) = $this->setSelector($id.'_combobox', $js);
$cs->registerScript(__CLASS__ . '#' . $id, $js);
}
Using this method will result in a simple rendering of "No data found!" whenever there are No members in the data for the ComboBox.
I solved the problem. By default, Yii gets the Not Null attribute of a column during runtime from the database, so if a column is marked as Not Null in database, it applies zero (0) as its default value. When "$this->model->{$this->attribute}" was getting executed, it was putting "0" instead of "problem_definition_id" which was throwing error. After making the column to Nullable in database, the error vanished. But since this does not seem a good solution. So after I created the $PatientProblem object, I explicitly set the problem_definition_id to null and it resolved the error.