Update area outside of CGridView via Ajax - ajax

I'm working with CGridview and updating the grid after an Ajax call. However before I get into the grid I have a a small title and a count $model->itemCount identifying how many records there are. How would I additionally try to update this piece of information along with the grid. Would it be a separate JS call?
Appreciate any help
This is my current code for the grid
'click'=>"function(){
$.fn.yiiGridView.update('item-grid', {
type:'POST',
url:$(this).attr('href'),
success:function(message) {
$('#Ajax-Flash').html(message).fadeIn().animate({opacity: 1.0}, 3000).fadeOut('slow');
$.fn.yiiGridView.update('item-grid');
}
})
return false;
}",

Not sure is this what yoy want but you can use beforeAjaxUpdate() in CgridView as shown below
<?php
$this->widget('zii.widgets.grid.CGridView', array('id'=>'insurance_grid',
'beforeAjaxUpdate'=>"function(id, data){
//Your code to update the title and count
}",
'dataProvider'=>$model->search(),
//'filter'=>$model,
'summaryText' => '', // 1st way
'template' => '{items}{pager}', // 2nd way
'selectableRows' => 2,
'selectionChanged' => "
function(id){
}",
'columns'=>array(array('id'=>'selectedCompanies',
'class'=>'CCheckBoxColumn',
array('name'=>'Agency Name',
'type'=>'raw',
'value'=>'$data->agencyname',
),
),
));
?>

Related

Content type is not saved when altering the node add form

Here, I have alter the add content type form as follows:
function hc_listings_form_alter(&$form, &$form_state, $form_id)
{
// print_r($form_id);
if($form_id =='home_care_popular_search_region_node_form'){
dpm($form,'form');
$selected_states=hc_listings_load_agecare_regions();
// dpm($selected_states,'selected');
reset($selected_states);
$first_state = key($selected_states);
// dpm($first_state,'$first_state');
$form['field_popular_state']=array(
'#type' => 'select',
'#default_value' => array_shift($selected_states),
'#title' => t('Popular State'),
'#description' => t('Home Care Popular State'),
'#options'=>hc_listings_load_agecare_regions(),
'#ajax'=>array(
'callback'=> 'hc_popular_region_form_ajax',
'wrapper'=> 'regions_list',
'event'=>'change',
'method'=>'replace',
),
'#required' => TRUE,
);
$form['field_popular_region']=array(
'#type' => 'container',
'#tree'=>TRUE,
'#prefix'=>'<div id="regions_list">',
'#suffix'=>'</div>'
);
$form['field_popular_region']['list']=array(
'#type' => 'checkboxes',
'#title' => t('Popular Search Regions'),
'#description' => t('Home Care Popular Search Regions'),
'#options'=>get_popular_regions($first_state),
'#required' => TRUE,
);
}
}
And the ajax Callback function is as follows:
function hc_popular_region_form_ajax($form, &$form_state){
if(isset($form_state['values']['field_popular_state'])){
$state=$form_state['values']['field_popular_state'];
hc_my_log($state);
$form['field_popular_region']['list']=array(
'#type'=>'checkboxes',
'#title'=>'Popular Search Regions',
'#description'=>'Home Care Popular Search Regions',
'#options'=>get_popular_regions($state)
);
hc_my_log($form['field_popular_region']['list']);
$form['field_popular_region']['list']=form_process_checkboxes($form['field_popular_region']['list']);
}
// $form_state['rebuild'] = true;
return $form['field_popular_region'];
}
This works but when the ajax callback is called it will execute the dpm($form,'form') (line:5) too. What is the reason for this?
And after that when I am submitting the form by clicking the default Save button in the node add form both popular regions and popular states values are not saved. What will be the cause of that? Should I have to alter the submission of the node too ?
Here ,I have altered the form fields in a wrong way so in the form submission it alerts me with errors saying that the form structure has been changed in my altering.
The error is that it is not directly targetting the specific form field..so it should be corrected as follows:
if($form_id =='home_care_popular_search_regions_node_form'){
$selected_states=hc_get_states();
reset($selected_states);
$first_state = key($selected_states);
dpm($first_state,'$first_state');
$state= (isset($form_state['values']['field_popular_state']['und'][0]['tid']))?$form_state['values']['field_popular_state']['und'][0]['tid']:$first_state;
//popular states field altering
$form['field_popular_state']['und']['#default_value']=$selected_states[$first_state];
$form['field_popular_state']['und']['#options']=$selected_states;
$form['field_popular_state']['und']['#ajax']['callback']='hc_popular_region_form_ajax';
$form['field_popular_state']['und']['#ajax']['wrapper']='regions_list';
$form['field_popular_state']['und']['#ajax']['method']='replace';
$form['field_popular_state']['und']['#ajax']['event']='change';
//popular regions field altering
$form['field_popular_region']['und']['#prefix']='<div id="regions_list">';
$form['field_popular_region']['und']['#suffix']='</div>';
$form['field_popular_region']['und']['#options']=hc_get_popular_regions($state);
}
Ajax callback is as follows:
function hc_popular_region_form_ajax($form, &$form_state){
return $form['field_popular_region'];
}
Note: the method hc_listings_load_agecare_regions() has been changed to hc_get_states()

