Welcome Guest, Not a member yet? Register   Sign In
Opening a new page w/ dynamic data
#1

(This post was last modified: 03-03-2017, 11:34 AM by codeguy.)

I'm trying to learn CI by converting an existing php app. In response to a click event I need to open a new page and pass an id to the controller. This allows the controller to populate the page with data, appropriate to the particular element of that class that was clicked. In the original version I just passed the ID to the controller along with the url (in the 'get' array)  Here's the js/jq code in my new CI code version that registers the event and provides the initial response:

    $('.tsEditButt').click(function() {
        var tuneID=$(this).closest('.tune').attr('id');
        window.open('c_tunesheet','_blank');
        $.post('c_tunesheet',{tuneID:tuneID},function(response) {
            alert('Response: '+response);  // For testing the strategy
        });
    });

The c_tunesheet controller to test this strategy:

    class C_tunesheet extends CI_Controller {
        function  __construct()   {
            parent::__construct();
            $this->load->helper('url');
        }
    public function index() {  // index function loads new tunesheet editor page / with this tune's data
        $pageTitle='MZ TS Editor';
        $tuneID=$this->input->post('tuneID');

        echo('<div>C_tunesheet, tuneID:'.$tuneID.' PageTitle:'.$pageTitle.'</div>');
    }
}

The problem:

Firebug (and the alert message correctly appearing in the first page) shows the expected string returned to the js/jq calling function as:


Code:
<div>C_tunesheet, tuneID:1632 PageTitle:MZ TS Editor</div>

But, the html that appears on the new page is:

    C_tunesheet, tuneID: PageTitle:MZ TS Editor

i.e. the $tuneID value is not getting passed to the controller. I suspect I'm missing something very fundamental here re: what happens within the CI app when a new page is opened. Hopefully someone can point me in the right direction. Thanks in advance.
Reply
#2

After examining this further I just realized that 'tuneID' is being passed to the controller in the post array and was successfully received. Otherwise it would not appear in the echoed response from the controller back to the jq $.post(), as it does.

But that still leaves the question: If tuneID is getting set in the post array and is converted to variable $tuneID and then gets echoed back to the .post() , why does it not appear on the 'c_tunesheet' page as well - as a result of the echo statement?

Everything in the echo stmt except the value of $tuneID appears on the new page as expected. i.e.

  C_tunesheet: tuneID: PageTitle:MZ TS Editor
Reply
#3

Your Javascript has this line of code before the AJAX call:
PHP Code:
window.open('c_tunesheet','_blank'); 
You are not passing any variables (POST or GET) to that url, so the TuneID will be NULL.
The page title will always show up, because you hardcoded it.
Reply
#4

(03-03-2017, 03:14 PM)Wouter60 Wrote: Your Javascript has this line of code before the AJAX call:
PHP Code:
window.open('c_tunesheet','_blank'); 
You are not passing any variables (POST or GET) to that url, so the TuneID will be NULL.
The page title will always show up, because you hardcoded it.

Thanks for your reply. This is the full js/jq function where I assume the problem lies:

   $('.tsEditButt').click(function() { //alert('tsEditButt clicked!');
        var tuneID=$(this).closest('.tune').attr('id');
        window.open('c_tunesheet','_blank');  
        $.post('c_tunesheet',{tuneID:tuneID},function(response) {
            alert('Response: '+response);  // For testing
        });
    });

Can you suggest what I need to do to make this code work? i.e. how do I open the new page and pass the ID variable to it?
Reply
#5

(03-03-2017, 05:04 PM)codeguy Wrote:
(03-03-2017, 03:14 PM)Wouter60 Wrote: Your Javascript has this line of code before the AJAX call:
PHP Code:
window.open('c_tunesheet','_blank'); 
You are not passing any variables (POST or GET) to that url, so the TuneID will be NULL.
The page title will always show up, because you hardcoded it.

Thanks for your reply. This is the full  js/jq function where I assume the problem lies:

   $('.tsEditButt').click(function() { //alert('tsEditButt clicked!');
        var tuneID=$(this).closest('.tune').attr('id');
        window.open('c_tunesheet','_blank');  
        $.post('c_tunesheet',{tuneID:tuneID},function(response) {
            alert('Response: '+response);  // For testing
        });
    });

Can you suggest what I need to do to make this code work? i.e. how do I open the new page and pass the ID variable to it?
It does not work. Window.open open a new window for you with the data from controller c_tunesheet. You do not send any post data to the controller. With the $.post you send an ajax request and get back the value you wanted, but the other window does know about it Smile.

Question:
- Do you need "POST" or can it be "GET"?
- Do you need a new page?
- what do you want?
Reply
#6

(This post was last modified: 03-04-2017, 10:46 AM by codeguy. Edit Reason: Clarity )

(03-03-2017, 11:49 PM)Paradinight Wrote:
(03-03-2017, 05:04 PM)codeguy Wrote:
(03-03-2017, 03:14 PM)Wouter60 Wrote: Your Javascript has this line of code before the AJAX call:
PHP Code:
window.open('c_tunesheet','_blank'); 
You are not passing any variables (POST or GET) to that url, so the TuneID will be NULL.
The page title will always show up, because you hardcoded it.

