Scenario: I have a view with a twitter bootstrap thumbnail grid that shows the countries. When the user clicks one image, it is supposed to show the cities related to that country, in the same grid (screen).
Technical: First I fill the dataProvider with countries, and then I should send a ajax request with the country id to my controller where it queries the database for cities related to that country and sends the new dataProvider, back to the view where it updates the same thumbnail dataProvider with new data.
Question: How do I do this?
Here is my code:
view with thumbnail declaration (name of the view: _detail)
<?php
$this->widget('bootstrap.widgets.TbThumbnails', array(
'id' => 'detailThumbnails',
'dataProvider' => $dataprov,
'template' => "{items}\n{pager}",
'itemView' => '_thumb',
));
?>
view called in thumbnail "itemView" property (name of the view: _thumb)
<?php
require_once '_detail.php';
?>
<li class="span3">
<a href="#" class="<?php echo "thumbnail".$data['id'] ?>" rel="tooltip" data-title=" <?php echo "Clicar.."; ?>">
<img src="<?php echo Yii::app()->getBaseUrl() . $data['photo'] ?>" alt="">
<a href=
"
<?php
echo $className;
echo $this->createUrl(get_class($data).'/view', array('id' => $data['id']));
?>
"
>
<?php
echo $data['name'].$data['id'];
?>
</a>
<?php
Yii::app()->clientScript->registerScript('thumbClick'.$data['id'],'
$(".thumbnail'.$data['id'].'").click(function(){
var request = $.ajax({
data: {
id : '.$data['id'].'
},
type: "post",
url:"'.Yii::app()->createAbsoluteUrl("tripDetail/getCities").'",
error: function(response, error)
{
alert("Error: " + response + " : " + error);
},
});
$(".thumbnail'.$data['id'].'").ajaxSuccess(function() {
$.fn.yiiListView.update("detailThumbnails");
});
});
');
?>
</a>
</li>
In case of success i need to update the same dataProvider, which is in the view named _detail, hence the require_once. What iam trying to do is pass the data from controller(below) in json and decode here. But i don't know how to build a new data provider from the json response, and dont know either if the encode is properly made. Is it????
controller (just some functions)
public function actionCreate()
{
$session = new CHttpSession;
$session->open();
if(isset($_SESSION['mySession']))
{
$data = $_SESSION['mySession'];
if ($data)
{
if(!isset($_GET['ajax']))
{
$dataprov = new CActiveDataProvider("Country");
$this->render('create',
array(
'dat'=>$data,
'dataprov'=>$dataprov
)
);
}
}
}
}
public function actionGetCities()
{
if(isset($_POST['id']))
{
$cityId = $_POST['id'];
$dataProvider = $this->getCitiesFromDb($cityId);
echo $this->renderPartial('_detail',array('dataprov'=> $dataProvider),true,true);
}
}
public function getCitiesFromDb($cityId)
{
$criteria = new CDbCriteria;
$criteria->select = "*";
$criteria->condition = "b4_Country_id = " . $cityId;
$dataProv = new CActiveDataProvider('City',
array('criteria'=>$criteria));
return $dataProv;
}
If this is not the right way to do this, please let me know
You are mixing Server Side Code and Client side code.
Server Side Code
This code resides on server and upon request it gets executed to provide the valid output to the client. Once it is done it does not maintains any connection with the client
Client Side code
Once request is sent to server client waits for response from server and receives anything sent from server. Once done it disconnects from server until further requests made by user or scripts.
What you did here is <?php$json = CJSON::decode(data)?> php tags are serverside thing and they can not be populated because they appear on client side as in your code. Consider following
If you successfully made the AJAX request you better try changing datatype of Ajax request. I guess you are half way there but you do not know how to decode the JSON received. you can use 'dataType'=>'json' in your ajax request. for more details see Updating fields with Ajax and Json
Hopes this makes life easier
As for update part you can do something like create page and call it via renderpartial and return HTML to your view
public function actionGetCities()
{
if(isset($_POST['id']))
{
$cityId = $_POST['id'];
$dataProvider = $this->getCitiesFromDb($cityId);
echo $this->renderPartial('updateView',array('dataprovider'=> $dataProvider),true,true);//see documentation for third and fourth parameter and change if you like
}
}
and in your view you can just update the div that initially have the orignal grid so no need to use json format.
updateView
<?php
$this->widget('bootstrap.widgets.TbThumbnails', array(
'id' => 'detailThumbnails',
'dataProvider' => $dataProvider,
'template' => "{items}\n{pager}",
'itemView' => '_thumb',
));
?>
Note:
This code is not tested and is given for an idea only.
Ok, yesterday i fixed the problem that was in the jquery. The html generated was right but was not being inserted, when the image refreshed, and then, a little light turned on:
Yii::app()->clientScript->registerScript('thumbClick'.$data['id'],'
$(".thumbnail'.$data['id'].'").click(function(){
var request = $.ajax({
data: {
id : '.$data['id'].'
},
type: "post",
success: function(data) {
$("#detailThumbnails").html(data);
},
url:"'.Yii::app()->createAbsoluteUrl("tripDetail/getCities").'",
error: function(response, error)
{
alert("Error: " + response + " : " + error);
},
});
});
');
The part of the code that says "sucess: "
Thank you very much for all the help you people gave me, specially bool.dev. Your help was precious.
Related
I try that: when clicking on an image a function is executed, this function collects a value and sends it via POST to the controller, this controller collects this data and displays the view. The problem is that everything works but it doesn't get to show me the view, I stay where I was.
Image that calls the function when clicking:
<img onclick="getSubjectPublication(<?php echo $inf->codiAsignaturaDesti; ?>)" id="click" src="/EEmobi/resources/images/click.png"/>
Function:
function getSubjectPublication(data){
console.log("EntroFuncion");
console.log(data);
$.ajax({
type: "POST",
url: "perfil.php/" + "subjectPublications",
data: {"data":data},
success: function(response) {
console.log(response);
},
error: function(t, e) {
window.alert("Error al intentar visualitzar les publicacions");
}
})}
The function calls this general controller (lib), it collects the sent data and passes it to the specific controller:
case 'subjectPublications':
$controllerName = "SubjectPublicationsController";
$actionName = "showSubjectPublications";
$data = $_POST['data'];
array_push($parameters, $data);
break;
Specific Controller:
<?php class SubjectPublicationsController{
function __construct(){
$this->view = new View();
}
public function showSubjectPublications($parameters){
require 'models/PublicationsSubjectModel.php';
$publicationsSubjectModel = new PublicationsSubjectModel();
$data = $parameters[0];
echo "<script>console.log('ENTROFINAL');</script>";
echo "<script>console.log('. json_encode( $data ) .');</script>";
$subjectPublications = $publicationsSubjectModel->getPublicationOfSubject($data);
$route = $this->view->show("PublicationsSubject.php");
$publicationsSubjectModel->disconnect();
include ($route);
}}?>
The case is that in the console browser it shows me the console.log that I do in the function and the response returns the entire web including the view that I include in the controller (the view that i wanted to show in the browser), but it doesn't show it on the screen, i continue with the same screen and not the one that I included in the controller. What am I doing wrong?
Browser Screenshot
When you complete a ajax request you generally want to send back a json object. In this case maybe about the image that you clicked. So then you do something with that in your success function e.g alert - or show a popup or something. Look at json_encode to send your data back from your php page php.net/manual/en/function.json-encode.php
I am trying to pass a javascript variable into a php code in the view file of the cakephp 2.
for (id in response) {
var book = response[id];
if (typeof(book.thumbnail_url) != "undefined") {
var x= book.thumbnail_url;
<?php
$file11 = WWW_ROOT . 'img' . DS . 'book_images';
define('DIRECTORY', $file11);
$content = file_get_contents($abc);
file_put_contents(DIRECTORY . '/'.$isbn.'.jpg', $content);
?>
}
}
i am trying to pass the value of x in the file_get_contents function in place of $abc so that it could save the image coming from the javascript's URL accordingly.
EDIT::
for (id in response) {
var book = response[id];
if (typeof(book.thumbnail_url) != "undefined") {
var x= book.thumbnail_url;
$.ajax({
type: "POST",
url: '/BookSearchs/test',
data: {'yourX':x}
}).done(function(result) {
alert("yes");
}).fail(function() {
alert("no");
});
}
}
This is what i wrote after implementing the answers i got . But Everytime it pops up "no". Here BookSearchs is my controller and test is my function inside it.
EDIT 2:
function handleResponse(response) {
var target = '';
for (id in response) {
var book = response[id];
if (typeof(book.thumbnail_url) != "undefined") {
var x = book.thumbnail_url;
$.ajax({
type: 'POST',
url: "BookSearchs/test",
data: {
myVal: x
},
success: function() {
alert('AjaX Success')
},
error: function() {
alert('AjaX Failed')
}
})
.done(function() {
alert('AjaX Done!');
});
}
}
return true;
}
Currently this is what i've have done so far , the form method did not work out . It was redirecting me to another page . Anyways this is my current code . And 'test' is the my function inside the controller where i want to access the myVal value using POST . Also i have this question do i need to create a physical file for test in order to make the ajax function work, because if i delete the test.ctp file then the ajax starts giving the fail message . So for now i have created a physical test.file in the BookSearchs folder in the view , although it's empty in order to make the ajax function work . I am having a doubt whether my Url in Ajax is wrong or i am not accessing the values properly in the controller.
I don't think that this is a proper way to do that in theory. But, sometime we might need this.
Before we proceed to this way, you might need to think other technologies such as NodeJs (e.g fs.readFileSync)
Basically, you can't directly do that. Because, JavaScript run on client side and PHP is run on sever side.
Anyway, there might be a few tweak to do that. But, this approach might be slow and it depends on how many loop you making.
for (id in response) {
var book = response[id];
if (typeof(book.thumbnail_url) != "undefined") {
var x= book.thumbnail_url;
$.ajax({
type: "POST",
url: '/yourcontroller/route',
data: {'yourX':x}
}).done(function(result) {
//if success, execute other code
}).fail(function() {
//DO other if fail
});
}
}
Then, read this value in your controller
$xValue = $_POST['yourX'];
$file11 = WWW_ROOT . 'img' . DS . 'book_images';
define('DIRECTORY', $file11);
$content = file_get_contents($xValue);
file_put_contents(DIRECTORY . '/'.$isbn.'.jpg', $content);
//do some checking success or fail
//I will assume success
$status = 'success';
echo json_encode(['status'=>$status]);
Usally I use a Trick to pass JS variable to a CakePhp Controller(php variable). Actionly I create a form that contain a hidden input, I'll also put the link of the page that will receive the php variable.
.ctp
<?=
$this->Html->link('<i class="fa fa-file-pdf-o"></i>' .__('Export'),
'javascript:myFunction();',
array('escape' => false, 'class' => 'btn btn-app dispatch', 'id' => 'dispatch_packages',
'style'=>'margin-right:0px;background: #f39c12;color:white;',
'disabled' => 'false'));
?>
<form id="sampleForm" name="sampleForm" style="display: none" method="post" action="<?= $this->Url->build([
'controller' => 'YourController',
'action' => 'youraction']) ?>">
<input type="hidden" name="variable" id="variable" value="">
</form>
JS
var jsVar=0;
function myFunction()
{
document.sampleForm.variable.value = jsVar;
document.forms["sampleForm"].submit();
}
I used it with the CakePhp 3.x framework & it's working very fine. You have just to write the url with the CakePhp 2.x Syntax.
Don't hesitate to comment my answer if you'll have any difficulties to apply it.
Good Luck !
Good day. I'm working on a admin page basically it is a content management system. I want to delete the data based on their id. But unfortunately i've encounter a error on the htpp request. here is the error.
Request URL: admin/ajax_delete
Request Method:POST
Status Code:500 Internal Server Error
Remote Address:144.76.136.165:8181
VIEW FILE:
<span class="glyphicon glyphicon-trash"></span>
$("#delete_tpi").click(function() {
alert("Are you sure you want to delete?");
var tpi = $('.datatpi').val(); //package includes
var did = $('#data-id').val();
$.ajax({
url: '<?php echo site_url('admin/ajax_delete'); ?>',
type: 'POST',
datatype: 'html',
data: {id: did, tpi: tpi},
success:function (b){
if (b == 'Success') {
$('.#data-id').val('');
$('.datatpi').val('');
location.reload();
}
}
});
});
$('body').on('click','.edit-content-modal',function(){
var id = $(this).attr('data-id');
$('#data-id').val(id);
});
Controller file:
public function ajax_delete(){
$did = $this->input->post('id');
$ptpi = $this->input->post('tpi');
$update = $this->products_model->row_delete($did,$ptpi);
var_dump($update);
echo ($update)?'Success':'Fail';
}
MODEL FILE:
function ajax_delete($did,$ptpi){
$this->db->where('id',$did);
$this->db->delete('products',$ptpi);
return $this->db->affected_rows() > 0;
}
Because <a></a> element does not expect a value tag. You can get the ID of the clicked #delete_tpi link by using attr():
var did = $("#delete_tpi").attr('data-id');
Your POST request to admin/ajax_delete returns 500 Internal Server Error. This is a server-side error. If you use codeigniter, take a look at application/logs/*.log files that will give you detail information about the error.
I think, your problem is calling a non-existing function from model:
In your controller, you have:
$this->products_model->row_delete($did,$ptpi);
But your model, contains:
function ajax_delete($did,$ptpi){
....
}
Do you have row_delete() function in your model?
Once again, i suggest you to look at logs file, because many problems can result in server-side error.
This is my first attempt at trying to update a database with ajax & wordpress. I am trying to set a field to a status of 'complete' when a link is clicked. Everything seems to go fine, I get a "200 ok" response from the console, and the jQuery even shows the success actions that I'm taking. However the php doesn't update the database. The proper variables are being echoed out to the console, so I know those are being set correctly. I don't know if it's my MySQL query that I'm trying or if there's something that I'm overlooking. Any help or suggestions would be greatly appreciated.
Here's my jQuery:
// Click to Complete Activity Functionality
jQuery(".complete-activity").click( function( e ) {
e.preventDefault();
nonce = jQuery(this).attr("data-nonce")
wp_user_id = jQuery(this).attr("wp_user_id")
activity_post_id = jQuery(this).attr("activity_post_id")
wp_user_id = parseInt(wp_user_id);
activity_post_id = parseInt(activity_post_id);
console.log('My wp user id is: ' + wp_user_id);
console.log('My Activity id is: ' + activity_post_id);
jQuery.ajax({
type : "post",
url : myAjax.ajaxurl,
data : {
action: "gw_complete_activity",
"wp_user_id" : wp_user_id,
"activity_post_id" : activity_post_id,
"nonce" : nonce
},
success: function(response) {
console.log('Your field has been set as completed');
jQuery('li#active-'+ activity_post_id).css('display', 'none');
}
})
}) // End click to complete activity
Here's my php code:
<?php
//Complete Activity in Database (AJAX)
add_action("wp_ajax_gw_complete_activity", "gw_complete_activity");
add_action("wp_ajax_nopriv_gw_complete_activity", "my_must_login_to_complete");
function gw_complete_activity() {
if ( !wp_verify_nonce( $_REQUEST['nonce'], "gw_complete_activity")) {
exit("No naughty business please");
}
$wp_user_id = $_REQUEST['wp_user_id'];
$activity_post_id_complete = $_REQUEST['activity_post_id'];
$date_completed = current_time('mysql', 1);
global $wpdb;
$wpdb->update (
'wp_gwactivities',
array( 'date_completed' => $date_completed, 'activity_status' => 'complete'),
array( 'wp_user_id' => $wp_user_id)
);
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
$result_add = json_encode($result_add);
echo $result_add;
}
else {
header("Location: ".$_SERVER["HTTP_REFERER"]);
}
die();
}
function my_must_login_to_complete() {
echo "You must be logged in to complete your activities.";
die();
}
?>
Just because you get a 200 (OK) from the requested page, doesn't mean the requested page didn't error out :) Secondly, it looks like this is going to be used in Wordpress... with that said, you can't use add_action without having wordpress loaded.
For files outside the normal wordpress install, you need to include wp-load.php include "/path/to/wordpress/wp-load.php", for example. Then you can use its functions.
After your update query ,put below code and check query in mysql directly.
print_r($wpdb->last_query);
provide your query here also if its not work.
Hi I’m quite new to jquery -ajax and I’d like some help please to join it with CI.
I have followed this tutorial on Submitting a Form with AJAX and I’d like to add this functionality to my CodeIgniter site. What I’d like to do is when the user submits the form, if there are any validation errors to show the individually on each input field (as in native ci process), or if this is not possible via validation_errors() function. If no errors occured to display a success message above the form.
Here's my code so far:
my view
// If validation succeeds then show a message like this, else show errors individually or in validation_errors() in a list
<div class="alert alert-success">Success!</div>
<?php echo validation_errors(); //show all errors that ajax returns here if not individualy ?>
<?php echo form_open('admin/product/add, array('class' => 'ajax-form')); ?>
<p>
<label for="product_name">Product *</label>
<input type="text" name="product_name" value="<?php echo set_value('product_name', $prod->product_name); ?>" />
<?php echo form_error('product_name'); ?>
</p>
<p>
<label for="brand">Brand</label>
<input type="text" name="brand" value="<?php echo set_value('brand', $prod->brand); ?>" />
<?php echo form_error('brand'); ?>
</p>
...
my controller
public function add($id){
// set validation rules in CI native
$rules = $this->product_model->rules;
$this->form_validation->set_rules($rules);
if ($this->form_validation->run() === true) {
// get post data and store them in db
$data = $this->input_posts(array('product_name', 'brand', 'category_id', 'description'));
$this->product_model->save($data, $id);
// no errors - data stored - inform the user with display success-div
} else {
// validation failed - inform the user by showing the errors
}
//load the view
$this->load->view('admin/products/add', $data);
}
and here’s the js script
$(document).ready(function () {
$('form.ajax-form').on('submit', function() {
var obj = $(this), // (*) references the current object/form each time
url = obj.attr('action'),
method = obj.attr('method'),
data = {};
obj.find('[name]').each(function(index, value) {
// console.log(value);
var obj = $(this),
name = obj.attr('name'),
value = obj.val();
data[name] = value;
});
$.ajax({
// see the (*)
url: url,
type: method,
data: data,
success: function(response) {
console.log(response); // how to output success or the errors instead??
}
});
return false; //disable refresh
});
});
How should I pass my validation results (either success or the post errors) throught the ajax request and display them on my view??
From some little research I did I've found that you can use a single controller, that holds both the native proccess and the ajax request (instead of using 2 controllers), but my main difficulty is, I don't understand how the results of the validation will pass through the js script and display them on my view?? Please note that I don't want to display anything on an alert box, instead show the results on a div or the errors individualy(if possible).
EDIT I did some changes to my application, here's the code so far:
the controller
public function manage($id = NULL){
$this->load->library('form_validation');
$data['categ'] = $this->category_model->with_parents();
//fetch a single product or create(initialize inputs empty) a new one
if (isset($id) === true) {
$data['prod'] = $this->product_model->get($id);
$data['attr'] = $this->attribute_model->get_by('product_id', $id, null, true);
} else {
$data['prod'] = $this->product_model->make_new();
$data['attr'] = $this->attribute_model_model->make_new();
}
if (isset($_POST['general_settings'])) {
if ($this->form_validation->run('product_rules') === true) {
// get post inputs and store them in database
$data = $this->product_model->input_posts(array('product_name', 'brand', 'category_id', 'general_description'));
$this->product_model->save($data, $id);
$status = true;
} else {
// validation failed
$status = validation_errors();
}
if ( $this->input->is_ajax_request() ) {
echo json_encode($status);
exit;
}
redirect('admin/product');
}
//if (isset($_POST['attributes_settings'])) { the same thing here }
// load the view
$this->load->view('admin/products/manage', $data);
}
and the js
success: function(response) {
//console.log(response);
if (data.status === true) {
$('#ajaxResults').addClass('alert alert-success').html(response);
} else {
$('#ajaxResults').addClass('alert alert-error').html(response);
};
}
But I'm having some issues
Although I get the error messages from validation_errors() as an alert-error when there are no errors I get the true in an alert-error too, insted of alert-success.
2.how should I return the success message too? eg. a message saying "Saves were done!".
Althought in a non-ajax-request the data are stored in the database, in case fo ajax the don't store. Any ideas What may be wrong???
HTML:
<div id="ajaxResults"></div>
Javascript ajax:
success: function(response) {
$('#ajaxResults').text(response);
}
this script you've wrote is only if the validation succeeds, right?
Wrong. The code in "success" gets executed any time you get a response back from the server (assuming the HTTP header is 200). Does your javascript knows if the server has any error for you? No.
You need your JavaScript to recognize if the validation failed or succeeded. You have many ways to do that. One of these could be sending the message to display followed by a 0 or 1.
So your PHP will looks like:
return "0 " . $errorMessage;
and
return "1 " . $successMessage;
and your javascript should then recognize, with if statement and substring, if the message starts with 0 or with 1.
Use this way i hope this will work for you
<script type='text/javascript'>
var base_url = '<?=base_url()?>';
function ajax_call()
{
var ids = $("#all_users").val();
$.ajax({
type:"POST",
url: base_url+"expense/home/get_expense",
data: "userid=" + ids,
success: function(result){
$("#your_div_id").html(result);
}
});
}
</script>