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

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.

Related

How to label a loading animation for WAI-ARIA?

I'm working on fixing some accessibility issues on a web page. I have this div that acts as a dialog, and inside at one point a div containing a loading animation and a text "Working..." is displayed.
I am unsure as to how to label these two items in order to correctly notify the blind user that there is a progress animation and that it's working and he should wait.
<div id="loading" style="display: none;">
<div class="mgBot15"><span class="txt16" role="alert">Working...</span></div>
<img src="loading.png" role="progressbar" aria-busy="true"/>
</div>
I tried adding the role and aria-busy properties to the img (also to the parent div, at first).
When this div appears (by changing the display style property), it correctly reads "Working..." but I hear no indication that it's busy and that the user should wait, am I missing something?
I've looked all over for examples for loading animations, to no avail so far.
Note: I'm using NVDA as a screenreader to test.
Thanks
The best solution I could come up with was using role alert, and aria-busy="true".
<div id="loading" style="display: none;">
<div class="mgBot15"><span class="txt16" role="alert" aria-busy="true">Working...</span></div>
<img src="loading.png" alt="loading" />
</div>
I believe the most sensible approach would to use the combo
aria-busy="true" aria-live="polite"
The reason for that is because some pages might have a lot of separate loaders (let's say one for each component, not a single loader for the whole page) and it you use aria-live="assertive" or role="alert" it will be very intrusive and each of the loaders will get called out.
The correct role to use here is progressbar as the original question used. Other roles like alert may work, but they are less specific, meaning assistive technology may present the information in a less ideal manner.
There are a few issue with the original question's example, though:
If you wish to have the text be announced in the same as an alert is, aria-live="assertive" should be used rather than the alert role. That aria-live value is what causes the screenreader to announce the text when it does for an alert.
The text to be announced should be set on the element with the progressbar role using the aria-valuetext attribute. It should not be set solely on a separate adjacent element. If it needs to also be included in another element for presentational reasons, that element should have aria-hidden="true".
Per the spec, aria-valuemin and aria-valuemax are to be specified even when the progress is indeterminate (like a spinning loading indicator). These could be set to 0 and 100 respectively as simple placeholders implying a percentage.
When the loading is complete, the aria-valuenow could be set to whatever was used for aria-valuemax, and aria-busy can be set to false.
This leads to one potential alternative to the original question:
<div id="loading" role="progressbar" aria-valuetext="Working…" aria-busy="true"
aria-live="assertive" aria-valuemin="0" aria-valuemax="100">
<div class="mgBot15" aria-hidden="true"><span class="txt16">Working...</span></div>
<img src="loading.png" alt="" />
</div>
After a day of fiddling with a similar issue, I was able to finally get this working with a lot of reading and experimenting. I'm using NVDA for a screen reader.
<div class="loader" show.bind="isLoading" role="alert" aria-label="Loading"></div>
The following attributes were key: role and aria-label.
Above example makes NVDA announce "Loading alert" once isLoading becomes true. Important to note is that NVDA pronounces the aria-label value, followed by "alert". Using roles "log" or "status" did not end up in any announcement.
Bootstrap used role="status" like this :
<div class="spinner-grow text-primary" role="status">
<span class="sr-only">Loading...</span>
</div>
and in MDN it said :
The status role is a type of live region and a container whose content
is advisory information for the user that is not important enough to
justify an alert, and is often presented as a status bar. When the
role is added to an element, the browser will send out an accessible
status event to assistive technology products which can then notify
the user about it.
There's a good article I came across that explains what needs to be done for this scenario Loading spinner accessibility
The spinner should be included inside the container. Its visibility can be toggled in relation to the aria-busy attribute. They should always be opposites, i.e, if currently loading, section[aria-busy="true"], .tn-spinner[aria-hidden="false"], once the content is loaded, toggle to false and true respectively.

Method as inline function in ASP.Net

I have a method, that returns a resource value based on a given file name and label.
This works fine in between HTML tags, but I cannot seem to get this to work with attributes.
This question has been asked so many times, but mostly on property values, not a method that returns data.
Given the following method:
GetGlobalResourceObject("Introduction", "ButtonStates")
It returns, from the Introduction.[culture].resx the current translation for ButtonStates label. In the following context it works:
<div class="ButtonLabel">
<label>
<%=GetGlobalResourceObject("Introduction", "ButtonStates")%>
</label>
</div>
How do I get this method working within an attribute?
<div class="ButtonLabel" data-label="<%=GetGlobalResourceObject("Introduction", "ButtonStates")%>">
I have tried all the varients I could find on the net, none of them work for a method:
<div class="ButtonLabel" data-label='<%=GetGlobalResourceObject("Introduction", "ButtonStates")%>'>
<div class="ButtonLabel" data-label="<%$PartialPage:GetGlobalResourceObject("Introduction", "ButtonStates")%>">
as examples.
try to use it like this
<div class="ButtonLabel" data-label="<%=Resources.Introduction.ButtonStates %>">
this will work fine if the element is html not asp.net element
but if you want to use it inline in asp control like button use like this
<input runat="server" id=txt placeholder="<%$Resources:Introduction,ButtonStates %>" />
this the way I used and it 's work I hope

Repeated content (sub-template) in AngularJS

I have a template which contains (in part) exactly the same content repeated two or three times with minor changes to the bindings, eg:
<div class="xyz-state0" data-ng-hide="data.error || !data.states[0].name">
<div class="xyz-content">
<img data-ng-src="{{data.states[0].image}}" width="48" height="48">
<span>{{data.states[0].name}}</span>
</div>
</div>
<div class="xyz-state1" data-ng-hide="data.error || !data.states[1].name">
<div class="xyz-content">
<img data-ng-src="{{data.states[1].image}}" width="48" height="48">
<span>{{data.states[1].name}}</span>
</div>
</div>
How do I write this to avoid duplicating this HTML? This is specific to its parent view (it won't be used anywhere else) so creating a full-blown widget seems wrong.
Basically I want something similar to ngRepeat, but I can't use that for the following reasons:
I need a specific (and different) style on each parent div.
I need to render a specific number of divs (2 in this case, 3 in another) regardless of whether or not they exist in the scope (ie. data.states could only have 1 element in it, but it still needs to create both divs).
In the other case the items need to be rendered out of order (first 1, then 0, then 2).
I've managed to get a template fragment in a separate HTML file and included it with ngInclude, but I don't know how to get a single name in its new scope to refer to a specific item. My first attempt was this, which doesn't work:
<div class="xyz-state0" data-ng-include="'state.tpl.html'" data-ng-init="state=data.state[0]"></div>
<div class="xyz-state1" data-ng-include="'state.tpl.html'" data-ng-init="state=data.state[1]"></div>
I suspect I could probably do it with a custom controller, but that seems like a heavy solution too. What's the Right Way™?
This is pretty much a textbook case for a custom directive. Define a directive, and then you can do
<state ng-repeat="item in data.states" item="item">.
Alternatively, if a custom directive is too much overkill (depends on whether you'll be reusing that view component elsewhere, mainly), you could just put an ng-repeat on the entire div. The only real issue is the class="xyz-stateN" stuff, but I bet you could hoke that up with ng-class usage.
EDIT:
if you do an ng-repeat, you can just use the $index key (as long as you're always counting up from zero and the state class is the same as the index). Something like
<div ng-class="{{'xyz-state'+$index}}" ng-repeat="state in data.states" data-ng-hide="data.error || !state.name">
<div class="xyz-content">
<img data-ng-src="{{state.image}}" width="48" height="48">
<span>{{state.name}}</span>
</div>
</div>
Would probably work fine. All that said, it's almost always worth making a directive in my opinion. Code gets recycled all the time, plus you can be cautious with namespacing and modularizing if that makes you nervous.
Well, this seems to do the trick (thanks to pfooti for the hint). I'm still not entirely happy with it as the directive is registered globally, whereas I really only want it in this one place.
state.tpl.html:
<div class="xyz-content" data-ng-show="state.name">
<img data-ng-src="{{state.image}}" width="48" height="48" />
<span>{{state.name}}</span>
</div>
view.tpl.html:
<div data-xyz-state="data.states[0]" class="xyz-state0"
data-ng-hide="data.error"></div>
<div data-xyz-state="data.states[1]" class="xyz-state1"
data-ng-hide="data.error"></div>
app.js:
app.directive('xyzState', [function() {
return {
templateUrl: 'state.tpl.html',
scope: {
state: '=xyzState',
},
};
}]);
Interestingly it doesn't work if I try to declare the introducing element as <xyz-state ...> instead of <div data-xyz-state="" ...>, despite the docs saying that this ought to work too. I assume there's some sort of validation thing interfering here.
Just as an FYI, I later revisited this code and decided to do it like this instead: (I'm letting my original answer stand as that is more like what I was originally asking for, and they both seem reasonable in different cases.)
view.tpl.html
<div data-ng-repeat="state in data.states" data-ng-if="!data.error"
data-ng-class="state.class">
<div class="xyz-content" data-ng-show="state.name">
<img data-ng-src="{{state.image}}" width="48" height="48" />
<span>{{state.name}}</span>
</div>
</div>
app.js
...
while ($scope.data.states.length < 2)
$scope.data.states.push({});
$scope.data.states[0].class = 'xyz-state1';
$scope.data.states[1].class = 'xyz-state2';
...
I've done something similar for the other (3-item) case, except there as I wanted to rearrange the order of the items I added an order property for the desired order in the controller and then used data-ng-repeat="button in data.buttons|orderBy:'order'" in the view.
This does mean that a bit of view definitions (display order and CSS classes) have leaked into the controller, but I think the benefit to code clarity outweighs that.

Unable to display error message in play1.2.4 framework html

I am currently using play framework. Here I need to display error message corresponding to a text box.
Below is the structure of the code I have been using --
<div class="row-fluid widgetRow span6 ${errors.forKey('orgName') ? 'error' : ''}">
<div class="span5 dataLabel"><label class="control-label noMargin " for="orgName">
Org Name</label><span class="required" title="required"> *</span></label></div>
<div class="span7 controls"><input id="orgName" class="" name="orgName" type="text"/></div>
</div>
Now the issue that I am facing is that, infact in a conceptual manner too, is that after I am firing an ajax save on the page, there is some play validation error(validation.required(...)) checks done in the backend, but the conditional class is never getting change. In fact as per my concept I think the condition of the class must be checked during the load of the page.
I hope this makes sense.
Please help me with this, whether there is somewhere I am mistaken
I'd personally either use #{ifError 'orgName'}error#{/ifError} or #{errorClass 'orgName'/} (and edit the CSS to include .hasError).
Aside from that, are you sure you are using the right key? You could check what errors are actually there by adding this to your template to output all errors:
#{ifErrors}
<p>Error(s) found!</p>
<ul>
#{errors}
<li>[${error_index}] ${error.key}: ${error}</li>
#{/errors}
</ul>
#{/ifErrors}

Linking to a specific tab / contentpane with Dojo

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().