dojo.data is undefined Flitering select - zend-framework

I am having a few problems with Dojo Filtering Selects when using the Zend Framework Forms and need some help to find out what I have missed as this is driving me mad.
I am currently getting this errors in firebug:
dojo.data is undefined
dojo.data.ItemFileReadStore is not a constructor
Below is the code that I am using to create the filter select and provide the json data to the calling controller.
Zend_Form Element (Dojo Enabled)
$industry = new Zend_Dojo_Form_Element_FilteringSelect('industry');
$industry->setAutocomplete(true)
->setStoreId('industrystore')
->setStoreType('dojo.data.ItemFileReadStore')
->setStoreParams(array('url' => $baseUrl.'/dojo/industry'))
->setAttrib("searchAttr", "title")
->setRequired(true)
->removeDecorator('DtDdWrapper')
->removeDecorator('label')
->removeDecorator('HtmlTag');
Dojo Controller
public function industryAction(){
$db = Zend_Db::factory($this->config->database);
$result = $db->fetchAll("SELECT * FROM industries");
$data = new Zend_Dojo_Data('industryid', $result);
$this->_helper->autoCompleteDojo($data);
$db->closeConnection();
}
The annoying thing is all my other Dojo elements on this form and other forms work well it is just whenever I do Filtering Selects that I hit these problems, and this problem causes all the other elements in a form to fail too.
Thanks in advance.

The problem is actually with how Zend Framework initializes the dijits and data stores before the toolkit is fully loaded, in this case specifically the methods assigning the store to the dijit. I ran into this issue as well and found the best way to work around the issues was to either pass the data store from the controller to a JavaScript variable defined in the view or do what your did with a specific autocomplete action. Based on your example I would make the following changes.
In your form I would simplify the element:
$industry = new Zend_Dojo_Form_Element_FilteringSelect('industry');
$industry->setAutocomplete(true)
->setRequired(true)
->removeDecorator('DtDdWrapper')
->removeDecorator('label')
->removeDecorator('HtmlTag');
In your view you want to connect the store to your dijit and make sure that you have loaded the dojo.data.ItemFileReadStore module:
<?php $this->dojo()->onLoadCaptureStart()?>
function(){
dijit.byId('industry').store = new dojo.data.ItemFileReadStore({ url: '/controller/industry' });
}
<?php
$this->dojo()->onLoadCaptureEnd();
$this->dojo()->requireModule('dojo.data.ItemFileReadStore');
?>
As I mentioned I ran into a similar issue which I answered here . Another issue I discovered is that the data store does not like dealing with labels declared anything other than "name" for the label declaration in the Zend_Dojo_Data.

Related

Joomla: how can I use one form for frontend and backend view?

I am creating a Joomla 2.5 component. In the backend I created a model/view/controller 'Members' which shows a grid. I also created an MVC 'Member' which is used to add or edit a member from the grid. So far so good.
Now, I would like to add a frontend view that is very similar to the 'Member' view in the backend, but this one is meant for visitors so they can subscribe themselves. It has to look more user friendly than the backend form, so I will create a slightly different 'Member' view in the frontend, but I would really like to reuse the form file (/administrator/components/mycomponent/models/forms/member.xml) from the backend!
So, my question is how my frontend view can find and use that backend form?
You definitely have to load it in the model. Your model has to extend JModelAdmin and then the getForm function has to load the form
public function getForm($data = array(), $loadData = true) {
// Get the form.
JForm::addFormPath(JPATH_COMPONENT_ADMINISTRATOR . '/models/forms');
JForm::addFieldPath(JPATH_COMPONENT_ADMINISTRATOR . '/models/fields');
$form = $this->loadForm('com_dpattachments.attachment', 'attachment', array('control' => 'jform', 'load_data' => $loadData));
if (empty($form)) {
return false;
}
....
}
I'm using the same approach in my DPAttachments component, it is for Joomla 3.1 but the main code, to use the same model and form on the front and back, should also run on Joomla 2.5. Here is the link to the getForm function
https://github.com/Digital-Peak/DPAttachments/blob/master/com_dpattachments/admin/models/attachment.php#L102
If you are following Joomla MVC guidance your frontend should be able to pick-up the forms automatically.
In your view (though it should request it from the model actually) you can write:
$formsPath = JPATH_ADMINISTRATOR.DS.'components'.DS.'com_mycom'.DS.'models'.DS.'forms';
$this->form = JForm::getInstance('myform', $formsPath.DS.'myform.xml');
You can also look at the summer of code cm_config project which pulls the config forms and the templateDetails form to the front end using JSON. https://github.com/Buddhima/joomla-cms/tree/gsoc_com_config or the com_services branch.

Zend creating forms based on requests within one controller/action

