Limit Find Fields/ Options
Archived from the Xataface Users forum.
moj0rising — Thu Jan 25, 2007 3:27 pm
I need to set things up so upon logging in to my Dataface application, users are presented with a limited search page – one that only has 2 fields/ criteria to search by instead of the standard form that allows users to search by any field in a given table (hopefully that makes sense).
The hardest part seems to be finding a way to limit what users can search by – I have checked high and low and looked through the code and can’t figure it out. I also still want to keep the existing find form where it is so it could be used later so I just need to create a new trimmed-down one.
Can anyone give me a push (or shove) in the right direction on how I should go about this?
Steve, thanks a lot for putting out this incredibly awesome tool! It has helped me incredibly.
Mike
shannah — Thu Jan 25, 2007 4:21 pm
Hi Mike,
There are a few ways to attack this problem. Honestly, the easiest way is to exploit Dataface’s url conventions (http://framework.weblite.ca/documentation/link/introduction-to-dataface-urls/view) and just make your own form on a custom action.
If your form puts the proper field names to what the user is searching, then it will automatically put him in the right place. You could add this search box to the left column and make it always available (using a block), or create a custom action and have this search box as the main content for that action.
I know this is conceptual and perhaps requires some examples, but hopefully it gets you on the right track. If you want clarification or examples, let me know, and I’ll see what I can come up with.
If there are things about the Dataface search form that you like, and you’d rather use it trimmed, down, there is a df_create_search_form() function that allows you to programmatically create a search form with only specific fields.. If you want more info about that, I can give examples too - but it sounds like the first option will probably be the easiest.
Best regards,
Steve
moj0rising — Thu Jan 25, 2007 5:45 pm
I read the presentation you linked me to and attempted to follow it but I must be messing something up – it says “no records found.”
I get no records found when I try to follow you examples in the link you sent.
There are a bunch of fields in my database. I need to give users the ability to refine by “jurisdiction” and “status.” So a user who logs in from California can search for all records for California with a status of approved.
I followed the example, Index.php?-action=list&-table=People&FirstName=Bob with -action=list&-table=certifications&Jurisdiction=California
The output is “No records matched your request.”
I also tried the -search parameter with the same results.
It also seems like I might need to pursue your second option. I’m not sure – if the first is the easiest, then that’s the one for me though.
Would you mind throwing in a quick example on what I should do to get a search page with only those two fields upon login?
Sorry I didn’t get that one on the first try. I really appreciate your help.
Mike
shannah — Thu Jan 25, 2007 6:07 pm
The examples that you cite should work. One thing to make sure is that for field and table names, capitals matter. Also, if you are using valuelists for any of the fields, you should be searching on what is actually stored in the database, not the associated label for that value.
E.g. if your Jurisdiction field stores integers and uses a valuelist like:
[jurisdictions]
1=California
2=Washington
3=Oregon
Then your query should include Jurisdiction=1 and not Jurisdiction=California.
Let me know if this is not the case… otherwise if you can give me a link to the app, I can take a closer look.
Best regards
Steve
moj0rising — Thu Jan 25, 2007 6:26 pm
Cool. That part works. I knew I was doing something wrong there.
I used the value name (e.g California) instead of the value on the left of the = (CA).
Now how can I put this together in a way people can use?
shannah — Thu Jan 25, 2007 8:12 pm
All you need to do is add a form somewhere on the page that allows the user to enter the search criteria, .
e.g.
- Code: Select all
- `Jurisdiction
Another field
<:input type=”submit” />`
An easy way to play around with this to see how it works (see if it works), is to put it in the Dataface_Application_Menu.html file in your templates directory. (This will get included in the left column of your application on all pages).
Alternatively you can create a custom action and place this in the content (see the getting started tutorial for info about custom actions).
I suspect that it will be about 2 seconds before you want to be able to use your jurisdictions valuelist to make a pull-down menu. A tip: The Dataface_Table class has a getValuelist() method that will return a valuelist by name as an associative array. e.g.:
$table =& Dataface_Table::loadTable(‘certifications’);
$jurisdiction_options = $table->getValuelist(‘jurisdictions’);
// will return an associative array like array(‘CA’=>’California’, ‘WA’=>’Washington’, etc…).
Then you can take this array and loop through it to form a select list - in either smarty or direct PHP.
However, once your into that, you may just want to use the df_create_search_form() function as follows:
- Code: Select all
$form = df_create_search_form('certifications', array(), array('jurisdiction','another_field')); if ( $form->validate() ){ $form->process(); } echo $form->display();
Best regards
Steve
moj0rising — Thu Jan 25, 2007 8:59 pm
I know I am so close now!
I did mess something up, though.
Now, when I go to my site, I get this message instead, “Fatal error: Class ‘actions_list’ not found in /var/www/dataface/Dataface/Application.php on line 763”
I added the form elements you printed above to Dataface_Application_Menu.html in my application’s templates directory and edited my actions.ini file to say:
[list]
template=Dataface_Application_Menu.html
Trying to work through it. I’m gonna take a break for now.
I would point you to my site but it is on an internal network right now. I’ll try to change that soon so I can at least work on it from any location easier.
Thanks, again,
Mike
shannah — Thu Jan 25, 2007 11:36 pm
OK.. One thing. The ‘list’ action is predefined in Dataface to be the list view. You don’t need to redefine it in your actions.ini (nor should you). I used the Dataface_Application_Menu.html example for a template because it is set to automatically be included in the left column if it exists. You wouldn’t even need to create a new action if you placed the form in that file.
If you create a new action, just call it something else:
e.g.
[my_action]
template=my_action_template.html
Then to access this action, you would just include -action=my_action in the get params of the url.
-Steve
moj0rising — Fri Jan 26, 2007 11:19 am
OK. Now my site comes up when I go to its URL but when I attempt a search, I get:
Fatal error: No template found for action ‘-list’.On line 48 of file /var/www/dataface/actions/default.php in function printStackTrace()
On line 801 of file /var/www/dataface/Dataface/Application.php in function handle(array(array(-list,-list)))
On line 1152 of file /var/www/dataface/Dataface/Application.php in function handleRequest()
On line 19 of file /var/www/torpedo/index.php in function display()
in /var/www/dataface/actions/default.php on line 48
I’m poking around to see what I changed that shouldn’t have been changed.
Mike
moj0rising — Fri Jan 26, 2007 12:11 pm
Progress! The above message stopped appearing when I took the “-“ out from this statement just before list.
was changed to
Now I don’t get any error message but I get “No results found” when I search.
Still checking around.
Mike
moj0rising — Fri Jan 26, 2007 12:12 pm
For some reason my code didn’t show up there. Oh, well.
Mike
moj0rising — Fri Jan 26, 2007 12:20 pm
I think I’m getting no results because it wants the “code” for the jurisdiction and can’t search by the name – the database field type is VARCHAR. I’m trying to do the drop-down menu thing now. Is there any documentation on that I can follow?
Thanks,
Mike
shannah — Fri Jan 26, 2007 12:50 pm
Note that Dataface uses Smarty for its templating and extends upon it. This means that you can use all of Smarty’s built-in tags to make stuff happen in your templates.
For example, you can use {html_options} to produce a select list with an array of options.
http://smarty.php.net/manual/en/language.function.html.options.php
Here’s a simple example. Let’s say you have an action called my_action, and you create an action controller for this class (my_action.php in the actions directory of your app). (See the Actions section of the getting started tutorial for more on action controllers).
- Code: Select all
- `class actions_my_action {
function handle(&$params){
$app =& Dataface_Application::getInstance();
$query =& $app->getQuery();
$table =& Dataface_Table::loadTable($query[‘-table’]);$options = $table->getValuelist(‘jurisdictions’);
df_display(array(‘jurisdictions’=>$options), ‘my_action.html’);
}
}`
See http://dataface.weblite.ca/df_display for information about the df_display function.
The first 3 lines load the application object, the user’s query parameters and the Dataface_Table object for the current table.
The call to getValuelist() returns an associative array of options defined in the jurisdictions valuelist (from your valuelists.ini file.
Then in your my_action.html template (in the templates directory, you could do something like:
- Code: Select all
- `{use_macro file=”Dataface_Main_Template.html”}
{fill_slot name=”main_section”}
Jurisdiction: {html_options options=$jurisdictions name=”Jurisdiction”}{/fill_slot}
{/use_macro}`
See http://framework.weblite.ca/documentation/tutorial/customizing-the-dataface-look-and-feel/extending for information about the {use_macro} and {fill_slot} tags.
shannah — Fri Jan 26, 2007 12:56 pm
Alternatively you could just use the df_create_search_form approach, in which case your action controller would look like this:
- Code: Select all
- `class actions_my_action {
function handle(&$params){
$app =& Dataface_Application::getInstance();
$query =& $app->getQuery();
$form =& df_create_search_form($query[‘-table’], $query, array(‘Jurisdictions’, ‘another_field’));
if ( $form->validate() ){
$form->process();
}
ob_start();
$form->display();
$form_html = ob_get_contents();
ob_end_clean();
df_display(array(‘form’=>$form_html), ‘my_action.html’);
}
}`
Then your my_action.html would look something like:
- Code: Select all
{use_macro file="Dataface_Main_Template.html"} {fill_slot name="main_section"} {$form} {/fill_slot} {/use_macro}
You may also want to check out the actions/find.php file in the dataface distribution for an example of the full find action controller to see how it works.
Best regards
Steve
moj0rising — Fri Jan 26, 2007 4:23 pm
Sorry for asking so many questions. This part is a little tough for me.
I followed your example and reviewed the Smarty documentation. The only exception I made is that I put the form elements in my Dataface_Application_Menu.html file.
The drop-down menu appears but it does not seem to be getting the menu items from my valuelists.ini file. I checked capitalization and spelling, et cetera and all that looks the same across all files and the database tables.
Any ideas on what I could be doing wrong??
Thank you!
Mike
moj0rising — Fri Jan 26, 2007 12:12 pm
For some reason my code didn’t show up there. Oh, well.
Mike
moj0rising — Fri Jan 26, 2007 12:20 pm
I think I’m getting no results because it wants the “code” for the jurisdiction and can’t search by the name – the database field type is VARCHAR. I’m trying to do the drop-down menu thing now. Is there any documentation on that I can follow?
Thanks,
Mike
shannah — Fri Jan 26, 2007 12:50 pm
Note that Dataface uses Smarty for its templating and extends upon it. This means that you can use all of Smarty’s built-in tags to make stuff happen in your templates.
For example, you can use {html_options} to produce a select list with an array of options.
http://smarty.php.net/manual/en/language.function.html.options.php
Here’s a simple example. Let’s say you have an action called my_action, and you create an action controller for this class (my_action.php in the actions directory of your app). (See the Actions section of the getting started tutorial for more on action controllers).
- Code: Select all
- `class actions_my_action {
function handle(&$params){
$app =& Dataface_Application::getInstance();
$query =& $app->getQuery();
$table =& Dataface_Table::loadTable($query[‘-table’]);$options = $table->getValuelist(‘jurisdictions’);
df_display(array(‘jurisdictions’=>$options), ‘my_action.html’);
}
}`
See http://dataface.weblite.ca/df_display for information about the df_display function.
The first 3 lines load the application object, the user’s query parameters and the Dataface_Table object for the current table.
The call to getValuelist() returns an associative array of options defined in the jurisdictions valuelist (from your valuelists.ini file.
Then in your my_action.html template (in the templates directory, you could do something like:
- Code: Select all
- `{use_macro file=”Dataface_Main_Template.html”}
{fill_slot name=”main_section”}
Jurisdiction: {html_options options=$jurisdictions name=”Jurisdiction”}{/fill_slot}
{/use_macro}`
See http://framework.weblite.ca/documentation/tutorial/customizing-the-dataface-look-and-feel/extending for information about the {use_macro} and {fill_slot} tags.
shannah — Fri Jan 26, 2007 12:56 pm
Alternatively you could just use the df_create_search_form approach, in which case your action controller would look like this:
- Code: Select all
- `class actions_my_action {
function handle(&$params){
$app =& Dataface_Application::getInstance();
$query =& $app->getQuery();
$form =& df_create_search_form($query[‘-table’], $query, array(‘Jurisdictions’, ‘another_field’));
if ( $form->validate() ){
$form->process();
}
ob_start();
$form->display();
$form_html = ob_get_contents();
ob_end_clean();
df_display(array(‘form’=>$form_html), ‘my_action.html’);
}
}`
Then your my_action.html would look something like:
- Code: Select all
{use_macro file="Dataface_Main_Template.html"} {fill_slot name="main_section"} {$form} {/fill_slot} {/use_macro}
You may also want to check out the actions/find.php file in the dataface distribution for an example of the full find action controller to see how it works.
Best regards
Steve
moj0rising — Fri Jan 26, 2007 4:23 pm
Sorry for asking so many questions. This part is a little tough for me.
I followed your example and reviewed the Smarty documentation. The only exception I made is that I put the form elements in my Dataface_Application_Menu.html file.
The drop-down menu appears but it does not seem to be getting the menu items from my valuelists.ini file. I checked capitalization and spelling, et cetera and all that looks the same across all files and the database tables.
Any ideas on what I could be doing wrong??
Thank you!
Mike
shannah — Fri Jan 26, 2007 4:41 pm
Hi Mike,
Unfortunately you can’t easily put the valuelist in your Dataface_Application_Menu.html file, because it is only a template. You need to be able to extract the valuelist using PHP. Hence, you will need to either fill in a block (http://framework.weblite.ca/documentation/tutorial/customizing-the-dataface-look-and-feel/customizing) e.g. ‘before_left_column’ using the delegate class, or by creating a custom action as described above.
Best regards
STeve
moj0rising — Mon Jan 29, 2007 5:08 pm
OK. My co-worker over here actually got the drop-down menus working! I’ll explain how he got that together later for everyones reference.
And then I had to mess it all up…
I did a very dumb thing – in trying to get the menus to display just right. I changed the file name he was using Dataface_Application_Menu2.html to left_slot.html and changed the fill_slot name=”left_column” line to fill_slot name=”left_slot” and nothing appeared on the web page at all after that change. When we put everything back the way it was, the site looked as if there was nothing in the left side of the screen – as if there was no Dataface_Application_Menu2.html or Dataface_Application_Menu.html file present at all. The menu is gone!
If we go to http://10.0.3.69/torpedo/index.php/?-action=my_action , we see the menu on the left side like we should but if we click “submit query,” it goes away.
I’m not sure what I could have done to cause this or how to fix it. What should we do?
Mike
moj0rising — Tue Jan 30, 2007 12:21 am
The custom action does not seem to get us anywhere – I get empty drop-down menus. Not really sure why. I *think* I set it up just like your example (a few tries) but there must be something wrong.
It seems the block is a good option for now – we’ll need to have a page dedicated to search later. The only thing is. We’re a little fuzzy on exactly how to work with that part (I have read the block tutorial a few times but still have some questions). In using blocks, exactly which file does the code go into and how? Can you show an example of a block in a file?
Here’s one of several attempts to make use of the block feature:
bmmcom@bmm.com [~/public_html/torpedo/conf]# cat ApplicationDelegate.php
getLoggedInUser();
if ( !isset($user) ) return Dataface_PermissionsTool::NO_ACCESS();
// if the user is null then nobody is logged in… no access.
// This will force a login prompt.
$role = $user->val(‘Role’);
return Dataface_PermissionsTool::getRolePermissions($role);
// Returns all of the permissions for the user’s current role.
}
}
class tables_departments{
function block__before_application_menu(){
$app =& Dataface_Application::getInstance();
$query =& $app->getQuery();
$table =& Dataface_Table::loadTable($query[‘-table’]);
$statusoptions= $table->getValuelist(‘Status’);
$options = $table->getValuelist(‘Jurisdiction’);
df_display(array(‘Jurs’=>$options,’Sta’=>$statusoptions), ‘Dataface_Application_Menu2.html’);
}
}
?>
“
I did actually get the application on the web. The URL is http://70.98.54.35/~bmmcom/torpedo/ . A user ID is nevada with a password of dataface.
Thanks again!
Mike
shannah — Tue Jan 30, 2007 2:58 am
It looks like your code is correct except for the fact that you have the block code inside a class named tables_departments. The above was a readout for the application delegate class, correct?
Your application delegate class file (ApplicationDelegate.php) should contain a single class ‘conf_ApplicationDelegate’. All methods go in there.
e.g.:
class conf_ApplicationDelegate {
function getPermissions(&$record){
…
}
function block__before_application_menu(){
echo “here is some test text - start up the application and
you will see me about the application menu
in the left column.”;
}
}
See a list of all of the blocks available in the main template at http://lamp.weblite.ca/dataface-0.6/docs/index.php?-table=SmartyTemplates&-action=browse&SmartyTemplateID=%3D55
Hope this helps.
-Steve
generatedname — Tue Jan 30, 2007 10:12 am
It looks like your code is correct except for the fact that you have the block code inside a class named tables_departments. The above was a readout for the application delegate class, correct?
Your application delegate class file (ApplicationDelegate.php) should contain a single class ‘conf_ApplicationDelegate’. All methods go in there.
shannah — Tue Jan 30, 2007 11:25 am
The code above works for me. Don’t know what to suggest at this point except if you can give me FTP access I can take a look.
-Steve
generatedname — Tue Jan 30, 2007 12:38 pm
Yea, must have been a bad day for coding, or something. I scrapped the whole delegate class and rewrote it. Now the page loads fine. Must have had too many braces or missing one or some other monday detail. Thanks again for the help, now I’m working on other tweaks for application flow and look&feel. See what I can come up with. Great library you got here btw. Thanks again for your time, and putting this together. I may have more questions on this board later of things don’t go at least 70% good =)
-Kurtis
generatedname — Tue Jan 30, 2007 12:46 pm
OK, already have my first new question for you. I’ve been trying to search through the DF to find the login action. What I need to know is how to control what template gets loaded after login.
What I’m trying to get:
User goes to web page, first screen is the login screen. Then submitting login information will send them to a new template (I’m calling it First_Page_Template.html). And this template has the search action that this whole thread has been about. Once they submit their first search, it takes them to the Dataface_Main_Template.html which is all set up and ready to go.
Right now, I have the default_action set to a new action I wrote that displays First_Page_Template.html. Then after they search two things can happen: They are redirected to the login screen if they are not logged in, or they are sent to the Dataface_Main_Template.html and it will show search results correctly.
So, I’m guessing I need to do away with my new action, and find where the login action directs the user to Dataface_Main_Template.html and change it to First_Page_Template.html.
I could be way off on this, its just a guess since I have not yet found it in the code.
Thanks again. I’ll continue looking, but if you know off the top of your head it could save me some time.
shannah — Tue Jan 30, 2007 12:57 pm
Good to hear the blocks are working.
Sounds like you are getting on the right track. One thing, with terminology, probably better to speak of actions rather than templates when it comes to talking about flow of control in the application. This is because templates can be reused in multiple actions. For example the Dataface_Main_Template.html is used in every single action in Dataface, even your own actions if you use the {use_macro} tag. Better to give your action a name (the action that displays your First_Page_Template.html template) and work from there.
e.g. The user logs in, they are directed to the ‘home’ action (which displays the First_Page_Template.html template) instead of the ‘list’ action as it normally would.
It seems to me that setting your ‘home’ (my working name for your custom action until I know what it is really called) as the default action should be sufficient to do what you want to do. You are able to control the redirect page after login explicitly using the -redirect GET parameter
e.g. yourapp/index.php?-action=login&-redirect=http://www.google.ca
Would redirect the user to google after a successful login.
If you are forming the url using PHP, you need to urlencode the redirect url.
e.g. $url = $app->url(‘-action=login’).’&-redirect=’.urlencode($_SERVER[‘REQUEST_URI’]);
Best regards
Steve
generatedname — Tue Jan 30, 2007 3:33 pm
Ok, I may have found a better way to ask.
For my “home” action, is there a way to check for login status? And say, if they are logged on then show my First_Page_Template.html, otherwise process login.
shannah — Tue Jan 30, 2007 11:25 am
The code above works for me. Don’t know what to suggest at this point except if you can give me FTP access I can take a look.
-Steve
generatedname — Tue Jan 30, 2007 12:38 pm
Yea, must have been a bad day for coding, or something. I scrapped the whole delegate class and rewrote it. Now the page loads fine. Must have had too many braces or missing one or some other monday detail. Thanks again for the help, now I’m working on other tweaks for application flow and look&feel. See what I can come up with. Great library you got here btw. Thanks again for your time, and putting this together. I may have more questions on this board later of things don’t go at least 70% good =)
-Kurtis
generatedname — Tue Jan 30, 2007 12:46 pm
OK, already have my first new question for you. I’ve been trying to search through the DF to find the login action. What I need to know is how to control what template gets loaded after login.
What I’m trying to get:
User goes to web page, first screen is the login screen. Then submitting login information will send them to a new template (I’m calling it First_Page_Template.html). And this template has the search action that this whole thread has been about. Once they submit their first search, it takes them to the Dataface_Main_Template.html which is all set up and ready to go.
Right now, I have the default_action set to a new action I wrote that displays First_Page_Template.html. Then after they search two things can happen: They are redirected to the login screen if they are not logged in, or they are sent to the Dataface_Main_Template.html and it will show search results correctly.
So, I’m guessing I need to do away with my new action, and find where the login action directs the user to Dataface_Main_Template.html and change it to First_Page_Template.html.
I could be way off on this, its just a guess since I have not yet found it in the code.
Thanks again. I’ll continue looking, but if you know off the top of your head it could save me some time.
shannah — Tue Jan 30, 2007 12:57 pm
Good to hear the blocks are working.
Sounds like you are getting on the right track. One thing, with terminology, probably better to speak of actions rather than templates when it comes to talking about flow of control in the application. This is because templates can be reused in multiple actions. For example the Dataface_Main_Template.html is used in every single action in Dataface, even your own actions if you use the {use_macro} tag. Better to give your action a name (the action that displays your First_Page_Template.html template) and work from there.
e.g. The user logs in, they are directed to the ‘home’ action (which displays the First_Page_Template.html template) instead of the ‘list’ action as it normally would.
It seems to me that setting your ‘home’ (my working name for your custom action until I know what it is really called) as the default action should be sufficient to do what you want to do. You are able to control the redirect page after login explicitly using the -redirect GET parameter
e.g. yourapp/index.php?-action=login&-redirect=http://www.google.ca
Would redirect the user to google after a successful login.
If you are forming the url using PHP, you need to urlencode the redirect url.
e.g. $url = $app->url(‘-action=login’).’&-redirect=’.urlencode($_SERVER[‘REQUEST_URI’]);
Best regards
Steve
generatedname — Tue Jan 30, 2007 3:33 pm
Ok, I may have found a better way to ask.
For my “home” action, is there a way to check for login status? And say, if they are logged on then show my First_Page_Template.html, otherwise process login.
shannah — Tue Jan 30, 2007 3:57 pm
First: Yes you can check the login status at any time by checking if the logged in user is null.
e.g.
- Code: Select all
$auth =& Dataface_AuthenticationTool::getInstance(); $user =& $auth->getLoggedInUser(); if ( !$user ) echo "User is not logged in"; else echo "User is logged in";
Second: It sounds like what you are trying to do is just assign permissions so that the user has to log in before he does anything. Is this correct?
If so, just set your permissions so that the user has to be logged in to receive access.
e.g.
- Code: Select all
- `class conf_ApplicationDelegate {
function getPermissions(&$record){
$auth =& Dataface_AuthenticationTool::getInstance();
$user =& $auth->getLoggedInUser();
if ( !$user ) return Dataface_PermissionsTool::NO_ACCESS();
else {
return Dataface_PermissionsTool::ALL(); // or whatever you think the permissions should be
// could also be things like Dataface_PermissionsTool::READ_ONLY();
}}
…`
If the permissions fail and the user is not logged in, then he will kicked to the login page. If he is logged in and permissions fail, then he will see a permission denied message.
-Steve
generatedname — Tue Jan 30, 2007 5:31 pm
I’ll tell you what man, you are amazing…..
function handle(&$params) {
$auth =& Dataface_AuthenticationTool::getInstance();
$user =& $auth->getLoggedInUser();
if ( !$user ) df_display(array(),’Dataface_Login_Prompt.html’);
else df_display(array(), ‘Dataface_First_Page_Template.html’);
}
I changed my home action to read that code exactly and BAM. works perfect. Thanks again Steve!
-Kurtis