Frontend custom post submission results in wp_insert_post() undefined

I've been struggling for a few days with this issue and I really hope you can help me out.
I've created a plugin, which is located in:
'/wp-content/plugins/my-cool-plugin'.
My plugin allows users to post a custom post type via a form on a public page, basically anyone should be able to post something.
Using jQuery, I listen to when my frontend form is submitted and using Ajax I pass the data from the form to a php file to process it into a post.
This file is located at:
'/wp-content/plugins/my-cool-plugin/inc/processor.php'.
Below is the content of my processor file:
$var1= $_POST['some'];
$var2= $_POST['data'];
$new_post = array(
'post_type' => 'my_custom_post',
'post_status' => 'publish',
'mcp_1' => $var1,
'mcp_2' => $var2
);
$post_id = wp_insert_post( $new_post, $wp_error );
if ($wp_error == 'false'){
$post_url = get_permalink( $post_id );
echo $post_url;
}else {
// some sort of error
}
When I test my form, it results in the following error:
Call to undefined function wp_insert_post() on line ... which is the following line:
$post_id = wp_insert_post( $new_post, $wp_error );
Do I need to include something since I'm not in the WordPress 'scope' anymore?
Or is there another (much better) way for inserting custom posts from a front end form?
Why are you running the file out of wordpress scope? That is not the best practive. Instead you could run it in wordpress scope and user wordpress native ajax.
add_action('wp_ajax_yourplugin_create_post', 'yourplugin_create_post');
add_action('wp_ajax_nopriv_yourplugin_create_post', 'yourplugin_create_post');
function yourplugin_create_post() {
// your code here
}
Then you would need your ajax url to be passed from php to js:
function your_plugin_ajaxurl() {
?>
<script type="text/javascript">
var yourPluginAjaxUrl = "<?php echo admin_url('admin-ajax.php'); ?>";
</script>
<?php
}
add_action('wp_head','your_plugin_ajaxurl');
Then you can use your ajax request but you would need to indicate action:yourplugin_create_post and url = yourPluginAjaxUrl
Try adding
require(dirname(__FILE__) . '/wp-load.php');
It took me some time to process Nick's answer, but I finally got it to work! Like Nick said, I dropped using the process file because is was out of the scope of WordPress. I moved my post creation from my proces file to a new function in the plugin init file (my-cool-plugin.php), as Nick suggested. This resulted in the following new function:
add_action('wp_ajax_coolplugin_create_post', 'coolplugin_create_post');
add_action('wp_ajax_nopriv_coolplugin_create_post', 'coolplugin_create_post');
function coolplugin_create_post() {
$var1 = $_POST['some'];
$var2 = $_POST['data'];
$new_post = array(
'post_type' => 'my_custom_post',
'post_status' => 'publish'
'post_title' => 'Some title'
);
$post_id = wp_insert_post( $new_post, $wp_error );
// check if there is a post id and use it to add custom meta
if ($post_id) {
update_post_meta($post_id, 'mcp_1', $var1);
update_post_meta($post_id, 'mcp_2', $var2);
}
if ($wp_error == false){
$post_url = get_permalink( $post_id );
echo $post_url;
}else {
// some sort of error
}
}
I also had to change the way I inserted my custom values into the newly created post, because the wp_insert_post() function only accepts default post parameters (see the wp_insert_post documentation for these parameters).
Next to my insert/create post function I also had to make some adjustments to my javascript file, which retrieves the filled in data from my form. Therefore (as Nick suggested) I needed to pass my Ajax URL from PHP to JS by adding the following function to my-cool-plugin.php like this:
function your_plugin_ajaxurl() { ?>
<script type="text/javascript">
var coolPluginAjaxUrl = "<?php echo admin_url('admin-ajax.php'); ?>";
</script>
<?php }
add_action('wp_head','your_plugin_ajaxurl');
By adding the coolPluginAjaxUrl variable to the head I'm able to use the URL in my javascript to post the data to when my form is submitted, like this:
$( '#form' ).on( 'submit', function(e) {
var request;
e.preventDefault();
var val_one = $( '#val-one' ).val();
var val_two = $( '#val-two' ).val();
var formData = {
action: 'coolplugin_create_post',
some: val_one,
data: val_two,
};
request = $.ajax({
type: 'POST',
url: coolPluginAjaxUrl,
data: formData,
});
});
The formData holds the coolplugin_create_post action defined in PHP and the request is posted to the coolPluginAjaxUrl URL, defined in the head.
Thanks Nick for pointing me into the right direction and I hope that my solution will also help others. Please note that I've stripped my code of several security measures for others to easily understand how the code works.

