3

Is it possible to return javascript function via Ajax from php? Normally I would just return a value then decide what to do with it in plain javascript, but now because I am handling Apache Cordova mobile app I want to do things differently.

account = localStorage.getItem("account");
account = JSON.parse(account);

$.ajax({
 type: "POST",
 url: example.php,
 data: { account = account.rule }
});

.php

$isAdmin = $conn->prepare("SELECT role FROM users WHERE username = :username");
$isAdmin->bindParam(":username", $username);
$isAdmin->execute();
$result = $isAdmin->fetch(PDO::FETCH_ASSOC);
if($result){
 $result = "<script>
 $("header nav").append(
  $("<a />").attr("href", "admin.html").text("Admin panel")
 )
</script>";
}
return $result;

And then run it. Ill do another check when user redirects to the site.

trincot
  • 317,000
  • 35
  • 244
  • 286
Jaakko Uusitalo
  • 655
  • 1
  • 8
  • 21
  • 2
    Possible duplicate of [Executing – Patrick Q Oct 23 '17 at 17:30
  • https://stackoverflow.com/questions/40875630/javascript-save-object-with-methods-as-a-string/40876342#40876342 – bassxzero Oct 23 '17 at 17:41

2 Answers2

3

Instead, consider a structured response

While what you are asking to do is possible, there are much better ways to handle this. Consider instead returning an array containing the data needed to build the links with client-side scripting. Build the Ajax to call add those links accordingly. You could expand this further to include more configurable objects, or building the html to be appended and returning that, rather than trying to run javascript eval.

function updateNav(links) {
    links.forEach(function(link){
        $li = $('<li></li>');
        $a = $('<a></a>');
        $a.prop('href',link['uri']);
        $a.html(link['text']);
        $li.append($a);

        $('#nav').append($li);
    });
}

var dummyData = {
    navLinks: [
        {
            uri: 'http://stackoverflow.com',
            text: 'StackOverflow'
        },
        {
            uri: 'http://google.com',
            text: 'Google'
        }
    ]
};

var dummyHtml = {
    navHtml: '<ol><li><a href="http://meta.stackoverflow.com">Meta StackOverflow</a></li></ol>'
};

function ajaxSimData() {
    var someAjaxObject = {};
        someAjaxObject.success = function(data) {
        updateNav(data['navLinks']);
    };

    someAjaxObject.success(dummyData);
}

function ajaxSimHtml() {
    var someAjaxObject = {};
    someAjaxObject.success = function(data) {
        $('#nav').after(data['navHtml']);
    };

    someAjaxObject.success(dummyHtml);
}

$('.ajaxTriggerData').click(ajaxSimData);
$('.ajaxTriggerHtml').click(ajaxSimHtml);
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.js"></script>

<div id="message">
    Simple Examples:<br>
    <button class="ajaxTriggerData">Populate Nav from Data</button><br>
    <button class="ajaxTriggerHtml">Load HTML string after Nav</button><br>
</div>
<div id="body">
    <h3>Some navigation elements: </h3>
    <ul id="nav">
        <li><a href="#">Nav1</a></li>
        <li><a href="#">Nav2</a></li>
        <li><a href="#">Nav3</a></li>
    </ul>
</div>

PHP side to generate the response

$isAdmin = $conn->prepare("SELECT role FROM users WHERE username = :username");
$isAdmin->bindParam(":username", $username);
$isAdmin->execute();

$navLinks = [];
if($isAdmin->fetch(PDO::FETCH_ASSOC)) {
    $navLinks = [
        ['uri' => 'admin.html', 'text' => 'Admin panel'],
    ];
}

return json_encode([
    'navLinks' => $navLinks
]);
Tony Chiboucas
  • 5,505
  • 1
  • 29
  • 37
2

Yes you can - response texts are just strings - but it might not be considered a good practice, especially if you make a pattern of it. Looking at your code, it looks like what you want to do is append a link to the nav that goes to the Admin panel of your app if the user is an admin. It might be better to take the following code client-side and wrap it in a client-side function:

function appendAdminLink() {
  $("header nav").append(
    $("<a />").attr("href", "admin.html").text("Admin panel")
  )
}

...and instead of returning that function, in PHP just return something like:

{ isAdmin: true }

Then client-side you can validate if the user is an admin, and if they are you can call appendAdminLink.

Benny Schmidt
  • 3,230
  • 1
  • 19
  • 14