views:

156

answers:

5

EDIT 1. The results of a query from my database are displayed on my view page. Next to each unique result is a button:

// first_view.php    
<?php echo form_open('controller/method'); ?>
<?php foreach($results_found as $item): ?>
<p><?php echo $item->name ?></p>
<p><?php form_submit('buy','Buy This'); ?></p>

When a user clicks on one of these buttons (lets say button 4), I would like to display the user's choice from the array onto another view.

I've tried using this:

 // first_view.php
<?php echo $this->session->set_userdata('choice',$item); ?>

immediately before

// first_view.php    
<?php echo form_close(); ?>

thinking that the user's final choice would be stored there so I can display it on another view like this:

// second_controller.php
$c = $this->session->userdata('choice');


// second_view.php
echo 'Your Choose: '. $c;

However, what actually displays is the last result displayed on first_view.php, not what the user choose.

My question is, if the user clicked on button 4, how do I get that particular choice displayed onto another view?

END OF EDIT1

ORIGINAL QUESTION

My view page (CodeIgniter) displays the contents of an array in the form of several links. If a user clicks on a link, I want the user to be taken to another view page (via a controller) that gives more information concerning that particular link (which is stored in that particular position in the array)

My question is, how do I access and display the contents of that particular location within the array on the second view file without getting a "Undefined variable error" on the second view?

Here is what I am trying to do in code form

// my_controller.php
$array_name['variable_name'];
$this->load->view('first_view.php');

// first_view.php
<?php foreach($variable_name as $vn): ?>
<?php echo anchor('controller_name' $vn->info ?> // if user clicks on 3rd link
<?php endforeach ?>                              // I want to beable to access
                                                 // index 2 of the array in the 
                                                 // second view file so I can 
                                                 // display more info 
// second_view.php
<?php $vn[2]->info ?>
+1  A: 

You can use a parameter in the URL to pass information to the 2nd view.

Jon Winstanley
+1. Thanks for the reply Jon. I will research this now
01010011
+1  A: 

Where did the array originally come from? I assume it came from a database or from some other "predictable" data source? In this case you can simply pass the reference to that data (a primary key from the database for example) via the URL when linking to the second page. If you don't have enough information to do this you may need to re-think your design. Having one view access the content of another distinct view would be a bad idea. You can of course create view fragments (just a PHP file you 'include' in your other templates) to minimize code duplication.

I'm not familiar with how CodeIgniter works but this is just general web development logic really.

EDIT

What should happen is that your form submits itself to your controller. Your controller then inspects the POST data and decides what selection the user made from the list. It then redirects to the second controller, passing a parameter in the URL so that the second controller can look up the item from the database.

A rudimentary example, not using your specific use-case, just some semantic pseudo-code. I hope you can follow along here. The example is a fictional multi-language book store where the user selects a language before seeing a list of books in that language. The framework code is purely fictional. I've omitted everything including sanity checking purely for brevity so you can see only the parts that make this workflow happen:

Language selection controller

class LanguagesController ... {
  public function selectLanguage() {
    // If the user submitted the form, collect the language_id
    // and redirect to the BooksController
    if ($this->_request->get('language_id')) {
      return $this->_response->redirect(array(
        'controller' => 'BooksController',
        'action' => 'viewBooks',
        'language_id' => $this->_request->get('language_id')
      ));
    }

    $languages = Language::findAllWithBooksInStock();
    $this->_view->set('languages', $languages);
  }
}

Language selection form

<form method="post">
  <fieldset>
     <label for="language">Select a language</label>
     <select name="language_id" id="language">
       <?php foreach ($languages as $lang): ?>
         <option value="<?php escape($lang->id); ?>"><?php escape($lang->name); ?></option>
       <?php endforeach; ?>
     </select>
  </fieldset>
  <fieldset>
    <input type="submit" name="submit" value="Continue" />
  </fieldset>
</form>

*The BooksController which gets the language_id value*

class BooksController ... {
  public function viewBooks() {
    $language = Language::findById($this->_request->get('language_id'));
    $books = Book::findAllWithLanguage($language);

    $this->_view->set('language', $language)
                ->set('books', $books);
  }
}

Now the BooksController can implement a view that displays all the books in the language selected at the previous controller. All that's been done to achieve this was to pass the primary key for the language in the URL between the two controllers.

PS: Don't use sessions for something like this. That's a bad habit to get into. Be RESTful.

d11wtq
+1. This is the very first time creating a website and all of this is new to me and I'm sure I'll have to rethink all of it when done. I think my original array came from my controller, the line just before I loaded the view: first_view.php
01010011
Ok, assuming you have just hard-coded this data into the controller and haven't taken it from a DB, the first step will be to get that array out of the Controller and into it's own class, which will be a model class. Now your second controller that you link to can load this same model class and get the data from it. Another general principle in MVC design. Keep your model logic out of your controllers ;)It makes much more sense once a DB is in the equation though.
d11wtq
Thanks for your reply d11wtq. I have in fact taken the data out of the database and displayed it onto the view. See edit 1 for more info.
01010011
Answer updated in light of this new information. Excuse the pseudo-code. I'm trying to portray design principles for the benefit of yourself and others, not copy )
d11wtq
Sorry, I misread your code block and thought the session->set was in a template. My bad. Removed the comment about not setting data from within a template. The rest still stands.
d11wtq
A: 

