How to beat my CodeIgniter bad practices - javascript

Accessing functions from the view?
I know the correct way should be that the controllers handles all the function calls, but
If I need to call another function and pass a variable that comes from a db data in a loop in view eg.
view:
if($persons != ""){
foreach($persons as $p){
echo $p->name;
echo $p->lastname;
// Now I need to call a function and pass parameters from loop
$is_banned = $this->model_users->checkIfBanned($p->name);
echo $is_banned;
}
}
How should I do this the right way in the controller?
Other thing is the javascript ajax calls. I have been putting lots of javascript in the controllers when I need to receive more than one response. For instance, if i need to get all the posts from a user via ajax and get the response to update the posts div, plus get the number of posts and update the post count div.
The wrong way I've been doing:
eg. js:
function insertNewPost(){
var the_text = $('#post_text_input').val();
if(the_text != ""){
$.ajax({
type:"POST",
url:base_url+"controller/insertNewPost",
data: {post_text: the_text},
cache:false,
success:function(response){
$('#post_output').prepend(response);
$('#post_text_input').val('');
}
});
}
Controller:
function insertNewPost(){
if($this->session->userdata('is_logged_in')){
$this->load->model('model_users');
$this->load->model('model_posts');
$email = $this->session->userdata('email');
$myid = $this->model_users->getUserId($email);
$post_text= $this->FilterData($this->input->post('post_text'));
if($this->model_posts->insertNewPost($myid,$post_text)){
$count = $this->model_posts->countPosts($myid);
echo 'More recent: '.$post_text;?>
<script>
var count = "<?php echo $count;?>";
$('#posts_count').html(count);
</script>
<?php
}
}else{
redirect("inicio");
}
}
Is it possible to get 2 responses at the same time and update content from 2 divs at the same time? How would I get hold of the $count variable and pass it on the same ajax response?
Any light shed would be very greatful.
Thanks in advance
As suggested by #charlietfl:
Changed the Controller:
function insertNewPost(){
if($this->session->userdata('is_logged_in')){
$this->load->model('model_users');
$this->load->model('model_posts');
$email = $this->session->userdata('email');
$myid = $this->model_users->getUserId($email);
$post_text= $this->FilterData($this->input->post('post_text'));
if($this->model_posts->insertNewPost($myid,$post_text)){
$content = 'More recent: '.$post_text;
$count = $this->model_posts->countPosts($myid);
$items = array($content,$count);
echo json_encode($items);
}
}else{
redirect("inicio");
}
}
And changed the js function:
function insertNewPost(){
var the_text = $('#post_text_input').val();
var post_count = '#posts_count';
if(the_text != ""){
$.ajax({
type:"POST",
url:base_url+"controller/insertNewPost",
data: {post_text: the_text},
cache:false,
success:function(response){
var content = json_encode(response);
$('#post_output').prepend(content[0]);
$(post_count).html(content[1]);
$('#post_text_input').val('');
}
});
}
it's not happening, i must be doing something wrong.

For your first problem:
Its OK the way you doing.But I don't recommend it because it is not programmer friendly.
You can solve it many way.
Here is one solution that you want.
Process your controller before sending data at view this way after getting persons
for($i=0;$i<sizeof($persons);$i++)
{
$persons[$i]->is_banned=$this->model_users->checkIfBanned($persons[$i]->name);
}
Now send this new $persons to your view.Your new view code will be like this
if($persons != "")
{
foreach($persons as $p)
{
echo $p->name;
echo $p->lastname;
echo $p->is_banned;
}
}
Hope you understand this.
For your second problem you can use #charlietfl solution.
Here is summary:
Instead of calling multiple ajax call- call one ajax and return all the results as array.Like
function insertNewPost()
{
//do your stuff;
$data['content']="something";//it may be anything array,string
//do your stuff;
$data['count']="something";
//do your stuff;
$data['moreresult']="something";
header('Content-type: application/json');
echo json_encode($data);
exit();
}
Now at your js
function insertNewPost()
{
var the_text = $('#post_text_input').val();
if(the_text != "")
{
$.ajax({
type:"POST",
url:base_url+"controller/insertNewPost",
data: {post_text: the_text},
dataType: "JSON",
success:function(response){
//here you will get datas as response.content,response.count,response.moreresult
//Now use them as you want as example
$('#post_output').prepend(response.content);
$('#post_text_input').val(response.count);
$('#anotherid').val(response.moreresult);
}
});
}
Hope it will help you.

Related

unable to parse xml data with AJAX + Wordpress

Ok, I am officially stumped. I have been trying to find why my calls for specific items in a PubMed xml data file are not working... I can execute this one with my current coding:
$test = (string)$id_json->PubmedArticle->MedlineCitation->PMID;
but if I try to get a variable that is in a deeper array, it does not return a value. I have even tested with console.log(data) and I get my PMID returning but not my other, deeper values in the XML file. For example;
$test = (string)$id_json->PubmedArticle->MedlineCitation->Article->Journal->ISSN;
returns nothing for data in console.log(data)
Here is my function in wordpress:
function get_abstract(){
$id = $_POST['abstractid'];
$pubmed_api_call = 'https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&retmode=xml&rettype=abstract&id='.$id;
$id_wpget = wp_remote_get($pubmed_api_call, array('timeout' => 20));
if( is_wp_error( $id_wpget ) ) {
echo "Error Contacting PubMed, please refresh page and try again";
die();
}
$id_xml = wp_remote_retrieve_body($id_wpget);
$id_json = simplexml_load_string($id_xml);
$test = (string)$id_json->PubmedArticle->MedlineCitation->Article->Journal->ISSN;
if($test === ""){
echo "NOTHING";
die();
}
echo $test;
die();
}
and here is my javascript AJAX call:
jQuery(document).ready(function() {
jQuery('.reference_header').click(function(e) {
jQuery(this).find("i").toggleClass("arrow-down arrow-up");
jQuery(this).nextUntil('.reference_header').slideToggle('fast');
var abstractid = jQuery(this).data("id");
e.preventDefault();
jQuery.ajax({
url: get_abstract.ajaxurl,
type: 'POST',
dataType: 'json',
data: {
abstractid: jQuery(this).data("id"),
action: 'get_abstract'
},
success : function(data){
jQuery('.'+abstractid).html("TESTING: "+data);
console.log(data);
}
});
});
});
I cannot find out why it doesnt work... any help is greatly appreciated.
So I figured out the solution to the issue... you need to pass the string text as a json object to AJAX for it to read properly...
working code:
PHP:
echo json_encode(array("result" => "$test"));
die();
AJAX:
success : function(data){
jQuery('.'+abstractid).html("TESTING: "+data.result);
console.log(data.result);
}

ajax request is successful, but php is not running

I have a very simple jquery function that sends an Ajax call to a php file that should echo out an alert, but for the life of me, cannot get it to run. For now, I'm just trying to trigger the php to run. Here is the javascript:
function getObdDescription(){
var $code = document.getElementById("vehicle_obd_code").value;
var $length = $code.length;
if($length == 5){
window.confirm($length);
$.ajax({ url: '/new.php',
data: {action: 'test'},
type: 'post',
success:function(result)//we got the response
{
alert('Successfully called');
},
error:function(exception){alert('Exception:'+exception);}
});
}
return false;
}
Here is new.php
<?php
echo '<script language="javascript">';
echo 'alert("message successfully sent")';
echo '</script>';
?>
I'm testing in Chrome, and have the network tab up, and can see that the call is successful, as well, I get the 'Successfully called' message that pops up, so the jquery is running, and the Ajax call is successful. I also know that the url: '/new.php is correct, because when I delete new.php from my server, I get a status "404 (Not Found)" from the console and network tab. I've even test without the conditional if($length ==... and still no luck. Of course, I know that's not the problem though, because I get the 'Successfully called' response. Any ideas?
This isnt the way it works if you need to alert the text, you should do it at the front-end in your ajax success function, follow KISS (Keep It Simple Stupid) and in the php just echo the text . that is the right way to do it.
You should do this:
function getObdDescription() {
var $code = document.getElementById("vehicle_obd_code").value;
var $length = $code.length;
if ($length == 5) {
window.confirm($length);
$.ajax({
url: '/new.php',
data: {
action: 'test'
},
type: 'post',
success: function (result) //we got the response
{
alert(result);
},
error: function (exception) {
alert('Exception:' + exception);
}
});
}
return false;
}
In your php
<?php
echo 'message successfully sent';
?>
You are exactly right Muhammad. It was not going to work the way I was expecting it. I wasn't really trying to do an Ajax call, but just to get an alert box to pop up; I just wanted confirmation that the call was working, and the PHP was running. Changing the alert('Successfully called'); to alert(result); and reading the text from the php definitely confirmed that the php was running all along.
I want to stay on topic, so will post another topic if that's what's needed, but have a follow-up question. To elaborate a bit more on what I'm trying to do, I am trying to run a function in my php file, that will in turn, update a template variable. As an example, here is one such function:
function get_vehicle_makes()
{
$sql = 'SELECT DISTINCT make FROM phpbb_vehicles
WHERE year = ' . $select_vehicle_year;
$result = $db->sql_query($sql);
while($row = $db->sql_fetchrow($result))
{
$template->assign_block_vars('vehicle_makes', array(
'MAKE' => $row['make'],
));
}
$db->sql_freeresult($result);
}
Now, I know that this function works. I can then access this function in my Javascript with:
<!-- BEGIN vehicle_makes -->
var option = document.createElement("option");
option.text = ('{vehicle_makes.MAKE}');
makeSelect.add(option);
<!-- END vehicle_makes -->
This is a block loop, and will loop through the block variable set in the php function. This work upon loading the page because the page that loads, is the new.php that I'm trying to do an Ajax call to, and all of the php runs in that file upon loading. However, I need the function to run again, to update that block variable, since it will change based on a selection change in the html. I don't know if this type of block loop is common. I'm learning about them since they are used with a forum I've installed on my site, phpBB. (I've looked in their support forums for help on this.). I think another possible solution would be to return an array, but I would like to stick to the block variable if possible for the sake of consistency.
I'm using this conditional and switch to call the function:
if(isset($_POST['action']) && !empty($_POST['action'])) {
$action = $_POST['action'];
//Get vehicle vars - $select_vehicle_model is used right now, but what the heck.
$select_vehicle_year = utf8_normalize_nfc(request_var('vehicle_year', '', true));
$select_vehicle_make = utf8_normalize_nfc(request_var('vehicle_make', '', true));
$select_vehicle_model = utf8_normalize_nfc(request_var('vehicle_model', '', true));
switch($action) {
case 'get_vehicle_makes' :
get_vehicle_makes();
break;
case 'get_vehicle_models' :
get_vehicle_models();
break;
// ...etc...
}
}
And this is the javascript to run the Ajax:
function updateMakes(pageLoaded) {
var yearSelect = document.getElementById("vehicle_year");
var makeSelect = document.getElementById("vehicle_make");
var modelSelect = document.getElementById("vehicle_model");
$('#vehicle_make').html('');
$.ajax({ url: '/posting.php',
data: {action: 'get_vehicle_makes'},
type: 'post',
success:function(result)//we got the response
{
alert(result);
},
error:function(exception){alert('Exception:'+exception);}
});
<!-- BEGIN vehicle_makes -->
var option = document.createElement("option");
option.text = ('{vehicle_makes.MAKE}');
makeSelect.add(option);
<!-- END vehicle_makes -->
if(pageLoaded){
makeSelect.value='{VEHICLE_MAKE}{DRAFT_VEHICLE_MAKE}';
updateModels(true);
}else{
makeSelect.selectedIndex = -1;
updateModels(false);
}
}
The javascript will run, and the ajax will be successful. It appears that the block variable is not being set.

AJAX take data from POST with PHP

i have a little problem with my script.
I want to give data to a php file with AJAX (POST).
I dont get any errors, but the php file doesn't show a change after AJAX "runs" it.
Here is my jquery / js code:
(#changeRank is a select box, I want to pass the value of the selected )
$(function(){
$("#changeRank").change(function() {
var rankId = this.value;
//alert(rankId);
//$.ajax({url: "/profile/parts/changeRank.php", type: "post", data: {"mapza": mapza}});
//$("body").load("/lib/tools/popups/content/ban.php");
$.ajax({
type: "POST",
async: true,
url: '/profile/parts/changeRank.php',
data: { 'direction': 'up' },
success: function (msg)
{ alert('success') },
error: function (err)
{ alert(err.responseText)}
});
});
});
PHP:
require_once('head.php');
require_once('../../lib/permissions.php');
session_start();
$user = "test";
if($_SESSION["user"] != $user && checkPermission("staff.fakeLogin", $_SESSION["user"], $mhost, $muser, $mpass, $mdb))
$_SESSION["user"] = $user;
header('Location:/user/'.$user);
die();
When i run the script, javascript comes up with an alert "success" which means to me, that there aren't any problems.
I know, the post request for my data is missing, but this is only a test, so im planning to add this later...
I hope, you can help me,
Greets :)
$(function(){
$("#changeRank").change(function() {
var rankId = this.value;
//alert(rankId);
//$.ajax({url: "/profile/parts/changeRank.php", type: "post", data: {"mapza": mapza}});
//$("body").load("/lib/tools/popups/content/ban.php");
$.ajax({
type: "POST",
async: true,
url: '/profile/parts/changeRank.php',
data: { 'direction': 'up' },
success: function (msg)
{ alert('success: ' + JSON.stringify(msg)) },
error: function (err)
{ alert(err.responseText)}
});
});
});
require_once('head.php');
require_once('../../lib/permissions.php');
session_start();
$user = "test";
if($_SESSION["user"] != $user && checkPermission("staff.fakeLogin", $_SESSION["user"], $mhost, $muser, $mpass, $mdb))
$_SESSION["user"] = $user;
echo json_encode($user);
This sample code will let echo the username back to the page. The alert should show this.
well your js is fine, but because you're not actually echoing out anything to your php script, you wont see any changes except your success alert. maybe var_dump your post variable to check if your data was passed from your js file correctly...
Just return 0 or 1 from your php like this
Your PHP :
if($_SESSION["user"] != $user && checkPermission("staff.fakeLogin", $_SESSION["user"], $mhost, $muser, $mpass, $mdb))
{
$_SESSION["user"] = $user;
echo '1'; // success case
}
else
{
echo '0'; // failure case
}
Then in your script
success: function (msg)
if(msg==1)
{
window.location = "home.php"; // or your success action
}
else
{
alert('error);
}
So that you can get what you expect
If you want to see a result, in the current page, using data from your PHP then you need to do two things:
Actually send some from the PHP. Your current PHP redirects to another URL which might send data. You could use that or remove the Location header and echo some content out instead.
Write some JavaScript that does something with that data. The data will be put into the first argument of the success function (which you have named msg). If you want that data to appear in the page, then you have to put it somewhere in the page (e.g. with $('body').text(msg).

Rewrite ajax request and the values returned

I need help to write this without the async: false,.
var imageX;
var groupX;
$.ajax({
type:'GET',
url:'php/myphp.php',
dataType:'json',
async: false,
success: function(response){
imageX = response[0].studentName,
groupX = response[0].subjectId;
alertImageX();
}
});
function alertImageX() {
(function() {
var image = {
'back': { 'url':imageX, 'img':null },
'front': { 'url':'img/bg.jpg', 'img':null }
};
php
$query = $db->prepare('SELECT studentName, subjectId FROM grade3 WHERE eligible = ? LIMIT 1');
$array = array('Yes');
$query->execute($array);
$result = $query->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($result);
"async: false" should not be needed in this situation because your response is already processed after AJAX request is complete, as it is placed inside the "success" element. Sorry if I missed any detail
EDIT:
Sorry I just read your comment regarding what you want to achieve. The response variable contains whatever the script called by AJAX echoed (in case of a PHP script), so you basically need to echo what you want the script to return and access that through the response variable.

JavaScript in CakePHP's controller

In my CakePHP view, I call method in controller, using jQuery:
function placeSensors(nk) {
$.ajax({
type:'post',
url:'/myapp/maps/placeSensors/' + nk,
success: function(r) {
if(r.status = 'ok') {
}
}
});
}
JS in controller is defined with ie.:
class MapsController extends AppController {
var $name = 'Maps';
var $helpers = array('Js');
var $uses = array('Measurings', 'Maps');
var $components = array('RequestHandler'); // added later, but still the same
function index( $id = null, $value = null ) {
$code = '';
?>
<script type="text/javascript">
alert('Hello!');
</script>
<?php
return $code;
}
So, with simple code, I can not get alert message on my web form. Very simple code I was using in some other project and it works there, and for some reason this does not work on this one...
I'm really stuck with this one, can you please help me.....
UPDATE: this is response i'm getting by Firebug:
<script type="text/javascript">
alert('Hello!');
</script>
You're trying to place code that should be viewed (javascript) by the client, inside a controller. Controller is for business logic, that the client doesn't see.
Place your javascript inside a javascript file in the /webroot/js/ directory.
For interacting with ajax, tell your controllers to use the RequestHandler component to determine that they're being called by ajax. From there you can return simple values, or return a json or xml view.
If that sounds complicated, don't worry about it for now and just start as simple as you need and slowly build up your application.
function placeSensors(nk) {
$.ajax({
type:'post',
dataType:'json',
url:'/myapp/maps/placeSensors/' + nk,
success: function(r) {
if(r.status) {
alert(r.code);
}
}
});
}
class MapsController extends AppController {
var $name = 'Maps';
var $helpers = array('Js');
var $uses = array('Measurings', 'Maps');
function index( $id = null, $value = null ) {
}
// update below code
function placeSensors( ) {
$nk = $_POST['nk'];
echo json_encode(array(
'status' => true,
'code' => "code"
));
exit();
}
Ok, i finally solved this one.
All I needed was to add one form and one text, or even better hidden element on form.
After that everything started to work.
So my mentioned code was ok, all I needed was that one text box......... Hope that somebody can tell me why?
Thank you on all your help and support.

Categories

Resources