So why not use a single function (e.g., search_results), and just pass all 
the other information as URL args? In the search_results function, you can 
read the request.args and deliver the appropriate results accordingly.

Anthony

On Friday, May 24, 2013 1:47:24 PM UTC-4, brac...@gmail.com wrote:
>
> 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.


Reply via email to