Following code will do its job as intended, if enablePrettyUrl will be set to false:
<?php
$script = <<< JS
$('#zip_code').change(function(){
var zipId=$(this).val();
$.get('index.php?r=locations/get-city-province',{zipId:zipId},function(data){
var data=$.parseJSON(data);
alert(data.city+" liegt in "+data.province+"! Die Id ist "+zipId);
$('#customers-city').attr('value',data.city);
$('#customers-province').attr('value',data.province);
});
});
JS;
$this->registerJS($script);
?>
Following code won't, if enablePrettyUrl will be set true:
$.get('locations/get-city-province',{zipId:zipId},function(data){
Here are rules of UrlManager:
'urlManager' => [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
'showScriptName' => true,
'enableStrictParsing' => true,
'rules' => [
'locations' => 'locations/index',
'locations_create' => 'locations/create',
'locations_delete' => 'locations/delete',
'locations_update' => 'locations/update',
'locations_SaveAsNew' => 'locations/save-as-new',
'locations_pdf' => 'locations/pdf',
'locations_view' => 'locations/view',
// ...
],
],
Any ideas, how to code $.get in correct way?
Here is method of Controller:
public function actionGetCityProvince($zipId) {
$location = Locations::findOne($zipId);
echo Json::encode($location);
}
Use Url::to() or Url::toRoute()
<?php
$url = yii\helpers\Url::to(['locations/get-city-province']);
$script = <<< JS
$('#zip_code').change(function(){
var zipId = $(this).val();
$.get('$url', {zipId:zipId}, function(data){
var data = $.parseJSON(data);
alert(data.city+" liegt in "+data.province+"! Die Id ist "+zipId);
$('#customers-city').attr('value',data.city);
$('#customers-province').attr('value',data.province);
});
});
JS;
$this->registerJS($script);
?>
Related
Am creating a file uploader using the kartik uploader bu the problem is that it doesn't pass extra data
The form(view) code
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>
<?= $form->field($model, 'case_description')->textArea();?>
<?php echo $form->field($evidence, 'path')->widget(FileInput::classname(), [
'options' => ['accept' => '*','multiple' => true,'name'=>'images'],
'pluginOptions' => [
'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ',
'showPreview' => true,
'showCaption' => true,
'showRemove' => true,
'showUpload' => true,
'browseLabel' => 'Insert Evidence',
'uploadUrl' => Url::to(['cases/upload']),
'maxFileCount' => 10,
'uploadExtraData' => [
'album_id' => "javascript: return $('#cases-case_description').val());",
],
],
]
);?>
The $evidence ,path is a table related to the models table
The controller that I have tested with (code)
public function actionUpload(){
$ann = empty($_POST['album_id']) ? '' : $_POST['album_id'];
var_dump($ann)
}
This returns null showing that the album_id is not passed to the controller and yet the $model->case_description is the field above the upload widget
The new controller
public function actionUpload(){
$images = $_FILES['evidence'];
$success = null;
$paths= ['uploads'];
// get file names
$filenames = $images['name'];
// loop and process files
for($i=0; $i < count($filenames); $i++){
//$ext = explode('.', basename($filenames[$i]));
$target = "uploads/cases/evidence".DIRECTORY_SEPARATOR . md5(uniqid()); //. "." . array_pop($ext);
if(move_uploaded_file($images['name'], $target)) {
$success = true;
$paths[] = $target;
} else {
$success = false;
break;
}
echo $success;
}
// check and process based on successful status
if ($success === true) {
$output = [];
} elseif ($success === false) {
$output = ['error'=>'Error while uploading images. Contact the system administrator'];
foreach ($paths as $file) {
unlink($file);
}
} else {
$output = ['error'=>'No files were processed.'];
}
// return a json encoded response for plugin to process successfully
echo json_encode($output);
Due the problem with dinamic/variable assign to extraData i suggest a simple solution based on POST / submit method (eventually set the proper action in your form)
use kartik\widgets\FileInput
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>
<?= $form->field($model, 'case_description')->textArea();?>
<?php echo $form->field($evidence, 'path')->widget(FileInput::classname(), [
'options' => ['accept' => '*','multiple' => true,'name'=>'images'],
'pluginOptions' => [
'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ',
'showPreview' => true,
'showCaption' => true,
'showRemove' => true,
'showUpload' => true,
'browseLabel' => 'Insert Evidence',
'uploadUrl' => Url::to(['cases/upload']),
'maxFileCount' => 10,
],
]
);
echo Html::submitButton($model->isNewRecord ? 'Upload' : 'Update', [
'class'=>$model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']
);
ActiveForm::end();
?>
I am using codeigniter 2.2.2 with HMVC and a custom session library
I have two views I'll call them V1.php and V2.php for simplicity
and in each view I have a product that can be added to the cart via ajax when you click on the button:
<button class="add-to-cart" id="123" type="button" class="btn btn-fefault cart">
both V1.php and V2.php are sending product details to a controller cart.php to the method add() via ajax
and here is the ajax call in both V1.php and V2.php
$(".add-to-cart").click(function()
{
var target_url = '<?php echo(base_url()."cart/add") ; ?>';
var prod_id = $(this).attr("id");
var qty = 1;
// prepare the data to be sent
var ProductData = {product_id:prod_id,quantity:qty};
$.ajax(
{
url : target_url,
type: "POST",
data : ProductData,
success: function(data)
{
cart = JSON && JSON.parse(data) || $.parseJSON(data);
$("#cart_num").html("( " + cart.num_of_items + " )");
},
error: function(jqXHR, textStatus, errorThrown)
{
$("#cart_notice").show();
$("#cart_notice").html('<pre><code class="prettyprint">AJAX Request Failed<br/> textStatus='+textStatus+', errorThrown='+errorThrown+'</code></pre>');
}
});
// prevent default
return false;
});
and here is the controller cart.php
public function add()
{
$product_id = $this->input->post('product_id');
$quantity = $this->input->post('quantity');
// prepare the array for the cart
$data = array(
'id' => $product_id,
'qty' => $quantity,
'price' => 39.95,
'name' => 'T-Shirt',
'options' => array('Size' => 'L', 'Color' => 'Red')
);
// insert the array in the cart
$cart_flag = $this->cart->insert($data);
//$cart_flag returns false if something went wrong
//$cart_flag returns an id if everything is ok
// prepare the array for the ajax callback function
$cart = array(
'num_of_items' => $this->cart->total_items(),
'total_price' => $this->cart->total()
);
echo json_encode($cart);
}
thanks to debugging tools I could see that :
1.when I add the product from V1.php everything is fine ($cart_flag returns an id)
but
2.when I add the product from V2.php it doesn't add anything ($cart_flag returns FALSE ) although $data is the same in both cases
what I'm I doing wrong ?
the answer was casting, it really gave me a hard time but at last I found it,
the $data looked the same but the type was not
this fixes the problem
$data = array(
'id' => (int)$product_id,
'qty' => (int)$quantity,
'price' => 39.95,
'name' => 'T-Shirt',
'options' => array('Size' => 'L', 'Color' => 'Red')
);
hope this helps someone else with the same issue
Can anyone help on editable column in gridview.I am using Yii2 and stuck with it.
I can't save data in my model.I can post from gridview column.
In my grid view:
$gridColumns= [
'patient_no',
'category_name',
'sdv_text',
[
'class' => 'kartik\grid\EditableColumn',
'attribute'=>'sdv_status',
'pageSummary' => true,
'editableOptions'=> [
'header' => 'profile',
'format' => Editable::FORMAT_BUTTON,
'inputType' => Editable::INPUT_DROPDOWN_LIST,
'data'=> $StatusList,
]
],
// 'date_sdv_performed',
[
'class' => 'kartik\grid\EditableColumn',
'attribute'=>'date_sdv_performed',
'editableOptions' => [
'header' => 'Date Sdv Performed',
'inputType'=>\kartik\editable\Editable::INPUT_WIDGET,
'format'=>\kartik\datecontrol\DateControl::FORMAT_DATE,
'widgetClass'=> 'kartik\datecontrol\DateControl',
],
],
[
'class' => 'kartik\grid\EditableColumn',
'attribute'=>'comments',
'hAlign' => 'top',
'vAlign' => 'middle',
'width'=>'100px',
'headerOptions' => ['class' => 'kv-sticky-column'],
'contentOptions' => ['class' => 'kv-sticky-column'],
'pageSummary' => true,
],
];
GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'layout'=>"{items}\n{pager}",
'pjax'=>true,
'toolbar' => [
'{export}',
'{toggleData}'
],
'responsive'=>true,
'hover'=>true,
'columns' => $gridColumns
]);
In my controller action:
public function actionMonitoring($site_name)
{
$this->layout = 'sdv-carolina-main';
$Countries = new Countries;
$model = new Flagging;
$searchModel = new FlaggingSearch();
$dataProvider = $searchModel->monitoringsearch($site_name);
$allocatedsites = new AllocatedSites;
if (Yii::$app->request->post('hasEditable'))
{
$model = $this->findModel($model['flagging_id']);
$out = Json::encode(['output'=>'', 'message'=>'']);
$post = [];
$posted = current($_POST['Flagging']);
$post['Flagging'] = $posted;
if ($model->load($post)) {
$model->save();
$output = '';
if (isset($posted['sdv_status']))
{
$output = $model->sdv_status;
}
$out = Json::encode(['output'=>$output, 'message'=>'']);
}
echo $out;
return;
}
return $this->render('monitoring',
[
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'Countries' => $Countries,
'model'=>$model,
'allocatedsites' => $allocatedsites,
]);
}
The problem is I can't update my model because of I can't get the id.
I just need the id to update specific row.How can I get the id while using editable column?
Thanks in advance.
Actually the solution is easy. I just need the id of that specific row to update that.And in my ajax post I got something like this:
Flagging[0][status] NO
_csrf TlhyUm5kajAoNxgVNy0/ZCoyHApZUlNUFh0rB1gRPGoAFSIdGSAifQ==
editableIndex 0
editableKey 13
hasEditable 1
and found the editableKey is the id of that specific row!
Now in my controller I write down this code given below:
$_id=$_POST['editableKey'];
$model = $this->findModel($_id);
Here $_id is the posted editableKey value which is the id of the specific row.
and with the id I use it to get the specific model and just update data based on that id.
Im new to PHP.
I'd like to build a module and i need json to pass specific content type fields.
Im trying with this but i dont know how to deal with callback function.
here is my ajax in .js
$.ajax({
type: 'GET',
url: '/mappy/ajax/poi',
data: {
nid: nid
},
dataType: 'json',
success: function(data){
alert(data)
}
});
})
here is my php in .module
function mappy_menu() {
$items = array();
$items['/mappy/ajax/poi'] = array(
'title' => 'Mappy Pois',
'page callback' => 'mappy_get',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items;
}
function mpapy_get() {
$nid = $_GET('nid');
$title = field_get_items('node', $node, 'field_title');
$result = json_encode(
db_query("SELECT nid,title FROM {node}", $nid)
);
drupal_json_output($result);
print $result;
}
Many thanks for advice.
Once you get the JSON response you need to convert it to a javascript array. For that, you can do:
var javaArray = $.parseJSON(data);
Now you can retrieve the data, using code like javaArray['key1']['key2'], etc.
.js
$.ajax({
type: 'GET',
// Do not use slash at the beginning, use Drupal.settings.basePath instead
url: Drupal.settings.basePath + 'mappy/ajax/poi',
data: {
nid: nid
},
dataType: 'json',
success: function(data) {
alert(data)
}
});
.module
function mappy_menu() {
$items = array();
// Never use slash at the beginning in hook_menu
$items['mappy/ajax/poi'] = array(
'title' => 'Mappy Pois',
'page callback' => 'mappy_get',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items;
}
function mappy_get() {
$node = node_load($_GET('nid'));
// Or equivalent
/* $node = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->condition('n.nid', $_GET('nid')))
->execute()
->fetchAll(); */
$values = array(
'nid' => $node->nid,
'title' => $node->title
);
#$result = json_encode(
# db_query("SELECT nid,title FROM {node}", $nid)
#);
// drupal_json_output already print the value
// print $result;
drupal_json_output($values);
drupal_exit();
}
When users click on a button (with id graph), I'd like to fill the default Drupal content div (<div class="content">) with a graphael instance.
The JavaScript:
jQuery(document).ready(function($) {
$('#toggle #graph').click(function() {
$.ajax({
url: "http://www.mysite.com/?q=publications/callback",
type: 'POST',
data: {
'format' : 'graph'
},
success: function(response) {
$('div#content div.content').html(response);
}
});
});
});
The PHP:
$items['publications/callback'] = array(
'type' => MENU_CALLBACK,
'title' => 'All Publications Callback',
'page callback' => '_process_publications',
'page arguments' => array(t('journal')),
'access callback' => TRUE,
);
which leads to the page callback: (I'm concerned with the if code block)
function _process_publications($venue) {
if( isset($_POST['format']) && $_POST['format'] == "graph" ){
_make_bar_chart($venue);
}
elseif( isset($_POST['format']) && $_POST['format'] == "list" ) {
_make_list($venue);
}
else{
return("<p>blah</p>");
}
}
and finally the function called within the callback function:
function _make_bar_chart($venue) {
// get active database connection
$mysql = Database::getConnection();
// if connection is successful, proceed
if($mysql){
// do stuff
$graphael = array(
'method' => 'bar',
'values' => $ycoordinates,
'params' => array(
'colors' => $colors,
'font' => '10px Arial, sans-serif',
'opts' => array(
'gutter' => '20%',
'type' => 'square',
),
'label' => array(
'values' => $xcoordinates,
'isBottom' => true,
),
),
'extend' => array(
'label' => array(
'values' => $ycoordinates,
'params' => array('attrText' => array(
'fill' => '#aaa',
'font' => '10px Arial, sans-serif',
)),
),
),
);
return theme('graphael', $graphael);
}
// else, connection was unsuccessful
else{
print("<p>bad connection</p>");
}
}
THE PROBLEM: returning a theme doesn't really send anything back to the AJAX request (unlike print statements). I tried to print the theme, but that produces a white screen of death. How would I generate the graph without printing something?
Much thanks to nevets on the Drupal forums for the helpful hint: http://drupal.org/node/1664798#comment-6177944
If you want to use AJAX with Drupal, you are best off actually using Drupal-specific AJAX-related functions. In my theme's page.tpl.php file, I added the following to make the links which would call AJAX:
<?php
// drupal_add_library is invoked automatically when a form element has the
// '#ajax' property, but since we are not rendering a form here, we have to
// do it ourselves.
drupal_add_library('system', 'drupal.ajax');
// The use-ajax class is special, so that the link will call without causing
// a page reload. Note the /nojs portion of the path - if javascript is
// enabled, this part will be stripped from the path before it is called.
$link1 = l(t('Graph'), 'ajax_link_callback/graph/nojs/', array('attributes' => array('class' => array('use-ajax'))));
$link2 = l(t('List'), 'ajax_link_callback/list/nojs/', array('attributes' => array('class' => array('use-ajax'))));
$link3 = l(t('Create Alert'), 'ajax_link_callback/alert/nojs/', array('attributes' => array('class' => array('use-ajax'))));
$output = "<span>$link1</span><span>$link2</span><span>$link3</span><div id='myDiv'></div>";
print $output;
?>
When one of the links above is clicked, the callback function is called (e.g. ajax_link_callback/graph):
// A menu callback is required when using ajax outside of the Form API.
$items['ajax_link_callback/graph'] = array(
'page callback' => 'ajax_link_response_graph',
'access callback' => 'user_access',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
.. and the callback to which it refers:
function ajax_link_response_graph($type = 'ajax') {
if ($type == 'ajax') {
$output = _make_bar_chart('journal');
$commands = array();
// See ajax_example_advanced.inc for more details on the available commands
// and how to use them.
$commands[] = ajax_command_html('div#content div.content', $output);
$page = array('#type' => 'ajax', '#commands' => $commands);
ajax_deliver($page);
}
else {
$output = t("This is some content delivered via a page load.");
return $output;
}
}
This replaces any HTML within <div class="content"> with the graphael chart returned from _make_bar_chart above.