Cakephp 2.x mobile theme and prefix - jquery-mobile

I am currently adding a custom mobile layout for one of my apps.
AppController.php
if ($this->request->is('mobile')) {
//$this->viewClass = 'Theme';
$this->theme = 'Mobile';
} else {
$this->theme = Configure::read('App.theme');
}
Working just fine.. Have jquery mobile running flawlessly now.
However, I would like to develop on separate functions in the controllers, as the main website, does gather much more data from the DB than the mobile version will require.
So I am thinking of an approach like, if request mobile => set this prefix = mobile or something like that? To allow for separate mobile functions in the controller.
Any suggestions?
Also, I would like to set a param when page is loaded, like, Do you want to view the mobile version? Yes / No. If No => show mobile = false, if yes => show mobile = true. Preferably by some sort of popup (like the tapatalk forum app notification).
Thanks for any help with this.. :)
-Tom

Just like you use $this->request->is('mobile') in your AppController, you can use the same method in all of your controllers and do your logic depending on the request type, it is a good way of achieving your goal.
Secondly;
You can create an element asking user "Mobile or Not?".
In your landing page controller (or if you want to make this check in each page, eg. if user lands on a specific page with link from other sites. Then do this in AppController beforeFilter()) you check a value like:
$mobilePref = Configure::read('Config.mobilePreference');
if($mobilePref){
$this->set('showMobileElement', true);
} else {
if($mobilePref == 'Mobile'){
$this->set('showMobileLayout', true);
} else {
$this->set('showMobileLayout', false);
}
}
And in your layout, you simply check $showMobileLayout, if it is true you show the mobile layout, if false you show the normal layout.
If it is not set you check $showMobilePref and if it is true, you call the "Mobile or Not?" element. And depending the answer of user from element, you set
Configure::write('Config.mobilePreference', true); //or false, depending on answer
That is roughly it, i suppose. Of course if you are authenticating users, you should save the choice of user and remember it next time user logs in.

Related

Rails how to remember the navbar status between clicks?

I have a rails app with a nice navbar that can fold and unfold. The navbar contains links that point to different controllers and actions.
Every time a user clicks on one of the links, the browser goes to the new page and the navbar gets reset to its initial state.
I need to maintain the fold/unfold status of the navbar between calls (that is better user experience).
I'm not sure how to do so.
I thought to add in the javascript that handles the folding a URL parameter so that the next view can dig it and load the menu in the previous state. This parameter would be completely handled in the view, so no changes in the controllers.
I'm not sure this is the best way to approach this.
I've been suggested to use the session object. but I think that this will still require some sort of passing params (still via URL), and would require changing the controllers (there are many, I'm not very happy to change them all and after all this is a purely user interface matter).
Would it be reasonable to use the window.local/session storage for this?
any suggestions?
You could have a boolean in your database that gets updated every time the user clicks a link in the navbar and then redirect to the appropriate view.
The view decides which status of the navbar to show (folded or unfolded) based on the value of the boolean.
In the end I went for using localStorage,
It was rather simple to implement, and it's a purely JS solution, the only side effect is that when the page load there's an extremely fast flicker when the navbar is open (the navbar is loaded closed, then JS opens it).
the code just runs down to these few lines of code:
$('.chevrons .open').click(function(event) {
localStorage.setItem('navbar', 'open')
....
});
$('.chevrons .close').click(function(event) {
localStorage.setItem('navbar', 'closed')
....
});
if (localStorage.getItem('navbar') === 'open') {
$('.chevrons .open').trigger('click')
}

Intercepting Grails GSP actions on either client or server side

