In SuiteCRM I have a module connected with module Contacts. And in this module I created custom button in a subpanel of Contacts which is called "Import". And I want to open the page with import of contacts when I click this button.
How can I do it?
array (
0 =>
array (
'widget_class' => 'SubPanelTopButtonQuickCreate',
),
1 =>
array (
'widget_class' => 'SubPanelTopSelectButton',
'mode' => 'MultiSelect',
), 2 => array (
'widget_class' => 'SubPanelImportButton',
),
Sugar load widget class from include/generic/SugarWidgets/.*
for example you can find definition of SubPanelTopSelectButton in this directory.The code above wont work because you haven't defined any widget class with name SugarWidgetSubPanelImportButton
Follow the below mentioned steps to achieve required behaviour:
Create directory in custom/include/generic/SugarWidgets/SugarWidgetSubPanelImportButton.php
Create a class SugarWidgetSubPanelImportButton
Extend this class with SubPanelTopSelectButton
Override the SubPanelTopSelectButton relevant methods in which you would like to change the default behaviour.
Related
I am using a paid theme which is using Redux Framework. I am trying to add a new field in Footer Options. I am able to add this field in options but only in print_r() function it is showing not showing in Themes Options Panel.
function add_another_section_bl($sections){
$sections[12]['fields'][] = array(
'id' => 'rd_footer_message_1',
'type' => 'textarea',
'title' => __('Text 2 to display in footer under bar', 'thefoxwp'),
'subtitle' => __('write your copyright information or anything you\'d like.', 'thefoxwp'),
'validate' => 'html', //see http://codex.wordpress.org/Function_Reference/wp_kses_post
'default' => 'Copyright 2015 Tranmautritam\'s team | All Rights Reserved'
);
return $sections;}
add_filter("redux/options/rd_data/register", 'add_another_section_bl');
In array data it is showing the required data but not in Options Panel in wordpress dashboard.
Kindly get me out of this.
There's a much simpler approach if you use the Redux API:
https://docs.redux.io/configuration/redux-api.html
You can modify, add, update any section or field before it is rendered. Please note, you may have to put your code within hooks. Also please note the Redux 4 method names have changed from setArgs to set_args (camelcase to non).
Otherwise, you will have all you need.
I'm using Drupal 7 with the view_database_connector module. I'm currently working with a view that consists of a table displaying database information. My goal is to have a field with action buttons corresponding to each row, such as delete.
I am not allowed to use global php as a field.
I've attempted to make a custom module following this. I can currently use this module on content tables, however, when I try to use it on my view_database_connector table, I'm unable to add it as a field, since it's not apart of the same group.
Here's where I set up the information for making the action:
function mymodule_views_data_alter(&$data) {
// debug($data['node']);
$data['node']['actions'] = array(
'title' => t('Actions'),
'help' => t('Clickable links to actions a user may perform on a Node.'),
'field' => array(
'handler' => 'mymodule_views_handler_field_actions',
'group' => 'Content',
'click sortable' => FALSE,
),
);
}
I've tried deleting Content, changing it to global, and changing it to the VDC type, but none of that changes it into Global or VDC.
Alternatively, if there's an easier way just to hook into a field that has a button to run my code which will download a file, that could circumvent this issue.
You don't have to create this feature on your own - it already exists in views. There is a field type with actions as delete.
Other option is to use option called "rewrite value of this field" (or similar). With it you can make your field from views interface, and totally rewrite it's output. You can use token and some of them for sure contains node id, so you can use it to generate link to node deleting/editing/viewing pages.
I'm working on a sf2 project using Sonata Admin Bundle.
The project is a Donations website for humanitarian mission.
I have a 'Personne' entity, represent benefactors (donation makers).
My problem is the following:
I have to filter results in the sonata list view using autocompletion.
I want filter results using the 'name' property of the current entity ('Personne').
What I'm expecting :
$datagridMapper
->add('personne', 'doctrine_orm_model_autocomplete',
array('label' => 'AutoComplete'),
null,
array('property' => 'name'))
// error output : " The option `association_mapping` must be set for field: `personne` "
You can see my full admin class and entity on this gist :
https://gist.github.com/chalasr/0658a02b1c04180f5563
I understand this field type is reserved to entity associations (by example I already use it for filter results of my Donation entity by Personne name (other admin class).
My question is :
Is it possible to do what I need ?
If I can't do that using this field type, what is the right way to achieve this task ?
Thank's for your help.
After a lot of tests, it seems this functionality isn't yet provided by Sonata.
So, I had build an homemade autocomplete method in my admin controller and used it as ajax in my overridden CRUD:list.html.twig template.
This method takes field name, other autocomplete fields values, and keyword as parameters and reload results on keyup event.
You can look on this gist:
https://gist.github.com/chalasr/5c27ae64dc596967f18a
If you have an idea/proposition for optimize my code (simple autocomplete field type for $formMapper ?), I'm really interested.
Well it's possible to make a choice field and use integrated select2 to handle autocomplete, I don't know how well it would fare with large tables though.
$datagridMapper
->add('personne','doctrine_orm_callback', array(
'callback' => array($this, 'filterByName'),
'field_type' => 'text',
), 'entity',array(
'class' => 'AppBundle\Entity\Personne',
'choice_label' => 'name'
))
We add 'doctrine_orm_callback' because regular string filter can't handle EntityType Field, so we need to do it ourselves.
public function filterByName($queryBuilder, $alias, $field, $value)
{
if (!$value['value']) {
return;
}
$queryBuilder
->andWhere($alias . '.name' . ' = ' . ':name' )
->setParameter('name' , $value['value']->getName());
return true;
}
1 more thing, select2 won't create autocomplete (search) box if dropdown box has less than 10 choices, because it's set up in Admin.js that way.
select.select2({
width: function(){
// Select2 v3 and v4 BC. If window.Select2 is defined, then the v3 is installed.
// NEXT_MAJOR: Remove Select2 v3 support.
return Admin.get_select2_width(window.Select2 ? this.element : jQuery(this));
},
dropdownAutoWidth: true,
minimumResultsForSearch: 10,
allowClear: allowClearEnabled
});
so you need to override it, if you want that to be less.
Fonctionnality is now bundled with Sonata as simple as:
$filter->add('label', ModelFilter::class, ['field_type'=>ModelAutocompleteType::class,'field_options' => ['property' => 'name']])
I am trying to create a back-end interface for silverstripe that gives the CMS user the option to choose between a set of Post Types (like tumblr) in Silverstripe3. So they can choose to create a News Post, Video Post, Gallery Post, etc.
I initially started off giving all Posts the necessary fields for each Type and adding an enum field that allowed the user to choose the Post Type. I then used the forTemplate method to set the template dependent upon which Post Type was chosen.
class Post extends DataObject {
static $db = array(
'Title' => 'Varchar(255),
'Entry' => 'HTMLText',
'Type' => 'enum('Video, Photo, Gallery, Music')
);
static $many_many = array(
'Videos' => 'SiteVideo',
'Photos' => 'SitePhoto,
'Songs' => 'SiteMp3'
);
public function forTemplate() {
switch ($this->Type) {
case 'Video':
return $this->renderWith('VideoPost');
break;
case 'Photo':
return $this->renderWith('ImagePost');
break;
etc...
}
function getCMSFields($params=null) {
$fields = parent::getCMSFields($params);
...
$videosField = new GridField(
'Videos',
'Videos',
$this->Videos()->sort('SortOrder'),
$gridFieldConfig
);
$fields->addFieldToTab('Root.Videos', $photosField);
$photosField = new GridField(
'Photos',
'Photos',
$this->Photos()->sort('SortOrder'),
$gridFieldConfig
);
$fields->addFieldToTab('Root.Videos', $photosField);
return $fields;
}
}
I would rather the user be able to choose the Post Type in the backend and only the appropriate tabs show up. So if you choose Video, only the Video GridField tab would show up. If you choose Photo Type only the Photo's GridField would show.Then I would like to be able to call something like
public function PostList() {
Posts::get()
}
and be able to output all PostTypes sorted by date.
Does anyone know how this might be accomplished? Thanks.
Well the first part can be accomplished using javascript. Check out this tutorial and the docs let me know if you have questions on it.
The second part would be trickier but I think you could do something with the page controller. Include a method that outputs a different template based on the enum value but you would have to set links somewhere.
I managed this with DataObjectManager in 2.4.7 as I had numerous DataObjects and all were included in one page but I'm not sure if that is feasible in SS3.
return $this->renderWith(array('CustomTemplate'));
This line of code will output the page using a different template. You need to include it in a method and then call that method when the appropriate link is clicked.
I'm trying to use hook_menu to create a link to a view which takes an argument. However if I use the path (in $items[view-path/%dest]) that I've already set as the path in the view then the link doesn't appear. I'm guessing there's a path conflict somewhere. Is there a way round this? Or can I use another method to return the view?
I'm using the following code:
/**
* implementation of hook_menu().
*/
function sign_custom_menu() {
$items['view-path/%dest'] = array(
'title' => 'Link to view',
'page callback' => 'sign_custom_hello',
'page arguments' => array(1), //(corrected typo from 'page arguements')
'access callback' => TRUE,
'type' => MENU_NORMAL_ITEM,
'menu_name' => 'menu-student-links',
);
return $items;
}
function dest_to_arg() {
// would normally be dynamic to get view with correct argument
$arg = 73;
return $arg;
}
Thanks in advance.
Addition
function sign_custom_hello() {
//return t('Hello!');
}
I managed to answer my problem. Basically I used a different path to the one I had set in the view and then used views_page() as my "page callback". I passed it the arguments for the view, the page ID and it's own additional arguments to make the view work. I was able to use a wildcard in the menu item to pass to views_page() by using the to_arg() function that works with hook_menu() to pass in wildcards. The 'page arguments' pass in the three arguments. The last argument, "1" is a reference to which position in the path the argument appears (starting from 0).
The working code is:
<?php
/**
* implementation of hook_menu().
*/
function sign_custom_menu() {
$items['view-path/%dest'] = array(
'title' => 'link to view',
'page callback' => 'views_page',
'page arguments' => array('view_name', 'page_1', 1),
'access callback' => TRUE,
'type' => MENU_NORMAL_ITEM,
'menu_name' => 'menu-student-links',
);
return $items;
}
//this function is needed from the "%dest" argument in hook_menu above
function dest_to_arg() {
// would normally be dynamic to get view with correct argument
$arg = 73;
return $arg;
}
?>
I don't have much experience with wildcard URLs in my custom modules much, but I researched the issue in the Pro Drupal Development book. From what I read in the "Wildcards and Parameter Replacement" section on page 77, I think you may want to use $items['view-path/%'] instead. Using %dest apparently makes drupal look for a dest_load function.
Items that appear in menus can't be created by a wildcard router item: each menu item corresponds to exactly one path. That is, if you have a router item that is foo/%bar and %bar can have 10 different values, Drupal's menu system isn't going to create 10 new menu items off of one router item definition.
So what you're going to need to do is create a router item for each possible argument ahead of time. Otherwise, you're going to have to look outside Drupal's menu system and think about creating a separate Views block that looks like a menu but is really a Views unordered list of the available options.
To do the former, you need to implement hook_menu_alter() to add your custom router item after everything else, including the wildcard router item you're trying to override. Your custom router item will be more or less the same as the wildcard router item, but with some defaults set that would normally be derived from the wildcard.
For example, if I wanted to create a new router item for user/1/edit which overrides the built-in user/%user_category/edit, I'd implement hook_menu_alter() as so:
function mymodule_menu_alter(&$items) {
// user_edit and user_edit_access expect a user object
$account = user_load(array('uid' => 1));
$items['user/1/edit'] = array(
'type' => MENU_CALLBACK,
'page arguments' => array($account),
'access arguments' => array($account),
) + $items['user/%user_category/edit'];
}
In this example, user/%user_category/edit calls user_edit() and user_edit_access() for the page and access callbacks, respectively, and they both attempt to use the wildcard. Since there is no wildcard in your router item, you need override the arguments to say "check user 1".
You'll do this for each and every possible value of the wildcard.
But this isn't enough: notice I used MENU_CALLBACK instead of MENU_NORMAL_ITEM. If you use MENU_NORMAL_ITEM, your router item is going to show up in the Navigation menu, not in your custom menu, even if you set menu_name (I don't know why this is: it should work). But you can get around this by using menu_link_save().
Consider this implementation of hook_init():
function mymodule_init() {
$router_path = 'user/1/edit';
// Check to see if the custom router item has been added to menu_links.
// This is to ensure the menu has already been rebuilt.
$router_item = db_fetch_object(db_query("SELECT * FROM {menu_links} WHERE router_path = '%s'", $router_path));
// Only create a new menu item if the router item exists and it
// hasn't already been created (it's hidden until created).
if ($router_item && $router_item->hidden) {
$item = array(
'link_title' => 'Edit Administrator',
'link_path' => $router_path,
'menu_name' => 'primary-links',
'router_path' => $router_path,
'mlid' => $router_item->mlid,
);
// Save the menu item.
menu_link_save($item);
}
}
In this implementation, it checks to see if the custom router has already been created and hasn't been otherwise modified. If this is true, it creates a menu link in the primary links menu that references your custom router item.
Obviously, since this is in hook_init(), it'll perform the check on every page: this is to ensure it fires after the menu is rebuilt. It shouldn't be much of a performance hit, but it's something to keep in mind.
As you can see, it's a long and drawn out process to do this: if you're not going to go the Views fake-menu route, it might be better to just manually create the links yourself.