I have a table that's been created by a module. I need to include some of its fields into an existing view.
I tried using the table wizard module, but all it does is create a separate view for that table. I'd like to be able to choose fields from that table to be added into an existing view as additional fields, or through relationships or something like that. Is there a workaround to do what I'm trying to do?
Ah. Views. Took me a while as well. This answer is for Drupal 6 and in the abstract shows how to define fields as well as using a relationship to allow the fields to link to the node table.
Inside modulename.module, you want a function that goes:
function modulename_views_api() {
return array(
'api' => 2,
);
}
Then you want to make a file called modulename.views.inc and define a function like this:
function modulename_views_data() {
$data['modulename_table'] = array(
'table' => array(
'group' => 'ModuleName',
'title' => 'Module name title',
),
'join' => array(
// to join to node, we'll use a field in modulename_table called 'nid'
'node' => array(
'left_field' => 'nid',
'field' => 'nid',
),
),
);
// now we define the fields in the table like this
// check out modules/views/handlers to see more specific handlers
$data['modulename_table']['fieldname'] = array(
'title' => 'fieldname',
'help' => 'fieldname description',
'field' => array(
'handler' => 'views_handler_field',
),
);
$data['modulename_table']['nid'] = array(
'title' => 'related node',
'help' => 'the field that relates back to {node}',
// here we implement a relationship to nid
'relationship' => array(
'base' => 'node',
'field' => 'nid',
'handler' => 'views_handler_relationship',
'label' => 'modulename row node',
),
// this relationship can be turned on in views
);
return $data;
}
You can use hook_views_data to define your table in code. As long as you don't want views to do special manipulations, it's almost as simple as defining the table with the schema API.
Your other option is to use table wizard to expose the tables to the database and then use the migrate module to create the views. http://drupal.org/project/migrate
I have found that the Views Custom Field module lets me do just about anything I need as far as adding oddball fields to views .. maybe it'd help ..
Related
I want to filter list that does not have an invalid email and opt-out email in Leads and Contact module using SugarCRM 7 API.
I have added below email filter in arguments but does not work. How to email filter via SugarCRM 7.x rest API.
$filter_arguments = array(
"filter" => array(
array(
"assigned_user_id" => 1,
),
array(
"email1" => array(
array(
'opt_out' => array(
'$equals' => ''
)
)
)
),
),
);
$url = $base_url . "/Contacts/filter";
Thanks.
This much code will not help you please check this :
Reference Link 1
Reference Link 2
The following example will demonstrate how to add a predefined filter on the Accounts module to return all records with an account type of "Customer" and industry of "Other".
To create a predefined filter, create a display label extension in ./custom/Extension/modules/<module>/Ext/Language/. For this example, we will create:
./custom/Extension/modules/Accounts/Ext/Language/en_us.filterAccountByTypeAndIndustry.php
<?php
$mod_strings['LBL_FILTER_ACCOUNT_BY_TYPE_AND_INDUSTRY'] = 'Customer/Other Accounts';
Next, create a custom filter extension in ./custom/Extension/modules/<module>/Ext/clients/base/filters/basic/.
For this example, we will create:
./custom/Extension/modules/Accounts/Ext/clients/base/filters/basic/filterAccountByTypeAndIndustry.php
<?php
$viewdefs['Accounts']['base']['filter']['basic']['filters'][] = array(
'id' => 'filterAccountByTypeAndIndustry',
'name' => 'LBL_FILTER_ACCOUNT_BY_TYPE_AND_INDUSTRY',
'filter_definition' => array(
array(
'account_type' => array(
'$in' => array(
'Customer',
),
),
),
array(
'industry' => array(
'$in' => array(
'Other',
),
),
),
),
'editable' => false,
'is_template' => false,
);
You should notice that the editable and is_template options have been set to "false". If editable is not set to "false", the filter will not be displayed in the list view filter's list.
Finally, navigate to Admin > Repair and click "Quick Repair and Rebuild" to rebuild the extensions and make the predefined filter available for users.
Adding Initial Filters to Lookup Searches
To add initial filters to record lookups and type-ahead searches, define a filter template. This will allow you to filter results for users when looking up a parent related record. The following example will demonstrate how to add an initial filter for the Account lookup on the Contacts module. This initial filter will limit records to having an account type of "Customer" and a dynamically assigned user value determined by the contact's assigned user.
To add an initial filter to the Contacts record view, create a display label for the filter in ./custom/Extension/modules/<module>/Ext/Language/. For this example , we will create:
./custom/Extension/modules/Accounts/Ext/Language/en_us.filterAccountTemplate.php
<?php
$mod_strings['LBL_FILTER_ACCOUNT_TEMPLATE'] = 'Customer Accounts By A Dynamic User';
Next, create a custom template filter extension in ./custom/Extension/modules/<module>/Ext/clients/base/filters/basic/.
For this example, create:
./custom/Extension/modules/Accounts/Ext/clients/base/filters/basic/filterAccountTemplate.php
<?php
$viewdefs['Accounts']['base']['filter']['basic']['filters'][] = array(
'id' => 'filterAccountTemplate',
'name' => 'LBL_FILTER_ACCOUNT_TEMPLATE',
'filter_definition' => array(
array(
'account_type' => array(
'$in' => array(),
),
),
array(
'assigned_user_id' => ''
)
),
'editable' => true,
'is_template' => true,
);
As you can see, the filter_definition contains arrays for account_type and assigned_user_id. These filter definitions will receive their values from the contact record view's metadata. You should also note that this filter has is_template and editable set to "true". This is required for initial filters.
Once the filter template is in place, modify the contact record view's metadata. To accomplish this, edit ./custom/modules/Contacts/clients/base/views/record/record.php to adjust the account_name field. If this file does not exist in your local Sugar installation, navigate to Admin > Studio > Contacts > Layouts > Record View and click "Save & Deploy" to generate it. In this file, identify the panel_body array as shown below:
1 =>
array (
'name' => 'panel_body',
'label' => 'LBL_RECORD_BODY',
'columns' => 2,
'labelsOnTop' => true,
'placeholders' => true,
'newTab' => false,
'panelDefault' => 'expanded',
'fields' =>
array (
0 => 'title',
1 => 'phone_mobile',
2 => 'department',
3 => 'do_not_call',
4 => 'account_name',
5 => 'email',
),
),
Next, modify the account_name field to contain the initial filter parameters.
1 =>
array (
'name' => 'panel_body',
'label' => 'LBL_RECORD_BODY',
'columns' => 2,
'labelsOnTop' => true,
'placeholders' => true,
'newTab' => false,
'panelDefault' => 'expanded',
'fields' =>
array (
0 => 'title',
1 => 'phone_mobile',
2 => 'department',
3 => 'do_not_call',
4 => array (
//field name
'name' => 'account_name',
//the name of the filter template
'initial_filter' => 'filterAccountTemplate',
//the display label for users
'initial_filter_label' => 'LBL_FILTER_ACCOUNT_TEMPLATE',
//the hardcoded filters to pass to the templates filter definition
'filter_populate' => array(
'account_type' => array('Customer')
),
//the dynamic filters to pass to the templates filter definition
//please note the index of the array will be for the field the data is being pulled from
'filter_relate' => array(
//'field_to_pull_data_from' => 'field_to_populate_data_to'
'assigned_user_id' => 'assigned_user_id',
)
),
5 => 'email',
),
),
Finally, navigate to Admin > Repair and click "Quick Repair and Rebuild". This will rebuild the extensions and make the initial filter available for users when selecting a parent account for a contact.
Adding Initial Filters to Drawers from a Controller
When creating your own views, you may need to filter a drawer called from within your custom controller. Using an initial filter, as described in the Adding Initial Filters to Lookup Searches section, we can filter a drawer with predefined values by creating a filter object and populating the config.filter_populate property as shown below:
//create filter
var filterOptions = new app.utils.FilterOptions()
.config({
'initial_filter': 'filterAccountTemplate',
'initial_filter_label': 'LBL_FILTER_ACCOUNT_TEMPLATE',
'filter_populate': {
'account_type': ['Customer'],
'assigned_user_id': 'seed_sally_id'
}
})
.format();
//open drawer
app.drawer.open({
layout: 'selection-list',
context: {
module: 'Accounts',
filterOptions: filterOptions,
parent: this.context
}
});
To create a filtered drawer with dynamic values, create a filter object and populate the config.filter_relate property using the populateRelate method as shown below:
//record to filter related fields by
var contact = app.data.createBean('Contacts', {
'first_name': 'John',
'last_name': 'Smith',
'assigned_user_id': 'seed_sally_id'
});
//create filter
var filterOptions = new app.utils.FilterOptions()
.config({
'initial_filter': 'filterAccountTemplate',
'initial_filter_label': 'LBL_FILTER_ACCOUNT_TEMPLATE',
'filter_populate': {
'account_type': ['Customer'],
},
'filter_relate': {
'assigned_user_id': 'assigned_user_id'
}
})
.populateRelate(contact)
.format();
//open drawer
app.drawer.open({
layout: 'selection-list',
context: {
module: 'Accounts',
filterOptions: filterOptions,
parent: this.context
}
});
I've defined a many-to-many relationship between Accounts and a custom module (Tags). Tags have a subpanel in Accounts; however, I need a custom filter on Accounts that will show all the Accounts records related to the Tag name you type in.
/custom/Extension/modules/Accounts/Ext/clients/base/basic/filterAccountsByTag.php
$viewdefs['Account']['base']['filter']['basic']['filters'][] = array(
'id' => 'filterAccountsByTag',
'name' => 'LBL_FILTER_ACCOUNTS_BY_TAG',
'filter_definition' => array(
array(
'custom_tags_accountscustom_tags_ida' => array(
'$equals' => ' ',
),
),
array(
'name' => ''
)
),
'editable' => false,
'is_template' => false
);
To sum it up, I want to display the primary module results based upon a filter from a sub-module. Has anyone been through this? This is not a relate field; it's a relationship.
I hope this below article will help you.
Apply initial filter in relate fields and relationship fields with quick(popup) search sugarcrm 7.x
How can I use has_one and has_many in codeigniter 3.0?
I would like to create relations through tables like in Ruby on Rails.
I.E
Class User
{
has_many: comments
}
Class Comments
{
belongs_to: users
}
This is the most common usage, and is used in almost every project. There is a simple pattern to defining this relationship.
Post has a creator and an editor, which may be different users. Here's how to set that up.
Post
class Post extends DataMapper {
$has_one = array(
'creator' => array(
'class' => 'user',
'other_field' => 'created_post'
),
'editor' => array(
'class' => 'user',
'other_field' => 'edited_post'
)
);
}
User
class User extends DataMapper {
$has_many = array(
'created_post' => array(
'class' => 'post',
'other_field' => 'creator'
),
'edited_post' => array(
'class' => 'post',
'other_field' => 'editor'
)
);
}
A couple of things to note here.
The relationship is now defined by the relationship key on either
side, not the model name. This has now become the only way to look
up the relationship.
The key on one side of the relationship becomes the other_field on
the opposite side, and vice-versa.
Because we need a way to specify the difference between posts that
were edited and those that were created, we have to declare the
slightly unusual edited_post and created_post relationships. These
could have any name, as long as they were unique and mirrored on
Post.
http://datamapper.wanwizard.eu/pages/advancedrelations.html
I'm trying to populate a dropdown/select tag in cakephp,fortunately I was able to populate it with the values coming from my database,
however it displays ALL. How can I limit the population to a specific ID?
To make things clear here's what I want to achieve:
Apples:
form start
dropdown-contains only values that are associated with apples from the DB
button
form end
Currently here's how it looks like
Apples:
form start
dropdown-contains all fruits values from the DB
button
form end
Here's my current code tnx any help/suggestions is very much appreciated
Controller:
$fruits = $this->Model1->Model2->find('list',
array('fields' =>
array('id',
'fruit_name',
//'conditions' => array(''=>'')
)));
$this->set('fruitsList', $fruits);
View:
echo $this->Form->input('Model1.salad_fruits_id',
array('type' => 'select',
'options' => $fruitsList,
));
If you have association between models between models it would be easier. Just add conditions to second model.
//if you don't have association between models
$this->Model1->bindModel(array(
'belongsTo' => array( //example binding
'Model2' => array(
'className' => 'Model2',
'foreignKey' => 'model2_id',
)
)
));
$fruits = $this->Model1->find('list', array(
'conditions' => array(
'Model2.name' => 'apple'
),
'fields' => array(
'id','fruit_name',
)
));
I have a gridview which contains a checkbox column and also uses pagination. When I check some checkboxes in the first page and navigate to the second page and check another one in the second page, the options I checked in the first page is not retained there. Is it posssible to retain the checkbox values during pagination?
Code for Gridview is
$widget = $this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' => $model->search(),
'cssFile' => Yii::app()->baseUrl . '/media/js/admin/css/admingridview.css',
//'filter' => $model,
'ajaxUpdate' => true,
'enablePagination' => true,
'columns' => array(
array(
'name' => 'id',
'header' => '#',
'value' => '$this->grid->dataProvider->pagination->currentPage * $this->grid->dataProvider->pagination->pageSize + ($row+1)',
),
array(
'class' => 'CCheckBoxColumn',
'selectableRows' => '2',
'header' => 'Selected',
),
array(
'name' => 'fb_user_id',
'header' => 'FaceBook Id',
'value' => 'CHtml::encode($data->fb_user_id)',
),
array(
'name' => 'first_name',
'header' => 'Name',
'value' => 'CHtml::encode($data->first_name)',
),
array(
'name' => 'email_id',
'header' => 'Email',
'value' => 'CHtml::encode($data->email_id)',
),
array(
'name' => 'demo',
'type' => 'raw',
'header' => "Select",
'value' => 'CHtml::checkBox("email[]","",array("class"=>"check","value"=>$data->email_id))',
),
),
));
Edit:
Extension for remembering the selected options in gridview,check this link Selgridview
Thanks to bool.dev
You could use sessions/cookies to store the checked values. I'm not very sure how to make cookies work, so i'll tell you how to do it with sessions. Specifically the user session that yii creates.
Now to use sessions we need to pass the checked (and unchecked) ids to the controller, therefore we'll modify the data being sent to the controller on every ajax update(i.e between paginations), to do this we exploit the beforeAjaxUpdate option of CGridView.
I'm also using CCheckBoxColumn instead of the following in your code(of course you can modify the solution to suit your own needs):
array(
'name' => 'demo',
'type'=>'raw',
'header' => "Select",
'value' => 'CHtml::checkBox("email[]","",array("class"=>"check","value"=>$data->email_id))',
),
GridView Changes:
<?php $this->widget('zii.widgets.grid.CGridView', array(
// added id of grid-view for use with $.fn.yiiGridView.getChecked(containerID,columnID)
'id'=>'first-grid',
'dataProvider'=>$model->search(),
'cssFile' => Yii::app()->baseUrl . '/media/js/admin/css/admingridview.css',
// added this piece of code
'beforeAjaxUpdate'=>'function(id,options){options.data={checkedIds:$.fn.yiiGridView.getChecked("first-grid","someChecks").toString(),
uncheckedIds:getUncheckeds()};
return true;}',
'ajaxUpdate'=>true,
'enablePagination' => true,
'columns' => array(
array(
'name' => 'id',
'header' => '#',
'value' => '$this->grid->dataProvider->pagination->currentPage * $this->grid->dataProvider->pagination->pageSize + ($row+1)',
),
array(
'name' => 'fb_user_id',
'header' => 'FaceBook Id',
'value' => 'CHtml::encode($data->fb_user_id)',
),
array(
'name' => 'first_name',
'header' => 'Name',
'value' => 'CHtml::encode($data->first_name)',
),
array(
'name' => 'email_id',
'header' => 'Email',
'value' => 'CHtml::encode($data->email_id)',
),
/* replaced the following with CCheckBoxColumn
array(
'name' => 'demo',
'type'=>'raw',
'header' => "Select",
'value' =>'CHtml::checkBox("email[]","",array("class"=>"check","value"=>$data->email_id))',
),
*/
array(
'class' => 'CCheckBoxColumn',
'selectableRows' => '2',
'header'=>'Selected',
'id'=>'someChecks', // need this id for use with $.fn.yiiGridView.getChecked(containerID,columnID)
'checked'=>'Yii::app()->user->getState($data->email_id)', // we are using the user session variable to store the checked row values, also considering here that email_ids are unique for your app, it would be best to use any field that is unique in the table
),
),
));
?>
Pay special attention to the code for beforeAjaxUpdate and CCheckBoxColumn, in beforeAjaxUpdate we are passing checkedIds as a csv string of all the ids(in this case email_ids) that have been checked and uncheckedIds as a csv string of all the unchecked ids, we get the unchecked boxes by calling a function getUncheckeds(), which follows shortly. Please take note here, that when i was testing i had used an integer id field (of my table) as the unique field, and not an email field.
The getUncheckeds() function can be registered like this anywhere in the view file for gridview:
Yii::app()->clientScript->registerScript('getUnchecked', "
function getUncheckeds(){
var unch = [];
/*corrected typo: $('[name^=someChec]') => $('[name^=someChecks]') */
$('[name^=someChecks]').not(':checked,[name$=all]').each(function(){unch.push($(this).val());});
return unch.toString();
}
"
);
In the above function pay attention to the selectors and each and push function.
With that done, we need to modify the controller/action for this view.
public function actionShowGrid(){
// some code already existing
// additional code follows
if(isset($_GET['checkedIds'])){
$chkArray=explode(",", $_GET['checkedIds']);
foreach ($chkArray as $arow){
Yii::app()->user->setState($arow,1);
}
}
if(isset($_GET['uncheckedIds'])){
$unchkArray=explode(",", $_GET['uncheckedIds']);
foreach ($unchkArray as $arownon){
Yii::app()->user->setState($arownon,0);
}
}
// rest of the code namely render()
}
That's it, it should work now.
For developing that scheme you would need to know working of what happens when you navigate.
When ever you navigate to a pagination page ajax calls are made and new data is received and it is fetched from CActive Record or what ever the data source. New data is in accordance of database records or source records. when you come back to previous page again Ajax call is made and content is updated so same comes as it is in database.
what i feel is you should save data of checked items temporary and make it permanent if action is made.
You can do something like this
<script type="text/javascript">
$("input:checkbox").click(function () {
var thisCheck = $(this);
if (thisCheck.is (':checked')){
// do what you want here, the way to access the text is using the
// $(this) selector. The following code would output pop up message with
// the selected checkbox text
$(this).val());
}
});
</script>
you can save temporary storage somewhere
Also make this work on normal form submit:
I wanted to add this as a comment on bool.dev's answer, but I do not have enough reputation to do that yet. So I had to put it in a separate answer.
bool.dev, your answer is great and it works well, thanx.
However, as intended, it only works when ajax calls update the gridview. I have the gridview forming part of a form, so I wanted it to also work on normal submission of the form, otherwise the checkboxes are not loaded again when there are other validation errors on the form.
So, in ADDITION to what you did, I added hidden fields on my form e.g.:
<input type="hidden" name='checkedBox1' id='checkedBox1' value=''>
<input type="hidden" name='uncheckedBox1' id='uncheckedBox1' value=''>
Then, before submitting the form, my sumbit button runs your getChecked() and getUncheckeds() functions and store their results in the hidden fields:
if ($('#checkedBox1').length >0) {$('[name=checkedBox1]').val(getChecked());}
if ($('#uncheckedBox1').length >0) {$('[name=uncheckedBox1]').val(getUncheckeds());}
In the controller, besides from checking for $_GET['checkedIds'], you also check for $_POST['checkedBox1'] and store its values to session in the same way you do for $_GET['checkedIds'], using the same session variable.
Do the same with $_POST['uncheckedBox1'].
That should work.