My question is:
How can I make my search/filter/ordering fields can be shown in the link after the search button is clicked. I have my model-controller-view-layout files. In model file requred fields are set as state variable in populateState function and are retrieved by the buildWhereQuery function to make it useable in querystring. Everything is going correct up to this point. But from now my problem arrises as what if a user want to send the listing link to his/her frind to show same listing. I need to set the link for this porpose but I don't know how to do this.
I just wrote a function for this in view file as following but I couldn^t figure out how can I use this created link to work. (the variable query is $query = $this->get('state'); in the format of JObject.
protected function preQuery($query){
$params = array();
foreach ($query as $key => $value) {
if(!isset($query->$key) || empty($value) || $value == ''){
unset($query->$key);
}else{
if(strpos($key,'filter') || in_array($key, array('limit','limitstart','order','order_Dir'))){
$params[$key] = $value;
}else{
unset($query->$key);
}
}
}
$que = JURI::buildQuery($params);
$cur = JURI::current();
return (strpos($cur,'?') ? ($cur.'&'. $que) : ($cur.'?'.$que));
}
EDIT:
Layout file contains the form which contains the all inputs some for redirection like view task layout component as joomla requred. Some for filterineg or searching. So I couldn't use the GET method for form :/
The search is starting from a form. Now you have two cases.
If you are invoking your view directly from the form, simply change the form method to GET (instead of the default POST) so your form will look like
<form method="GET" ....
If you however are invoking a controller, and in turn the controller redirects to the form, you might need to change some logic. In this latter case, it doesn't matter if you use POST or GET invoking the controller; but the controller must not set the user state variables, instead add the parameters to the URL you are redirecting to
setRedirect(JRoute::_("index.php?option=com_something&view=results¶m1=SOMETHING etc.
A final alternative after your comment: to only include some fields in the URL, assuming you are pointing directly to the view:
<form method="POST" action="<?php echo JRoute::_("index.php?option=com_yourcomponent&view=yourview&explicit_param_1=something&explicit_param_2=somethingelse
<input type="hidden" ...
but this poses more problems as the page should be able to function both with and without the extra params, which won't be present if the user shares the url. You might be better off handling this in a (sub)controller without a redirect (just instantiate the view and its display method in the controller function being invoked).
Remember you can have the syntax task=subcontroller.task to shorten your url.
Related
I have created a search form in TYPO3. The user can filter results by selecting options in a form. the form is handled using the FLUID form line as follows:
<f:form method="POST" action="list" name="eventsearch">
...this works correctly (and I noticed the cHash at the end of the URL when submitting)
When the user finds the item they want they can click on it which takes them to another page. On that page there is a back button which directs them back to the search page, but all the filtered variables are lost and they are sent back to the first search page. This is to be expected, but is there any way it can retain this information?
I have tried passing through the url reference (with has key), but that didn't work. I also tried classic window.history.back() but as the search form uses POST they would have to refresh the screen again. I have also tried swapping my form post to GET, but I get an error regarding an incorrect cHash.
I'm assuming there is a way, as the FLUID pagination buttons can retain the information even though they appear to be using GET.
I would store the form data into the session of the user. This way they can be restored from session regardless from where the user navigates back to the form.
This would mean, if you have a showFormAction and a showResultsAction you need to store the form data in the showResultsAction as follows:
public function showResultsAction(FormData $formData)
{
$this->storeInSession($formData);
// do something with the formData here
}
protected function storeInSession(FormData $formData)
{
if ($GLOBALS['TSFE']) {
$GLOBALS['TSFE']->setAndSaveSessionData('tx_myext_formdata',$formData);
} elseif($GLOBALS['BE_USER']) {
$GLOBALS['BE_USER']->setAndSaveSessionData('tx_myext_formdata',$formData);
}
}
You are going to fetch the form data on the users next visit of showFormAction like this:
public function showFormAction(FormData $formData = NULL)
{
if ($formData === NULL) {
$formData = $this->getSessionData();
}
$this->view->assign('formData', $formData);
// do more stuff for the form here
}
protected function getSessionData()
{
$formData = NULL;
if ($GLOBALS['TSFE']) {
$formData = $GLOBALS['TSFE']->fe_user->getSessionData('tx_myext_formdata');
} elseif ($GLOBALS['BE_USER']) {
$formData = $GLOBALS['BE_USER']->getSessionData('tx_myext_formdata');
}
return $formData;
}
And give the formData to your form view helper <f:form method="POST" action="list" name="formData" object="{formData}">.
FormData in this example is a DTO that is storing the forms individual fields as properties, like a model but not persisted into a database table like the AbstractEntities. This way it is easier to give the restored values back to the form, because the form is prefilling its fields automatically with values from the DTO.
For example if you have a field <f:form.textfield name="somefield" /> in your form, you give the FormData DTO the property property $somefield = '';, a getter and a setter and change the view helper to become <f:form.textfield property="somefield" /> and the form will handle the prefilling all by itself.
as #Kevin Ditscheid pointed out, I could save my form data as session data. Using 8.7.10 I used the following function to store my data:
$GLOBALS['TSFE']->fe_user->setKey("ses","some_variable_name",$data);
...which can be retrieved like so:
$GLOBALS["TSFE"]->fe_user->getKey("ses","some_variable_name");
When a user navigates back from another page via a button, I ensure a variable "returned=1" is included in the URL. My controller class looks for this variable and if found, returns the form post data from my session data.
I have a page in view that has two parts actually which are accessed through # tags, like login#signin and login#signup. When the page loads for the first time it shows login form without having #signin without a problem.
So signin is not causing a problem as it loads at folder/login. But when I try to put folder/login#signup to load directly signup part it gives an error that there is no view login#signup.php. How to cope with this situation?
$this->load->view('workers/login#signup'); is not working.
When I don't put #signup it loads login form that is weird.
I'll expand more on my initial comments for the cause of this error, and how to fix things.
The cause of the issue
As mentioned throughout the comments, you cannot a view using an anchor point. For example, this does not work:
view('workers/login#signup'); // The #signup should not be here.
The documentation states:
Loading a View
To load a particular view file you will use the following method:
$this->load->view('name');
Where name is the name of your view file.
The name is the file is "name", not "name#signup".
Further down,
The .php file extension does not need to be specified unless you use something other than .php.
This implies, that when you use view('name'), CodeIgniter will, by default, load the file name.php. If you include a #signup in it, then CodeIgniter will not be able to find name#signup.php because that file does not exist.
Correct way to handle things
You mentioned you're using the form validation, so we need to ensure no value is lost during the transition process.
Here's a simplified explanation for how to handle it:
function login() {
// Data to be passed to the view (you may or may not already have this)
// More info: https://codeigniter.com/user_guide/general/views.html#adding-dynamic-data-to-the-view
$data = array();
// Validation has failed...
$this->form_validation->run() == FALSE ) {
// Set variable to redirect to #signup upon page load
$data['redirect_to_signup'] = true;
}
// Load view with $data which contains values to be passed to the view
$this->load->view('workers/login', $data);
}
In your workers/login view file, we just need to check if the redirect_to_signup value exists. If it does exist, then we can use some simple JavaScript to scroll down the #signup form:
<?php if (isset($redirect_to_signup) && $redirect_to_signup === true): ?>
<script>
var top = document.getElementById('signup').offsetTop;
window.scrollTo(0, top);
</script>
<?php endif; ?>
Because your validation object is still valid, you can use the built-in CodeIgniter functions to preload your form elements with the set_value() helper functions. For example:
<input type="text" name="email" value="<?php echo set_value('email'); ?>">
That hopefully explains how to achieve what you're after:
Validate user submitted form; and
If there are errors, reload the form with validation messages; and
Scroll down to the #signup form on the page.
One alternative is using redirect('login#signup'), but I would not recommend this method. You would need to save your form values and validation errors to the session to show them on the next page. You also run into the issue that the user might click the refresh button and all values would be lost then.
I'm trying to do something very basic: retrieve a post value from a hidden field. The hidden field is obviously in my view file and I want to retrieve the value in my controller. I'm using the framework SimpleMVCFramework.
I have a hidden field in my projects.php file (the list with projects). When you click on a project, a method in the controller renders the clicked project and the corresponding page. This corresponding page is called project.php
The hidden field in my projects.php view:
<form method="post" action="project.php">
<input type="hidden" name="project-id" value="<?php echo $project['id'];?>">
</form>
This hidden form is displayed correctly in my lists with projects. I checked them in the console.
In my ProjectController.php, I try to retrieve the data using
$data['id'] = $_POST['project-id'];
Then, I send the $data variable with the rendered page, so that I can use the id. So every project in projects.php has a hidden file that outputs correctly. When I try and click on a project, it brings me to project.php, but when I check out the $data variable, the id is just empty.
The routing works like a charm, because e.g. $data['title'] = "Project"; works great and is visible when I check the $data variable. When I change
$data['id'] = $_POST['project-id'];
to
$data['id'] = "foobar";
the id in project.php isn't empty anymore, but shows foobar. So I guess that something goes wrong with retrieving the value.
I also tried to remove the action=".." from the form, but that also didn't work.
The thing I'm trying to achieve is so simple, that I don't understand what is going wrong. Is it possible that the problem lies with the framework and that the code is right?
Thanks in advance and sorry for my bad English.
I have a login controller, which is suppose to redirect to my index page when the user is valid. The redirect works, but at the index page the url is still that of the validation method ex: login/validate_login/. If i click on a link on the index page, and then try and go back in the brower history, the browser points me to the validate method and not the index page.
How do i fix this?
I have tried using redirect with both refresh and location, but both with no luck.
I suspect this is a problem with the ajax call of jQuery mobile, but i'm not sure.
Any help appreciated.
Kind regards
NOTE: I would post an image of the url at the index page, but i'm not allowed to because i'm a new user.
My validate method:
function validate_login($controller='',$method='') {
$this->load->library('form_validation');
$this->load->model('workout_model');
$this->form_validation->set_rules('ex_password','Koden','trim|required|min_length[4]|max_length[4]|callback_pw_check');
if($this->form_validation->run() == FALSE) {
$this->index();
} else {
if($query = $this->workout_model->validate()) {
$data = array(
'is_logged_in' => true,
'user_id' => $query->id,
'current_exercise' => '1'
);
$this->session->set_userdata($data);
if($controller=='' || $method=='') {
redirect("workout");
} else {
redirect($controller."/".$method);
}
} else {
$this->index();
}
}
}
Two things seem to be necessary for the URL to be correctly updated: use redirect(...) instead of method calls AND disable jQuery Mobile ajax call. Two ways of doing that: add and attribute to the link that initially points to your method,
<a href='.../validate_login/...' data-ajax='false'>...</a>
or, disable ajax calls globally by editing the settings (not tested).
There are two ways to handle this and it has nothing to do with AJAX it's the way CI does things. The quickest and easiest way is to change
$this->index();
to
redirect(index);
The way you're doing it you're not actually redirecting, you're calling the index function on the current URL which is validate_login. The problem with doing it this way is if the login fails it will still remain on the validate_login URL for the next try.
The best way to handle it is to have the actual validate_login function called from your index function in the controller rather than the form itself. So send the form back to index, have the index controller check for the form data and if true call validate_login(). That way you're never actually leaving the index page, it just handles whether or not the login form has been submitted. Solving the URL issue. I actually do this with all my pages that submit forms for any kind of validation.
when you submit via HTML form, such as login register .then you have also some kind of dashboard redirection, you need to update your form tag like this.this occurs when I'm using Codeigniter and jquery mobile use data-ajax="false"
<form id="login-box" method="post" action="<?php echo base_url('index.php/auth/login_user'); ?> " data-ajax="false">
I have a form to post with for example "title" data, once the submit button is pressed, the model will be used to process the data. the controller then uses the processed data to display in a view to the user. That is the flow I follow.
After getting the view, the user will choose to edit something. he thus needs to get back to the edittable form (same as the original one) to fix the title data. Here is the form
<?php form_open("blog/edit_updated")?>
Title:<input type="text" col="30" value="<?=$edit[0]['title']?>" name="edit_title"/><br/>
Comment:<br/><textarea name="edit_comment" width="20" col="5"><?=$edit[0]['comment']?></textarea><br/>
<input type="hidden" name="postcomment" value="TRUE"/>
<input type="submit" value="Update"/>
<?=form_close()?>
That form will call the following controler function
public function edit_updated()
{
if(!file_exists('application/views/blog/edit_succeed.php'))
{
show_404();
}
else
{
print_r($this->url_title);
if($this->blog->update_row_with_title(XXXXX,$_POST['edit_title'],$_POST['edit_comment']))
$this->load->view('blog/edit_succeed');
}
}
the function update_row_with_title is only used to seach and update the specified item with exact match of the given title. I test and it always return one (UPDATE command is used). XXXX is the title of the NOT_YET_TO_FIX title used to search in the database, the rest of parameters are those newly entered fields that will be used for SET in UPDATE command. However, XXXXX is always empty. Could you tell me a way to retrieve the original title ?
Summary
Form 1 (with data)--> post --> use data as part of url for GET --> fix the form (with new data) --> UPDATE [right here I lost the original data that is used as an identity for db searching]
It's a bit ambiguous your description, I'm not sure I understand what you want, but I'll try to offer a solution.
If you need the old title in the controller method you can actually send that as a parameter to it in the URL. To do this you have to make the following changes:
in the view containing the form change the argument of form_open to something like
<?php form_open("blog/edit_updated/" . $edit[0]['title'])?>
add an argument to the edit_updated() controller method like this
public function edit_updated($old_title = null) {
...
...
}
and now in the controller method you can replace that XXXXXX variable with $old_title.
Was this helpful ?