You can always use session or flashdata.

You can store the data when you show the first page. You can then retrieve it in the next view.

Thorpe Obazee
+1 Thanks for your reply. Im new to this but this sounds like the solution. Ok, I already have session auto-loaded. Now, what I'm trying to figure out is (i) how to get the array's index into this session data and (ii) where I write it (in the controller or view). The link the user clicked on represents info on a book stored in an array and this book has a title, author's name etc all at that specific location. How do I store that info in the session data? Do I do something like this: $this->session->set_userdata($newdata); If so, how do I get the detail of that array position in $newdata?
01010011
I have an array that stores a few books and each book has a title, author's name etc and each book will generate a link on the view page. I still can't figure out how to store the book the user selected based on the link they clicked on.
01010011
I'm thinking, when the user clicks on the link, that link should return some info which I could then put into this session data, maybe something like this: $this->session->set_userdata('some_name', 'some_value'); If this makes sense, how do I return info upon the user clicking on the link?
01010011
You should write them in the controller... Your last comment is best.
Thorpe Obazee
@Thorpe, I feel like I came really close with this one
01010011
+1  A: 

It sounds like you need two controllers and two views.

Controller 1 queries the database to get a list of things. Call the controller "list", and the method "index".

http://mysite.com/list/

Controller 2 queries the database to get more information about one particular thing. Call the controller "item", the method "detail", and the third URL parameter will be the name of the item or some other identifier that you can pass into your database.

http://mysite.com/item/detail/436 or
http://mysite.com/item/detail/the-name-of-book-436

That third parameter provides the info that you use to query your database to find more info about the book. Complete this query as part of controller 2, and pass the data to view 2.

Other answers have suggested using session data. I think that's kind of a strange idea, since session data is for user-specific information and details about books are not user-specific.

Summer
+1  A: 

What you do (as I see it) is that you create form, generate row sumbit buttons and then close that form.

If you want to use forms as indication of what user wants to buy, you have to generate form for each row from result, something like this (it's generated html, but you need to edit it to suit your needs):

Edit (pseudocode wasn't enough :) :

<!-- repeat row times -->
<?php foreach($items as $item): ?>
<p><?php echo $item->name; //echo name ?>
  <?php form_open(/*your settings*/); ?>
  <input type="hidden" name="idToAdd" value="<?php echo $item->id;?>" />
  <input type="submit" value="Buy this" />
  </form>
</p>
<?php endforeach; ?>
<!-- end repeat -->

This way, everytime user clicks 'buy-it' button, different form submits and in your controller/view, you can get id of what user wants to buy through $this->input->post('idToAdd').

Adam Kiss
+1 TYVM for your helpful reply. Your suggestion is getting me closer to my goal. I included the form_open() and form_close() tags (CodeIgniter) within the loop. However, 2 things happen: firstly, the text on all of the buttons changes to "1" whereas I want the text on the button to read "Buy It". Secondly, "1" prints in the controler with this statement: $result = $this->input->post('idToAdd'); echo 'Your Choice: '.$result; Intrestingly though, if I replace value="1" with value= $item->id; I get back the primary key of the user's choice, which is what I want, but I don't want id on button name
01010011
Edited code. 15c
Adam Kiss
@Adam, It worked! Thank you Sir! These lines did the trick: <input type="hidden" name="idToAdd" value="<?php echo $item->id;?>" /> <input type="submit" value="Buy this" />
01010011
I knew it will, I just hope you also learned something :]
Adam Kiss