load view via ajax cakephp 2.x - ajax

i want to load a list of items on my view via ajax here is my code on lst.cpt
<div id='benpane' class='clearfix'>
<script type="text/javascript">
<?php echo $ajax->remoteFunction(array(
'url'=>array('controller'=>'benefits', 'action'=>'display'),
'update'=>'benpane',
'indicator'=>'benIndicator'
)); ?>
</script>
</div>
here is the lst function in my controller
function lst() {
$this->paginate = array('order' => array('ben_name' => 'ASC'),'conditions' => array($this->Benefit->parseCriteria($this->passedArgs)));
$benefit = $this->paginate('Benefit');
$this->set('bens', $benefit);
}
when i try to open the view i get the error
Error: Call to a member function remoteFunction() on a non-object
File: /var/www/hassportal/app/View/Benefits/lst.ctp
Line: 14
what could i be doing wrong?

Besides the fact that the Ajax Helper has been deprecated (and/or perhaps you are not using cakephp 2.x), you seem to be calling the wrong action:
'action'=>'display'
should be:
'action'=>'lst'
Also, I would move the code outside of the DIV that is supposed to be updated with the data coming from that action.

Use this
$this->Ajax->remoteFunction
insited of
$ajax->remoteFunction
Ex:-
<?php echo $this->Ajax->remoteFunction(array(
'url'=>array('controller'=>'benefits', 'action'=>'display'),
'update'=>'benpane',
'indicator'=>'benIndicator'
)); ?>

Related

How to create dynamic Checkboxlist in Yii?

I would like a help to solve this problem. I'm using Yii 1.1 and trying to create a dynamic CheckBox list in which its elements change depending on the value selected in a DropDown element.
I created this DropDown element with the arguments in Ajax to perform the function update in the Controller. The function in the Controller is doing the lookup in the table according to the value passed.
Up to this point, the code is working fine, generating an array with the values that should be displayed. The problem is that I'm not able to configure the return of these data and I can't even display them in the View.
Below is the code data:
View - DropDown element:
echo CHtml::activeDropDownList($model, 'standard',
array(CHtml::listData(standard::model()->findAll(), 'name','name')),
array('empty'=>'',
'ajax'=>array(
'type'=>'POST',
'url'=>CController::createUrl('/getTeam',array('form'=>'Team','field'=>'standard')),
'update'=>'#Audit_team'),
)
);?>
Controller:
public function actionGetTeam($form,$field) {
$post = $_POST;
$standard = $post[$form][$field];
$Lists = TblAuditStandard::model()->findAll("standard = $standard");
foreach ($Lists as $List){
$AuditTeam[] = $List->name." - ".$List->login;
asort($AuditTeam);
foreach ($AuditTeam as $id=>$value )
echo CHtml::tag('option',array('value'=>$id),$value,true);
}
}
View - Checkbox element:
<div class="row">
<?php echo $form->labelEx($model,'team'); ?>
<?php echo CHtml::activeCheckBoxList($model,'team',array()); ?>
<?php echo $form->error($model,'team'); ?>
</div>
I hope someone can help me solve this problem. Thanks.

AJAX pagination with CakePHP

I'm struggling to get some ajax pagination with cakephp working. I've read the instructions here and various other pages on the internet eg: SO link
However I get an error in the console:
Uncaught type error undefined is not a function
Which occurs on the $(document).ready() function generated by $this->Js->writeBuffer().
Any ideas on what I'm doing wrong?
In my view index.ctp I set the paginator's options:
$this->Paginator->options(array(
'update' => '#content',
'evalScripts' => true)
);
Then carry on with the remainder of the view, in particular I render the table. The controller has fetched data to be displayed.
I output my pagination controls:
echo $this->Paginator->prev();
echo $this->Paginator->numbers();
echo $this->Paginator->next();
At the end of my view I do:
echo $this->Js->writeBuffer();
I have added the relevant helpers and components to my controller:
public $helpers = array('Js' => array('jquery'));
public $components = array(
'Paginator',
'RequestHandler'
);
In default.ctp I have included jquery by adding this to the end of the HTML (just before </body>:
<script src="https://code.jquery.com/jquery.js"></script>
It looks it works in that it generated the relevant javascript and provides the id's for the links but clicking the links just works like normal.
Functions need to exist before they are called
In default.ctp I have included jquery by adding this to the end of the HTML (just before </body>
Jquery needs to be loaded before it is used. Ensure that script tags appear in the rendered html in this order:
<script src="//code.jquery.com/jquery.js"></script>
... anything or nothing ...
<script>
$(document).ready(
...

Yii ClientSide Validation on Render Partial not Working

I have a Yii form which calls a render partial from another model (team has_many team_members). I want to call via ajax a partial view to add members in team/_form. All works (call, show, save) except for ajax validations (server and client side). If i submit form, member's model isn't validating, even in client side, it's not validating the required fields.
Any clue?
//_form
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'team-form',
'enableAjaxValidation'=>true,
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
'validateOnChange'=>true
),
'htmlOptions' => array('enctype' => 'multipart/form-data'),
)); ?>
//Controller
public function actionMember($index)
{
$model = new TeamMember();
$this->renderPartial('_member',array(
'model'=> $model, 'index'=> $index
)
,false,true
);
}
public function actionCreate()
{
$model=new Team;
$members = array();
if(isset($_POST['Team']))
{
$model->attributes=$_POST['Team'];
if(!empty($_POST['TeamMember'])){
foreach($_POST['TeamMember'] as $team_member)
{
$mem = new TeamMember();
$mem->setAttribute($team_member);
if($mem->validate(array('name'))) $members[]=$mem;
}
}
$this->redirect(array('team/create','id'=>$model->id,'#'=>'submit-message'));
}
$members[]=new TeamMember;
$this->performAjaxMemberValidation($members);
$this->render('create',array(
'model'=>$model,'members'=>$members
));
}
//_member
<div class="row-member<?php echo $index; ?>">
<h3>Member <?php echo $index+1; ?></h3>
<div class="row">
<?php echo CHtml::activeLabel($model, "[$index]name",array('class'=>'member')); ?>
<?php echo CHtml::activeTextField($model, "[$index]name",array('class'=>'member')); ?>
<?php echo CHtml::error($model, "[$index]name");?>
</div>
</div>
ProcessOutput was set to true. No dice.
Switch renderPartial() to render(). No dice.
If you will look at the CActiveForm::run:
$cs->registerCoreScript('yiiactiveform');
//...
$cs->registerScript(__CLASS__.'#'.$id,"jQuery('#$id').yiiactiveform($options);");
Then you will understand that you validation will not work, because you render partial and not the whole page. And these scripts show up at the bottom of the page. So you should solve this by execute these scripts.
After you partial is rendered, try to get activeform script which should be stored at the scipts array:
$this->renderPartial('_member',array('model'=> $model, 'index'=> $index));
$script = Yii::app()->clientScript->scripts[CClientScript::POS_READY]['CActiveForm#team-form'];
after, send it with rendered html to page:
echo "<script type='text/javascript'>$script</script>"
Also remember before you will append recieved html on the page you should include jquery.yiiactiveform.js, if you not already did it(by render another form, or registerCoreScript('yiiactiveform')), on the page from calling ajax request. Otherwise javascript error will raised.
Hope this will help.
Edit:
Sorry I'm not understood that you are render part of form and not the whole. But you validation will not work exactly with the same issue. Because jQuery('#$id').yiiactiveform($options); script was not created for the field.
The actual problem is that the ActiveForm saves its attributes to be validated in the "settings" data attribute. I see you are already using indexes so what you need to add the new elements to this settings object in order for the validation to work. After the ajax response this is what must be done:
//Get the settings object from the form
var settings = $("#form").data('settings');
//Get all the newly inserted elements via jquery
$("[name^='YourModel']", data).each(function(k, v) {
//base attribute skeleton
var base = {
model : 'YourModel',
enableAjaxValidation : true,
errorCssClass : 'error',
status : 1,
hideErrorMessage : false,
};
var newRow = $.extend({
id : $(v).attr('id'),
inputID : $(v).attr('id'),
errorID : $(v).attr('id') + '_em_',
name : $(v).attr('name'),
}, base);
//push it to the settings.attribute object
settings.attributes.push(newRow);
});
//update the form
$("#form").data('settings', settings);
```
This way the ActiveForm will be aware of the new fields and will validate them.
Well, setting processOutput to true in renderPartial (in order to make client validation works on newly added fields) will not help in this case since it will only work for CActiveForm form and you don't have any form in your _member view (only input fields).
A simple way to deal with this kind of problem could be to use only ajax validation, and use CActiveForm::validateTabular() in your controller to validate your team members.

How to send a parameter and update an element using ajax in cakephp 2.x

I have an input field "#PostTitle" in which the user can enter a URL.
I want to send the user's input (upon change or upon exiting the field) to an action in my Posts controller which returns an array. Without CakePHP I think this would look something like this:
$(document).ready(function(){
$('#PostTitle').change(function(){
$.ajax({
type: 'POST',
url: '/posts/setPostImages',
data: $(this).serialize(),
success: function(data){
do something;
},
error: function(message){
console.debug(message);
}
});
return false;
});
});
The action in the Posts controller sets an array of links called $imageArray
(I CURL the page and return an array of all the images on that page, if it's of any interest).
Then, after I make the request, I would like to update an element which depends the contents of that array. The element contains the following code:
<div id="slider-wrap" class="boxframe">
<div class="coda-slider" id="slider-id">
<?php foreach ($imageArray as $image): ?>
<div class="crop">
<?php echo $this->Html->image($image); ?>
</div>
<?php endforeach; ?>
</div>
</div>
Any help is appreciated!
Edit: If I try this, the action isn't called at all:
echo $this->Js->link('update',
array('action' => 'setPostImages'),
array(
'update' => '#selectImage',
'data' => 'www.stackoverflow.com',
'async' => true,
'dataExpression'=>true,
'method' => 'POST'
)
);
If you want to generate this JS with CakePHP, take a look at JsHelper's event method and request method
The action the POST request hits should render your element and respond with HTML. JsHelper::request will then replace the contents of the element specified by the update param with your HTML.
Personally, I find it fairly obtuse to generate Javascript with a PHP framework. It quickly becomes difficult to do what you want. If you have even a moderate amount of Javascript, I recommend just writing it directly (you already seem to know how to do this!).
Your edit refers to a possibly different issue. What kind of Javascript errors are you getting in your browser's console when you click the link generated by that snippet?

cakephp ajax pagination works only once - scripts are not evaluatedd?

I followed tutorial from cakephp site but pagination with ajax works only once - the content is updated and its ok. But for the second time I click some page-link the whole page is reloaded - I think that click() event handlers are not binded again when content is refreshed by ajax - I don't know why... I am using this:
$this->Paginator->options(array(
'update' => '#content',
'evalScripts' => true
));
When I load page in the source code there is:
« Previous
$(document).ready(function (){
$("#link-925538478").bind("click", function (event) {
$.ajax({dataType:"html", success:function (data, textStatus){
$("#content").html(data);}, url:"\/final\/books\/index\/page:10\/sort:id\/direction:desc"});
return false;});
...
When I click for example next page (for the first time), everything is refreshed (the link hrefs also so it works) but the scripts are not reloaded so no click events are binded I think and clicking next page again just uses the link.
This is strange because I added this just after the pagination links:
<script>
$(document).ready(function (){
alert('yes');
});
</script>
And the alert is shown after first ajax refresh...
And I set up this thing ofc. <?php echo $this->Js->writeBuffer(); ?> at the end...
-------------------edit
I recognised that its not the paginator - for the following 2 links:
<?php echo $this->Js->link('link1', array('author' => 'abc'), array('update' => '#content')); ?>
<?php echo $this->Js->link('link2', array('author' => '123'), array('update' => '#content')); ?>
Its the same - when I click link1 its ajax, then when I click link2 there is normal reload - so it's somthing with script evaluation after ajax refresh... What that might be?
I am setting up JSHelper like this:
var $helpers = array('Js' => array('Jquery'));
I figured it out!!!
It's because ajax request sets the layout to app/View/Layouts/ajax.ctp and ajax.ctp is:
<?php echo $this->fetch('content'); ?>
I had to add this line
<?php echo $this->Js->writeBuffer(); ?>
To ajax.ctp to write java scripts (so the ajax links work after ajax request).
And now pagination works perfect!!!
Cake php Ajax Paginator not seems to be working fine. I had similar issues also.
I would recommend you to use the cakephp plugin Cakephp-DataTable
This plugin has implemented the pagination and it has most of the features by default. They have also provided documentation and if you find any difficulty in implementing please go throught the issues section
Also the developer is very responsive and can get clarifications for that plugin if you have any.

Resources