Yeah, I'll try your suggestion and see what happens:
{{=A('click for more information', _href=URL("search_results", args=[
'myCallback', 1]))}}
On Friday, May 24, 2013 1:51:59 PM UTC-4, Anthony wrote:
>
> 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, [email protected] 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, [email protected] 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, [email protected] 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, [email protected] 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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.