Joomla setredirect override in save method breaks apply method - save

I have three toolbar buttons in my edit page of my component (joomla 3.0).
view.html.php
protected function addToolBar()
{
JToolBarHelper::apply('editpage.apply');
JToolBarHelper::save('editpage.save');
JToolBarHelper::cancel('editpage.cancel');
}
This works great. But now when I change the redirect path of my save method in the controller like this...
controller/editpage.php
function save()
{
parent::save();
$this->setredirect(JRoute::_('index.php?option=com_mycom&view=productlist', false));
}
... than by a click on "apply", the user was also redirected to this path. And this is the problem. Without this override method in controller, the apply button works fine. All fields will be saved and the edit page will not leave. So how can I solve that problem?

Both Save and apply method call to the same function of joomla library to save the records. The better way to over come the issue is
view.html.php
protected function addToolBar()
{
JToolBarHelper::apply('editpage.tasktoApply'); // any name other then apply
JToolBarHelper::save('editpage.tasktoSave'); // any name other then save
JToolBarHelper::cancel('editpage.cancel');
}
controller/editpage.php
function tasktoApply()
{
parent::save();
$this->setredirect('ANY CUSTOM REDIRECT AS PER YOUR NEED', false));
}
function tasktoSave()
{
parent::save();
$this->setredirect('ANY CUSTOM REDIRECT AS PER YOUR NEED', false));
}
This would sort out your issue

Related

How to wait for routing to finish?

When a user clicks on a link, it uses routing to send the user to another component, you start at home and can click to charts. My problem is that I need to get the queryselector for the charts element, but when code is loaded from the component, it doesn't exist yet. How can I wait for the element to be created to execute the code?
I solved this by adding a MutationObserver inside the constructor.
Element chartsElement;
ChartsComponent() {
MutationObserver observer = MutationObserver(_onMutation);
Element my_app = querySelector('my-app');
observer.observe(my_app, childList: true);
}
_onMutation(List<dynamic> mutations, MutationObserver observer) {
mutations.forEach((value) {
MutationRecord record = value as MutationRecord;
if (record.addedNodes.contains('charts')) {
chartsElement = record.addedNodes[0];
}
});
observer.disconnect();
//Do stuff
}

Prevent loading page

I have a controller create and return content where it triggers an alert.
The problem it load an empty page. How can I prevent it to load an empty page and stays in the current view and do nothing just pop the alert.
What I really wanted here is before the user can create new data, it will validate first if the diseaseID is already existing for specific assessmentID, and when the result is null, it will just pop an alert and do nothing. But here I'm just trying make alert() work properly.
Controller:
public ActionResult CreateDisease(int? diseaseID,int? assessmentID, DiseaseList diseaselist)
{
diseaselist.DiseaseID = diseaseID;
diseaselist.AssessmentID = assessmentID;
db.DiseaseLists.Add(diseaselist);
db.SaveChanges();
return Content("<script language='javascript' type='text/javascript'>alert('Item already exist');</script>");
}
You dont need to return the script as content from the controller, just return the values as json that will tell you that the item already exist and based on that true or false value show an alert from the client side js.
your controller code will look something like this
diseaseModel.DiseaseID = diseaseID;
diseaseModel.AssessmentID = assessmentID;
diseaseModel.AlreadyExist = true;
return Json(diseaseModel);

ListGrid put focus in the FilterEditor

I have a ListGrid defined like this:
ListGrid lgrid = new ListGrid();
ListGridField first = new ListGridField("first",first");
ListGridField second = new ListGridField("second ",second ");
lgrid.setFields(first, second);
lgrid.setShowFilterEditor(true);
¿How can i put the keyboard focus in the first filter editor field after i call show() in the layout?
Thxs in advance.
Depending on what your use case is (which would be useful to provide a more focused answer), the solution you posted might not be what you really need, because if you scroll on your ListGrid, it could trigger a new data fetch (if there are more records to show), and move the cursor to the filter editor as a result (if your user is editing some records at that point, the cursor moving to the filter row is not what she would want to happen!!).
In such a case, you probably just want to call grid.focusInFilterEditor("fieldToFocus") after the listGrid.show() statement or in the ClickHandler of some button you use to fetch the data, etc.
Anyway, you don't need the Timer either. This works:
listGrid.addDataArrivedHandler(new DataArrivedHandler() {
#Override
public void onDataArrived(DataArrivedEvent event) {
grid.focusInFilterEditor("fieldToFocus");
}
});
I got the solution, its focusInFilterEditor, this is an example to set the focus after the data arrived to the grid:
// Put the focus on the first listGrid field when is loaded
listGrid.addDataArrivedHandler(new DataArrivedHandler() {
#Override
public void onDataArrived(DataArrivedEvent event) {
Timer t = new Timer() {
public void run() {
if(listGrid.getFilterEditorCriteria() == null){
listGrid.focusInFilterEditor("fieldToFocus");
}
}
};
t.schedule(600);
}
});

MVC 5 Session not presisted when going to another View

Session variable lost after a controller calls another View to render.
public ActionResult Index(Customer model, string cancel, string effective)
{
if(!string.IsNullOrEmpty(cancel))
{
//update database
Session["variable2"] = new Info(){ Text = "Do not processed"};
return View("Cancelation"); //error stated occurs when calling another view
}
if(!string.IsNullOrEmpty(effective)
{
//do data base update
Session["variable1"] = new Info(){ Text = "Processed"};
return View(model); //All good here
}
{
I have a MVC controller that when post back to it I set a Session variable "variable1", then I do return View(model). In this case all is good I can access the new Session variable1 everywhere.
But when I post back to the same controller again, I check the button clicked and then I set another Session variable, "variable2" this time I do return View("Cancelation").
This last variable2 is lost and does not show on HttpContext.Current.Session["variable2"] anywhere in the application.
Can someone help to understand why?
What I found was that because I was using SQL Server as Session store, I had to use Serialize() attribute on the object, then it worked.

Monotouch.Dialog - How to push a view from an Element

It seems like this should be very easy, but I'm missing something. I have a custom Element:
public class PostSummaryElement:StyledMultilineElement,IElementSizing
When the element's accessory is clicked on, I want to push a view onto the stack. I.e. something like this:
this.AccessoryTapped += () => {
Console.WriteLine ("Tapped");
if (MyParent != null) {
MyParent.PresentViewController(new MyDemoController("Details"),false,null);
}
};
Where MyDemoController's gui is created with monotouch.dialog.
I'm just trying to break up the gui into Views and Controlls, where a control can push a view onto the stack, wiat for something to happen, and then the user navigates back to the previous view wich contains the control.
Any thought?
Thanks.
I'd recommend you not to hardcode behavior in AccessoryTapped method, because the day when you'll want to use that component in another place of your project is very close. And probably in nearest future you'll need some another behavior or for example it will be another project without MyDemoController at all.
So I propose you to create the following property:
public Action accessoryTapped;
in your element and its view, and then modify your AccessoryTapped is that way:
this.AccessoryTapped += () => {
Console.WriteLine ("Tapped");
if (accessoryTapped != null) {
accessoryTapped();
}
};
So you'll need to create PostSummaryElement objects in following way:
var myElement = new PostSummaryElement() {
accessoryTapped = someFunction,
}
...
void someFunction()
{
NavigationController.PushViewController (new MyDemoController("Details"), true);
}

Resources