Refer to my code below, when user click on en button, the content will be changed to English, while clicking tw button, the content will be changed to Chinese.
However, the page will be refreshed each time when user click either en or tw button. I want to ask how can I implement AJAX content update in this case?
The result is when user click either en or tw button, the page won't be refreshed to change the content language.
Thanks
I have refer to Yii docs here, but seem that it is not appropriate for my case
C:\wamp\www\website\protected\views\site\index.php
<?php
$lang = isset($_GET["lang"]) ? $_GET["lang"] : "en_uk";
$lang = $lang == "en" ? "en_uk" : "zh_tw";
Yii::app()->setLanguage($lang);
?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="get">
<input type="submit" value="en" name="lang" />
<input type="submit" value="tw" name="lang" />
</form>
<div class="main">
<?php echo Yii::t(Yii::app()->controller->id, "Causeway Bay"); ?>
</div>
Best practice is to reload the page in these cases, because usually you have to update so much, that it is just not worth it.
That said, CHtml's ajaxSubmitButton is the cleanest way to implement this, because you can map every event of your call very easily. It looks something like this:
<?php
echo CHtml::ajaxSubmitButton('en', CHtml::normalizeUrl(array('site/changeLanguage')),
array(
'error'=>'js:function(){
alert("error");
}',
//if you add a return false in this, it will not submit.
'beforeSend'=>'js:function(){
alert("beforeSend");
}',
'success'=>'js:function(data){
alert("success, data from server: "+data);
}',
'complete'=>'js:function(){
alert("complete");
}',
//'update'=>'#where_to_put_the_response',
)
);
?>
You don't have to use every parameter of course. The update parameter can update a HTML tag instantly.
EDIT:
This can be done easily if you use the controller's renderPartial method, for instance in your site controller if you have the action responsible for the index.
public function actionIndex(){
//get variables, etc
if(Yii::app()->request->isAjaxRequest) {
$lang = $_POST['nameOfSubmit'];
}else {
//...
}
//if the 3rd parameter is true, the method returns the generated HTML to a variable
$page = $this->renderPartial('_page', array(/*parameters*/ ), true);
echo $page;
}
And then, in your view file you can simply have
<?php echo CHtml::ajaxSubmitButton('en', CHtml::normalizeUrl(array('site/index')),
array('update'=>'#content_div',));?>
and
<?php echo CHtml::ajaxSubmitButton('tw', CHtml::normalizeUrl(array('site/index')),
array('update'=>'#content_div',));?>
Related
I have a simple form in my tmpl/default.php:
<form id='AddForm' action="<?php echo JRoute::_('index.php?option=com_mycomponent&task=addcam'); ?>" >
<p>
<label for="CamName">Name:
</label>
<input type="text" id="CamName" name="cam_name" />
</p>
<button type='submit' class='submit_cam' name='addcam' value='Add'>Add</button>
<button type='reset' class='cancel_changes' name='cancel_changes' value='Cancel'>Cancel</button>
</form>
In my controller.php file I'm trying to process the values:
function addcam()
{
$add_name=JRequest::getString('cam_name');
$model = &$this->getModel();
$model->AddWebcam($add_name); //send to model to add to DB
}
In my model I just return the result of the query. With this implementation I just get routed to an empty page. I'd like to have it refresh the current page. Typically you do this with action="" but in my case I need it to route to the function called addcam in the controller. Or is there a better way to do this?
A common technique in Joomla when directing to the task is to have that function do a full redirect to a view at the end. This prevents a page refresh from trying to resubmit the data and leads to a cleaner url for the client. To do this, try the following:
function addcam()
{
$add_name=JRequest::getString('cam_name');
$model = &$this->getModel();
$model->AddWebcam($add_name); //send to model to add to DB
JFactory::getApplication()->redirect(JRoute::_(index.php?option=com_mycomponent&view=whatever));
}
Obviously, update the JRoute bit to the url you actually need. You can also include a message if you would like (like "Saved!"): http://docs.joomla.org/JApplication::redirect/1.6
I am using codeigniter for this project. I hava a id value in which i pass from controller A to view A. This id value is echo between an anchor tag. When this anchor tag is clicked on, it redirects to another controller B with the id value and processed this id value within controller B. Is there any other way of doing this other than using the uri class? Want to keep the url clean.
I thought of a way of appending hidden input elements when I shift from controller A to view A to controller B, but i realised it can be very messy.
Any clean ways of doing this? Thanks in advance guys!
New to using Stackoverflow See if you could understand my layout:
METHOD 1
Use the URI Class except you have good reasons not to.
From CONTROLLER_A
$data["id"] = ("ID NUMBER");
$this->load->view("VIEW_A", $data);
ANCHOR IN VIEW A
link
IN CONTROLLER_B
$id = $this->uri->segment(3);
.
METHOD 2
USE FORM POST if you want to keep things hidden:
$data["id"] = ("ID NUMBER");
$this->load->view("VIEW A", $data);
ANCHOR IN VIEW A
<form name="myform" id="myform" action="<?php echo base_url() ?>/controllerB/controllerfunction/" method="post">
<input type="hidden" name="id" id="id" value="<?php echo $id ?>" />
<input type="submit" value="See more" />
</form>
You could also use javascript to submit the form here via link if you which:
See more
Tips:You could also use css to hide submit button in the form by setting opacity to 0;
If link is within the form, you could use javascript:this.submit();
OR JQUERY
See more
$('#link').click(function() {
$('#myform').submit();
});
IN CONTROLLERB
$id = $this->input->post("id");
Well hidden inputs will work, and there's may another workaround that once you redirected to the method and use your id value i.e. get data from database, redirect again to another controller method with the clean URL you need , hope this is helpful
I am having an issue with PHP session in Firefox. There is a change in Session after each refresh/page reload. On other browsers, it is working fine.
In my WordPress template, I have initialized the session, comparing the post/session variables. A shortcode "inf_kit" defined in functions.php file will be called while executing "the_content()" function.
The shortcode defined in functions.php will call functions kit() and CSRF() which will set a session variable and add a hidden text field to the form, returned in my template. When I submit the form, I am getting a different value. In IE, Chrome is it OK. Does someone have any idea, where the issue might have?
Code in template file
<?php
session_start();
if(isset($_POST["s_405"])){
print_r($_SESSION);
if($_SESSION['token_valid'] == $_POST['token_valid']) echo 'Good'; else echo 'issue';
}
the_content();
?>
Code in functions.php
<?php
add_shortcode( 'inf_kit', 'kit');
function kit($atts){
$form .= '<form name="kit" method="post">
<input type="hidden" value="'.time().'" name="s_405"/>'
. CSRF('valid').
'</form>';
return $form;
}
function CSRF($key){
$tkn = sha1($key.uniqid(rand(), true));
$_SESSION['token_'.$key] = $tkn;
return '<input type="hidden" name="token_'.$key.'" value="'.$tkn.'">';
}
?>
I created a confirmation page for deleting an item. This works perfectly.
Now I want to appear the confirmation page in fancybox, still passing all the variables and delete the data or close the dialog.
It's important that the process still works as it does now (delete->confirmationpage->redirect/deletion) so that users with javascript disabled can perform these actions without a problem.
Now have I been reading about zend framework,ajax, json and more, but the more I read, the less I understand.
So in a nutshell, my question:
I want to pass a variable to the fancybox and if 'yes' perform the delete action or on 'no' close the dialog. This within the zend framework and jquery.
Any advice or tips are greatly appreciated!
You need to use content switching in your ajax which will then render your action appropriately, for example:
function confirmDeleteAction() {
if($this->_request->isXmlHttpRequest()) {
//This is ajax so we want to disable the layout
$this->_helper->layout->disableLayout();
//Think about whether you want to use a different view here using: viewRenderer('yourview')
}
//The normal code can go here
}
function deleteAction() {
//You probably don't want to show anything here, just do the delete logic and redirect therefore you don't need to worry where it's coming from
}
And in your fancybox, have a view that has a form and two buttons, the form should point to your delete action with the id of whatever your deleting as a get param. Set some javascript up that says something like (and this is mootools code, but you can convert it easily):
$('confirmButton').addEvent('click', function(e) {
e.preventDefault();
this.getParent('form').submit();
}
$('cancelButton').addEvent('click', function(e) {
e.preventDefault();
$('fancyBox').destroy(); //I'm not sure it has an id of fancyBox, never used it
}
Came across the question today and figured I could give it a fresh look. For Zend Framework the solution is really simple:
This is how the action looks:
public function deleteAction()
{
$this->_helper->layout()->disableLayout();
$this->view->news = $this->newsService->GetNews($this->_getParam('id'));
if($this->getRequest()->isPost())
{
if($this->getRequest()->getPost('delete') == 'Yes')
{
$this->newsService->DeleteNews($this->_getParam('id'), $this->view->user->username, $this->view->translate('deleted: ').'<strong>'.$this->view->pages[0]['title'].'</strong>');
$this->_helper->flashMessenger(array('message' => $this->view->translate('The page is deleted'), 'status' => 'success'));
$this->_helper->redirectToIndex();
}
elseif($this->getRequest()->getPost('delete') == 'No')
{
$this->_helper->flashMessenger(array('message' => $this->view->translate('The page is <u>not</u> deleted'), 'status' => 'notice'));
$this->_helper->redirectToIndex();
}
}
}
The delete.phtml
<div>
<h2><?php echo $this->translate('Delete news'); ?></h2>
<?php
foreach($this->news as $news)
{
?>
<p>
<?php echo $this->translate('You are now deleting <strong>\'').$news['title'].$this->translate('\'</strong>. Are you sure about this?'); ?>
</p>
<p>
<?php echo $this->translate('<strong>Note! </strong>This action is inreversable, even for us!'); ?>
</p>
<form action="<?php echo $this->baseUrl(false).'/news/index/delete/'.$news['id']; ?>" method="post">
<?php
}
?>
<input class="submit deleteYes" type="submit" name="delete" value="<?php echo $this->translate('Yes'); ?>" />
<input class="submit deleteNo" type="submit" name="delete" value="<?php echo $this->translate('No'); ?>" />
</form>
And this is how the link to delete a file looks (within a foreach loop with my database results)
<a class="deleteConfirmation" href="<?php echo $this->baseUrl(false).'/news/index/delete/'.$news->id; ?>">delete</a>
This works like you would expect; when you click on delete the user goes to the delete confirmation page and redirects the user back to the index after the form is submitted. But I wanted the confirmation in a dialog (in my case I use fancybox). To achieve this, add the following jquery to your index:
$('.deleteConfirmation').fancybox({
// Normal fancybox parameters
ajax : {
type : "POST"
}
});
I understand how to do it w/ a plain form w/o existing values, but let's say I have a view that I can call via http://domain.com/account/settings. let's say I have two fields, username, password and city, which are all pulled from the DB (except for password of course). So, if a user tries to submit the form and fails validation for whatever reason, where should I "redirect" them to? Right now, I have it showing the same view but the problem is, it pulls the info from the DB again. Should I be creating two different views?
The second view would essentially show the information they tried to enter along w/ the error message.
You do not need two separate views. Check out Form Helper's functions set_value(), set_select(), set_checkbox() and set_radio(). These re-populate form after its submission and validation. So in your case, you should specify the fields this way:
<input type="text"
name="username"
value="<?php echo set_value('username', $user['username']); ?>" />
<input type="text"
name="city"
value="<?php echo set_value('city', $user['city']); ?>" />
By default, the input will have $user['city'] value. But after failed validation it will be re-populated with previously entered values (including incorrect ones).
Just remember that all fields you want to re-populate need to be passed through form_validation library:
$this->form_validation->set_rules('username', 'Username', 'required');
$this->form_validation->set_rules('city', 'City', '');
On the same controller you could have something like this:
if ($this->form_validation->run('create_comment') === TRUE)
{
$this->comments_model->name = $this->input->post('name', TRUE);
$this->comments_model->email = $this->input->post('email', TRUE);
$this->comments_model->website = $this->input->post('website', TRUE);
$this->comments_model->comment = $this->input->post('comment', TRUE);
$this->comments_model->create_comment();
redirect(current_url());
}
$this->load->view('your_view');
That's all there is to it.
The idea is to have it redirect to itself or wherever you want, when the validation returns 'true' so that we kind of refresh the page, hence, update the page.
If the validation returns 'false' then you won't have to do anything.
Redirect to the same form.
And in your view give error information to the visitor.
There are two ways you can do this.
Use this error in your view. This will show validation error info.
echo validation_errors('<p class="error">','</p>');
Or you can use flashdata()
In your controller
...
...
$this->session->set_flashdata('msg', 'All fields are required. or other useful info here. Please try again!');
redirect('yourcontroller');
And in your view, you need to show it.
<?php
if ($this->session->flashdata('msg')){ //change!
echo "<div class='message'>";
echo $this->session->flashdata('msg');
echo "</div>";
}
?>
Had the same problem and discovered that a redirection makes you lose the data that would have been provided by form_error(...) or validation_errors(), except you store such data in a session or in an array being passed into the loaded view.
The point to note is that you should redirect only if the data you want passed around is in session, else you should just load a view. The latter ensures that you have your validation errors intact when you reach the loaded view.
Just load same view if form validation failed
controller
$userData=array(
'username'=NULL,
'password'=NULL
);
#set form validation rules
$this->form_validation->set_rules('username', 'Username', 'required');
$this->form_validation->set_rules('password', 'Password', 'required');
#get all posted data ,this helps you in two ways,
# 1. Get all form data and can be use here server side
# 2. repopulating the form data by passing to view page
$userData=$this->input->post(NULL, TRUE);
#check form validation result
if ($this->form_validation->run() == TRUE) {
//do the operation
redirect(URL);
}else{
$this->load->view($view, $userData);
}
View page
<form method=post action='URL'>
<input type='text' name='username'value='<?php echo $username?>'/>
<?php echo (form_error('username')) ? form_error('username', "<div style='color:red'>", "</div>") : ""; ?>
<input type='text' name='password' value='<?php echo $password?>'/>
<?php echo (form_error('username')) ? form_error('username', "<div style='color:red'>", "</div>") : ""; ?>
<input type='submit' value='submit'/>
</form>
This code display form errors and repopulate the form