I wanted to display a resultset using the same view template. To be more specific, we can take an online store example:
A navbar will consist of several main links which are categories. A list of subcategory links will show up if you hover over a category link. When a user clicks on a subcategory, all products associated with that category+subcategory will be displayed in the main html body. When a user clicks on a category, all subcategories associated with that category will be displayed in the main html body. A user can then click on a subcategory and then it will refer to the scenario above (rendering its respective products). For a category, this is an example anchor link: {{=A(category.name, _href=URL('category_nav_callback', args=1))}} and the resulting URL should be 'default/search_results/category/1' For a subcategory, this is an example anchor link: {{=A(subcategory.name, _href=URL('subcategory_nav_callback', args=[1,1]))}} and the resulting URL should be 'default/search_results/category/1/subcategory/1' >From there, their respective callback functions in the controller would manipulate the database to get an eventual result set. To display these results, I wanted to use a generic template view (search_results.html) and pass a resultset to it and it would render it on that page. In the future, I may want to add in new links (like genre or favorites), and then I can reuse the search_results template to display the results. Maybe I overcomplicated this too much? I could just create individual search pages like this: {{=A(category.name, _href=URL('searchCategory', args=1))}} {{=A(category.name, _href=URL('searchSubcategory', args=[1,1]))}} and then in controllers: def searchCategory(): # do stuff return dict(resultSet=resultSet) def searchSubcategory(): # do stuff return dict(resultSet=resultSet) And I could create their views in both searchCategory.html and searchSubcategory.html: {{for i in resultSet:}} # do stuff {{pass}} But it seems like a lot of repetitive work, although it is probably the easier approach? On Friday, May 24, 2013 12:33:33 PM UTC-4, Anthony wrote: > > It might be helpful if you explain what you're really trying to do. Do you > want users to be able to click different links that all point to the > /search_results page, but with different types of searches done depending > on the link? In that case, why not something like: > > {{=A('click for more information', _href=URL("search_results", args=[ > 'myCallback', 1]))}} > > def search_results(): > if request.args(0) == 'myCallback': > resultSet = myCallback(request.args(1)) > ... > return dict(resultSet=resultSet) > > def myCallback(someId): > return db(...) > > Of course, in this simple example there's no need for the separate > myCallback function, but I assume you want to have multiple such functions > with more complexity. The idea is to send all the requests to the > search_results function, and use the request.args to identify the type of > results, and potentially dispatch to external functions to generate those > results. > > Anthony > > On Friday, May 24, 2013 11:42:46 AM UTC-4, brac...@gmail.com wrote: >> >> Thanks, however I just noticed in the original code that I had >> incorrectly written the callback function as "myButton()". It should have >> been "myCallback()". I modified the code: >> >> def search_results(): >> div = DIV(.....) >> response.view = 'default/search_results.html' >> return dict(div=div) >> >> def myCallback(): >> someId = request.args(0) >> resultSet = db(....) >> >> return search_results(resultSet) >> >> Sorry about the confusion. This way works, but after clicking the button, >> it displays the resultSet on a page with the URL "default/myCallback/1". I >> wanted it to be something like "default/search_results/1". >> >> But web2py follows this pattern to URLs: >> /[application]/[controller]/f >> >> So 'f' would be the "myCallback" since it's the function that was called >> when you clicked on the button. I thought a redirect would fix it since I >> would be directing the controller function to search_results, and then the >> URL would be correct. What I couldn't figure out was how to pass data from >> the callback function to the redirected function. >> >> Is there a way to fix this using what you suggested or is there a better >> way to do this (given the fixed code)? >> >> On Thursday, May 23, 2013 6:22:52 PM UTC-4, Anthony wrote: >>> >>> But presumably the myButton() function does not have its own view given >>> that it was originally written to always redirect to another URL. In that >>> case, why not just make the myButton.html view render the search results as >>> desired? If you want a search_results.html view to be used from multiple >>> functions, that's no problem either -- here are three options: >>> >>> def search_results(resultSet): >>> div = DIV(.....) >>> response.view = 'default/search_results.html' >>> return dict(div=div) >>> >>> So, any time the search_results() function is called by another >>> function, it sets the view to search_results.html. Or, you can set the view >>> within the calling function: >>> >>> def myButton(): >>> someId = request.args(0) >>> resultSet = db(....) >>> response.view = 'default/search_results.html' >>> return search_results(resultSet) >>> >>> Or you could include the search_results view in another view. For >>> example, in myButton.html, you can do: >>> >>> {{extend 'layout.html'}} >>> {{include 'default/search_results.html'}} >>> >>> Anthony >>> >>> >>> On Thursday, May 23, 2013 4:02:29 PM UTC-4, brac...@gmail.com wrote: >>>> >>>> search_results() will have to be exposed since I want to display the >>>> results on a different page (in search_results.html). I think returning >>>> the >>>> div using your suggestion would still be on the same page? >>>> >>>> >>>> >>>> On Thursday, May 23, 2013 3:38:17 PM UTC-4, Anthony wrote: >>>>> >>>>> Why do you need to redirect at all? You can just call the >>>>> search_results() function directly from the myButton() function: >>>>> >>>>> def search_results(resultSet): >>>>> div = DIV(.....) >>>>> return dict(div=div) >>>>> >>>>> def myButton(): >>>>> someId = request.args(0) >>>>> resultSet = db(....) >>>>> return search_results(resultSet) >>>>> >>>>> If the search_results() function is needed in other controllers, you >>>>> could define it in a model file or in a module and import it. Note, >>>>> functions that take arguments (as search_results does above) are not >>>>> exposed as actions accessible via URL -- they are for internal use only >>>>> (same for a function that begins with a double underscore, even if it >>>>> doesn't take any arguments). >>>>> >>>>> Anthony >>>>> >>>>> On Thursday, May 23, 2013 2:51:24 PM UTC-4, brac...@gmail.com wrote: >>>>>> >>>>>> In my views, I have: >>>>>> >>>>>> {{=A('click for more information', _href=URL("myCallback", args=[1 >>>>>> ]))}} >>>>>> >>>>>> >>>>>> When the anchor button is clicked, my callback will do some lookup >>>>>> and processing in the db, and then will redirect to a new page populated >>>>>> with the new information: >>>>>> >>>>>> def search_results(): >>>>>> resultSet = request.args(0) >>>>>> # Build HTML helpers using resultSet >>>>>> div = DIV(.....) >>>>>> >>>>>> return dict(div=div) >>>>>> >>>>>> def myButton(): >>>>>> # Figure out the id from the request >>>>>> someId = request.args(0) >>>>>> >>>>>> # get some data from db using the id >>>>>> resultSet = db(....) >>>>>> >>>>>> >>>>>> # want to redirect to another page with the new data in the >>>>>> resultSet >>>>>> redirect(URL('search_results', args=resultSet)) >>>>>> >>>>>> But doing the redirect with the resultSet args will screw up the URL >>>>>> and I'll end up with an invalid request. >>>>>> >>>>>> I've thought of two ways around this: >>>>>> >>>>>> 1) Create a temporary session variable and store the resultSet there. >>>>>> Once I'm done with the data, I'll explicitly clear it. >>>>>> >>>>>> 2) Instead of doing the database logic in the callback, pass the id >>>>>> to the search_results() and do the database logic there. >>>>>> >>>>>> I'm hesitant to adopt the first option because it seems messy to >>>>>> create a bunch of session variables for temporary things (unless this is >>>>>> standard practice?). >>>>>> >>>>>> The second option seems okay, but I'm afraid that the code will >>>>>> become too specific to that particular anchor tag. That is, if I create >>>>>> a >>>>>> new anchor tag to do some other search, the database logic may be >>>>>> different >>>>>> than the one inside the search_results(). For this, I guess the better >>>>>> question should be if the database logic code should live in the >>>>>> callback >>>>>> function or in the target redirect controller function? >>>>>> >>>>>> >>>>>> In spite of this, what would be the clean or proper way of sending >>>>>> data with a redirect from a callback function? >>>>>> >>>>> -- --- You received this message because you are subscribed to the Google Groups "web2py-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.