SugarCRM implementing AJAX calls on Custom Module fields - php

How can I implement AJAX calls to my custom module's one of the field. My requirement is when we change some dropdown, it should check in the database and update the result in another field in same screen.
For normal modules, i See the .tpl files where I can insert script code and call. But for custom modules I didnt see the .tpl files except the cache directory (which are generating runtime).
Is there any method to implement.
I am using Sugar Professional.

Here are the steps you need to follow
Create a .php file which will read the values with query string and process the result as echo/print.
Go to editviewdefs.php in your custom module directory (eg. /custom/modules/...)
Find your field name and call a javascript function
array (
'name' => 'days_required_c',
'label' => 'LBL_DAYS_REQUIRED',
'displayParams' =>
array (
'field' =>
array (
'onChange' => 'setRenewalDate();',
),
),
),
Here RenewalDate is your javascript function name.
Create the script function which will call AJAX functionality like below.
var connectionObject =
YAHOO.util.Connect.asyncRequest ("GET", "getnextnum.php", callback);
YAHOO.util.Event.onContentReady("EditView", function () {
ldelim
}
initEditView(document.forms.EditView);
//alert("Loaded");
//document.getElementById("keyid_c").value = initCall();
{}
);

Related

How to make referenced column sortable in drupal 7 view

I have one view in Drupal 7, which displays user information like (Name, address, Status, etc..). I have one column in this (Table)view as "Published event". Basically events are created by users do I want to make this column sortable. I have attached image for more reference.
I tried with applying relationship but no success.
table settings
my handler code is like below :
$handler->display->display_options['sorts']['event_count_published'] ['id'] = 'event_count_published';
$handler->display->display_options['sorts']['event_count_published'] ['table'] = 'search_api_index_user_search_index';
$handler->display->display_options['sorts']['event_count_published'] ['field'] = 'event_count_published';
$handler->display->display_options['sorts']['event_count_published'] ['order'] = 'DESC';
'mail' => array(
'sortable' => 1,
'default_sort_order' => 'asc',
'align' => '',
'separator' => '',
'empty_column' => 0,
),
'event_count_published' => array(
'align' => '',
'separator' => '',
'empty_column' => 0,
'sortable' => 1,
),
above code is in "tcd_reporting.views_default.inc" file, if I put 'sortable => 1', it still does not provide sorting
field is created by below code:
$properties['event_count_published'] = array(
'label' => t('Published Events'),
'description' => t('Number of published events authored by user.'),
'type' => 'integer',
'getter callback' => 'tcd_event_content_type_count_published_get',
'computed' => TRUE,
'entity views field' => TRUE,
);
[Introduction] Which function is responsible for 'click sort' in views?
Click sort -this checkbox from your second screen- in views table settings is function which is enabled only for fields which have properly defined handlers. As you may know each field in views have few handlers (for displaying, filtering, sorting). And for click sort to be possible on specified column its field handler must have two functions defined: click_sortable and click_sort. First one just need to return true, while second need to properly implements sorting on view. For example see handler: [views_module_path]/handlers/views_handler_field.inc.
Your case:
It seems that your column "Published event" have defined handler which does not have click_sortable and click_sort functions (or click_sortable simply returns false).
Possible fix:
Find place where you defined your view source (it depends on how you informed views about it, if I understand its something like "User info" - maybe in hook_entity_info function or hook_views_data function), check what handler is assigned to your "Published event" field and change it.
It's hard to tell where you need to look as it depends on your implementation.
I suggest you to try create hook_views_data_alter function and dpm() it for start. Later you can alter it like that:
mymodule_views_data_alter(&$data) {
$data['some_view_info']['published_event']['field']['handler'] = 'views_handler_field_numeric';
}
Edit 1
First could you tell where this code is? Is it inside handler class, or maybe some views hook? Views gives you a lot of flexibility but this make them hard to understand, and I'm not sure what exactly you achieve and how.
Assuming your field works properly you can try to simply enable click sort.
Example: I created hook_views_data_alter function to see content of views data
function mymodule_views_data_alter(&$data) {
dpm($data,'d');
}
You might need to clear cache to see dpm of *_alter hooks.
Inside dpm'ed array I found "users" for generic example, and its field name looks like this:
I suggest you to try alter your field with click_sortable = TRUE and see what happens. If this wont help please provide more information about your field, how you created it, how it looks in hook_views_data_alter and which handlers it has defined.
Edit 2
Ok, so you have your views exported to code into views_default file. But this only allows you to export view you created from database to code, so it is basically a reflection of what you done in views web editor (eg. page yourwebsite.com/admin/structure/views/view/your_view_name/edit). What you need to do is to change behavior of one of your fields so it became sortable (add click_sortable and click_sort functions in handler class) or change handler of this field to one with sorting option (change field handler to other one like views_handler_field_numeric). If you don't have experience in creating handlers and this is one of generic handlers i suggest you to go back to my Edit 1, examine your dpm, and try to alter $data array to find solution.
Edit 3
Little explanation to prevent confusion. When creating new view you select collection on which this particular view base on (simpliest example - it may be MySQL table, and view will use SQL queries to retrieve data from it). By digging down we have:
Collection - eg. User which is database table user, it is what you select as source when creating new view.
Field - eg. mail which is database column mail, this fields you add to your view.
Field handler - eg. views_handler_field_numeric, this is class name of handler to use by specified field
Now, if you don't created your own handler then your field "Published event" have one of generic views handler. You shouldn't ever change code of contributed modules - especially so widely used as views handlers. That's why my suggestion to add functions click_sortable and click_sort is incorrect. Instead you should change handler responsible for field "Published event".
Best way is to define proper handler in place where you define your field "Published event". If it's somehow impossible the only way I can think of is hook_views_data_alter see docs for more info and examples. I suppose you should try to redefine handler of your field to generic numeric handler views_handler_field_numeric as it should have full sorting functionallity, or try to add click_sortable property to field array as you can see in first image of my post, but I can't provide you fully tested example.

