Best solutions for merging two controllers/views in CakePhp - cakephp

I have two models:
Book
Category
I have two views:
books/browse
In this view there is paginated list of books, with sort options, book language select, author/title filters and so on. One thing there isn't - book category tree. In fact this controller takes as a parameter category_id and displays only books from this category.
categories/tree
This view (controller) finds the category tree and it takes one parameter -> category_id -> to determine how to print the tree (to show all parent nodes, and parents list and so on).
Now I need a view (for example browsetree) where there is category tree on the left and a list of books (with all stuff) on the right.
What will be best solution to accomplish this? (The problem is also I want to be able to save the link to book browse view with all it's params (category_id param + sorting + few GET params for filtering) and I also don't want to rewrite any view or controller method...
-------------- edit
Okay I have my tree in element
categorytree
and it looks like this:
$params = $this->requestAction('/categories/tree/'.$category_id);
print_category($params['tree'][0],$params['parents'],$category_id);
The $category_id is passed to the element as parameter.
This is inside /books/browse:
<?php echo $this->element('categorytree', array("category_id" => $category_id)); ?>
What I need is that in categorytree element I want that each tree node was a valid link to /books/browse based on current url that books/browse is loaded from.
I mean that the url might be:
books/browse/34/sort:asc/page:4?author=Author&something=something
I could get this link
inside /books/browse/...
view and pass it to the element and then parse it to replace /34/ (it's category id) with other categories... But is there any easier / more elegant way of doing this?

Put your category tree in an element and use CakePHP's requestAction to get it's data from the Category controller.
You can keep your tree view in the Books area (which makes sense, since that's what the user is browsing) - up to you which view you put it in.
Bottom line, the user is searching books, so that's where the view and the code should be. Use the Category tree to just pass a variable for which category you want to use in your query against the books.

Related

How to load data from another table/model

Having just started with Cake, I'm now very frustrated having already spent several hours reading examples etc What I want to do seems so simple, but I can't make enough sense of the documentation to find out how to do this. It's very simple:
I have 2 tables:
items
categories (eg books, cd)
New items will be created constantly, each has a category.
All I want to do is create a dropdown filter in the items list view. But to do this I need to load the list of categories.
So the basic problem is, how do I access the categories table from the items table?
Finally a solution.
In the items controller:
$this->loadModel('Categories');
$categories = $this->Categories->find()->all();
Or to remove all the cake crud from the returned object:
$categories = $this->Categories->find("list", array("fields"=>array("Categories.title")))->all();

cakephp including two views on the home page

I'm a cakephp and MCV newbie, so bear with me. I've been reading until my head exploded, but I'm not getting the big picture yet.
I have a TransactionsTable, TransactionsController with add() method, and an "add" view that outputs an "Add Transaction" form.
I have an AccountsTable, AccountsController with index() method, and an "index" view that outputs a list of Accounts.
What's the best way to include this form AND this list on the home page?
If you just want to add the list into your add view then your really don't need two views. Here's a simple way of doing what you want though: In your add() method you can get the list of accounts by loading the Accounts table, then just pass that to your view.
In add() :
$this->loadModel('Account');
$articles = $this->Account->find(//Add whatever you use to produce the list here);
$this->set('articles', $articles);
Then just display the list as you did in your accounts/index page. You're essentially combining two views into one.

How to correlate view order (using orderBy) with model order

I have an obviously simple but yet challenging problem in my AngularJS app:
When using orderBy on the view I loose the correlation between the order of the related model and the view order.
What I want to do: My view is a table. I want to set a highlight class for the selected row and I want to use cursor up/down keys to move this highlight.
I tried to decouple $index from the tracking by using track by currentDocument.objectid, but that doesn't seem to work.
How can I correlate the currently highlighted row in the view with the currently highlighted element of the related model in a way that I can use -1 or +1 with the cursor keys?
As the order of the data is important to your business process, it makes sense to make the order part of your actual model. If you read the last example of orderby on the angular api (https://docs.angularjs.org/api/ng/filter/orderBy), you will notice they achieve this very thing. Basically, instead of binding orderby directly to some model value, create your own order function and manually order your model.
I have created a plunker here: http://plnkr.co/edit/oM97ZTAIHTjI6YFiGDwI?p=preview Just click on the persons name to see the example (and reorder the list and try again).
Basically you create a manual sort function like this:
$scope.order = function(predicate, reverse) {
$scope.friends = orderBy($scope.friends, predicate, reverse);
};
Which actually reorders the model itself, rather than just the view array. You can call it however you like. Then you can simply pass $index from the view, and it will correlate correctly to the view order.

Get content Id (nid) from path on views block

I just can't seem to wrap my head around Drupal relationships. I have been reading and watching tutorials, but as soon as I try to get my own project done - I fail. I think it's very basic, so I would love to understand it. Maybe someone here can help me understand how it works :)
On my drupal site, I want to keep track of some private game tournaments.
I have created a content type called contestant, which has fields like: Tournament date, Player name, Final Position. I can then create a view that list the information from one tournament. I used the help I got from this thread: drupal views dynamic filter
I would like to have the view described above as a block. And then place that block-view on a "tournament description" page. I could do this, by simply creating a new block each time, and then manually place it on the page it should be shown (structure-->Blocks-->configure), but that is not an elegant way to do it. I am pretty sure this is where Relationships should be used. But I fail to understand how to create this relationship, so that the specific block view, that matches the specific tournament description page will be displayed together.
Use a Content:Nid as a Contextual filter.
WHEN the Filter value is not in the URL >>
Provide default value
Content ID from URL

Dataview List and items

I am looking at a different way of doing my application.
Actually It's kind of static. My Projects have Categories. Each Category has Subcategories. Categories are containers and Subcategories are element which have values that can be edited.
After analysis of the data , we saw that it was not enough general for it. We are now looking at a Tree Structure. Doing so, we would have Projects filled with Folders/Categories) and those Folders would be filled with other Category/Folders or with SubCategories/Items/Files. That way we can go has deep has we want in complexity.
That is doable, I know it. What I need to know is how hard it will be to implement it in the app.views...
Is it possible to have a single Ext.DataView.dataview display different Ext.DataView.component.DataItem side by side.
Exemple : Having a row in my List that shows a slider and update itself according to it, but that on the 2nd row it is an arrow that on click would open the next level of my Tree.
Visual:
DataView_List
Small Car---------------------------Label------------------------SLIDER
Fuel----------------------------------Label------------------------------ >
SUV----------------------------------Label------------------------TxtField
Small Car and SUV are leaves with different template and Fuel is a category/folder that need to open on click.
So I already have 3 differents templates that would need to show in the same dataview list.
How should I proceed to achieve such results? Is Dataview List the way to good or should I implement my own kind of list inside a container?
If you want to present different kinds of data inside one list or dataview - you can achieve by following strategy:
You still need to use one store to keep it all
In the model class include something like 'record_type' field indicating what kind of data you have
Combine all data you need into one model
Create a template that based on the 'record_type' would render different content
Here is how your template would look like:
<tpl switch="record_type">
<tpl case="car">
<div>CAR + SLIDER</div>
<tpl case="fuel">
<div>FUEL + LABEL</div>
<tpl default">
</tpl>
This is screenshot from my list which contains multiple record types and uses this approach:

Resources