I have some template files in the project for example '/view/dynamic.html' containing these simple data :
<div class="dynamic"></div>
On the client side : I have a clickable element on my web page using Jquery that posts an asynchronous request to the server side.
$('a.clickable').on('click', function()
{
var $this = $(this);
var $type = $this.data('type');
var $project_id = 1;
$.ajax({
type: 'POST',
url: "php/zeek.php",
data: {
'method': 'clicked',
'type': $type,
'project_id': $project_id
},
dataType: 'text',
success: function($input)
{
console.log('result:' + $input);
},
error: function($request, $status, $error)
{
$('div.dynamic').replaceWith(
'<div class="dynamic"><h2>'
+ $error + '</h2></div>');
console.log($status + ' : ' + $error);
}
});
});
On the server side :
I have a function that is displaying the content of the dynamic view file.
public function dynamic_display() {
ob_start();
include 'view/dynamic.html';
return ob_get_clean();
}
and finally I have function that receives the request :
case 'clicked':
$type = strtolower($params['type']);
if ($type == 'disconnect') {
echo("? " . $this->dynamic_display() . " ?");
return true;
}
The problem :
when I test my function 'dynamic_display' with unit test, this function sends back the correct expected string. Using var_dump, I obtain :
string(28) "<div class="dynamic"></div>
"
When I click on the element on my page : I doesn't obtain the same result on the console
"result:? ?"
Why it doesn't work? What is happening? How should make it working?
Thanks & Regards!
Leo
It does work when I use
include '/home/leo/zeek/view/dynamic.html';
instead of
include 'view/dynamic.html';
I am really surprised? Somebody could explained?
Related
How do you run Classes from an external file from the functions.php?
I'm using WordPress and the Beaver Builder plugin. I have a pagination list with info from the WP db. This is on a page using a search template (search.php). It includes a file (get-jobs.php). In order to see the results, I have to use a PHP Snippet plugin to set a global variable on the page that recognizes the $result variable provided by get-jobs.php, as I use the built-in modules to layout the page.
This works so far. I can see my formatted results.
When the pagination button is clicked, a function is called from my js file(custom-script.js) to update the results.
function selectJobs() {
$.ajax({
url: site_url + '/get-jobs.php',
type: "GET",
data: {
ajax': '1',
'state': GetURLParameter('country'),
'limit': GetURLParameter('limit')
},
success:function(data) {
console.log(data);
},
error: function(errorThrown){
console.log(errorThrown);
}
});
}
This doesn't work and I received a 403(Forbidden) error. I changed it to this:
function selectJobs(country) {
var country = country;
$.ajax({
url: ajaxurl,
type: "POST",
data: {
'action':'country_ajax_request',
'country' : country
},
success:function(data) {
console.log(data);
},
error: function(errorThrown){
console.log(errorThrown);
}
});
}
...which got rid of the error, and submitted the request.
In my functions.php, I have this:
function country_ajax_request() {
//include_once( get_stylesheet_directory() .'/get-jobs.php');
MY FUNCTIONS GO HERE
}
add_action( 'wp_ajax_country_ajax_request', 'country_ajax_request' );
add_action( 'wp_ajax_nopriv_country_ajax_request', 'country_ajax_request' );
Here's an bit of what's in get-jobs.php:
<?php
$get = (!empty($get) ? $get : $_REQUEST);
if(isset($get['ajax']) && $get['ajax'] == 1) {
require_once($_SERVER['DOCUMENT_ROOT'] . '/wp-load.php');
}
class GetJobs {
private $wpdb;
public function __construct($input) {
global $wpdb;
$this->wpdb = $wpdb;
$this->tableName = $this->wpdb->prefix . 'job_postings';
$this->country = (!empty($input['country']) ? $input['country'] : '');
$this->page = (!empty($input['page']) ? $input['page'] : '');
$this->limit = (!empty($input['limit']) ? $input['limit'] : 10);
}
public function getLocations() {
$result = [];
$states = $this->wpdb->get_results("SELECT country FROM " . $this->tableName . " WHERE deleted_at = '0000-00-00 00:00:00'");
foreach ($country as $key=>$row) {
$result[$row->country] = $row->country;
}
return $result;
}
// almost 200 more lines of this
}
$get['page'] = (!empty($get['page']) ? $get['page'] : 1);
$jobs = new GetJobs($get);
$query = $jobs->getQuery();
$jobsQuery = $jobs->getJobsQuery($query,(!empty($get['limit']) ? $get['limit'] : $jobs->limit));
$result['postings'] = $jobs->formatPostings($jobsQuery);
if(isset($get['ajax']) && $get['ajax'] == 1){
echo json_encode($result);
}
I tried to include the file, but that didn't work. It pulled data, but didn't seem go through the functions.
I want to reuse the existing file to perform the update list task. I don't want to rewrite get-jobs.php, if possible. I've used this same code just fine on other projects. Just not with this plugin.
Any thoughts or assistance as how I can approach this problem is appreciated.
Thanks.
UPDATE
I took another look at that include. It is pulling data. However, it's generates a json file, following by all of the html. The HTML is malformed. Here's what the beginning looks like:
<div id="postings" style="display: block;">{"states":{"AB":"AB","AZ":"AZ","BC":"BC","CA":"CA","FL":"FL","GA":"GA","IL":"IL","KS":"KS","NC":"NC","NS":"NS","ON":"ON","PA":"PA","QC":"QC","WA":"WA"},"category":{"":"","Accounting":"Accounting","Customs":"Customs","Finance":"Finance","Human Resources":"Human Resources","IT":"IT","Information Technology":"Information Technology","International":"International","Marketing":"Marketing","Marketing and Communications":"Marketing and Communications","Operations":"Operations","Project Management":"Project Management","Reception":"Reception","Sales":"Sales","Warehouse":"Warehouse"},"postings":"\n\t\t\t\t\t
I have my autocomplete working fine if there is hard coded data being fed into it. My PHP is returning a JSON result. I'm not sure where I am going wrong.
HTML
<div class="form-group bgcolor">
<label for="send_to">Direct to: </label><input type="text" name="send_to" id="send_to" class="form-control send_to typeahead" placeholder="Leave blank normally">
</div>
Jquery
$('.typeahead').typeahead({
source: {
groupName: {
ajax({
url: 'scripts/order_messaging.php',
method: 'POST',
data: JSON.stringify({action: 'autocomplete_to_user', query:query}),
contentType: 'application/json',
dataType: 'json',
success:function(data)
{
result($.map(data, function(item){
return item;
}));
}
})
},
},
debug: true
});
PHP
//autocomplete user name for user_to
if ( $_POST['action'] == 'autocomplete_to_user' ) {
$stmt = $pdo->prepare('select * from login where username like :query');
$stmt->bindValue('query', '%'.$_POST['query'].'%');
$stmt->execute();
$result = array();
while($user_name = $stmt->fetch(PDO::FETCH_OBJ)) {
array_push($result, $user_name->username);
}
echo json_encode($result);
}
I think it's this line in my jQuery: data: {action: 'autocomplete_to_user', query:query}, Maybe I have a syntax problem.
As per jQuery Ajax Documentation, dataType: 'json' evaluates the response as JSON and returns a JavaScript object.
You need to stringify your data by using JSON.stringify({action: 'autocomplete_to_user', query:query}) before you send it to PHP. Also, you need to add header Content-Type: 'application/json' that tells you PHP code that request data is JSON. You can do this by adding contentType: 'application/json' in your Ajax settings.
Your final jQuery code would look like this:
$('.typeahead').typeahead({
source: function(query, result)
{
$.ajax({
url: 'scripts/order_messaging.php',
method: 'POST',
data: JSON.stringify({action: 'autocomplete_to_user', query:query}),
contentType: 'application/json',
dataType: 'json',
success:function(data)
{
result($.map(data, function(item){
return item;
}));
}
})
}
});
Refer to jQuery Ajax Documentation for mode details.
Hope this helps!
EDIT:
You need to update your PHP code to read JSON. Please refer to this link.
Your PHP Code should look like this:
<?php
// Read the input stream
$body = file_get_contents("php://input");
// Decode the JSON object
$object = json_decode($body, true);
//autocomplete user name for user_to
if ( $object ['action'] == 'autocomplete_to_user' ) {
$stmt = $pdo->prepare('select * from login where username like :query');
$stmt->bindValue('query', '%'.$object['query'].'%');
$stmt->execute();
$result = array();
while($user_name = $stmt->fetch(PDO::FETCH_OBJ)) {
array_push($result, $user_name->username);
}
echo json_encode($result);
}
?>
In my humble opinion, the documentation has some errors. For instance, in the demos, specifically the example Country v2 states
A POST request will be sent with data myKey: myValue
when in actuality the request being sent in the example is GET, because it depends on the type key of the ajax object of the first source (country in this case), which is not set, thus defaulting to GET.
So, that being said, you really should stick to the proposed HTML structure (at least start with it, then take away stuff you don't want gradually as long as it'll let you).
HTML
<form id="form-country_v2" name="form-country_v2">
<div class="typeahead__container">
<div class="typeahead__field">
<div class="typeahead__query">
<input class="typeahead" name="country_v2[query]" placeholder="Search" autocomplete="off">
</div>
<div class="typeahead__button">
<button type="submit">
<i class="typeahead__search-icon"></i>
</button>
</div>
</div>
</div>
</form>
JS
$(document).ready(() => {
$('.typeahead').typeahead({
template: "{{display}} <small style='color:#999;'>{{group}}</small>",
source: {
users: { //might as well be 'willy wonka', it doesn't matter
ajax: {
type: "POST",
url: "scripts/order_messaging.php",
//this is not actually needed for the request to work (reach the server),
//this is used to access said request's returned data, it all
//depends on how you structure the response in the server,
//check out the php part
path: "data.users",
data: {
action: 'autocomplete_to_user',
query: 'username'
}
}
}
},
callback: {
//this is just to help you show the response in the html
onResult: function(node, query, result, resultCount) {
if (query === "") return;
var text = "";
if (result.length > 0 && result.length < resultCount) {
text = "Showing <strong>" + result.length + "</strong> of <strong>" + resultCount + '</strong> elements matching "' + query + '"';
} else if (result.length > 0) {
text = 'Showing <strong>' + result.length + '</strong> elements matching "' + query + '"';
} else {
text = 'No results matching "' + query + '"';
}
$('#result-container').html(text);
},
onInit: function(node) { //and this is just informational
console.log('Typeahead Initiated on ', node, node.selector);
}
}
});
});
order_messaging.php
if ($_POST['action'] == 'autocomplete_to_user') {
$stmt = $pdo->prepare('select * from login where username like :query');
$stmt->bindValue('query', '%' . $_POST['query'] . '%');
$stmt->execute();
$result = array();
while ($user_name = $stmt->fetch(PDO::FETCH_OBJ)) {
array_push($result, $user_name->username);
}
echo json_encode(array(
"status" => true,
"error" => null,
//here you use whatever structure you want to return the data in,
//as long as the payload is an array ($result).
//remember in the JS you are expecting 'data.users'?
//this is where it's coming from
"data" => array(
"users" => $result,
)
));
} else
echo json_encode(array(
"status" => true,
"error" => null,
"data" => array(
"users" => [],
)
));
HIH
Well, after much trial and error I got an autocomplete working using jQuery .autocomplete.
I don't know what I was doing wrong with the typeahead but the documentation was hard to understand (probably because of my limited experience with jQuery).
To all those in the future that need some help with this; here is a tutorial I found that was helpful: jquery ui autocomplete tutorial
Thank you to everyone
I've tested the library and you need to change two things in order to make it work.
1) You need to restructure the source parameter. You were giving it an AJAX callback which is not supported. According to the documentation, it accepts an array or an object with settings, so AJAX needs to be defined like this:
$('.typeahead').typeahead({
source: {
// source has an "ajax" property where you just need to place
// the object with AJAX params (the one you'd normally place inside
// an $.ajax() call)
ajax: {
url: 'scripts/order_messaging.php',
method: 'POST',
data: {
action: 'autocomplete_to_user',
query: query,
},
dataType: 'json',
path: '',
},
},
});
The path property of the ajax object is key here. It tells the typeahead function where to look for the data that was returned by the AJAX action. Since you're encoding a one-dimensional array of values, you need to set it to an empty string, meaning your data is in the root of the response.
If you were to return, for example, an array like echo json_encode(['users' => $result]); then you'd have to set the path to 'users' (because that is the index in the response that holds your data).
2) You have to follow a strict HTML structure in order to make it work:
<div class="typeahead__container">
<div class="typeahead__field">
<div class="typeahead__query">
<input class="js-typeahead" name="q" autocomplete="off">
</div>
</div>
</div>
If you leave out any of these elements, it doesn't trigger the functionality. This HTML structure is one of the first things they mention in the documentation.
I am having trouble with a form I created and trying to redirect the data someplace else by a JavaScript method that I call whenever the submit button is clicked.
The first thing that is happening, is that the form is created and filled in, then the user will click on the HTML generated button with this action in it:
onclick="javascript:saveEssayScore(<?php echo $key . "," . $pid; ?>);"
Secondly the script file is read and performed. The code is below:
<script type="text/javascript" language="javascript">
document.body.className = document.body.className.replace("modal", "");
function saveEssayScore(key, pid){
var user_id = document.getElementById("user-"+key).value;
console.log("user " + user_id);
var grade = document.getElementById("grade-"+key).value;
console.log("grade " + grade);
var teacher_answer = document.getElementById("feedback-"+key).value;
console.log("teacher_answer " + teacher_answer);
var question_id = document.getElementById("question-"+key).value;
console.log("question_id " + question_id);
var quiz_id = document.getElementById("quiz-"+key).value;
console.log("quiz_id " + quiz_id);
var req = new Request.HTML({
method: 'post',
url: "<?php echo JURI::base();?>index.php?option=com_guru&controller=guruAuthor&task=saveFeedback&tmpl=component&format=raw",
data: { 'pid' : pid, 'user_id' : user_id, 'grade' : grade, 'teacher_answer' : teacher_answer, 'question_id' : question_id, 'quiz_id' : quiz_id},
onSuccess: function(response, responseElements, responseHTML){
alert('yeyy');
}
}).send();
}
Now in the URL, it is read to run the method (task) saveFeedback() in the controller guruAuthor which is in the component com_guru.
The problem I am having is, how do I read the data that I just send through the HTML request? I am trying stuff like $user_id = JRequest::getVar("user_id"); But whenever I'm trying to echo or dump, it is returned to me but empty. Not the values that I am dumping in JavaScript console.log(user_id);
JRequest is deprecated
Use JInput instead. Read - Retrieving request data using JInput
In your mentioned code - if the controller function is being called, try this code-
$jinput = JFactory::getApplication()->input;
$user_id = $jinput->get('user_id', '', 'INT');
I hope this helps.
I am trying to implement a "like" button for my website. I am using Codigniter, Ajax and Jquery. When the like button is clicked data should be entered to database and if unlike button is pressed data should delete from database. But I am facing a problem in model, data is not added to database when I click like button. Please help me to find a solution.
This is my Jquery file "likeitem.js"
function likeItem(postId)
{
if ($("#likeItem_"+postId).text() == "Like")
{
$("#likeItem_"+postId).html('Unlike');
var purpose = "Like";
}
else
{
$("#likeItem_"+postId).html('Like');
var purpose = "UnLike";
}
$.ajax({
type : "POST",
url : "http://localhost/codeig_smarty/index.php/user/likeItem",
data : "postId=" + postId + "purpose=" + purpose,
success : function()
{
}
});
return false;
}
This is my model "usermodel.php"
public function itemLike()
{
$id = $this->session->userdata('userID');
$postId = $this->input->post('postId');
$purpose = $this->input->post('purpose');
if($purpose=="Like")
{
// echo 'test';
// exit();
$data = array(
"userID" => $id,
"postTextID" => $postId,
);
$this->db->insert('like', $data);
}
else
{
echo 'hai';
}
}
This is my view file "home.tpl"
<li><a class="like-unlike" href="#" id="likeItem_{$item['postID']}" onclick="likeItem({$item['postID']})">Like</a></li>
This is my Controller "user.php"
public function likeItem()
{
$this->usermodel->itemLike();
}
You mistake here. You forgot to put & symbol. Try this code.
data : "postId=" + postId + "&purpose=" + purpose,
Full code:
If you want to manipulate result returned from ajax, you can do something on success block as following code :
$.ajax({
type : "POST",
url : "http://localhost/codeig_smarty/index.php/user/likeItem",
data : "postId=" + postId + "&purpose=" + purpose,
success : function(data)
{
// do seomthing here with data
// console.log(data) --> to see data return or not
}
});
in order to set two dependent drop downs i'm using jQuery.ajax, but i have some troubles and i think the url of the controller action i set on my $.ajax is not accessible.
this is my controller action code :
public function fillIncidentsAction()
{
$request = $this->getRequest();
if ($request->isPost())
{
$code_categ = (int) $request->getPost('code_categ',0);
$data = new JsonModel(array(
'success' => true,
'results' => $this->getTableInstance('TypeIncidentTable')
->getListTypeIncident($code_categ),
));
return $data;
}
}
and this is the main part of my js function
$('#'+source).change(function() {
if($('#'+source).val() != '')
{
$.ajax({
type: 'POST',
async: false,
url: url,
cache: true,
dataType: 'json',
data: { code_categ: $('#'+source).val() },
success: function(data){
alert(data.success);//<------ i added this to test if this function is executed or not
if(data.success)
{
$('#'+target).prop('disabled', true);
if(data.results != ""){
var options = new Array();
$.each(data.results, function(key, value){
options[((key) ? key : 0)] = '<option value="' + key + '">' + value + '</option>';
});
$("#"+target).html(options.join(''));
$('#'+target).prop('disabled', false);;
}
}
},
});
I don't know where i'm wrong. Any suggestions?
Thanks for help !
Sorry, this is how i set my url :
<script type="text/javascript">
$(document).ready(function() {
var url = "<?php echo $var =$this->url('gims/default', array('controller' => 'evenement', 'action' => 'fill_incidents')); ?>";
// initialize the js function
dependentDropDown('firstList','secondList',url);
});
</script>
Hope this will give you more details.
The problem was in my moodule.config.php, i haven't enabled the Json strategy.
'view_manager' => array(
//...
'strategies' => array(
'ViewJsonStrategy',
),
),