How do I access the property of a widget

I'm new to the Yii framework and I'm trying to access a property of the of a widget let's say CMenu where I want to change the values of some public properties like activeCssClass, firstItemCssClass, lastItemCssClass, htmlOptions etc. so how do you change the property of a widget in Yii.
Details:
I'm using Yii version 1.1.12 (Aug 19, 2012) and I'm trying to generate a multilevel menu but I need to change the values of some public class parameters and I don't know how?
Well, normally you apply needed values when you call the widget. You set them at the appropriate array inside widget call after widget class name.
$this->widget('zii.widgets.CMenu',
array(
'items' => $items,
'id' => 'main_menu',
'htmlOptions' => array('class' => 'nav'),
'activeCssClass' => 'active',
'firstItemCssClass' => 'first_item'
)
);
BUT! If you want to apply the values after you created some widget, but have not rendered it yet (really rare case) you can do this thing:
$widget = $this->beginWidget('application.components.MyOwnWidget');
$widget->public_property = 'aaa';
$widget->renderSomething();
$this->endWidget();
Adding on the previous answer, in case you missed it, don't forget to check the short and simple official documentation on this.

PHP object or an array

I am writing an app that allows users to modify and change some of their site settings. I am just constructing a form generator that will send various options to variuous plugins to generate the code what I am wondering is whether I should be using objects for this rather than multidimensional arrays? If so how would I change my code?
So right now I have made this- its very long and going to get longer so I have only pasted part of it for the sake of brevity:-
$scopeSettings = array(
'site_background' => array(
'subpanels' => array(
'colour' => array(
'plugins' => array(
'colourchooser' => array(
'tip' => "The background colour appears underneath the 'Background Image' (if set)-hover over the '?' around the colour chooser for extra tips on how to use it",
'element' => 'body',
'gradientenabled' => 'true',
'opts' => array (
'closed' => 'true',
'advanced' => array(
'tip' => "You can paste in your own generated gradient codes in here",
'checkbox' => true
)//end advanced
)//end Opts
)//end colour chooser
)//end plugins
),//end colour sub panel
'pattern' => array(
'plugins' => array(
'patternselector' => array(
'tip' => "Use the pattern selector to apply effects like moire or scan lines to your background image",
'element' => 'patimg'
)//end patternselector
)//end plugins
),//end pattern sub panel
)//end subpanels
)//end site background
);//end scope settings
What would be best practice with this sort of thing?
Maybe this is a stupidity, but you can use "YAML" or "JSON" as configuration format for an application no?
As for example Symfony or other framework.
My advise: try YAML or XML or JSON to get a more readable config file, then parse it back to an array in your own code.
I would store the settings in <insert your markup language of choice> (XML, JSON, YAML, etc.).
You can then cache these in a $_SESSION variable, and populate it when you bootstrap if they don't already exist:
session_start();
if (!isset($_SESSION['settings'])) {
// Assuming you choose JSON...
$settings = json_decode(file_get_contents('settings.json'), TRUE);
$_SESSION['settings'] = $settings; // array
$_SESSION['settings'] = (object)$settings; // object
}
Whether or not you use an array or object then becomes just a matter of what access syntax you prefer:
$_SESSION['settings']['site_background']['subpanels']['colour']...
// vs.
$_SESSION['settings']->site_background->subpanels->colour...
I would say that some like Array Oriented Programmation and that, with PHP 5.4 they can express themselves in a great way.
However, more people are used to OOP -so do I- and It can be a more readable way to code your solution.
I think in this route I would go with a structured object oriented route. You can have a parent object, that holds all of the children objects (setting groups) and you can even retrieve on setting group as an object of its own. Each object will have its own definitions and properties which can be documented in the code that provides useful information within an IDE (if you use docblocks).
I would use objects. Assuming you are making a form, you should have several classes:
Form - to hold the form, will have a property $input_list (or $node_list to hold all of the inputs
Input - to describe a single input item, it should have properties like label, type, tip etc.
Fieldset - to describe a fieldset, to hold additional items inside. Like the Form class, it would have an $input_list to hold all of the inputs inside of it.
Those classes can stand alone, and can be extended to have customized common input types (for instance)
class Checkbox extends Input {
public $type = 'checkbox'
....
}
As other's people here also my opinion is to use YAML or JSON - using this it could be done in very simple way.
Just for instance an example of JSON format of Your data structure:
var settings = {
'site_background' : {
'subpanels' : {
'colour' : {
'plugins' : {
'colourchooser' : {
'tip' : "The background colour appears underneath the 'Background Image' (if set)-hover over the '?' around the colour chooser for extra tips on how to use it",
'element' : 'body',
'gradientenabled' : 'true',
'opts' : {
'closed' : 'true',
'advanced' : {
'tip' : "You can paste in your own generated gradient codes in here",
'checkbox' : true
}//end advanced
}//end Opts
}//end colour chooser
}//end plugins
},//end colour sub panel
'pattern' : {
'plugins' : {
'patternselector' : {
'tip' : "Use the pattern selector to apply effects like moire or scan lines to your background image",
'element' : 'patimg'
}//end patternselector
}//end plugins
}//end pattern sub panel
}//end subpanels
}//end site background
};//end scope
You can use PHP functions like json_encode and json_decode for JSON <-> PHP data transformation. Using curly braces means that the elements are objects while when replaced by [ and ] you got arrays...
But also a PHP OOP approach could be used succesfully especially when using extendability. You could have one main class Settings having some default properties and e.g. magic __get and __set functions and then You can implement many subsettings subclasses extending from this main Settings class.

Modify default forms in Symfony

I'd like to use forms generated by propel
( propel:generate-module --with-show --non-verbose-templates frontend user users )
but I'd like do modify them a little bit. e.q. I'd like to remove fields that are foreign keys. Is it possible, or do I have to create my own forms?
EDIT
in file: project_name/lib/form/form_file.class.php there is an empty class which derives from some base class. If put there something like this:
$this->setWidgets(array(
'name' => new sfWidgetFormInput()
));
All the default fields disappear and there is only this 'name' field in the form, which is not what I'm looking for.
If you are using admin generator as you indicated, you can edit your forms via a generator.yml file. With this file you can do any number of things include set which widgets you want to appear, order of entry, actions, etc.
The generator.yml file is located in /apps/app_name/modules/module_name/config
You can read more about it in the symfony docs.
-- Edit --
If you are not using the generator.yml file, you can edit the form class directly, read this article relating to symfony forms for more info.
Example widget manipulation:
//-----
//Remove Unwanted
//-----
unset(
$this['created_at'],
$this['updated_at'],
$this['ingredient_list'] //Will be embedded due to extra meta data
);
//-----
// Add a select menu using model to populate values
$this->widgetSchema['state_list'] = new sfWidgetFormPropelChoice(array('model' => 'State', 'multiple' => true, 'order_by' => array('name', 'asc')));
// Add matching validator
$this->validatorSchema['state_list'] = new sfValidatorPropelChoice(array('model' => 'State', 'column' => 'id', 'multiple' => true));
// I can also force widget presentation order
$this->getWidgetSchema()->moveField('country_list', sfWidgetFormSchema::AFTER, 'state_list');
// You can also add a callback function when the form is submitted
$this->validatorSchema->setPostValidator(
new sfValidatorCallback(array('callback' => array($this, 'dupeCheck')))
);
If you're not using admin generator, you can just edit the templates generated in the folder /app/modulename/templates/.
For example, modify the indexSuccess.php file contained in that folder to change the structure/info of the table created which by default will display all the info that exists in your DB table.

How to add new tab on publish form in ExpressionEngine 2.x

I’m writing an extension that called when an entry is submitted.
Now i want to add a tab with few fields in publish from?
Can i do this from extension?
I know there are EE1.x hooks - publish_form_new_tabs, publish_form_new_tabs_block ....
but i need this for EE 2.x
The 2.x module API allows this. Documentation here: http://expressionengine.com/user_guide/development/modules.html
You can combine a module and extension of the same type with a structure like this:
/system/expressionengine/third_party/addon_name/
ext.addon_name.php
language/
english/
lang.addon_name.php
mcp.addon_name.php
mod.addon_name.php
tab.addon_name.php # Add fields to tab here, per API spec
upd.addon_name.php # Add/remove tab here, per API spec
When a user installs either the extension or module, they'll be asked automatically if they want to install both at the same time. Obviously if the purpose is just to add a tab/fields to the publisher, your mcp and mod classes may be just the minimum needed to successfully install a module.
Hope this is a good starting point.
To add to the first answer,
one thing that I constantly had problems with is not calling the add_layout_tabs method anywhere in the update file of your module (i.e .the file that starts with upd.)
So suppose your update file is called: upd.addon_name.php. Then in the install looks like this (note: the following functions are all part of the Addon_name_upd class inside your update file:
function install () {
// ... create databases or any necessary code for your module
$this->EE->load->library('layout');
$this->EE->layout->add_layout_tabs($this->tabs(), 'addon_name');
return TRUE;
}
Notice the call to $this->tabs() method: That method looks something like this:
function tabs() {
$tabs['addon_name'] = array(
'field_1_inside_publish_form' => array(
'visible' => 'true',
'collapse'=> 'false',
'htmlbuttons' => 'true',
'width' => '100%'
)
);
return $tabs;
}
Where field_1_inside_publish_form is a field that would be defined in your corresponding tab file for the module (i.e. tab.addon_name.php ).
The install method will in effect save a new tab to the existing publish layout that includes your module's tab configuration.
However, you must add a method to remove your configuration in the uninstall method of the update file by calling the delete_layout_tabs method like so:
function uninstall() {
// necessary code to drop your database tables or whatever
$this->EE->load->library('layout');
$this->EE->layout->delete_layout_tabs($this->tabs(), 'addon_name');
return TRUE;
}
One more thing, if you develop like I do: make a little change here, test your change, go back and code some more, then you'll find that if new fields added to the tab file tab.addon_name.php after your module is enabled don't appear in your new tab on the publish page. The reason is because the method add_layout_tabs that you call in the install method of your update file needs to be ran.
However, this method only gets executed when you enable your module. So that means you have to disable your module, which is a drag if your module adds database tables. Luckily you can make the update method of your update file load your new tab configuration (in addition to adding or dropping any new database tables as part of your module's updates.)
The idea is that you delete your previous configuration and you add the configuration, which, calls your tabs method which has the names of the the new fields for your module's tab section.
So, suppose your tabs method has a new field called 'field_2_inside_publish_form' like so:
function tabs() {
$tabs['addon_name'] = array(
'field_1_inside_publish_form' => array(
'visible' => 'true',
'collapse'=> 'false',
'htmlbuttons' => 'true',
'width' => '100%'
),
'field_2_inside_publish_form' => array(
'visible' => 'true',
'collapse'=> 'false',
'htmlbuttons' => 'true',
'width' => '100%'
)
);
}
then your update method can update the layout like so (assume that you've updated your $this->version property in the udpate file from '1.0' to '1.5'.
function update($current='') {
// don't do anything if the version hasn't changed
if($current == $this->version) {
return FALSE;
}
// the version property has a version higher than current version in db
// this means the module is being updated.
if($current < $this->version) {
// update the tab layout
// delete old layout
$this->EE->load->library('layout');
$this->EE->layout->delete_layout_tabs($this->tabs(), 'addon_name');
// add new tab layout which calls tabs method with updated code
$this->EE->load->library('layout');
$this->EE->layout->add_layout_tabs($this->tabs(), 'addon_name');
}
return TRUE;
}
Remember that the update method of the update file of your module gets run everytime you are in your module's control panel page defined in in your modules control panel page file (i.e. mcp.addon_name.php ). Your module's main control panel page would probably correspond to the index method of the Addon_name_mcp class of your control panel page file.
It would correspond to a link uri like this: admin.php?S=0&D=cp&C=addons_modules&M=show_module_cp&module=addon_name&method=index
Hope that helps. It's kind of long winded but I wrote it more for my own benefit than for anyone else (cause I wasted like 3 hours trying to get my module to work.)

Categories