Linking to a specific tab / contentpane with Dojo - html

I want to navigate from a link on a html site to another where a TabContainer with two different tabs is located.
I have one tab selected by default (which I want to keep) in the destination html file.
How do I have to put the link so that this is working? I found several documents on the net but nothing works. So probably someone needs to explain this to me the dumb way.
Here is the destination TabContainer:
<div dojoType="dijit.layout.TabContainer" region="center" tabStrip="true">
<div dojoType="dijit.layout.ContentPane" title="Contact" selected="true">
some text
</div>
<div dojoType="dijit.layout.ContentPane" title="Imprint" selected="true">
some text
</div>
I want to place a link to autmatically be navigated to the title "Imprint".
Can someone help?
Thanks a lot and all the best
TTP

You can either select it from javascript, or generate the markup for the tab from your server with the selected attribute to true (you'll need to set the other to false). This second alternative, depends on your server technology.
For the first option, add ids to the container and tabs and select the tab when the page finished loading. Something like:
<div id="tabContainer" dojoType="dijit.layout.TabContainer" region="center" tabStrip="true">
<div id="tab1" dojoType="dijit.layout.ContentPane" title="Contact" selected="true">
some text
</div>
<div id="tab2" dojoType="dijit.layout.ContentPane" title="Imprint" selected="false">
some text
</div>
</div>
<script>
dojo.ready(function() {
dijit.byId('tabContainer').selectChild(dijit.byId('tab2'));
});
</script>
If you want to dynamically select either tab, you'll need to pass some kind of parameter in the URL to your page. You can use a query parameter (variables after the ? symbol) or a hash fragment (anything after #). Query parameter you can read both from the server and from javascript. Hash fragments, only from javascript.
You can access those parameters by inspecting the location object. For example, using a hash fragment, you'd link to your page like http://host/page.html#imprint. Then in the <script> tag above:
<script>
dojo.ready(function() {
if (location.hash == '#imprint') {
dijit.byId('tabContainer').selectChild(dijit.byId('tab2'));
}
});
</script>
For query parameters, also see dojo.queryToObject().

Related

Dialog element from file

I've been reading with interest about the dialog element in HTML:
<dialog id="helpOnName">
<p>
The name is arbitrary. There is no validation, whatsoever.
</p>
</dialog>
So, that's well for this simple text. However, with growing complexity, I'd rather have something like
<dialog url="helpOnName.html"></dialog>
In other words: Rather than embedding the dialog contents into the opening page, I'd like it to be read from another file.
Is that possible? How? (Using JQuery would be fine.)
You may have different options to achieve the goal to have content loaded from an external resource.
Doing an ajax request that will return a response to embed
dynamically in the dialog
Embedding the content inside an <iframe> tag
Referencing the content with an <object> tag
This is the demo for the third and most original option of those.
The content for the <dialog> is specified by an <object> element fed by an url having its content. As a fallback, I added the option that will override its content with a default template defined in the page itself.
<object>: The External Object element
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object
:scope (worth of mention)
*for selecting only starting from the direct children
https://developer.mozilla.org/en-US/docs/Web/CSS/:scope
This is an answer better covering <iframe> <embed> <object>
Difference between iframe, embed and object elements
And I would add I forgot to mention <link>
document.addEventListener('DOMContentLoaded', ()=>{
const dialog = document.getElementById('primaryDialog');
fillDialogContent(dialog);
})
function fillDialogContent(dialog){
const template = dialog.querySelector(':scope > .fallback');
const content = template.content.cloneNode(true);
const objectEl = dialog.querySelector('object');
objectEl.append(content);
}
<dialog id="primaryDialog" open>
<object data="your-custom-dialog-content.html" type="text/html"></object>
<template class="fallback">
<div class="container">
<p>This is the default dialog content</p>
<p>An error occurred in the attempt to load the custom template</p>
</div>
</template>
</dialog>
Here is another way of doing it with fetch():
document.addEventListener('DOMContentLoaded', function(ev) {
document.querySelectorAll("[data-url]").forEach(el=>
fetch(el.dataset.url).then(r=>r.text()).then(html=>el.innerHTML=html)
)
});
<h3>First dialogue</h3>
<div data-url="https://baconipsum.com/api/?type=all-meat&paras=3&format=html">hello</div>
<h3>Second dialogue</h3>
<div data-url="https://baconipsum.com/api/?type=all-meat&paras=5&make-it-spicy=1&format=html">hello again</div>

AMP email - [checked] bound attribute doesn't affect checkbox status

I have an AMP email and I want checkboxes to appear as checked or unchecked depending on a value coming from my server. If the value {{done}} is false, I want the box to appear unchecked and if {{done}} is true, I want the box checked.
Here is the code for the email:
<amp-list
template="checklist-item-template"
src="MY_SOURCE_URL"
layout="responsive"
binding="refresh"
width="600"
height="56"
><template
id="checklist-item-template"
type="amp-mustache"
>
<div class="task-row outline">
<div class="task task-checkbox">
<input
type="checkbox"
id="checkbox-{{id}}"
value="checked"
name="{{id}}"
[checked]="{{done}}"
on="change:checklist-form.submit"
/>
</div>
<div class="task task-name">
{{done}}
</div>
<div class="task small-text task-icons">
{{deadline}}
</div>
<div class="task task-burger"></div>
</div>
</template>
<div overflow class="list-overflow">
See more
</div>
</amp-list>
The other dynamic fields populate correctly. My problem is that I can't pass the done boolean directly into the checked attribute because false is rendered as a string, which is truthy and checks the box.
I have found a very similar question for this issue here. This approach is what I originally used and it worked well. However, now my checkboxes are unchecked regardless of the value passed into the [checked] attribute.
I suspect that there may be some ongoing development with AMP email as I had a similar issue, which was confirmed by the AMP team to be a bug at their end.
You are using [checked], which is the syntax for attribute binding and only works if amp-bind is imported. You need to add <script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>.
Maybe AMP should print a warning to the JS console for better developer experience, so consider filing a feature request.
You are using binding=refresh on amp-list, which tells the component to only evaluate binding when refreshing the list and not during the initial load of the list. To evaluate [checked] on initial load, you need binding=always or omit the binding attribute altogether.

How to handle multiple nav panel menus using jquery mobile?

jquery mobile newbie -- I inherited this project.
I have quite a few 'pages' in my jquery mobile app. On each page I have a nav panel. Each page is set up much like this:
<div data-role="page" id="help_manual" data-theme="d">
<div data-role="panel" id="navpanel_help_manual" data-theme="d" data-display="overlay" data-position="right">
<div data-role="controlgroup" data-corners="false">
Home
User main menu
</div>
</div>
<div data-role="header" data-position="fixed" data-tap-toggle="false">
<a data-icon="bars" class="ui-btn-right" style="margin-top:10px;" href="#navpanel_help_manual"
data-iconpos="notext">Menu</a> <!-- this is the button that actually brings up the above panel-->
<h3>User Manual</h3>
</div>
<div data-role="content">
BLAH BLAH CONTENT
</div>
<div data-role="footer" data-position="fixed" data-tap-toggle="false">
Back to main menu
</div>
</div>
This all works well and good.
Then you make another page. ... Then another... Then another... Suddenly you've got a few dozen pages all with their own 'menus'. They all work, but there is a LOT of redundant code, given all the menus are identical.
Now I want to make a change to all of the menus.... and instead of modifying one 'navigation panel' I have to make the change a few dozen error-prone times.
I have tried simply taking the 'panel' code and moving it outside the 'page' div... but that results in, effectively, a 'new' 'page' when the button is clicked. Other attempts at moving the various parts of this code around are similarly broken.
An include could remove the 'list' from the 'core' of the control group... unfortunately, that still leaves a lot of redundant code and I've got one fun tweak: This page needs to be able to work offline. The purpose of this app is to be able to go offline, collect data 'in the field', and come back and upload it. So a SSI isn't an good option.
Help?
Here is a JsFiddle with multiple pages and the panel written only once.
You should write your panel once outside the page. (If you have one file per page, just write the panel outside the index page as a sibling of the page) :
<div data-role="panel" id="navpanel_help_manual" data-theme="d" data-display="overlay" data-position="right">
...
</div>
<div data-role="page" id="help_manual" data-theme="d">
...
</div>
Doing so and as it becomes an external panel. You should then initialise it manually.
$('#navpanel_help_manual').panel();
The panels below are all located outside the page. Panels outside of a page must be initalized manually and will not be handled by auto init. Panels outside of pages will remain in the DOM (unless manually removed) as long as you use Ajax navigation, and can be opened or closed from any page.

Conditionally render .hbs templates emberjs

EDIT:
I would like to conditionally display templates inside of a larger template as long as the presence of the larger template is True.
in sidebar.hbs
<div id="sidebar-wrapper" class="super-super-float-right-col">
<div id="sidebar-wrapper" class="super-float-right-col">
<div id="sidebar-wrapper" class="float-right-col">
{{#if permit.id}}
{{render 'applicant'}}
{{render 'location'}}
{{else}}
<h2>Nope!</h2>
{{/if}}
</div>
</div>
</div>
In application.hbs I call the sidebar and the outlet
{{render sidebar}}
{{outlet}}
So technically the sidebar is currently unrelated to the results of the {{outlet}}.
I want to connect the the results of the {{outlet}} with which templates are rendered in sidebar.hbs.
Right now I'm getting "Nope!"
EDIT: I was able to use {{#if this.id}} to make the conditions on the permit.hbs page true. Now I'm trying to figure out how to apply that same logic for rendering
Much love,
Ian
If you're in the permit template there is no point in checking if you're in the template. That's analogous to saying if true, because the only reason that code would be executing would be because it's there executing it.
If that wasn't exactly what you meant update your question.
If you want something in your template to change based on the route, the application controller has a property called currentPath which has the current application path, you can watch it and create computed properties that change based on the current path.
http://emberjs.jsbin.com/iCIkEsib/2/edit

ColdFusion.navigate alternative?

In another question, "Using Google Map with ColdFusion", I ran into a problem of not able to display a google map using CF. After much experimenting, I found out that if you use ColdFusion.navigate to point to a page from one cflayoutarea to another cflayoutarea, the map in the destination cflayoutarea would not show. (However, if you just run the page, both by itself or when it is inside the destination cflayoutarea, the map will show)
So my question now is: is there an alternative approach where I don't need to use coldfusion.navigate to navigate from one cflayoutarea to another?
Your English isn't great, so I'm going to paraphrase to a question that makes sense (to me) and answer that question...
It sounds like you have 2 CFLayoutArea's, and you want to have a link (or button, etc) in one of them that will change the contents of the other.
If you're eliminating ColdFusion.navigate as an option, then it seems to me you're going to have to try one of a few other options that are all basically the same thing. I like jQuery. If you don't like jQuery, you can use another library, or roll your own solution, but they will all do the same job.
Since this code:
<cflayout name="foo" type="hbox">
<cflayoutarea name="nav">nav</cflayoutarea>
<cflayoutarea name="content">content</cflayoutarea>
</cflayout>
Produces this HTML:
<div id="foo">
<div id="nav" style="overflow:auto;float:left;">
nav
</div>
<div id="content" style="overflow:auto;float:left;">
content
</div>
</div>
You can use the ID attribute of the content DIV, with jQuery, to change its contents:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#goLink").click(function(e){
$("#content").load("content.cfm");
e.preventDefault();
});
});
</script>
<cflayout name="foo" type="hbox">
<cflayoutarea name="nav">go</cflayoutarea>
<cflayoutarea name="content">content</cflayoutarea>
</cflayout>