Providing parameter to navigate back function in a Kendo View
According to the Kendo UI documentation, you can easily navigate backwards to the previously visited mobile View using the following function:
app.navigate("#:back");
With default navigation it's quite easy to provide parameters, like app.navigate("#my-view?id=xxx&foo=bar"). However, is it possible to provide a parameter to the back function? Meaning something like this (fictional) example:
app.navigate("#:back?pageIndex=5");
If not, are there any other smart suggestions to look into? Obviously, my pseudo sample doesn't work.
The reason is that all my views are seperated in loose files and the page that calls the back function works somewhat like a dialog: sometimes it should provide arguments back to the previous view. And sometimes not. In the fictional example, I want to basically intercept certain functions in the 'parent view' if certain parameters are provided.
Despite the fact that using a ModalView would normally be a better fit here, or even a decent global datasource, I'm curious about this one.
Related
I would like to replicate Google's home page functionality in Angular, and it's causing me grief. I've gone through the Egghead videos and read the entire API, but there's no particular example for that exact behavior. What I'd like it to do is the following:
user comes to home page, main search bar is present and generic black header bar
user searches for something, and only when he presses "search" does the main search bar disappear, the url changes to mysite.com/q/searchTerm and a new sub-header appears under the black header bar much like with Google's home page, where the main search field is removed and placed in a grayish bar under the main header bar (if you have instant-search off)
the results of the search appear in place of the now gone main search bar, just like with Google, but this part I can handle with routes and views. The layout switch between two identical controllers is what bothers me.
So far what I've tried was:
make a parent controller for both MainCtrl sub controllers, and set its scope.data = {searchHeaderDisplay: false}
have both sub controllers share the same name (MainCtrl) because they share the exact same functionality
make the one in the header bar ng-show="data.searchHeaderDisplay" and the main one ng-hide="data.searchHeaderDisplay" and then try switching the data.searchHeaderDisplay on ng-click of Search Button. This didn't work - no effect was produced.
I'm still coming to terms with AngularJS, so I'm sure it's quite simple, I just need a practical example or two to learn from.
Edit: would it be better to shove the secondary header (with the smaller search field) into a separate view template along with the search results, and just have the root view be the main search field? The documentation is very lax on best practices regarding views and routes, especially routes that will have multiple controllers doing something.
If I understand you correctly, you set scope.data = {searchHeaderDisplay: false} on the parent controller of the two MainCtrl controllers, with the intention to enable the MainCtrl controllers to share the same model data. That's all fine.
Without seeing your code, my guess is that the problem lies in how you switch data.searchHeaderDisplay on ng-click. You might have set data.searchHeaderDisplay at the child scope level (ie. the scopes that corresponds the MainCtrl controllers) when you should have assign the value to their parent scope level. Let me know if you need me to elaborate.
UPDATE:
After taking a look of the provided code, the problem is indeed as what I suspected earlier (above).
mainProductSearch() is what needs to be changed. Instead of scope.data.searchHeaderVisible = true;, you need scope.$parent.data.searchHeaderVisible = true for the reason briefly explained earlier. If the rationale behind is still not clear to you, then you probably need to familiarize yourself with prototypal inheritance chain of AngularJS scope (and/or Javascript object in general). Scope prototypal inheritance an essential part of AngularJS. Here is a great article on the topic.
Instead of an AppCtrl (which is essentially acting like $rootScope), and using $parent (which is a fragile solution because changing the HTML structure could cause this to break -- e.g., you might find you need to use $parent.$parent... if you add an intermediate ng-controller), I suggest a service for storing model data related to your header. Let's call it searchService.
Controllers that need to affect this model can inject the service. This has the additional advantage that the dependencies are clear (vs controller $scope inheritance, where the dependencies are not clear). E.g., when the user presses "search", the controller can call a notification method defined on the service: searchService.newSearchTerm(searchTerm). Now, all views (like the header view) that are watching for changes in the model will notice the change and can update accordingly.
You might consider using ng-view for the main content area of your page.
See also https://stackoverflow.com/a/14619122/215945, where a very similar layout is discussed. In that SO post, a shopping basket with an item count is in the header. The item count needed to be updated by multiple controllers, so we put it into a service.
So I have been making stuff in Unity3D and decided to try an extension called Playmaker. Basically is uses a FSM (Finite State Machine) to design the flow of states and events. You can drag an event to a different state to trigger another state of events, etc. (Reference : http://www.hutonggames.com/features.html)
NOTE : The actual product I linked has nothing to do with the idea I want to try and build. Just a reference.
Well I would love to be able to do something simliar in Javascript. I think I have some of the logic down but I'm thinking more about User Experience. I want a user to be able to create an FSM with my logic in the browser using Javascript.
I'm not asking for anyone to code this for me or anything as I am experienced enough in javascript to do the bulk of it. I was thinking more about the way you can drag one event to another and it creates a visual arrow showing the user what events are connected. If you look at the first tutorial on the referenced link I provided you will understand what I mean. The arrow length and curves would be dynamic. Possibly be able to drag around states to re organize the layout of the states. This would obviously change the way the arrows pointed as well.
I hope that all made sense.
Ideas? Pointers? Maybe someone has done something like this already? I did find one Javascript State Machine but it generates once, doesn't allow users to move anything, the event dragging to another state is very important.
I'm starting to learn Backbone.js and can't figure out one thing: In a typical rails app, I have a layout view and a nested view. My layout usually contains navigation links that are processed by rails routing.
How do I do the same with Backbone? I'm using Rails 3.2 and eco templates.
Should I create nested templates in eco?
Should my navigation links be plain html links with a href or should the navigation be event driven?
For example I have a list of categories on the left, and a category items on the right. I want my categories to be shown on every view and the corresponding category items (with a URL in browser corresponding to selected category) too.
Please point me to right direction, because most tutorials on the Web are 'todo' style applications with no navigation at all.
Thank you.
UPDATE
Turns out, my question wasn't clear, so let me narrow it down.
How can the concept of RoR layouts be applied to backbone.js applications?
And I'm curious about two possible ways of navigation:
create
%a{:class => "customers", :href => "#customers"} Customers
handle ".customers click" event in my view
Which way is better?
And I'm curious about two possible ways of navigation:
create %a{:class => "customers", :href => "#customers"} Customers
handle ".customers click" event in my view
Which way is better?
neither is better until you know the specific context in which you are working. they are simply options for achieving your goal and desired functionality.
there are times when both should be used, as well. for example, if you are supporting search engine optimizations and accessibility.
Here are some better questions to ask:
Which of these will be the simplest thing that can get the job done? will it be more code to write the route handler, or the click handler?
Will the route handler tightly couple the functionality to a router, when I don't need that?
Do I really need a route for this link, so that people can bookmark it and come back to it directly?
Will a click handler cause my code to jump through several hoops of calling other objects that aren't directly related, or can I use a simple event to cause the other objects to run?
There isn't a single correct answer to any of these questions. I recommend trying many different ideas when you can. Keep in mind that you will likely change your answer as you develop new features. The answer that you want, today, won't be what you need tomorrow. But that shouldn't stop you from picking an answer now and moving on. Pick one, put it in place, and when you need to change it, change it.
Beatports new interface has solved a major problem I was looking for the solution too.
Namely, it keeps a "player" interface at the moment and you can browser to different parts of the site (also changing the url) without reloading or interrupting the player.
I cannot for the life of me understand how they have done this, can any of you guys figure it out?!
Many thanks for any replies I get
Looks like they are just using AJAX to load new content but have taken care to make it work and look pretty seamless. You can get better insight into what events are attached to what elements via the Visual Events bookmarklet. Once you find the code that triggers the event, you can run the obfuscated javascript through JSBeautifier to examine it more closely.
Specifically, it looks like they're adding click handlers to all anchor tags, passing off the event if it was triggered with a middle click or modified with a keyboard key, otherwise passing it to a dynamic loader which handles state and other specific conditions like multiple clicks. The seamlessness of it comes from the way they deal with URLs making every page bookmarkable and the browser history so the back and forward buttons work as you would expect on a "normal" site.
I'm coming across a bit of an awkward problem. I have a Web page with quite a few buttons on it that need to be disabled and enabled at various points. Now if this were a Swing (or any otehr desktop UI interface for that matter), it would be quite trivial: I would simply add listeners for the model changes I was interested in and update the UI accordingly.
This is basic MVC stuff really.
Thing is, I'm at a bit of a loss as to how to handle this nicely in Javascript. I'm going down a route that will end up with some real spaghetti code where the click listeners for the buttons are updating the UI controls and that's just not going to end well.
EDIT: Let me give you a more concreate example.
Example
Imagine a screen that lists open orders. Those orders are presented in a table as each row (order) has multiple attributes against it, such as who is currently managing the order, who made the order, what it's for, when the order was made and the status of the order.
I've done it so you can select one (or more) of these orders by clicking on the rows. This adds a "selected" class, which changes the styling, much like a list.
As to the behaviour, if a user selects one order then certain actions become available, such as Open Order (to view the details), Take Owneship, Cancel and so on. The attributes of the order may also affect what actions are available eg if the order is "owned" by somebody else already, certain actions will be disabled.
Some of these options (like opening the order) aren't available if you've selected multiple orders.
Additionally via a background Ajax call the list refreshes with new orders periodically. The user can also click refresh or can filter the orders (by name, date range and so on) and then reload the orders. While the orders are reloading certain buttons get disabled.
I was going to do a second example but I think that one is sufficiently complex to illustrate the kind of problem. Now I've started this by giving various controls classes. For example, elements with the "select" class might be disabled/enabled/styled when an item is selected.
Now this works reasonably well in simple cases but I'm running into problems where the state of a control depends on multiple conditions. Also the classes are getting fractured by things like some elements want to be styled, some controls want to be disabled/enabled and in some cases both things need to happen.
In Swing I tended to handdle this kind of thing by having a sort of updateUI() method, which would be called whenever the state of a relevant control or model was changed. It would then set the state of all the controls explicitly. Now this is arguably not the most efficient way (eg if you have 30 controls and only need to update one of them it's a bit of a waste) but I found the simplicity was worth it. The alternative was that controls/models ended up with too information about what controls they depended on or those that depended on them. It go tmessy from a coupling point of view.
But I have no such (obvious) mechanism in Javascript. Inobtrusive Javascript as advocated by jQuery is great because it stops random code snippets being littered throughout your code. But I need to go a step further nad have some way of managing the complexity of this (because it is quite a complex screen and will only get more complex).
If you want to preserve your sanity, use a state machine.
You don't really give details about what your UI does, so I'll make up an example. Let's say you have a file upload page. The user should be able to select a file, click an upload button, and then be returned to the page they came from, when uploading is complete. So you could have three states, "SelectFile", "Uploading", "Finished". In the "SelectFile" state, controls should be enabled to allow the user to select a file. In the "Uploading" state, these control should be disabled, and the user should see a progress indicator. In the "Finished" state, the user should be redirected.
Of course, it sounds like your case is more complicated, but the same ideas will apply. You may need more than one state machine, if portions of user interface interact. That's fine.
When you want to change the enabled/disabled elements on the user interface, you just change the state of the state machine. The state machine itself tells the various user interface controls to update themselves based on the current state. You can use a Bharani's (good, up voted) suggestion of using classes to do this. Or whatever mechanism works for you.
The nice thing is that the controls no longer interact with each other. They only interact with the state machine. So you get rid of all the cases where states bounce around incorrectly or endlessly recurse.
Assign specific class names to the divs. That way even if they overlap in functionality you can simply keep adding class names to the div and because of the chain nature of jquery all registered event handlers will be executed.
For controlling form elements during ajax call - you can add ajaxStart and ajaxEnd or you can use ajaxComplete and handle all your code inside the callbacks.
I think i get your problem. I have worked on such screens before and i always ended up refactoring to structure the code better. But at times it will be easier if you could re-organize the functionality itself so that you don't have to handle all things in one place. I think GUI should also be treated like a function - do one thing and one thing well.
I think data modeling is important for JavaScript apps. I am working on this scheduling project for medical clinics and I have a JSON data structure that models chairs/patients in an office. Ember updates the views (UI widgets) automatically when the business logic changes in the models. So right off the bat a lot of sphagetti code is eliminated. If you are doing something graphically intense with user interaction it is almost a crime not to use an existing MVC pattern or to create your own MVC JS classes. The structured discipline is off putting at first but when you see later how it lowers your blood pressure and makes maintenance so much more enjoyable it is worth it. I wouldn't use it for simple one-off projects if they are small. It is better for medium complexity or advanced complexity. Anything that will take me more than a week I will use Ember. I have used knockout.js and Angular and I really like Ember with its Handlebars templating syntax. Easy on the eyes and efficient.