Ajax pagination and remembering last page

I have ajax pagination:
class AjaxPager extends CLinkPager {
protected function createPageButton($label,$page,$class,$hidden,$selected)
{
if($hidden || $selected)
$class.=' '.($hidden ? $this->hiddenPageCssClass : $this->selectedPageCssClass);
return '<li class="'.$class.'">'.CHtml::ajaxLink($label,$this->createPageUrl($page), array(
'update'=>'#auctionList',
'data' => array('price_from'=>$_GET['price_from'],'price_to'=>$_GET['price_to'])
), array('id'=>'link-'.uniqid())).'</li>';
}
}
When i am on second page, click to view item details and go back, then i am on first page. I know i must use history.pushState but I don't know how use it in AjaxPager. Can you help me?
Edit:
I add 'complete' => 'function(){ window.history.pushState({}, "", this.url); }', but when I use back button it loads only ajax content from cache, instead of layout with it. How to prevent this?

can we use sessions in cgridview to store the value obatined on cbuttoncolumn clicked

i need to know can we use sessions in cgridview to store the value obatined.
something like
in view
// cgridview
..........
' name',
array
('header'=>'ID',
'value'=>'Yii::app()->SESSION['id']=$data["rid"]'),
.......
this is my gridview
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$dataP10,
'ajaxUpdate'=>true,
'columns'=>array(
array('name'=>' Name','value'=>'$data["name"]'),
array('name'=>' createdate','value'=>'$data["createdate"]'),
array(
'class'=>'CButtonColumn',
'template'=>'{view}',
'buttons'=>array(
'view'=>array(
'url'=>'Yii::app()- >createUrl("controller/action",array("id"=>$data["id"]))',
),
),
),
),
));
?>
here data["id"] i dont want it to be querystring but something in session for that particular record its id to be in session
'view'=>array(
'url'=>'Yii::app()- >createUrl("controller/action",array("id"=>$data["id"]))',
),
can anyone let me know can this happen if so then do suggest your guidance
Your grid definition is mystery to me !
What I think you need is sth like this, ajax event on cbuttoncolumn
array(
'class'=>'CButtonColumn',
'header'=>'Add',
'template'=>'{add}',
'buttons'=>array(
'add'=>array(
'label'=>'Mark It',
'url'=>'Yii::app()->createUrl("Controller/markIt", array("id"=>$data['id']))',
'options'=>array(
'ajax'=>array(
'type'=>'POST',
'url'=>'js:$(this).attr("href")',
'success'=>'function(data, textStatus, jqXHR){
var json = $.parseJSON(data);
}',
'error'=>'function(jqXHR, textStatus, errorThrown){
alert(errorThrown)
}',
),
),
),
'view'=>array(
'url'=>'Yii::app()->createUrl("controller/view",array("id"=>$data["id"]))',
),
),
),
In the controller you have to define a function e. g
Controller
public function markIt($id){
if(Yii::app()->getRequest()->getIsAjaxRequest()) {
$_SESSION['id']=$id;
}
}
public function view($id){
//view records
}
Now given your comments down I am puzzled , you want to click on the record and
--> Add the respective record id to session
--> View the record
If you need to perform both actions you just need to put this at the top of view funciton e.g
function view($id){
//check if record found
$_SESSION['id']=$id;
...
reset of the code
}
else see above code where you have two buttons one to set the value to session other to view the record . You need to be clear about the flow of actions first .

Help with ajax callback and drupal_process_form