Thanks for your reply. This is the full  js/jq function where I assume the problem lies:

   $('.tsEditButt').click(function() { //alert('tsEditButt clicked!');
        var tuneID=$(this).closest('.tune').attr('id');
        window.open('c_tunesheet','_blank');  
        $.post('c_tunesheet',{tuneID:tuneID},function(response) {
            alert('Response: '+response);  // For testing
        });
    });

Can you suggest what I need to do to make this code work? i.e. how do I open the new page and pass the ID variable to it?
It does not work. Window.open open a new window for you  with the data from controller c_tunesheet. You do not send any post data to the controller. With the $.post you send an ajax request and get back the value you wanted, but the other window does know about it Smile.

Question:
- Do you need "POST" or can it be "GET"?
I'd like to use "GET" but searching online I find that CI strips query strings from URIs and even if I enable query strings in the CI config file some browsers may not handle it properly. But I used a query string in my original non-CI version to do this and it worked fine.

- Do you need a new page?
Yes, although I could possibly do this in a popup frame. (Which I suppose would still be a new page - in a frame rather than a window - although I do not clearly understand the difference. I have a general sense of it but it may be wrong.)

- what do you want?
When the user clicks on an element in the primary page I simply want to open a new page in a second browser tab where the user can edit a text file that appears in a "textarea" box. While editing occurs I want the primary page not to close but remain available to the user either by clicking its browser tab or by closing the second tab when editing is completed. With both pages available in their tabs the user may wish to do some copy/paste-ing between the two.

I've spent several days on this now and I'm leery of some of the hacks that some developers have posted online. I'm looking for a "best practices" strategy. 

Thanks for your patience. I wish I knew how to ask the question more clearly. But if I did I probably would not need to ask it. Wink

PS: What you have told me is helpful and accurate. I agree with what you say is the reason my code does not work. I just can't figure out the right way to do this.
Reply
#7

You can do this to open the new page with the right parameters:
Code:
window.open('<?= base_url();?>c_tunesheet/index?tuneid='+tuneID,'_blank');  

There's no need to set $config['enable_query_strings'] to TRUE. If you do, CI expects URL's like:
Code:
www.example.com/index.php?c=controllername&m=methodname[&extraparam=....]
That's not recommended however. The default uri's are segment-based.
Reply
#8

(03-04-2017, 02:38 PM)Wouter60 Wrote: You can do this to open the new page with the right parameters:
Code:
window.open('<?= base_url();?>c_tunesheet/index?tuneid='+tuneID,'_blank');  

There's no need to set $config['enable_query_strings'] to TRUE. If you do, CI expects URL's like:
Code:
www.example.com/index.php?c=controllername&m=methodname[&extraparam=....]
That's not recommended however. The default uri's are segment-based.

Use site_url()

if it only one param e.g. tuneID
Code:
window.open('<?= site_url('c_tunesheet/edit/');?>' + tuneID ,'_blank');  
Reply
#9

Much thanks to both of you for the advice. I've spent time exploring your suggestions. Here's what I found:

With my uri_protocol set to either 'QUERY_STRINGS'; or 'REQUEST_URI'; in config.php and . . .
using this window.open statement, 'window.open("<?= site_url('c_tunesheet/');?>"+tuneID,'_blank');'
on the new page that appeared  I got:


Access forbidden!
You don't have permission to access the requested object. It is either read-protected or not readable by the server.
If you think this is a server error, please contact the [email=postmaster@localhost]webmaster[/email].
Error 403
localhost
Apache/2.4.7 (Win32) OpenSSL/1.0.1e PHP/5.5.9

I get a similar result using base_url() instead of 'site_url()' method.

However I was able to pass data using the not-recommended method:

window.open('c_tunesheet?tuneID='+tuneID,'_blank');

Note that I first tried: window.open('localhost/CID17/c_tunesheet?tuneID='+tuneID,'_blank');

In that case I got the good old "404 Page Not Found
But using just: window.open('c_tunesheet?tuneID='+tuneID,'_blank');
It works with either uri-protocol above.

I extracted the data and displayed it using:

    $tuneID=$this->input->get('tuneID');
    echo "<div>c_tunesheet controller says: Tune ID: $tuneID";

. . .  in the controller.

I spent some trying to understand how I could modify my .htaccess or my php.ini file to allow access to wherever I was being denied but gave up after hitting the first few layers of confusion. Smile 

Thanks to your hints, I now have a strategy that opens the new page and passes the tuneID. This is not data that could cause any security problems on a production site but I'm still hoping to find a better solution eventually.

Another good thing is I can stick with $config['uri_protocol']    = 'REQUEST_URI'; since that's the default and I won't have to change anything elsewhere.
Reply
#10

It's all because CI expects URL's to have at least 2 segments: controller and method. If the second segment is omitted, the controller will execute the index method by default.
Code:
c_tunesheet/edit   //means: open then c_tunesheet controller and find the edit method inside it
c_tunesheet/edit/44  //means: find the edit method (like the first example) and pass the value 44 to the first parameter
c_tunesheet  //means: open the c_tunesheet controller and find the index method

The command
Code:
window.open("<?= site_url('c_tunesheet/');?>"+tuneID,'_blank');
will assume that tuneID is the name of the method!

This should work:
Code:
window.open("<?= site_url('c_tunesheet/index');?>"+tuneID,'_blank');

But then, your index method should look like this:
PHP Code:
public function index($tuneID NULL) {
 
 //your code here

to pass the parameter!
= NULL means that the variable $tuneID will be set to NULL if no parameter is passed.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB