So I'm running into an issue and I can't seem to figure it out, so I'm reaching out to see if anyone can help me.
I have a method called show_instagram_table() which has the following:
private function show_instagram_table(): string
{
$table = '';
if ($authenticated_users = get_option('instagram_authenticated_users')) {
foreach ($authenticated_users as $authenticated_user) {
$table .= '<table class="widefat"><tbody>';
// ----------- Remove other items non-needed ---------------
if (Instagram::get_items()) {
$table .= $this->show_authenticated_buttons($authenticated_user);
}
$table .= '</tbody></table>';
}
}
return $table;
}
Which calls on show_authenticated_buttons():
private function show_authenticated_buttons($user): string
{
$buttons = '<tr>';
$buttons .= $this->show_deauthorize_instagram_button($user);
$buttons .= '</tr>';
return $buttons;
}
This calls on show_deauthorize_instagram_button():
private function show_deauthorize_instagram_button($user): string
{
return '<td><button class="button button-primary instagram-deauthorize" style="margin-right: 5px">Deauthorize</button>';
}
Using AJAX, when the button is clicked, is will target that method and send the response back to PHP:
So..
jQuery('.instagram-deauthorize').click(function(e) {
e.preventDefault();
const data = {
'action': 'deauthorize_instagram_via_button',
};
jQuery.post(instagram_object.ajax_url, data, function() {
window.location = url;
});
});
Will trigger this method (I've tested it, it deletes the option):
public function deauthorize_instagram_via_button($user)
{
if (!get_option('instagram_authenticated_users')) {
return;
}
$users = get_option('instagram_authenticated_users');
if (count($users) === 1) {
delete_option('instagram_authenticated_users');
$this->instagram->delete_cache();
}
exit;
}
Here is where I am stuck:
I am wanting to send authenticated_user data inside the foreach from show_instagram_table all the way to my deauthorize_instagram_via_button() method, but it's impossible for me to target it.
Does anyone know what I can change/improve? I've already tried passing it down using $user params and no luck.
(Sorry for the lack of pictures, I am not allowed to post them).
Thanks all!
You can add one more attribute for each row.
You can use something like data-id or else.
For example :
private function show_authenticated_buttons($user): string
{
$buttons = '<tr data-id="'.$user->id.'">';
$buttons .= $this->show_deauthorize_instagram_button($user);
$buttons .= '</tr>';
return $buttons;
}
Then, you can get each user id (by using $(this).attr("data-id")).
jQuery('.instagram-deauthorize').click(function(e) {
e.preventDefault();
const data = {
'action': 'deauthorize_instagram_via_button',
'user_id': $(this).attr("data-id")
};
jQuery.post(instagram_object.ajax_url, data, function() {
window.location = url;
});
});
Finally your deauthorize_instagram_via_button will get the user_id.
Related
BotMan Version: 2.1
PHP Version:7.3
Messaging Service(s):
Cache Driver: SymfonyCache
Description:
I trying to have conversation. In every next method I lost data from conversation properties, that was saved in properties before!
class GetAlertDataConversation extends AppConversation
{
public $bot;
public $alertTitle;
public $alertDescription;
public $alertLatitude;
public $alertLongitude;
public $alertAuthorId;
public $alertAuthorName;
public function __construct($bot)
{
$this->bot = $bot;
}
private function askTitle()
{
$this->ask('Что случилось? (кратко)', function (Answer $answer) {
$this->alertTitle = $this->askSomethingWithLettersCounting($answer->getText(), 'Слишком коротко!', 'askDescription');
\Yii::warning($this->alertTitle);
});
}
public function askDescription()
{
$this->ask('Расскажи подробней!', function (Answer $answer) {
$this->alertDescription = $this->askSomethingWithLettersCounting($answer->getText(), 'Слишком коротко!', 'askLocation');
\Yii::warning($this->alertTitle);
});
}
private function askLocation()
{
\Yii::warning($this->alertTitle);
$this->askForLocation('Локация?', function (Location $location) {
// $location is a Location object with the latitude / longitude.
$this->alertLatitude = $location->getLatitude();
$this->alertLongitude = $location->getLongitude();
$this->endConversation();
return true;
});
}
private function endConversation()
{
\Yii::warning($this->alertTitle);
$alertId = $this->saveAlertData();
if ($alertId)
$this->say("Событие номер {$alertId} зарегистрировано!");
else
$this->say("Ошибка при сохранении события, обратитесь к администратору!");
}
private function saveAlertData()
{
$user = $this->bot->getUser();
$this->alertAuthorId = $user->getId();
$this->alertAuthorName = $user->getFirstName() . ' ' . $user->getLastName();
$alert = new Alert();
\Yii::warning($this->alertTitle);
$alert->name = $this->alertTitle;
$alert->description = $this->alertDescription;
$alert->latitude = $this->alertLatitude;
$alert->longitude = $this->alertLongitude;
$alert->author_id = $this->alertAuthorId;
$alert->author_name = $this->alertAuthorName;
$alert->chat_link = '';
$alert->additional = '';
if ($alert->validate()) {
$alert->save();
return $alert->id;
} else {
\Yii::warning($alert->errors);
\Yii::warning($alert);
return false;
}
}
}
There is user's text answer in the first \Yii::warning($this->alertTitle); in the askTitle() function.
But all other \Yii::warning($this->alertTitle); returns NULL!!!!
As the result, saving of Alert object not working!
Please, help me. Some ideas?
I think, that it can be by some caching + serialise problem.
I was trying to change cache method to Redis. Same result.
Problem was in this function call and caching:
$this->askSomethingWithLettersCounting($answer->getText(), 'Слишком коротко!', 'askDescription');
If you will read other conversation botman issues in github, you wil see, that most of issues in conversation cache and serialise.
Not any PHP code of conversation can be cached right.
In this case, not direct call of functions askDescription() and askLocation() broken conversation caching.
I fixed that by removing askSomethingWithLettersCounting() function.
I am using JQuery Datatables to display all the users of my forum in a page from a table called 'users'. I am using Code Igniter for server-side processing. I looked up the Datatables documentation on how to render data and I got it going. However, I have some PHP variables and functions that I want to echo into a JavaScript variable so I can use them within the render function for the target column. However, I am wondering how to echo a model function from a different table with a parameter into the JavaScript variable, or whether that is even a good approach. Below is my set-up. I have only posted the lines that are relevant to this question (unless I am doing it all wrong).
Model (Dashboard_model)
public function my_followee($followee) {
$username = $this->session->username;
return $this->db->get_where('followers', array('user' => $followee, 'follower' => $username))->row_array();
}
JS:
{
"targets": [-1],
"data": null,
"orderable": false,
"render": function ( data, type, full ) {
var myself = "<?php echo $this->session->username; ?>";
var is_following = "<?php echo $this->dashboard_model->my_followee('+full[1]+');" //full[1] is username column
if(is_following == false && myself !== full[1]) {
return Follow ';
} else if(is_following == true && myself !== full[1]) {
return Unfollow ';
} else if(myself == full[1]) {
return 'This is you';
}
}
}
Basically, I want to check if the loggedin user is already following the currently selected user. If no, show follow button, otherwise, show unfollow button.
When I check the page, all the buttons have follow (except the currently logged in user), whereas some should return true and show unfollow. I suspect I'm violating syntax rules in this line:
var is_following = "<?php echo $this->dashboard_model->my_followee('+full[1]+');"
I am new to JQuery and Datatables and can't seem to figure out the right way to do this. Please can someone point me to the right direction, or suggest better ways of achieving my aim? I would really appreciate the help.
EDIT
I tried this in my controller that handles the ajax call request
public function users_ajax_list()
{
$this->load->model('user/users_model', 'users');
$this->load->model('dashboard_model');
$list = $this->users->get_users();
$data = array();
foreach ($list as $user) {
if ($this->dashboard_model->my_followee($user->username) == true) {
$is_following = true;
} else {
$is_following = false;
}
$row = array();
$row[] = $user->profile_image;
$row[] = $user->username;
$row[] = ucfirst($user->surname);
$row[] = ucfirst($user->first_name);
$row[] = ucfirst($user->state);
$row[] = ucfirst($user->lga);
$row[] = $user->followers;
$row[] = $user->following;
$row[] = $user->total_posts;
$row[] = $user->gender;
$data[] = $row;
}
$output = array(
"draw" => $_POST['draw'],
"recordsTotal" => $this->users->count_all_users(),
"recordsFiltered" => $this->users->count_filtered_users(),
"data" => $data,
);
//output to json format
echo json_encode($output);
echo json_encode($is_following);
}
It produced errors: wrong JSON response. What am I doing wrong? And how is the best way to do it? And how can I access the JSON variable within the render function for the targeted column.
Below is my script in Dashboard module.
$(function()
{
var o;
$.get('dashboard/xhrgetInsert',function(o)
{
for(var i = 0;i <= o.length; i++)
{
$("#appendHere").append("<div>"+o[i].text+"</div>");
}
},'json');
$("#randomInsert").submit(function()
{
alert("hi");
var data = $(this).serialize();
var url = $(this).attr("action");
$.post(url,data,function(o)
{
$("#appendHere").append("<div>"+o+"</div>");
},'json');
return false;
});
});
Supposedly, when I'm in the dashboard page this function(xhrgetInsert) has to return value to be appended in the HTML. Unfortunately, it doesn't append anything and as I checked in the chrome console 'response'..it says method doesn't exist. But If I type the method name in the url, it shows the values returned in json format as I specified so.
Same goes for 'xhrInsert()' function as it doesn't return value to be appended. Database connection is perfect as it can insert and select data from db just unable get back the values..
I'm wondering first, why it says the method doesn't exist, and secondly why doesn't return any value?
My 'Dasboard controller making call to dashboard model'
public function xhrInsert()
{
$this->model->xhrInsert();
}
public function xhrgetInsert()
{
$this->model->xhrgetInsert();
}
Dashboard model contains mysql queries to the database whcih return values in jason format
public function xhrInsert()
{
$text = $_POST['text'];
$sql = $this->db->prepare("INSERT INTO data(text)VALUES(:text)");
$sql->execute(array(':text'=>$text));
echo json_encode($text);
}
public function xhrgetInsert()
{
$sth = $this->db->prepare("SELECT * FROM data");
$sth->setFetchMode(PDO::FETCH_ASSOC);
$sth->execute();
$data = $sth->fetchAll();
echo json_encode($data);
}
Finally, this is my HTML for dashboard
<h1>Dashboard</h1>
<form id="randomInsert" action="<?php echo URL;?>dashboard/xhrInsert" method="post">
<label>Text: </label><input type="text" name="text"/><br/>
<input type="submit"/>
</form>
<div id="appendHere"></div>
Console Screenshot
Function should return the result json data to ajax request so it won't render the whole html page with result.
public function xhrInsert(){
echo $this->model->xhrInsert();
die;
}
public function xhrgetInsert()
{
echo $this->model->xhrgetInsert();
die;
}
Model
public function xhrInsert()
{
$text = $_POST['text'];
$sql = $this->db->prepare("INSERT INTO data(text)VALUES(:text)");
$sql->execute(array(':text'=>$text));
return json_encode($text);
}
public function xhrgetInsert()
{
$sth = $this->db->prepare("SELECT * FROM data");
$sth->setFetchMode(PDO::FETCH_ASSOC);
$sth->execute();
$data = $sth->fetchAll();
return json_encode($data);
}
Ok, so I have a table that looks like this:
echo "<table id='tbl'>";
foreach ($questions as $q1)
{
if($q1->parinte==0)
{
echo "<tr class=".clickable">";
echo "<td class='parrent".$q1->parinte."' id='".$q1->id."'>".$q1->text."</td>";
echo "</tr>";
}
}
The questions variable is passed from my controller and used here.
What I want is when i click a row in that table, I want to check the id of that row with something from my database and then rewrite the table with other rows from my database.
I think it's simplier in jQuery but I kinda new to jQuery and Codeigniter.
Can someone give me an example on how to send the ID when I click a row and compare to something in my database?
Thanks.
LE:
My model:
class Support_help_model extends CI_Model
{
public function get_questions()
{
//Intrebari principale
$query = $this -> db -> query("SELECT * FROM decision_tree");
return $query->result();
}
}
My controller:
class Support_help_controller extends CI_Controller
{
public function index()
{
$this->load->model("support_help_model");
$data['questions'] = $this->support_help_model->get_questions();
$this->load->view('welcome_message', $data);
}
}
onClick of the row, send the variable to your php script (save.php) using ajax. Just like this-
$(".parrent0").click(function() {
$.post( "save.php", { param: this.id }, function( data ) {
alert(data); // here you'll get the db rows returned
});
});
Receiving the variable and returning the result back; save.php-
$param = $_POST['param'];
//
// db queries
//
$db_data; // data/rows to be returned back
echo json_encode($db_data);
(Original Questions) I am using jquery ui's selectable script to control specific active keywords in my webapp. View here: www.rickymason.net/letschat/main/home for reference
I have very little experience with javascript and I'm trying to figure out how to launch a function I have in my main model.
Updated function based on answers:
I have updated my code to support the new JSON/AJAX format. This required me to create an active/inactive session filter so that the user can add filters normally, and always use AJAX to update the thread list. This just made more sense to me.
Here is the code I have currently, which still is not working. I am attempting to make it so when the user clicks on a selectable category (through Jquery UI), the divID associated with the selection is passed through AJAX and returns a threadlist array that updates the div id ="board".
Here is my current Controller set up:
public function home($page = 'home')
{
$data['user_id'] = $this->tank_auth->get_user_id();
$data['username'] = $this->tank_auth->get_username();
$data['threads'] = $this->thread_model->session_load();
$data['title'] = ucfirst($page); // Capitalize the first letter
$data['page'] = $page;
$this->load->view('templates/head', $data);
$this->load->view('templates/nav', $data);
$this->load->view('main/newthread', $data);
$this->load->view('main/addfilter', $data);
$this->load->view('main/checkbox', $data);
$this->load->view('main/displayfilter',$data);
$this->load->view('main/board', $data);
$this->load->view('templates/footer');
}
public function updatefilters($filters)
{
$filterarray = split("|", $filters);
$this->thread_model->create_session_filter($filterarray);
$threadarray = $this->thread_model->get_threads();
$data['json'] = '{"content":' + $threadarray + '}';
$this->load->view('json_view', $data); // See step 4!!!
}
Here is my current model code:
public function get_threads()
{
$filter = $this->session->userdata('filter');
$num_tags = count($filter);
if ($num_tags > 0 && $num_tags <= 8) {
$sql_select = "SELECT DISTINCT t.* ";
$sql_from = " FROM ";
$sql_where = " WHERE ";
$sql_joins = "";
$sql_order = "ORDER BY t.timestamp DESC";
for ($i=0;$i<$num_tags;++$i) {
if ($i==0) {
$sql_from .= " filter AS f ";
$sql_where .= " f.tag LIKE '%" . $filter[0] . "%'";
$sql_joins .= " INNER JOIN filter_thread AS ft ON ft.filter_id = f.filter_id
INNER JOIN thread AS t ON ft.thread_id = t.thread_id";
}
else {
$sql_where .= " OR f.tag LIKE '%" . $filter[$i] . "%'";
}
}
} else {
break;
}
$sql = $sql_select . $sql_from . $sql_joins . $sql_where . $sql_order;
$query = $this->db->query($sql);
$thread = $query->result_array();
return json_encode($thread); //I am aware this is not correct
}
public function create_session_filter($filterstring)
{
$filterarray[] = $filterstring;
$filter['filter'] = $filterarray;
if ($this->session->userdata('filter') == TRUE) {
$sessionfilter = $this->session->userdata('filter');
$new = array_merge($sessionfilter, $filter['filter']);
$this->session->unset_userdata('filter');
$filter['filter'] = $new;
$this->session->set_userdata($filter);
} else {
if (!$filterstring) {} else {
$this->session->set_userdata($filter);
}
}
}
public function create_session_inactive_filter($filterstring)
{
$filterarray[] = $filterstring;
$filter['inactivefilter'] = $filterarray;
if ($this->session->userdata('inactivefilter') == TRUE) {
$sessionfilter = $this->session->userdata('inactivefilter');
$new = array_merge($sessionfilter, $filter['inactivefilter']);
$this->session->unset_userdata('inactivefilter');
$filter['inactivefilter'] = $new;
$this->session->set_userdata($filter);
} else {
if (!$filterstring) {} else {
$this->session->set_userdata($filter);
}
}
}
And here is my current view code:
application/main/json_view.php
<?php
header("Content-Type: application/json");
echo $json;
?>
aplication/main/bdisplayfilter.php
<script>
$(function() {
$( "#selectable" ).selectable({
selected: updateFilters,
unselected: updateFilters
});
function updateFilters(ev, ui){
alert ("hello");
// get the selected filters
var $selected = $('#selectable').children('.ui-selected');
// create a string that has each filter separated by a pipe ("|")
var filters = $selected.map(function(){return this.id;}).get().join("|");
$.ajax({
url: '/main/updateFilters', //see step 2
data: { filters: filters },
success: function(data){
// data is whatever json you decide to return from the server.
// An easy way to do things is have data look like this:
// { content: "<div>All my new threads that I want to show up</div>" }
// then, you can replace some element on the page with the new content
// For example, say your container has an id of threadContainer:
$('#select').replaceWith(data.content);
}
}); }
});
</script>
<ol id="selectable">
<li class="ui-state-default" id="everything">Everything!</li>
<li class="ui-state-default" id="entertainment">Entertainment</li>
<li class="ui-state-default" id="sci/tech">Sci/Tech</li>
<li class="ui-state-default" id="news">News</li>
<?php
if ($this->session->userdata('inactivefilter') == true) {
$inactivefilter = $this->session->userdata('inactivefilter');
foreach ($inactivefilter as $new)
{
echo "<li class='ui-state-default' id='custom'>$new</li>";
}
}
?>
</ol>
<?php
if ($this->session->userdata('inactivefilter') == true) {
echo "<form action='".base_url()."main/clear_filter'><input type='submit' value=clear></form>";
} ?>
EDIT: I've updated the url and data parts of the ajax call and added an additional step to enable query string parameters.
1) Make the AJAX call
You will want to make the same call for selected and unselected, since you can have multiple filters and you need things to update accordingly on both events. So, I'll define a common function that both events can call.
$(function() {
$( "#selectable" ).selectable({
selected: updateFilters,
unselected: updateFilters
});
function updatefilters(ev, ui){
// get the selected filters
var $selected = $('#selectable').children('.ui-selected');
// create a string that has each filter separated by a pipe ("|")
var filters = $selected.map(function(){return this.id;}).get().join("|");
$.ajax({
url: '/index.php',
data: { c: main, m: updateFilters, filters: filters },
success: function(data){
// data is whatever json you decide to return from the server.
// An easy way to do things is have data look like this:
// { content: "<div>All my new threads that I want to show up</div>" }
// then, you can replace some element on the page with the new content
// For example, say your container has an id of threadContainer:
$('#threadContainer').replaceWith(data.content);
}
});
}
});
2) Enable query string parameters in application/config.php
The section called Enabling Query Strings at the bottom of this article explains how to do that:
http://codeigniter.com/user_guide/general/urls.html
3) Create an action that will receive the filters
Note that I'm using a controller called Page (which would live in /application/controllers/page.php). This action (updateFilters) could live in any controller you want.
class Page extends CI_Controller {
function __construct()
{
parent::__construct();
}
function index()
{
}
function updateFilters($filters)
{
$filterarray = split("|", $filters);
create_session_filter($filterarray);
$articlesHTML = getThreadList($filterarray); // See step 4!!!
$data['json'] = '{"content":' + $articlesHTML + '}';
$this->load->view('json_view', $data); // See step 5!!!
}
/* I've updated this slightly to accept an array */
public function create_session_filter($filterarray)
{
$filter['filter'] = $filterarray;
//... the rest of your stuff you already had
}
}
4) Implement getThreadList method
I don't think you mentioned if you already had something set up for this. This would basically take an array of filters and then render a thread list based off that.
5) Create json_view (if not already there)
This will set the content type so that the browser knows the content is json.
In /application/views/json_view.php:
<?php
header("Content-Type: application/json");
echo $json;
?>