I have a form that is added through the nodeapi displayed only on view mode. Users can select an item from a select menu and their choice will automatically get saved to the database with a hook_menu callback on change. If the user has javascript disabled, it'll submit normally with the form api. This is all working fine, but now for security reasons I want to submit the ajax version via the form api too. My form_name_submit is simple like:
function mymodule_test_form_submit($form, &$form_state) {
global $user;
db_query("INSERT INTO {mymodule} (nid, uid, status, created) VALUES (%d, %d, %d, " . time() . ")", $form['#parameters'][2], $user->uid, $form_state['values']['mymodule_status']);
}
My ajax:
$('.mysubmit').css('display', 'none');
$('.myclass').change(function() {
$.ajax({
type: 'POST',
url: Drupal.settings.basePath + 'mymodule/set/' + $nid + '/' + $('.myclass').val(),
dataType: 'json',
data: { 'ajax' : true, 'form_build_id' : $('#mymodule-form input[name=form_build_id]').val() }
});
});
And my callback function:
function mymodule_set($nid, $status) {
$form_build_id = $_POST['form_build_id'];
$form_state = array('storage' => NULL, 'submitted' => FALSE);
$form = form_get_cache($form_build_id, $form_state);
$args = $form['#parameters'];
$form_id = array_shift($args);
$form['#post'] = $_POST;
$form['#redirect'] = FALSE;
$form['#programmed'] = FALSE;
$form_state['post'] = $_POST;
drupal_process_form($form_id, $form, $form_state);
}
Originally my callback function was about the same as my submit function, but now I'm trying to use the submit function with ajax as well. Is this the right way to use drupal_process_form? The form is grabbed from the cache, it get's validated and submitted if no errors? I'm using some code from this tutorial to apply to my situation: http://drupal.org/node/331941 There doesn't seem to be any examples of what I'm trying to do. I also have $form['#cache'] = TRUE; in my form function.
How does drupal_process_form compare the submitted values with the original form to check for integrity? Am I supposed to add my values to the form_state since the form state will be empty with ajax. Been stuck on this for a few days, hopefully someone has experience with this.
Thanks.
I had to do somenthing similar to you in the past and read the same tutorial you posted, unfortunately there isn't much information avalaible about this and it was headache for me to make it work. I don't remember well the details but I was taking a look to the code I wrote and here are a couple of suggestions that may work for you:
Do not submit the form using your own jQuery code, instead use the new "#ahah" property of form elements that can be used for calling your callback in the onchange of the select http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html/6#ahah
IF you are doing this in a node form, adding the #ahah property in a form alter may not work, I remember having seen an issue about this that wasn't solved at that moment. if this is the case, use this code for attaching the ahah binding, you'll not need "efect", "method" or "progress" since you just want to submit the form, not to change anything about it:
function YOURMODULE_form_alter(&$form, $form_state, $form_id) {
if ('YOURCONTENTTYPE_node_form' == $form_id) {
//the only way I could make it work for exisiting fields is adding the binding "manually"
$ahah_binding = array(
'url' => url('YOURCALLBACKPATH'),
'event' => 'change',
'wrapper' => 'FIELD-wrapper',
'selector' => '#FIELD',
'effect' => 'fade',
'method' => 'replace',
'progress' => array('type' => 'throbber'),
);
drupal_add_js('misc/jquery.form.js');
drupal_add_js('misc/ahah.js');
drupal_add_js(array('ahah' => array('FIELDd' => $ahah_binding)), 'setting');
//force the form to be cached
$form['#cache'] = TRUE;
}
}
Here is my callback function, note that it has some modifications from the tutorial you posted:
function YOURMODULE_js() {
// The form is generated in an include file which we need to include manually.
include_once 'modules/node/node.pages.inc';
// We're starting in step #3, preparing for #4.
//I have to add the 'rebuild' element, if not an empty node was created
$form_state = array('storage' => NULL, 'submitted' => FALSE, 'rebuild' => TRUE);
$form_build_id = $_POST['form_build_id'];
// Step #4.
$form = form_get_cache($form_build_id, $form_state);
// Preparing for #5.
$args = $form['#parameters'];
$form_id = array_shift($args);
$form_state['post'] = $form['#post'] = $_POST;
$form['#programmed'] = $form['#redirect'] = FALSE;
// if you want to do any modification to the form values, this is the place
// Step #5.
drupal_process_form($form_id, $form, $form_state);
// Step #6 and #7 and #8.
$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
// Final rendering callback.
drupal_json(array('status' => TRUE, 'data' => $output));
}
As I said before there are details that I have forgot but maybe this will help you.
Good Luck.

Resources