Yii2 wrong route like controller/controller/action - yii2

I'm facing the following problem: In a table with ordered records I want to insert a new record at a specific location or copy / move a record to another position.
In the index view I defined the additional action buttons {new} {copy} {move} in the grid view. A click onto one of them routes to a new view called select (controller/select) with a grid view of the same table with only two action buttons, {before} {after}, indicating whether the record should be placed above or below the selected record.
Clicking on one of these buttons routes to the controller action create (if formerly was selected new) or the controller action copy-move (controller/create or controller/copy-move). The controller does his job and returns to the index view with $this->redirect(['index']). This works properly.
Clicking again onto one of the action buttons in index view {new} {copy} {move} I see a strange route: controller/controller/select instead of controller/select. This behaviour stops only when I call the index view from the menu it doesn't by refreshing the browser.
Why does this happen? Is it maybe because of immediatly creating a grid view after selecting an action in a grid view before? And how to avoid this behaviour?
This is the work-flow:
call index view
click on action button {new} {copy} or {move}
create route controller/select
get the select view
in select view click on action button {before} or {after}
create route controller/copy or controller/copy-move
create a new record at the choosen position or copy / move it there
return $this->redirect(['index']) after controller has done his job
in index view again click onto action button {new} {copy} or {move}
create route controller/controller/select instead of controller/select which ends in a 404 error.

You are facing problem with relative and absolute urls. In yii2
// relative route: /index.php?r=admin%2Fpost%2Findex
echo Url::to(['post/index']);
// absolute route: /index.php?r=post%2Findex
echo Url::to(['/post/index']);
NOTE:- forward slash is required
For more information see this

Looks like I got the answer to my question. I removed all logic from the view file defining a specific action with it's route letting kartik grid view generate the url in the action section of columns. So in index.php I have three actions with an own route for each: {new} routes to new, {copy} routes to copy and {move} routes to move.
Then I did the same for select.php where the actions are {before} routing to before and {after} routing to after.
In the controller, the routes then are redirected to select action in the first case and to create action resp. copy-move action in the second case.
This seams to work properly and I don't get that wrong route anymore.
Thanks for helping.

Related

Polymer: How to implement navigations

The way I currently implemented navigation in my Polymer 1 application is this:
I use paper-menu and paper-submenu
on iron-select, I will create a route based on the names of the paper-item
for example groups, example, test will be concatinated into a route like: /groups/example/test. User when then be routed there using this.set('route.path', '/groups/example/test')
Also, on page load, to highlight the correct menu items, I parse the URL and selected the correct menu items. So far so good.
The problem here is: suppose I have even further nesting like /groups/example/test/subpage1/subsubpage2. When the user navigates to such a URL, he is forced back to /groups/example/test because the parsing of URL to select the correct items.
The workaround I have currently is: instead of attaching on-iron-select I will setTimeout then attach this handler. This is so that the user does not get forced back to the wrong page, but this feels wrong. Whats the correct way of doing this?

Storing selected tab for restoration using React Redux and Router

Currently I have a sample which I'm working on which is a basic master details page. This sample uses react-router-redux. Within the details panel I have a number of tabs which use can see different facets of the selected item... all fairly standard stuff.
When the user selects an item from the master list, the URL that the clicked <Link ... /> send them to is something like customer/123. Within the route that is registered for that url (i.e. :id), I have an indexRoute route which replacess the route to default route/tab /customer/${nextState.params.id}/address.
All this works well and the user can navigate between tabs just fine. The problem comes when the user closes the detail window and selects a different detail. As expected, it opens the tab based on the route specified by the indexRoute. Under normal circumstances, this might be fine but I want it to remember which route was selected. I'm wondering if anyone has ideas on how this should be done?
I think I can do achieve this by registering a callback with the onClick event of the Link and dispatching an event which will result in key of the selected tab being saved in the store. Then within the onEnter of the indexRoute I can access the store and pull out this saved state and target the replace to this that item.
This should work but seems like a lot, just wondering if this seems right to other?
I would use the same approach - dispatch an action when the tab is clicked and store the tab key in the store.
Use mapStateToProps to retrieve the value.

