Below i have an ajax tab example:
$this->widget('zii.widgets.jui.CJuiTabs', array(
'tabs' => array(
'StaticTab 1' => 'Content for tab 1',
'StaticTab 2' => array('content' => 'Content for tab 2', 'id' => 'tab2'),
// panel 3 contains the content rendered by a partial view
'AjaxTab' => array('ajax' => $this->createUrl('/AjaxModule/ajax/reqTest01')),
),
// additional javascript options for the tabs plugin
'options' => array(
'collapsible' => true,
),
));
but i don't know what happens in /AjaxModule/ajax/reqTest01.
There is a missing part in this example, the rendering view, and i don't know how to design it so that the ajax call to work. Thanks.
According to the code you have put up, specifically this line:
'AjaxTab' => array('ajax' => $this->createUrl('/AjaxModule/ajax/reqTest01')),
We know that we need ajaxmodule, ajax controller, reqtest01 action, so do the following steps:
First
Create a module, it'll have to be named AjaxModule.
Second
Create a controller in this AjaxModule named Ajax.
Third
Create an action within this Ajax controller, named ReqTest01.
Within this action you can either directly echo html, or use renderPartial(), to render a view file partially for ajax.
So your controller Ajax and the action within looks somewhat like this
<?php
class AjaxController extends Controller
{
public function actionIndex()
{
$this->render('index');
}
public function actionReqTest01(){
// directly echoing output is hardly of any use, like echo "Directly echoing this";
$this->renderPartial('rendpar_ajax'); // renderPartial is way better as we have a view file rendpar_ajax.php that we can manipulate easily
}
}
Fourth
Now we can code the rendpar_ajax.php view file, create this file in the views folder of the ajaxController controller in the AjaxModule module.
<?php
// rendpar_ajax.php file for ajax tab
// have any code here, use widgets, form, html helper etc
echo "<h1>AjaxModule--AjaxController--actionReqTest01</h1>";
echo "<p>This view is partially rendered</p>";
Read more about creating modules, controllers, actions, and how they are used, and how the yii directory hierarchy works.
Good luck!
Edit: Note that to a view we can also pass dataproviders for getting complex dynamic views.
Related
I want to create a custom widget named 'IssueList' which will extend 'ListView'.
<?php
namespace frontend\components;
use yii\base\Widget;
use yii\widgets\ListView;
class IssueList extends Widget{
public $dataProvider;
public function init(){
parent::init();
}
public function run(){
return ListView::widget([
'dataProvider' => $this->dataProvider,
'itemOptions' => [
'class' => 'item issue-item'
],
'options' => [
'class' => 'issue_list'
],
'itemView' => '_issueListView',
'layout' => '{items}{pager}',
]);
}
}?>
However the ListView has a custom itemView. When rendering the widget I get this error
The view file does not exist:
/var/www/clients/client1/web1/frontend/views/comments/_issueListView.php
Its obviously looking in the wrong directory, how do I change this?
itemView is passed to yii\base\View render() which is responsible for rendering view. So you can change view path how you want, using aliases if needed:
Renders a view.
The view to be rendered can be specified in one of the following
formats:
path alias (e.g. "#app/views/site/index");
absolute path within application (e.g. "//site/index"): the view name starts with double slashes. The actual view file will be looked
for under the view path of the application.
absolute path within current module (e.g. "/site/index"): the view name starts with a single slash. The actual view file will be looked
for under the view path of the current module.
relative view (e.g. "index"): the view name does not start with # or /. The corresponding view file will be looked for under the view path
of the view $context. If $context is not given, it will be looked for
under the directory containing the view currently being rendered
(i.e., this happens when rendering a view within another view).
If you want it to be more dynamic, you can pass closure to itemView with the following signature:
function ($model, $key, $index, $widget) {
...
}
See docs for itemView here.
Besides the API Documentation, rendering views and specifying paths is described in official docs in Views (Rendering Views) section.
well i trying build a website on ZendFrameWork 2 i want execute various actions in my layout main like a fild of search, or a form for loguin etc. each one of this i believe should are in views diferents with your actions, how i do for references this actions with your views that will return this element for i put where i want in my layout. like the helper $this->content; where it return the context view and action no just the view with no function, which are the best way for i do this or a way alternative
I think what you need are view partials. You can read on view partials in the ZF2 official documentation.
You have to create your partials and then you register them under your template_map inside the view_manager config.
'view_manager' => array(
//...
'template_map' => array(
'my/form' => __DIR__ . '/../view/partials/form.phtml',
'my/partial' => __DIR__ . '/../view/partials/partial.phtml',
)
),
Then in every layout you can simply embed them like this:
echo $this->partial('my/form');
echo $this->partial('my/partial');
If you need to pass variables to your partials you can pass a second argument:
echo $this->partial('my/form', array('foo' => 'bar'));
I would like to include multiple views within a view in ZF2.
I read this link:
http://framework.zend.com/manual/current/en/modules/zend.view.quick-start.html
but there is a problem. In this way, I have to pass the values that are within a view, like this:
$secondView = new ViewModel (array('var1' => $var1 ......));
In this mode the controller and second action are bypassed.
Is there a way to include a view without bypassing them? I would like variables to be passed from the second action controller, like an include php statement
If I understood correctly your question, I think that what you're asking is not possible.
My suggestion would be to move the retrieval of the data you need for the secondView somewhere else, away from the controller, and call it both from the second controller and form the first controller to pass them to the secondView.
If you really want to go on with your approach, the only possibility I see is to use javascript and ajax calls to retrieve the partials you need in your view
You can use partials for that.
In your module.config.php under the 'view_manager' key you define a template map for your partial:
'view_manager' => array(
'template_map' => array(
'myPartial' => __DIR__ . '/../view/mymodule/partial/myPartial.phtml',
),
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
Then in the view container you can use that partial using the partial() View Helper:
<div><?php echo $this->partial('myPartial', array('var1' => 'value1'); ?></div>
You can also pass variables to your partial. Those variables are referenced in your partial like any other view variable:
echo $var1;
I was hoping someone could share some advice on the file structure a mobile app with jQuery Mobile, Ajax and PHP.
I am pretty new to Ajax and I am struggling to integrate it into my MVC framework.
I have my Models, Views and Controller files and normally I would simply use my Controllers to feed my Views with the data from the Models.
However, when using Ajax, I understand that you can not POST (or GET) data to a specific function in a Controller directly. (Please correct me if I am wrong)
What is the best practice here?
Create a specific Ajax Controller with no functions?
Have a separate "connecting" php-file and post the Ajax call to that file which then calls the Controller files and retrieves the data.
Any ideas and maybe even some sample code would be greatly appreciated.
Here is an example how you do it with Yii framework.
This is your ajax class 'AjaxController.php':
class UserController extends Controller
{
/**
* Specifies the access control rules.
* This method is used by the 'accessControl' filter.
*
* #return array access control rules
*/
public function accessRules()
{
return array(
array('allow',
'actions' => array('foo', 'bar'),
'users' => array('?'),
),
array('allow',
'actions' => array('foo', 'bar'),
'users' => array('*'),
),
array('allow',
'actions' => array('foo', 'bar','regform'),
'users' => array('#'),
),
array('deny', // deny all users
'users' => array('*'),
),
);
}
// [...] all the common Yii Controller functions
public function actionRegform()
{
//get some data from database
$data = Yii::app()->db->createCommand('some sql')->queryRow();
//or render a view
$this->render('regform', array('mydata' => $dataFromDb));
//push out everything you want
echo 'my function was called!';
}
}
In your javascript you just call the url /ajax/regform and your MVC will know that ajax is the controller and actionRegform the function you are calling.
Do not forget to implement your function to the access rules of this controller.
The fact that You are using AJAX doesn't change much, the simplest way to use AJAX on your site is to put an extra POST (try not to use GET) parameter with will help You to determine if this is AJAX request. It can be just ajax=1. Then You can make a seperate view to show only those things that should be shown by ajax. this can be done on every components separately, or just in Your main index.php (or whatever your mine view file is called). In this file give some code like this:
if( ( isset($_POST['ajax']) ) and ( $_POST['ajax'] == 1 ) ){
echo just_main_content();// or $component->content - whatever You use
}else{
//normal page code
}
I believe that this is the easiest way
Currently I'm trying to implement this behavior:
I make several routers
Inside a router, I change an environment variable
That environment variable is accessible on before.dispatch
Basically, I want to be able to do this:
$app->get('(/)', function() use ($app, $env) {
$env['title'] = 'My page title';
$app->render('index.tpl', array(
'test' => 'Test!!!',
));
});
While I also have this:
$app->hook('slim.before.dispatch', function () use ($app, $env) {
$app->view()->appendData(array(
'env' => $env
));
if (!isset($env['partial']) || $env['partial'] != true)
$app->render('header.tpl');
});
Problem is, the $env['title'] is only available in index.tpl, and not header.tpl, I'm assuming because in before.dispatch, I don't apply the route yet.
How can I achieve this behavior without having to applyHook() at every route I need to change header template variables for?
Thank you!
You've got a scope issue, and the way you're attempting to get a variable from your route into the variable in your hook simply isn't going to work.
Instead, you should be adding $env to view via the $app->render() call in your route, like so:
$app->render('index.tpl', array(
'test' => 'Test!!!',
'env' => $env,
));
When you do that, the data in $env will be available in any of the slim.after hooks.
IMPORTANT: Since you're appending 'env' to the view data in your hook, I highly recommend naming your page title array key title, or else the env data you've appended in the render method will be overwritten. The new render arguments would look like:
$app->render('index.tpl', array(
'test' => 'Test!!!',
'title' => 'My page title',
));
Your template engine should now be able to access the title in both header.tpl and index.tpl.