How to define $.get url using enablePrettyUrl=>true - ajax

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

Passing extra data to yii uploader

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();
?>

CanĀ“t add products to CodeIgniter Cart from another view

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

How to save data in model using Yii2 grid with Editable column

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.

Need JSON to pass values to AJAX from specific content type fields

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();
}

How to "print" a theme during AJAX request (Drupal)

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.

Resources