React Router - change url without navigation

I have a new product page with the url /product/0. When product is saved using a button, I want to show 'Saved Successfully' message and change url to /product/1024 without actually navigating to that page as this would cause GET requests for the product and other data on the page.
I tried the Navigation mixin, however both, the transitionTo and replaceWith actually cause componentWillReceiveProps and I can't figure out a way how to distinguish my case (when all data on the page is already relevant) from navigation between different products, when data has to be reloaded.
So basically I am looking for a way to just change the url with React Router.
In a SPA there's no navigating to another page, the history change could lead to a different route being rendered, but as per your example, the same route will be rendered, so the only thing that did happen is a state change of the props of the Route component.
So you need to check this state with the previous state in componentWillReceiveProps and see if you need to refetch the data.

incompatible type passed in as a parameter created by loading a GUI component.

I am having a problem with a UI that I am building in a Google Spreadsheet. I will First explain a little about how it works and than I will get to the problem. The UI is fairly simple program that connects to a SQL database, it allows users to create new records, Query, search, and render reports. I have created all the panels (eg the intro page, the create record) in the GUI builder. As the user navigates through the UI I swap out a Grid with the new panel that i want the user to see. For example on the intro page there is a create button when the user clicks the button the gird where there intro panel was is replaced by the create record panel. I have created two ways for the user query/search for data. The first way is to select a number range on the intro panel and click the Query button. This will than query the last 10 or so records into a GUI built Panel that I will call MainForm. The second way is to "search" for a job. On the intro page there is a search button when the user clicks with button it goes to a new page; the grid is switched to the search panel. On the new page/panel the user can put in some parameters to search for. After the user clicks the search button the program should load the search results into the MainForm in the same way as when you Query from the intro page. I have taken the whole function apart line by line, so i am sure that the issue has to do with loading the panel/Component. What i mean by that is these few lines of code.
var Component = app.loadComponent("MainForm");
var panel = app.createVerticalPanel().setSize("770px", "900px").add(Component);
app.getElementById("contentGrid").setWidget(0,0, panel);
But why would it load in one case, but not in another? Also it is not the method of loading the Component, rather it is the returning the panel/ Component.
To Summarize, When I load the Component with the query function it works, but when i load the Component in the search function I get and error: Incompatible type passed in as a parameter. Also I load the MainForm Component in two other functions as and it works most of the time, but some times I get the same error.
I think your approach is not ideal, load component is not supposed to be called multiple times. It would be far more efficient to get all your panels in the same compnent and play with visibility of each panel to show / hide them on demand. Each panel should be inserted in a vertical panel so that the "new panel" slips to its place when the "old one" hides.
An example of this approach is shown in this post to simulate tabs and could easily be adapted to your needs.
btw, this method is also very fast and responsive since the full UI is ready from the very beginning ;-)

Auto Refresh of a page

I have a web page consisting of a dropdown menu. What i want is the contents of other dropdown menus present in the page must change according to what has been selected in the first dropdown box. For example if a dropdown consists of Degree as its element. If i select Degree element then another dropdown must show only degree courses. This must happen automatically without clicking any button. How can i achieve this?
I would make this a comment, but I do not have commenting abilities. You are going to want to use $.post with jquery and ajax to accomplish this: http://api.jquery.com/jQuery.post/ . Ajax with JQuery is not difficult to do.
You will want to use the onchange event of the first drop down to use a jquery ajax $.post call to post to the server, passing the selection from the drop down as a parameter. The page that it post's to should us GET to get the selected attribute from the drop down, and then retrieve ( from the database or where ever) the options that go into the second drop down, based on the parameter. The code should be written out to the page. The jquery ajax call has a way to get the response and let you define a custom function to be run once the post returns. The return should be what you had written out to the page, and then you can just update the second drop down list with the returned data inside this function.
I hope this helps!