My BackboneJS app has a detail view, say for a Book, that is represented by url like editorial/book/edit/4. The Book view consists of several tabs, based on TwitterBoostrap markup, e.g. tabs General/Special/Admin for a Book.
If I use Boostrap tabs as prescribed in their docs, e.g.
<li><a data-toggle="tab" href="#special">Special</a></li>
then once tab is clicked URL in the address bar becomes invalid, instead of siteurl/editorial/book/edit/4#special it the nav bar displays siteurl#special.
Q1: What's the best way to build a tab with valid url with Backbone/Boostrap? The next step I aim at is to make this view reloadable, e.g. so that when a tab is selected and user hits "Reload" in browser, at least same view is loaded, ideally - with latest tab selected.
Q2: What's the ideal way - to build one router function for all detail screen with its tabs or split into a few router functions per each tab?
My recommendation would be to handle the navigation via JS side.
Answer to question 1
When a user clicks on the tab, on the handler use the backbone navigate function:
app.navigate("siteurl/editorial/book/edit/4" + '#' + tabId, {trigger: true});
(This examaple has the URL path hardcoded, just grab it with document.URL or another function that fulfill your needs)
Answer to question 2
That would depend on the logic you need to implement and if that logic is heavy or not. As in your question you said that each tab has a different view, I would suggest to just split the logic inside one router function as all of they apply to the same path (e.g. siteurl/editorial/book/edit/4) and they just differ in the fragment URL.
routes: {
"siteurl/editorial/book/edit/4#:tabId": "tab",
}
router.on("siteurl/editorial/book/edit/4#:tabId", function(tabId) {
//Split your logic based on the tabId
});
Related
I'm hoping to select a particular Region to highlight on the page load based on the link the user follows to get to that page. This is a drill-down report with multiple options, so the goal is to have all options available but focus on the one the user selected to reduce the number of times a user has to navigate to/from the base report to the drill-downs.
Currently, I'm trying to implement this solution https://svenweller.wordpress.com.../, further explained in an Oracle Community discussion here: https://community.oracle.com/..., but it is not working for me.
What I have now is similar to what is shown in those examples, and for now I'm just trying to link to a static Region Display Selector (RDS) tab (the goal will be to have the selected Region be dynamic based on which link is clicked in the feeder page, but I'm clearly not there yet).
I have a Dynamic Action set to fire on Page Load event, and a True action that executes JavaScript code and uses the JavaScript in the example (both with and without the Timeout function suggested in the Oracle thread). I have set Static IDs for the RDS and Region, but when I load the page the RDS still defaults to Show All (or the first region if Show All is off).
Can someone help me understand what I'm doing wrong?
Thanks.
let sesStorage = apex.storage.getScopedSessionStorage({
useAppId:true,
usePageId:true});
setTimeout(sesStorage.setItem( "tabs.activeTab", "#R3" ) { apex.region("tabs").widget().aTabs("getTabs")["#R3"].makeActive();}, 300);
\\version without setTimeout
let sesStorage = apex.storage.getScopedSessionStorage({
useAppId:true,
usePageId:true});
sesStorage.setItem( "tabs.activeTab", "#R3" );
I have done something like this in the past. Create a hidden variable on the page P1_TEST, make sure to set the value not to be protected.
You will need to set the value of that variable when the link is clicked.
Then you need to add static IDs TAB1, TAB2 etc. to the tabs of you region display selector.
Then add a DA on Page Load:
if (apex.item("P1_TEST").getValue() === "Value1"){
$(".apex-rds [href='#TAB1']").trigger('click');
} else if (apex.item("P1_TEST").getValue() === "Value2"){
$(".apex-rds [href='#TAB2']").trigger('click');
}
I have a page that catalogues media (think similar to an instagram page). The media is viewable on modals, and I'd like to record a "view count" for each piece of media. So whenever the modal containing that media is toggled open, it records a view.
This is a simplified version of my code:
<button data-toggle="modal" data-target="media-number-999">Click to view Media 999!</button>
<div class="modal" id="media-number-999">Media #999 viewable here!</div>
I also have a page set up where visiting that page automatically increases the viewcount by 1, and then redirects elsewhere (using django)
urls.py:
path('views/<id>/', views.media_views, name="mediaviews"),
views.py:
def media_views(request,id):
Media.objects.filter(id=id).update(views=F('views') + 1)
return redirect('media_detail', id=id)
The reason I'm doing this is so that I can then reference the viewcount in the database to use for sorting/filtering/etc.
How can I make a button that both opens the modal, and also records a visit to /views/999/ ? Also open to alternative approaches if there are better ways! I've tried to figure out how to use Ajax to do this but haven't had any luck.
Thanks!
Add an onclick function to
</button data-toggle="modal" data-target="media-number-999" onclick="recordview(999)">Click to view Media 999!<//button>
Create a new endpoint on your app that has the following format: /record/{id}
Make a function recordview() that makes a simple HTTP request (No need for AJAX) to your new endpoint
Remove the Media.objects.filter(id=id).update(views=F('views') + 1)in media_views to avoid double recording (From when they clicked vs when they opened) or change the model in media_views
(There is no / at the start of but i had to add it otherwise StackOverflow wouldn't format it properly. Make sure to remove it (And let me know if you know how to format it without the damn slash!)
In my Ember app, I initially start at the root level (/) and I have multiple links (say Link1, Link2, Link3)
Now each of these links displays a common grid i.e. I use same route/controller/template JS, but re-render the grid, by setting some attributes dynamically on the controller
Thus in my application.js, I do
this.controllerFor('my-grid').set('attr1', params[0].value);
this.controllerFor('my-grid').set('attr2', params[1].value);
this.transitionTo('my-grid');
Is this the correct way to transition ?
I mean, specifically I need
this.transitionTo('my-grid');
to be called only once (say on click of link1 from root), since after then, clicks on link2, link3 would just need a change of attribute values on my same controller and should just re-render the grid (after server api call)
Please suggest if there is some condition that I can check for calling
this.transitionTo('my-grid');
In your application you can check ApplicationController.currentPath:
this.controllerFor('my-grid').setProperties({
attr1: params[0].value,
attr2: params[1].value
});
if (this.controllerFor('application').get('currentPath') !== 'my-grid') {
this.transitionTo('my-grid');
}
I have a jquery portfolio gallery with 4 categories which are sortable. When you click on a category the portfolio is rearranged on the same page through jquery showing only those project in that category. Upon clicking a specific project the user can then see the project page/details. I want to add a back button on this page so that when a user is viweing a project they can return to category they were at before.
I tired the following which creates the back button but it take me back to the main portfolio page, not the category which I was browsing before.
function goBack() {
window.history.back();
}
This is one of the gallery page just in case: http://goo.gl/JeSNjD
Not knowing any of your application's code, this is a bit of a shot in the dark but I think I know what you're probably missing.
Using the history.back() will take you to the last page you visited (a page visit is only recorded if the URL is updated). If you are updating content in your website with jQuery and not loading a new page, your browser's history doesn't record this so back takes you back to the top page still.
What you will need to do is change your back button code to hide the current project, and redisplay the category page. You cannot use history.back().
Edit:
If you need more data to correctly rebuild the previous page, you can either change the url for the category page (not necessarily simple to implement but perhaps the most robust thing to do), or to store information about what page they came from. If you are using cookies, you could save navigation there, but you could also add a ref value to the query string when you navigate to a project page.
Category page:
Link to project
Project page:
Back button
Then use that information to reopen or resort your categories.
One problem is knowing which category a back button should return to.
For example, /portfolio/foothill-pasadena-2 should route back to the office category and /portfolio/131house should route back to the Residential category. If I emailed you a link to one of those and you clicked it to go straight to the project page, should there be a back button on the page when you go to it and would it take you back to all categories or to the category related to the project?
One thing you could do is to change your permalink structure to include the category, such as /portfolio/office/foothill-pasadena-2 and /portfolio/residential/131house. Then your could hard-code your back button to go to /projects. You have some jquery running there (wp-content/themes/yourtheme/js/jquery.custom.js):
var isotopeContainer = jQuery('.portfolio-wrapper, .gallery-wrapper'),
isotopeFilter = jQuery('#filter'),
isotopeLink = isotopeFilter.find('a');
isotopeContainer.isotope({
itemSelector : '.isotope-item',
layoutMode : 'fitRows',
filter : '.food-service'
});
isotopeLink.click(function () {
var selector = jQuery(this).attr('data-category');
isotopeContainer.isotope({
filter : '.' + selector,
itemSelector : '.isotope-item',
layoutMode : 'fitRows',
animationEngine : 'best-available'
});
isotopeLink.removeClass('active');
jQuery(this).addClass('active');
return false;
});
That is finding the four category links inside your filter div and adding a click function.
Maybe you can add some extra code that would get the document.referrer, checks it for a match against yoursite.com/new/projects/{category}/{project}, and pulls out the value of {category}. If the category matches one of your four values (food-service, office, residential, other), then call the click function on that element.
I'm trying to create a simple sorting option for posts in my blog. The problem is the last thing I want to use is a JS-based redirections because of the fact some users don't have JS enabled in their browsers, thats why they wont be able to sort posts in me blog. Let me give you an example:
I have several categories in my blog:
//categories selection
<ul>
<li class="active"><a id="cat1" href="/?category=music">Music</a></li>
<li><a id="cat2" href="/?category=photo">Photo</a></li>
<li><a id="cat3" href="/?category=cinema">Cinema</a></li>
<li><a id="cat4" href="/?category=computers">Computes</a></li>
</ul>
Also, I have two sorting options:
//sorting options
<div>
<a class="active">Last posts</a>
<a>Last comments</a>
</div>
Depening on current active elements, user is redirected on page with such parameters, e.g. '/?category=music&sort=posted' or '/?category=personal&sort=commented'.
For example, lets take that in categories selection 'CINEMA' tab is active at this moment (
<li class="actvie"><a id="cat3" href="/?category=cinema">Cinema</a></li>
). So, if user clicks Last comments link, it should redirect to
'/?category=cinema&sort=comments'
Another example: currently Last comments is active (
<a class="active">Last comments</a>
). User clicks on Computes in category selection and it should redirect to
'/?category=computers&sort=comments'.
So, are there any variants for performing such feature without JS? If no, could you suggest me the most elegant solution except manually running over every element in category and sorting optiona and generation link with JS/jQuery?
Thanks in advance!
SERVER SIDE:
db.collection("posts", function (err, collection) {
//getting posts dependinc on requested category
collection.find({category: req.query['category']}, {sort: [['time_added', -1]], limit:20}, function (err, posts) {
//getting posts and rendering page
});
});
UPDATE: I've found a so-so solution. For a separate category I render two div's with different posts list. One for 'Last posted', the second - for 'Last commented'. And the sort selector will just hide one div and shows another. The problem is just twice data size transfering to client side. I know, it will require a bit JS, but the main category links would be clear without '#'-hrefs. And sort options - it's just a toogle, it may not have real link.
Seems like you are doing a page refresh for selecting a new category. Use the selected category parameter to determine the URL of the sorting options. Would need some more code from your server side to give you a more concrete example.
If you don't want to use Javascript you will have to generate the href-attribute of your sorting links <a class="active">Last posts</a> dynamically based on which category is selected. How are you rendering the page today? Just static files? Have a look at a template engine like mustache.js and then you could do it like this:
<a class="active" href="/?category={{category}}&sort=comments">Last posts</a>
Have a look at this tutorial for an Node.js example using mustache.js
http://mrjaba.posterous.com/a-gentle-introduction-to-nodejs
Edited after your comment: Or something like this using EJS
<div>
Last posts
Last comments
</div>
Are you talking about doing the actual sorting on the client side or the server side? If the latter, there's no problem; just stick with the URLs you have and have the server rewrite them and redirect to the new ones (if you even have to do that; you could just treat the "shorter" URLs as the actual ones for the sorted content). This is no way relies on client-side scripting being available.
You can, of course, implement client-side sorting on top of this as a convenience for users who do have client-side scripting available; the key here is to use unobtrusive JavaScript (e.g. install handlers at load time to intercept clicks on the sorting links).