I don't really know how to word the title well, but here's my issue. I decided instead of having 25 controllers to handle pages, I have one PageController with a viewAction that takes in a :page parameter - for example, http://localhost/website/page/about-us would direct to PageController::viewAction() with a parameter of page = about-us. All of the pages are stored in a templates folder, so the viewrenderer is set to render application\templates\default\about-us.phtml.
I did this so I can consolidate and it seemed like a better approach. My question is the following: lets say when the page request is contact-us, I would need a Zend_Form to be used within the contact page. So, I would need a way within PageController::viewAction() to recognize that the page needs to have a form built, build the form, and also upon submission the need to process it (maybe this should be handled in an abstract process method - not sure).
I have no idea how to implement this. I thought maybe I can store a column with the name of a form and a connecting page identifier. Even better, create a one-to-many page to forms, and then in the submission loop through the forms and check if submitted and if so then process it (maybe there is a isSubmitted() method within zend_form. I really don't know how to handle this, and am looking for any help i can get.
Thanks!
Here is something that came to mind that may work or help point you in a direction that works for you.
This may only work well assuming you were to have no more than one form per page, if you need more than one form on a page, you would have to do something beyond this automatic form handling.
Create a standard location for forms that are attached to pages (e.g. application/forms/page). This is where the automatic forms associated with pages will be kept.
In your viewAction, you could take advantage of the autoloader to see if a form for that page exists. For example:
$page = $this->getParam('page');
$page = ucfirst(preg_replace('/-(\w)/ie', "strtoupper('$1')", $page)); // contact-us -> ContactUs
$class = 'Application_Form_Page_' . $page;
// class_exists will invoke the autoloader to map a class to a file
if (class_exists($class)) {
// a form is defined for this page
$form = new $class();
// check if form was posted
if ($this->getRequest()->isPost()) {
if ($form->isValid($this->getRequest()->getPost()) {
// form is valid - determine how to process it
}
}
// assign the form to the view
$this->view->pageForm = $form;
}
All this really leaves out is the action you take to process a specific form. Since the contact form will likely generate an email, and another form may insert data into a database, you will need some sort of callback system or perhaps another class that can be mapped automatically which contains the form processor code.
Anyway something along those lines is what came to mind first, I hope that helps give you some more ideas.

Zend Form Element with Javascript - Decorator, View Helper or View Script?

I want to add some javacsript to a Zend_Form_Element_Text .
At first I thought a decorator would be the best way to do it, but since it is just a script (the markup doesn't change) then maybe a view helper is better? or a view script?
It seems like they are all for the same purpose (regarding a form element).
The javascript I want to add is not an event (e.g. change, click, etc.). I can add it easily with headScript() but I want to make it re-usable , that's why I thought about a decorator/view helper. I'm just not clear about the difference between them.
What is the best practice in this case? advantages?
UPDATE: Seems like the best practice is to use view helpers from view scripts , so decorators would be a better fit?
Thanks.
You could create your own decorator by extending Zend_From_Decorator_Abstract and generate your snippet in it's render() method :
class My_Decorator_FieldInitializer extends Zend_Form_Decorator_Abstract {
public function render($content){
$separator = $this->getSeparator();
$element = $this->getElement();
$output = '<script>'.
//you write your js snippet here, using
//the data you have in $element if you need
.'</script>';
return $content . $separator . $output;
}
}
If you need more details, ask for it in a comment, i'll edit this answer. And I didn't test this code.
Use setAttrib function.
eg:-
$element = new Zend_Form_Element_Text('test');
$element->setAttrib('onclick', 'alert("Test")');
I'm not actually seeing where this needs to be a decorator or a view-helper or a view-script.
If I wanted to attach some client-side behavior to a form element, I'd probably set an attribute with $elt->setAttrib('class', 'someClass') or $elt->setAttrib('id', 'someId'), some hook onto which my script can attach. Then I'd add listeners/handlers to those targeted elements.
For example, for a click handler using jQuery , it would be something like:
(function($){
$(document).ready(function(){
$('.someClass').click(function(e){
// handle the event here
});
});
})(jQuery);
The benefit is that it is unobtrusive, so the markup remains clean. Hopefully, the javascript is an enhancement- not a critical part of the functionality - so it degrades gracefully.
Perhaps you mean that this javascript segment itself needs to be reusable across different element identifiers - someClass, in this example. In this case, you could simply write a view-helper that accepts the CSS class name as the parameter.
"the markup doesn't change", Yap,
but I like to add some javascript function throw ZendForm Element:
$text_f = new Zend_Form_Element_Text("text_id");
$text_f->setAttrib('OnChange', 'someFunction($(this));');
The best way is if you are working with a team, where all of you should use same code standard. For me and my team this is the code above.

Loading view file into a variable in Zend Framework

I am trying to send mail using mail templates. To do this I want to load a .tpl into a variable. Instead of loading an HTML file and substituting placeholders, I wonder if it is possible to set values of the view in the controller, and then load this view into a variable. This way I would have a variable containing the HTML mail filled out with the information set in the controller prior to loading the view.
Any alternatives are also welcome, I mean, if there are already ways of doing mail templating in a more standardized way.
A great idea Erik, and I've done this many times.
Zend_View is really just a templating system, and can be used to generate anything, not just HTML.
Sample code - create a view, assign some data, render the view and send the mail!
$view = $this->getHelper('ViewRenderer')->view;
$view->email = $data['email'];
$view->password = $data['password'];
$text = $view->render('mail/new-user.php');
$mail = new Zend_Mail();
$mail->addTo($data['email'], $data['forename'] . ' ' . $data['lastname']);
$mail->setSubject('Account Details');
$mail->setBodyText($text, 'utf-8');
$mail->send();
In the first line I retrieve the ViewRenderer's view so I have access to the normal script paths. You can create a new Zend_View object, but you'll need to add the path to your view scripts manually.
In my example text based content is generated, but you could generate HTML all the same.
Sorry guys (and girls). My google skills must have noticed it was early in the morning. I found what I was looking for here:
http://myzendframeworkexperience.blogspot.com/2008/09/sending-mails-with-templates.html

Loading models in Zend_Form using Zend Framework

I'm trying to build a form using the Zend_Form component, but the number of elements varies. The information for each Zend_Form element is stored in a database (name, options, validators, filters, etc.).
The application I'm working on consists of building surveys which contain a varying number of questions. Each question is associated with different arrays of answers. Ultimately my goal is to build arrays of radio/checkbox buttons, dynamically, server-side.
I'm looking for a pretty way to generate my form, but I'm not sure of the best way to load the model within the form. Should the model be loaded in the controller then passed (somehow, via a parameter?) directly to the form, or is it better to load the model within the Form init() method? Where's the best place to put the logic, should it be within the form class, or within the controller, or within the model?
My idea is to fetch form element properties (name, rules, filters, etc.) in the database, then iterate and finally render the form. What do you think of this approach? Ultimately, elements will be dynamically added (client-side), this time, using AJAX and a JavaScript library (such as jQuery).
Here are a couple useful links I found via Google, but I think they all answer a slightly different question than mine:
On building dynamic forms, server side:
http://framework.zend.com/wiki/display/ZFPROP/Zend_Form+generation+from+models+-+Jani+Hartikainen
http://weierophinney.net/matthew/archives/200-Using-Zend_Form-in-Your-Models.html
http://codeutopia.net/blog/2009/01/07/another-idea-for-using-models-with-forms/
On building dynamic forms, client side, with AJAX processing:
http://www.jeremykendall.net/2009/01/19/dynamically-adding-elements-to-zend-form/
I think I found a possible solution, it involves passing an array of Zend Form elements to the Zend Form::__construct() method. The constructor takes an array of options, one of them is called "elements". Have a look at the source code within the Zend Framework library.
I coded a new private method within the controller, called buildSurveyForm(). Note : the object, passed as a parameter, is built from a huge SQL query with half a dozen JOIN statements, fetching data from a few tables (surveys, questions, answers, etc.) within the database. One of the public attributes for this class consists of an array of questions, stored as objects (with public methods/attributes as well, etc.). Same for answers. The code for building these classes is pretty trivial and out of topic here.
Here's the code within the survey controller. I copy/pasted and edited/dropped a few lines to make it a lot clearer :
private function buildSurveyForm(MyApp_Object_Survey $survey)
{
foreach ($survey->questions as $question)
{
$element = new Zend_Form_Element_MultiCheckbox($question->order);
$element->addMultiOptions($question->getAnswersLabels());
$element->setName($question->order);
$element->setLabel($question->title);
$elements[] = $element;
}
// Here's the trick :
$formOptions = array('elements' => $elements);
$surveyForm = new MyApp_Survey_Form($formOptions);
$urlHelper = $this->_helper->getHelper('url');
$surveyForm->setAction($urlHelper->url(array(
'controller' => 'survey',
'action' => 'vote'),
'default'
));
$surveyForm->setMethod('post');
$this->_forms['survey'] = $surveyForm;
return $this->_forms['survey'];
}
The MyApp Survey Form class only contains a Submit button within the init() method. The dynamically generated elements with the code above are added BEFORE this submit button (which is unexpected, but useful). This class simply extends Zend_Form.
Then, within survey controller / view action :
public function viewAction()
{
$surveyModel = $this->_model['survey'];
$survey = $surveyModel->getFullSurvey($this->_getParam('id'));
$survey = new MyApp_Object_Survey($survey);
// Calls above private method :
$surveyForm = $this->buildSurveyForm($survey);
$this->view->assign(array(
'surveyForm' => $surveyForm,
));
}
Adding filters, validators and decorators to form elements is now trivial. My proposal is a bit dirty, but I think it gets the job done. I will add a new proposal if I find something more elegant. Feel free to post different answers/solutions.
You could extend Zend_Form.
Zend form is not good place for logic, only form representation.
So, Load all needed elements using model in controller and pass them to the form in contructor as parameters.