Is there a Zend Helper to generate a Html Table using and array as input ?
partialLoop() is probably best if you need a lightweight, easily customizable table generator. If you want something a little more to take all but the business logic of report generation in Zend, take a look at zfdatagrid.
Most of all I use partialLoop() to generate tables. But sometimes, for simple data that don't require formatting, I use my simple view helper: https://gist.github.com/812481 .
Usage:
<?php echo $this->table()->setRows($rows); ?>
or...
<?php echo $this->table(null, $rows); ?>
The $rows can be associative array or any object that has toArray method (Zend_Db_Table_Rowset, Doctrine_Collection etc.). Following is more complicated example, with headers, caption, additional column:
echo $this->table()
->setCaption('List of something')
->setAttributes(array('class' => 'mytable', 'id' => 'currenciesList'))
->setColumns(array(
'currency' => 'Currency',
'rate' => 'Rate',
'edit_options' => '' // Custom column
))
// content for custom column.
->setCellContent(
'Delete', 'edit_options'
)
->setFooter('Something to write in footer...')
->setEmptyRowContent('Nothing found')
->setRows($rows);
But this approach is not as convenient as partialLoop, cause it takes input data and display it as is - it doesn't allow you to format values using Zend_Date, Zend_Currency or do custom cell formatting.
There is no native table zend view helper. However, you could use partialLoop view helper to ease generation of tables.
You can also use a PEAR's HTML_Table package. You can throw an array to the table class and it is gonna populate the table for you. It has some nice features like colouring odd and even lines, set parameters per row, per columns and per table body.
Find more info at http://pear.php.net/package/HTML_Table/docs/latest/HTML_Table/HTML_Table.html
Related
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.
I'm unpicking someone's project written in CakePHP. I am familiar with the MVC paradigm, just not with Cake.
The resulting HTML is a select dropdown. The data for this dropdown comes from the controller and is assigned as follows:
$this->set(compact('venues', 'eventTypes', 'positions', 'hms'));
where $hms is the array containing the data for the select element (defined from a query on the model). However in the view this is all I have for the dropdown:
echo $this->Form->input('Event.hm_id', array('label' => 'House Manager', 'empty' => '(none)', 'class' => 'chzn-selectaaa'));
In the view I was expecting to see some reference to the value of $hms. Where does the HTML form helper get the data to build the dropdown?
There is some auto-wiring magic that happens on the input Form helper that maps hms array to hm_id.
This piece of the CakePHP doc should help you understand how the magic is actually done. It is all based on naming conventions in both Tables and fields in the DB and the Model itself.
http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#creating-form-elements
Here is the API doc piece as well.
http://api.cakephp.org/2.6/class-FormHelper.html#_input
I hope this helps.
In Symfony I have a line include_component('core', 'ohrmList'); that prints a table. But I am unable to find the for loop that generates the table.
I want some conditional formatting on the table. Should I go and edit in exact for loop or is there any way to do this?
You can read about components here Chapter 7 - Inside The View Layer
I think you must find module core, and in templates folder,file _ohrmList.php
Components are like "little" controllers. Their goal is pretty much the same as partials' but you use components when you need to do some extra action which would normally not fit into the view layer (e.g. a database call, some complicated computations etc.).
You can find the functions of the components in your module's actions directory in the components.class.php file.
Each component renders a partial named after its' own name. So the ohrmList component will render the _ohrmList.php partial after running the executeOhrmList() function.
In your case you should look inside the core module.
You can format component output based on values passed to it.
For example, you can render you view with
include_component('core', 'ohrmList', array('name' => 'Maria', 'status' => 'approved') )
and in _ohrmList.php you can do something like
<?php echo $name ?> - <?php if ( $status == 'approved' ): ?>congrats, you were approved!!!<?php endif; ?>
I am changing the data provided by my model in the afterFind() method, so the id is clickable text, like this:
$this->id = CHtml::link($this->id, array('/admin/auditTrail/view', 'id' => $this->id));
However, this changes every single occurrence of id value - it is in lists, in detail page, even in breadcrumbs, which is unwilling of course. How can I decide which format I will use in different views? For example, in breadcrumbs and in view.php I just want the raw value, but in the list (admin.php) I would like to use the html link, like this:
'columns'=>array(
array(
'name' => 'id',
'type' => 'html',
),
On a separate note - is this a good approach in terms of MVC, I mean changing display in a model? Should not be model only used for a database manipulation stuff?
No, this is not a good approach. There are a number of alternative approaches that would be better, for example:
Let the view do the conversion
Don't do anything in the model. When the view wants to display clickable anchors instead of bare ids, it should generate the URLs itself. This is somewhat quick and dirty (it puts the logic of URL generation in the view, which is not ideal) but it's easy and it works well if you only need to do it in one or two places.
Expose the URL as a separate property
Place a calculated read-only property in your model:
public function getAuditTrailUrl()
{
return Yii::app()->createUrl('/admin/auditTrail/view',
array('id' => $this->id));
}
You can then use the auditTrailUrl property in any view. The nice thing about this approach is that the URL generation is opaque to the views and therefore easily modifiable.
You can use this syntax to easily render links from these URLs in your CDataGrid:
'columns' => array(
array(
'class' => 'CLinkColumn',
'urlExpression' => '$data->auditTrailUrl',
)
),
In the above definition $data refers to each model in the grid, as per the documentation.
How would I go about creating a real world form creation class that I can use to display a new form with fields of different types, as how many fields I want, I can use drop downs and I can do all of this by using OOP?
To be honest I wouldn't roll my own, considering there are a few mature form packages out there for PHP.
I use PEAR's HTML_QuickForm package (http://pear.php.net/manual/en/package.html.html-quickform.php) for PHP4 sites.
For PHP5, I'd have a look into Zend_Form (http://framework.zend.com/manual/en/zend.form.html).
For my quickform code, I use a helper class that lets me define forms using a config array. For example:
echo QuickFormHelper::renderFromConfig(array(
'name' => 'area_edit',
'elements' => array(
'area_id' => array('type' => 'hidden'),
'active' => array('type' => 'toggle'),
'site_name' => array('type' => 'text'),
'base_url' => array('type' => 'text'),
'email' => array('type' => 'text'),
'email_admin' => array('type' => 'text'),
'email_financial' => array('type' => 'text'),
'cron_enabled' => array('type' => 'toggle'),
'address' => array('type' => 'address'),
),
'groups' => array(
'Basic Details' => array('site_name', 'base_url'),
'Address Details' => array('address'),
'Misc Details' => array(), // SM: Display the rest with this heading.
),
'defaults' => $site,
'callback_on_success' => array(
'object' => $module,
'function' => 'saveSite',
),
));
Note that the above element types 'address' and 'toggle' are in fact multiple form fields (basically, meta-types). This is what I love about this helper class - I can define a standard group of fields with their rules (such as address, credit_card, etc) and they can be used on lots of pages in a consistent fashion.
You definitely can. Consider a Form class which stores information about the form itself: the method, action, enctype attributes. Also throw in stuff like an optional heading and/or description text at the top. Of course you will also need an array of input elements. These could probably be put into their own class (though subclassing them for InputText, InputCheckbox, InputRadio maybe be a bit over the top). Here's a vague skeleton design:
class Form {
var $attributes, // array, with keys ['method' => 'post', 'action' => 'mypage.php'...]
$heading,
$description,
$inputs // array of FormInput elements
;
function render() {
$output = "<form " . /* insert attributes here */ ">"
. "<h1>" . $this->heading . "</h1>"
. "<p>" . $this->description . "</p>"
;
// wrap your inputs in whatever output style you prefer:
// ordered list, table, etc.
foreach ($this->inputs as $input) {
$output .= $input->render();
}
$output .= "</form>";
return $output;
}
}
The FormInput class would just need to store the basics, such as type, name, value, label. If you wanted to get tricky then you could apply validation rules which would then be converted to Javascript when rendering.
I will go against other advice here and suggest that you build your own library to generate forms. If you fail, you will still learn a lot in the process.
The design process is most important here. You start from the top and ask yourself what goes on a form. At an abstract level, a form is full of elements. Some are visible, some are not, some can be entered by the user but others cannot, some elements can trigger other elements... and the list goes on...
Eventually you end up with elements that are "decorative" (Text, Headings, Separators, Fieldsets, Links, Images), elements that are interactive (Inputs, Dropdowns, Checkboxes, Radio buttons, Submit Buttons) and finally elements that are neither decorative nor interactive (Hidden Inputs, Anchors and elements that act as containers to group other elements.)
Once you have the different categories organised you start looking into features that all elements have and you can put that into the base element class. Then you go up the chain making your classes doing more and more, inheriting from other simpler element classes. In my library, the base element class is called form_element and each form_element has a unique name that no other element within the same form can have. A form_element also has a set of attributes. It has a function that all elements have called render(). In the base class render() does nothing (so a base element is always invisible) but in derived classes it starts producing HTML. By the way, I never make any of my classes create HTML. Instead I have a static class called html which writes HTML for all the classes that needs its services.
Very early in the chain of form elements, you should have one, a container that groups others. It should have an add() function and its render() function should consist of calling the render() function of all its sub-elements. the form class will be derived from this container class.
Spend plenty of time on the design. Pay attention to compatibility with the rest of your library.
If you want the data from the form to come from a database and be saved to one, you will need to add this functionality and have a form element class linked to a table and column. Here too, I have a separate DB class that can retrieve/save the data. I have a query class that creates queries. Form elements should have nothing to do with creating HTML, creating queries or accessing a database. My static class DB and my query class take care of the dirty work. The form class should only be involved with form stuff. The form class collects into an array all the tables and columns for the fields that need to be saved and pas it to the query class which creates the query which is then passed to the DB class which executes it.
Once you are properly setup, what appears to be horrendously complicated suddenly becomes very easy with properly designed classes.
Because you have a class that can write HTML, your form class needs to just html::init() and follow it with render() and the entire HTML code for the form is available within the html buffer. html::output() flushes everything out.
Validation is also handled externally with a static validation class. Form elements that can be validated hold validation instructions within an array in a format that can be passed directly to the validation class. Each element that needs to be validated is bound to an error element which displays the error if the element does not validate or remains invisible if all goes well.
This is to show you that when you design a form environment (or anything else) you really need to consider absolutely everything before you get started. The work that you put into it may not immediately translate into code that can power your application but it will sure make you a much better developer, thus making your future projects much easier to handle.
The form class creates a form, the html class creates the HTML, the query class makes queries and the DB class handles the database. If your classes start doing work that should be done by separate classes, you have a design problem.
Here is a code sample to show how my form library works:
$fm = new form('myform');
$fm->binding(FORM_DATABASE);
$fm->state(FORM_RETRIEVE);
$fm->set_recno(1);
$fm->add(new form_heading("My form"));
$fm->add($el=new form_input("name",40));
$el->bind_data('mytable','mycolumn');
$el->set_attribute('size', 25);
$el->set_default('Name');
$fm->add($el=new form_submit("submit_btn","Submit"));
if($fm->manage())
{
redirect or do something else here. The interaction with the form is done. The initial state for the form was FORM_RETRIEVE. If it had been FORM_NEW it would have displayed default values instead of the retrieved record and saved the form as a new record in the table.
}
Note that the manage() function of the form takes care of absolutely everything, retrieving data from the database, rendering the form into the view, validating data and saving it back to the database.
One of the advantages of creating forms programmatically (as above) is the option to write your own form-based code generator to create the code to make your forms.
I hope this can help you or someone else.
Just for reference, Object Oriented Forms by Khurram Khan is an excellent OO forms implementation for PHP.
Here is a sample of what the code looks like:
$form = new Form("Register", "form.php");
$personal = new Block("Personal Information");
$name = new Text("name", "Your name");
$name->setDescription("this is my description");
$name->addValidator(new MaxLengthValidator("The name you have entered is too long", 30));
...
Another more popular implementation is PHPlib. However, I find this to be a bit clunky; it seems like it's just some standard functional programming wrapped in a class.
Another option would be writing an abstraction for the built in DOM library. This will allow you to manually create any kind of form and form element using OO notation, with the added benefit that you will be returned an OO DOM instance that can be used elsewhere in your program.
You definitely should use OO PHP to do forms, and all the rest of your HTML output. I could not find any PHP library (many of the links in these answers are dead) to do what I wanted, so I wrote PHPFUI. It is not a generic HMTL output library, but outputs pages for the Foundation CSS Framework. You could easily use the same technique to output a more vanilla page, or Bootstrap or what ever. I did not want to write a generic HTML OO PHP library, as I wanted something lean and mean for performance reasons. Also I don't like to over engineer stuff, so it is hard coded to Foundation. But the same principles would apply to any PHP library that would want to output clean HTML with no validation issues, which you often find in hand written HTML.