I am preparing a POC to use IMDB auto complete. I am facing a strange issue. When I enter any keyword, the controller doesn't get call. Here is snippets of javascript and the controller.
index.html
<script type="text/javascript">
$(function(){
$("#q").focus();
$("#q").autocomplete({
minLength: 0,
delay:5,
source: "suggest",
focus: function( event, ui ) {
$(this).val( ui.item.value );
return false;
},
select: function( event, ui ) {
$(this).val( ui.item.value );
return false;
}
}).data("uiAutocomplete")._renderItem = function( ul, item ) {
//code to render autocomplete list
};
});
</script>
application/controller/suggest.php
<?php
$term = trim(strtolower($_REQUEST['term']));
echo $term;
?>
My url is
/movies/index.php/suggest?term=g
Would anyone please guide me how to fix this?
Try returning a json string from php:
$arr = array(
0 => array(
'label' => 'item 001',
'value' => 1
),
1 => array(
'label' => 'item 002',
'value' => 2
),
2 => array(
'label' => 'item 003',
'value' => 3
),
);
echo json_encode($arr);
in source just give proper path for suggest controller by adding base_url define a global variable in javascript in base_url before calling script
<script>
var base_url = "<?=base_url()?>";
</script>
source: base_url+"suggest",
Related
Right now when I update my plugin page the settings save and does what I want besides calling my action hook, test handler. Overall, the ajax request seems to be working and adding my options to the database but not calling my test handler function. Is it possible to post to the options.php and call a custom function to perform a few more things?
Here is my jQuery code that submits the form data to WordPress options.php
jQuery(document).ready(function($) {
$('#yacht-form').on( 'submit', function(event) {
console.log($("input#submit").attr("disabled","disabled"));
var ylocations = $('#ylocations').val();
if (ylocations == 0) {
$('.button-save').html('<p>Error! Empty Value.</p>').show().fadeIn();
$('.button-save').addClass('button-error');
$('.button-save').delay(5000).fadeOut();
$("input#submit").removeAttr("disabled");
return false;
}
var settings = $(this).serialize();
console.log(settings);
// submit the data
$.post( 'options.php', settings, { action: 'test_handler'} ).error(
function() {
alert('error');
}).success( function() {
$('.button-save').html('<p>Changes Saved!</p>').show().fadeIn();
$('.button-save').delay(3000).fadeOut();
});
$("input#submit").removeAttr("disabled");
return false;
});
});
Here is the code I am calling the action
function test_handler() {
$post_arr = array(
'post_title' => 'Test post',
'post_content' => 'Test post content',
'post_status' => 'publish',
'post_author' => get_current_user_id(),
'tax_input' => array(
'hierarchical_tax' => $hierarchical_tax,
'non_hierarchical_tax' => $non_hierarchical_tax,
),
'meta_input' => array(
'test_meta_key' => 'value of test_meta_key',
),
);
wp_insert_post($post_arr);
wp_die();
}
add_action( 'wp_ajax_test_handler', 'test_handler' );
I'm having issues converting the following jQuery/AJAX call to CakePHP's JS Helper.
Here is what currently works:
<script type="text/javascript">
//<![CDATA[
$(document).ready(function () {
$("#DatabaseServerId").bind("change", function (event) {
var server_id = $("#DatabaseServerId").val();
$.ajax({
async:true,
dataType:"html",
evalScripts:true,
success:function (data, textStatus) {
$("#DatabaseEnvironmentId").html(data);
},
url:"\/apsportal\/servers\/get_environments/"+server_id
}
);
return false;
});
});
//]]>
</script>
Here is what I have thus far:
$data = $this->Js->get('#DatabaseServerId')->serializeForm(array('isForm' => true, 'inline' => true));
$this->Js->get('#DatabaseServerId')->event('change',
$this->Js->request(
array('controller' => 'servers', 'action' => 'get_environments'),
array(
'update' => '#DatabaseEnvironmentId',
'async' => true,
'type' => 'html',
'dataExpression' => true,
'evalScripts' => true,
'data' => $data,
)
)
);
The issue is that the parameter passed has an array key specified and narrows the usage of this action.
http://my.domain.com/servers/get_environments?data%5BDatabase%5D%5Bserver_id%5D=36
Since server_id is being used in other models, I would rather have this as generic as possible.
Note: I figure if I standardize to the JS Helper, if something changes in the future, I'll only have to change things once.
Per the comments, I used raw jQuery instead of CakePHP's methods.
I have a custom module right now in order to text AJAX functionality with Drupal Messages. The module has the following code (test_error.module):
<?php
function test_error_user_view_alter(&$build) {
//_assassinations_player_profile($build);
}
function test_error_form_alter(&$form, &$form_state, $form_id) {
$form['test_error'] = array(
'#type' => 'button',
'#name' => 'Error',
'#value' => t('Error'),
'#ajax' => array(
'callback' => 'test_error_error',
'wrapper' => 'the-wrapper-div-field',
),
);
$form['test_warning'] = array(
'#type' => 'button',
'#name' => 'Error',
'#value' => t('Error'),
'#ajax' => array(
'callback' => 'test_error_warning',
'wrapper' => 'the-wrapper-div-field',
),
);
return $form;
}
function test_error_error() {
drupal_set_message("Header error", 'error');
}
function test_error_warning() {
drupal_set_message("Header warning", 'warning');
}
Then, in page.tpl.php, I have the following to output $messages:
<div id="messages-wrap"><?php print $messages; ?></div>
The AJAX function happens when the button is clicked - setting the message - while the message only displays after the page reloads. I tried to hack my way through the return AJAX call like so:
jQuery(document).ready( function(){
jQuery('.ajax-processed').each( function(){
jQuery(this).unbind();
});
jQuery('#edit-test-warning, #edit-test-error').click( function() {
var the_form = jQuery(this).closest('form');
var form_action = the_form.attr('action');
var details = the_form.serialize();
jQuery.ajax({
type: "POST",
url: form_action,
data: details
}).done( function(){
jQuery('#messages-wrap').load("/ #messages-wrap");
});
});
});
The binding of a click event on the #edit-test-x buttons never occurs because of Drupal's native ajax.js preventing it by adding its ajax-x classes.
It's driving me crazy that this problem is so persistent and so difficult to solve when the goal is such a simple thing. What am I missing? Google searching and StackOverflow browsing has come up surprisingly fruitless.
Thanks!
At first, here is some explanations:
1. So you trying to render drupal messages as part of the form, you must to render drupal messages manually.
2. With using '#ajax' key, there is no additional (custom) JS required.
3. On the button click the form is rebuilded, so, all you need is to place message rendering code inside the form logic.
Code example for the simple case:
function test_error_form(&$form, &$form_state) {
$form['test_error'] = array(
'#type' => 'button',
'#value' => t('Error'),
'#ajax' => array(
'callback' => 'test_error_error',
'wrapper' => 'the-error-container',
),
);
$form['test_warning'] = array(
'#type' => 'button',
'#value' => t('Error'),
'#ajax' => array(
'callback' => 'test_error_warning',
'wrapper' => 'the-error-container',
),
);
return $form;
}
function test_error_error($form) {
drupal_set_message("Header error", 'error');
return array(
'#type' => 'markup',
'#markup' => theme('status_messages'),
);
}
function test_error_warning($form) {
drupal_set_message("Header warning", 'warning');
return array(
'#type' => 'markup',
'#markup' => theme('status_messages'),
);
}
Note, that you must have div with id="the-error-container" on the page.
If you want to render new drupal messages on the standard place, try to use ajax commands, like this:
$commands = array();
$commands[] = ajax_command_replace($selector, theme('status_messages'));
return array(
'#type' => 'ajax',
'#commands' => $commands,
);
where $selector - is a css/jquery selector of your message area.
Please ask, if there is some unclear.
I am using Yii Booster Yii extension for UI. I need to update the content of the tabs using ajax. Using below code I am able to get the content using renderPartial but instead I want to make ajax call and update the content.
$this->widget('bootstrap.widgets.TbTabs', array(
'type' => 'tabs',
'tabs' => array(
array('label' => 'Home', 'content' => $this->renderPartial('home', NULL, true), 'active' => true),
array('label' => 'Test', 'items' => array(
array('label' => 'Sub Tab 1', 'content' => $this->renderPartial('testpage', NULL, true)),
array('label' => 'Sub Tab 2', 'content' => 'some content ')
)),
)
)
);
Do I need to use jquery or something else to work with Yii Booster widgets ?. This is the first time I am using php/yii/extensions.
I am a bit confused so Yii Booster has integrated Bootstrap widgets so that they can be used with php. But for client side do I need to use jquery to manipulate bootstrap widgets ?
Are there any tutorials for using Yii Booster, I know the link to yii booster site, but there we just have simple examples nothing related to events, ajax.
Got this working. As #Sergey said I need to use 'shown' event. I gave ids to each tab to identify specific tab and load content. Here is the code
<?php $this->widget('bootstrap.widgets.TbTabs', array(
'id' => 'mytabs',
'type' => 'tabs',
'tabs' => array(
array('id' => 'tab1', 'label' => 'Tab 1', 'content' => $this->renderPartial('tab1', null, true), 'active' => true),
array('id' => 'tab2', 'label' => 'Tab 2', 'content' => 'loading ....'),
array('id' => 'tab3', 'label' => 'Tab 3', 'content' => 'loading ....'),
),
'events'=>array('shown'=>'js:loadContent')
)
);?>
We have 3 tabs, the content will be loaded using loadContent javascript function.
<script type="text/javascript">
function loadContent(e){
var tabId = e.target.getAttribute("href");
var ctUrl = '';
if(tabId == '#tab1') {
ctUrl = 'url to get tab 1 content';
} else if(tabId == '#tab2') {
ctUrl = 'url to get tab 2 content';
} else if(tabId == '#tab3') {
ctUrl = 'url to get tab 3 content';
}
if(ctUrl != '') {
$.ajax({
url : ctUrl,
type : 'POST',
dataType : 'html',
cache : false,
success : function(html)
{
jQuery(tabId).html(html);
},
error:function(){
alert('Request failed');
}
});
}
preventDefault();
return false;
}
Here we get the target, that should be the anchor element of the tab that we clicked, get the href value which should be the id that we configured. Decide the url based on this id, load content and update the div's. The id of div's are the same as href.
I haven't found way to load content of the initial active tab, there should be way to fire loadContent function, for now I have used renderPartial to get the content instead
I extended the TbTabs class with #Abdullahs example. It's tested with YiiBooster, but should work with other Bootstrap plugins as well.
Usage:
$this->widget(
'ext.ajaxTabs.widgets.ajaxTabs',
array(
'reload' => true, // Reload the tab content each time a tab is clicked. Delete this line to load it only once.
'tabs' => array(
array(
'label' => 'Static',
'content' => 'Static content'
),
array(
'label' => 'Static rendered',
'content' => $this->renderPartial('index', null, true),
),
// And finally AJAX:
array(
'label' => 'AJAX',
'content' => 'loading ....',
'linkOptions' => array('data-tab-url' => Yii::app()->createAbsoluteUrl('site/'))
)
),
)
);
/protected/extensions/ajaxTabs/widget/ajaxTabs.php:
<?php
Yii::import('bootstrap.widgets.TbTabs');
class ajaxTabs extends TbTabs
{
/**
* #var bool Reload the tab content each time the tab is clicked. Default: load only once
*/
public $reload = false;
public function run()
{
$id = $this->id;
/** #var CClientScript $cs */
$cs = Yii::app()->getClientScript();
$cs->registerScript(
__CLASS__ . '#' . $id . '_ajax', '
function TbTabsAjax(e) {
e.preventDefault();
var $eTarget = $(e.target);
var $tab = $($eTarget.attr("href"));
var ctUrl = $eTarget.data("tab-url");
if (ctUrl != "" && ctUrl !== undefined) {
$.ajax({
url: ctUrl,
type: "POST",
dataType: "html",
cache: false,
success: function (html) {
$tab.html(html);
},
error: function () {
alert("Request failed");
}
});
}
if(' . ($this->reload ? 0 : 1) . '){
$eTarget.data("tab-url", "");
}
return false;
}'
);
$this->events['shown'] = 'js:TbTabsAjax';
parent::run();
}
}
Its a new version to loadContent
function loadContent(e){
var targetUrl = e.target.getAttribute('data-tab-url');
var contentID = e.target.getAttribute('href');
$(contentID).load(targetUrl, function(){
$('.tabs').tabs(); //reinitialize tabs
});
e.preventDefault();
return false;}
in Form
$form['assignJob'] = array(
'#type' => 'checkbox',
'#title' => 'AssignJob',
'#default_value' => 1,
'#suffix'=>"<script>$js</script>"
)
in $js i defined the JS.
$js = <<<EOJS
Drupal.behaviors.checkboxrender = function(context) {
$('#edit-assignJob', context).change(function(event, ui) {
var method = $(this).val();
if(method){
$.get('/assignJob/',null,responseDetails);
}
});
var responseDetails=function(response){
alert(response);
}
};
EOJS;
In hook_menu in defined the menu
$items['assignJob'] = array(
'page callback' => 'assignee',
'type' => MENU_CALLBACK,
'access arguments' => array('access administration'),
);
return $items;
function assignee() {
$output='xxxx';
return drupal_json(array('status' => TRUE, 'data' => $output));
drupal_exit();
}
So whenever i click on checkbox it return me the blank value. Can anybody help in this.?
When i render this i got warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'assignee' not found or invalid function name in C:\Server\www\drupal-final\includes\menu.inc on line 350.
I'll try to help you . But all i know that what's responsible for Ajax call or javascript is the ahah property . have a read on drupal api http://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/6#ahah
Also read this http://drupal.org/node/348475
By the way i never saw suffix that takes Script . i always use ahah property .
You can download this example http://www.kristen.org/content/drupal-ahah-form-examples
and read this article http://fuseinteractive.ca/blog/how-create-custom-drupal-ajax-module-0