Grails 2.4.5 here. I am trying to implement the following UX behavior for my GSPs:
If a user has permission to click a button, then they may do so; however
If the user doesn't have permission to click a button, then when they click the button, a banner message (flash?) appears across the top of the screen with an rose/pinkish/red background stating 'You don't have permission to take this action'
To determine whether the user has the required permission, I have access to functionality from both the Groovy and GSP/taglib layers.
From the Groovy/controller layer:
SecurityUtils.hasPermission(String permission)
Ex: SecurityUtils.hasPermission('UPDATE_BUZZ')
From the GSP/taglib layer:
<sec:hasPermission permission="<permission name>">???</sec:hasPermission>
Ex: <sec:hasPermission permission="UPDATE_BUZZ">???</sec:hasPermission>
So, given those two available access checking mechanisms, and given the following controller:
class FizzController {
BuzzService BuzzService
def buzz() {
SomeData dataModel = buzzService.getModel(params)
render(view: 'buzz', model: [ dataModel: dataModel ])
}
}
...where buzz.gsp is:
<!-- Lots of HTML/GSP here -->
<g:submitButton name="update" value="Update" />
<!-- Lots more HTML/GSP down here -->
Given all that, my question is: How/where should I: (1) respond to the 'update' button's click handler, (2) perform the access check, and (3) render the error/banner/flash message? Code example (even pseudo-code) would be most awesome!
Here is what I would suggest:
Make sure your controller method is role based
Remove permission check in GSP, if the button should be visible to everyone
Create an AJAX call upon submission, if the response status is 403, display the banner.
If I were you, I'd probably try to use before-action filter in this case. In this filter I'd make a checking if current user has permissions to such an action (checking permissions should always be done in server-side, because of security reasons) and than:
if security check passes - just return true (controller will continue it's flow)
if security check fails - you can use default flash.message and return false (with propriate css style flasheed message could appears across the top of the screen with an rose/pinkish/red background)
Example code:
class UserFilters {
def filters = {
// ... other filters ...
permissionAllCheck(controller: '*', action: '*') {
before = {
doPermissionCheck(delegate)
}
}
}
private boolean doPermissionCheck(filters) {
if (! YourService.checkForPermissionForCurrentlyLoggedUser()) {
filters.flash.message = "You don't have permission to take this action"
return false
}
true
}
}
If you want to use filter only to specific controller/action, check applying section. Remember also, that you can use invert rule filter.
More info about different filterTypes.
You should also remember to add flash.message section to your layout (or selected views). You can always specify type of flash message and it's css style.
I am assuming by your question that you don't want a page refresh and perhaps not even an ajax call. Because if you did that then showing a banner is not difficult. You just want this to behave like JavaScript client-side validation (UX wise). If this assumption is wrong then don't read and use Aramiti's solution. Otherwise go ahead.
First solution
You can create a tag which takes a permission as input. Something like
<myTagLib:flashOnNoPermission permission="PERM" name="name" value="value">
</myTagLib:flashOnNoPermission>
This tag's definition can check the permission using sec:hasPermission. Then this tag can just render a template containing something like this
<hidden flash message>
<g:submitButton name="name" value="value" onclick="<unhide flash if no permission>"/>
Basically create a wrapper over grails button so that you can have flash messages alongwith buttons.
Problem
What if user's permissions are changed when user is on screen? Ajax takes care of that but this does not. Once screen is loaded then everything is fixed.
The banner is alongwith the button
Second solution
Add a common div at the top of your layout for displaying flash messages. Then create a tag similar to the above. Just don't add the flash message in the rendered template. Something like
<g:submitButton name="name" value="value" onclick="<unhide flash at top of layout if no permission>"/>
Problem
What if user's permissions are changed when he is on the screen?
Not sure why you need things onclick handler but if there is no reason just Aramiti's solution.
Best way would be to hide the button if the user has no permission to use it. That could be easily achieve through <sec:hasPermission permission="UPDATE_BUZZ">button</sec:hasPermission>
If you want button to be displayed even for user without permission, you could use the same hasPermission to add an extra class to the button. Now capture the clock event for that class using jQuery and show your message.

Hide Ionic(AngularJS) back button from appearing

Working on an iPhone app using the ionic framework(which is great). Currently im am using the $state variable to redirect usings, say 'on a successful login'.
I am writing this like so...
$state.go("app.search");
I have also tried
$state.go("app.search", {}, {reload: true});
Both of which correctly load the /search page but provide me with the back button at the top left with the menu.
Now i want the back button on the other functionality. I'm wondering if I need to call a different method to changes pages or if i can temporarily disable it on some views?
Any pointers would be great!
This might be a little late but in case someone else gets here looking for an answer, you can use the $ionicViewService as described below
function controller($scope, $state, $ionicViewService) {
$ionicViewService.nextViewOptions({disableBack: true});
$state.go("app.search");
}

Ruby- Change the layout on button release without changing the URL

I would like to have my Flash animation in fullscreen when I press a html button under the animation. I have a ../views/layout/viewer.rhtml (this one loads all menus). I have ./views/layout/fullscreen.rhtml (this one do not have menus, it has only 100% width and 100% height and the flash object). I would like to avoid Javascript method.
I have a show_controller:
layout "viewer"
def index
h = Histoire.find_by_label(params[:story_name])
# Checks if current_user has a subscription which allows the story whose ID is passed by param to be seen
if h.price != 0 && (current_user.nil? || current_user.abonnement.histoires.delete_if{|histoire| histoire.label != params[:story_name]}.length == 0)
flash[:notice] = "Sorry, your subscription doesn't allow you to access this story, please contact sales service"
redirect_to index_url
else
#histoire = Histoire.find_by_label(params[:story_name])
render :action => :show
end
end
I have a flash object:
My flash Animation need to have a fixed URL to run: /show/Story_Name, the current layout is viewer. When I press FullScreen button, I'd like Ruby to change the layout from "viewer" to "fullscreen".
Is there a way to change the layout from viewer to fullscreen when a button is pressed?
I'm beginner in this matter. Thanks a lot to the one who will help me.
Ruby code is executed on the server side, it won't do anything unless you reload the page to make another call to your controller, for example using a "layout_mode" parameter you may use in your view template.
I would use an unobtrusive javascript approach :
use a link to reload the page and change the layout_mode to fullscreen. This behavior allows user with Javascript disabled to access he fullscreen switch feature
use jQuery to modify this link so it changes the layout on click without reloading the page for the regular users
Side note : I would advice you to avoid naming your model objects in French, as Rails is strongly convention-oriented and makes an extensive use of english-inflections : Rails will consider stories as a collection and story as an individual member. It would work with "gourou" and "joujou" but won't with "hibou", "caillou", "chou"... ;)

Is there a way to change the browser's address bar without refreshing the page?

I'm developing a web app. In it I have a section called categories that every time a user clicks one of the categories an update panel loads the appropriate content.
After the user clicked the category I want to change the browser's address bar url from
www.mysite.com/products
to something like
www.mysite.com/products/{selectedCat}
without refreshing the page.
Is there some kind of JavaScript API I can use to achieve this?
With HTML5 you can modify the url without reloading:
If you want to make a new post in the browser's history (i.e. back button will work)
window.history.pushState('Object', 'Title', '/new-url');
If you just want to change the url without being able to go back
window.history.replaceState('Object', 'Title', '/another-new-url');
The object can be used for ajax navigation:
window.history.pushState({ id: 35 }, 'Viewing item #35', '/item/35');
window.onpopstate = function (e) {
var id = e.state.id;
load_item(id);
};
Read more here: http://www.w3.org/TR/html5-author/history.html
A fallback sollution: https://github.com/browserstate/history.js
To add to what the guys have already said edit the window.location.hash property to match the URL you want in your onclick function.
window.location.hash = 'category-name'; // address bar would become http://example.com/#category-name
I believe directly manipulating the address bar to a completely different url without moving to that url isn't allowed for security reasons, if you are happy with it being
www.mysite.com/products/#{selectedCat}
i.e. an anchor style link within the same page then look into the various history/"back button" scripts that are now present in most javascript libraries.
The mention of update panel leads me to guess you are using asp.net, in that case the asp.net ajax history control is a good place to start
I don't think this is possible (at least changing to a totally different address), as it would be an unintuitive misuse of the address bar, and could promote phishing attacks.
This cannot be done the way you're saying it. The method suggested by somej.net is the closest you can get. It's actually very common practice in the AJAX age. Even Gmail uses this.
"window.location.hash"
as suggested by sanchothefat should be the one and only way of doing it. Because all the places that I have seen this feature, it's all the time after the # in URL.

Resources