Data binding for dynamically generated HTML in Polymer? - polymer

When I write the following inside my <template>-tag, everything works fine:
<ul id="breadcrumbList" class="breadcrumb">
<li><a on-click="{{breadcrumbClick}}">{{overviewName}}</a></li>
</ul>
I dynamically generated a new <li>-element of the same structure, like this:
crumb = document.createElement("li");
crumb.innerHTML = '<a on-click="{{breadcrumbClick}}">'+category+'</a>';
But when I click this element, the event-handler isn't called.
The event-handler looks like this:
breadcrumbClick: function(event, detail, sender) {
/*reaction*/
}
I did not find any documentation about whether it's possible or impossible to use data binding for dynamically generated content.

This is possible with injectBoundHTML(). We haven't documented it yet, but you can see the method signature and demo here: https://github.com/Polymer/docs/issues/607
Example:
<li id="myli></li>
this.injectBoundHTML('<a on-click="{{breadcrumbClick}}">...</a>', this.$.myli);

Related

Loading span as text

I'm running into an issue with JqueryUI autocomplete in which the span that is being returned is rendering as text in the drop down (as seen below).
I'm using Jquery Ui 1.8.17 and Jquery 1.6.4
The autocomplete function:
$('#search').autocomplete({
source: '/Search/AutoComplete',
html: true,
delay: 0
});
The browser is not loading the span into the DOM. The reason i assume is because it needs to HTML encode the text. Here is the markup. As you can see it isn't encoded.
<li class="ui-menu-item" role="menuitem">
<a class="ui-corner-all" tabindex="-1"><span class="autocomplete cat">Cat</span></a>
</li>
<li class="ui-menu-item" role="menuitem">
<a class="ui-corner-all" tabindex="-1"><span class="autocomplete carbon">Carbon</span></a>
</li>
I had read a few thing of an HTML extension but I didn't find anything concrete. Is this issue fixable with J Query or do I need to modify my source data?
the solution posted in Using HTML in jQuery UI autocomplete was the solution for this.
My JS ended up looking like:
$('#searchPhrase').autocomplete({
source: '/Search/AutoComplete',
html: true,
delay: 0,
minLength: 2
}).data("autocomplete")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" + item.label + "</a>")
.appendTo(ul);
};

AngularJs - how to support a textbox with hyperlinks

I'm new to Angular but I'm trying to implement a textbox that allows users to enter in links. I only want to support links, and otherwise I want to block all html from being presented as such. I could theoretically use something other than a textarea, but my requirements are that it must be bound to a variable in my scope (right now with ng-model) and I cannot accept html tags other than '< a >'
Here is my example plnkr
In the example, I would like the second seeded item to display as a link, blue and underlined. However, the third item should display as it is currently shown (without interpreting it as html).
HTML:
<textarea maxlength="160" ng-model="val.text"></textarea>
<div class="btn" ng-click="submit()">Submit</div>
<br><br>
<div ng-repeat="item in items">
{{display(item)}}
</div>
JS:
$scope.submit = function() {
if (!$scope.val.text) return
$scope.items.push($scope.val.text);
}
$scope.display = function(txt) {
return txt;
// something here? if txt contains <a> and </a> indicate
// that we should display as html
}

HTML onclick attribute with variable URL

Below code is for navigating to the Google Webpage when the element <li> is clicked.
<li onclick="window.location='http://www.google.com';" style="cursor:pointer;">Google</li>
Now I have another <li> which goes to different websites depending on a parameter. I tried this
<script>
document.write('<li onclick="window.location='http://www.google.com/mmm/yyy/' + random_variable + 'ddd/eee';" style="cursor:pointer;">Google</li>');
</script>
This isn't working fine. What am I doing wrong?
You don't want to use document.write. Instead you can change the attributes of the tags themselves. onClick is just javascript inside your code so you can replace variables
<li onclick="location.href='http://www.google.com/mmm/yyy/' + random_variable + 'ddd/eee';">Google</li>
It's a little messy. I'd personally do it with jQuery and a regular <a> tag
Javascript/jQuery
$(document).ready(function() {
$('#someid').click(function(e) {
e.preventDefault()
location.href= 'http://google.com/' + random_variable;
});
});
Or if your random variable is available onload you could just replace the href attribute
$(document).ready(function() {
$('#someid').attr('href','http://google.com/' + random_variable);
});
HTML
<li>Google</li>
var targetElement = document.getElementById("id");
targetElement.appendChild('<li>...</li>';
The first line find the existing element, where you want to insert the <li>.
The second line insert it.

Adding tabindex dynamically

I'd like to add tabindex to all form elements. The form is dynamic and I can't add it to the HTML. I would like to run it as a function.
If there are several radio buttons with the same name, each must have it's own tabindex value. Most of the form elements on page start as <input>, except <select>. How do I account for that?
I guess I will need to run a loop and add the attribute, right?
var n = 1;
$('input, select').each(function() {
$(this).attr('tabindex', n++);
});
Strange question, but yes that's the basic idea:
$(":input:not(:hidden)").each(function (i) { $(this).attr('tabindex', i + 1); });
This uses :input to get everything including buttons and text areas. :not(:hidden) will just exclude the hidden inputs to avoid unnecessary tabs.
Might be better to avoid n++ to set different tabindex numbers.
Instead, try setting tabindex to 0:
$(':input:visible').each(function() {
$(this).attr('tabindex', '0');
});
tabindex="0" means that the element should be focusable in sequential keyboard navigation, but its order is defined by the document's source order.
~ developer.mozilla.org
The :input selector basically selects all form controls.
The :visible selector basically selects all elements that are visible.
or as suggested in the comments, if you have no other changes to apply to each visible input, then this should be enough:
$(':input:visible').attr('tabindex', '0');
Here, I described how can add aria-selected and tabindex value dynamically via jquery. I also want to see that how accessibility work with tablist, tab, and tabpanel role and how aria attributes work.Hope helps this code :
var $tabs = $('.tabs');
var $panels = $('.panel');
$tabs.on('click', 'a', function (e) {
e.preventDefault();
var id = $(this).attr('href');
// Find the currently visible tab and panel and hide them
$tabs.find('[aria-selected="true"]').attr({
'aria-selected': false,
'tabindex': -1
});
$(this).attr({
'aria-selected': true,
'tabindex': 0
});
});
Tab Wrapper:-
<ul class="tabs" role="tablist">
<li role="presentation">Tab 1</li>
<li role="presentation">Tab 2</li>
<li role="presentation">Tab 3</li>
</ul>
<div class="tab-panels">
<div class="panel" id="tab-1" role="tabpanel" aria-hidden="false">…</div>
<div class="panel" id="tab-2" role="tabpanel" aria-hidden="true">…</div>
<div class="panel" id="tab-3" role="tabpanel" aria-hidden="true">…</div>
</div>
One approach is to move an element higher in the DOM. The element at the top of the DOM tree will be focused first using Tabs as compared to lower ones.
For what's it's worth, I don't think you actually need to use an each loop here or even $(this).
jQuery is configured to execute functional arguments in place of plain values and runs the function once per loop, similarly to how an each loop would work.
You can read more on how that works in the official jQuery documentation here: .val( function )
So rather than using an each loop, you can accomplish the same effect using just this:
let n = 1;
$(':input:visible').attr('tabindex', function() { return n++; });
or if you're okay using the modern ES6 arrow function syntax—
let n = 1;
$(':input:visible').attr('tabindex', () => n++);
Using () => n++ instead of just n++ here allows jQuery to run the function for each instance's value rather than taking in the initial value of n++ and applying it to all matching elements.

mootools load content with function

I am using mootools and i want to load in a div (named response) content.
The div content i pass in javascript with $('response').set('html', content) where content is variable. in the content variable i have some html code with buttons and want to create a event handle ( click ).
the content I load with a json request and pass to the element:
<div id="undo">
<ul>
<li> <button value="1">foo</button> </li>
<li> <button value="2">bar</button> </li>
</ul>
</div>
my javascript looks like
$('undo').addEvents({
'click:relay(button)': function(ev, element){
alert('a button clicked!');
}
});
but I don't know why the event didn't work.
I think the problem is that $('undo') doesn't exist when the dom object is ready but i don't know how to fix this.
Delegate further up the dom tree to an element that is there at the time of domready block running. eg, if you have <div id=content>... </div> (or response if it's static)
document.id('content').addEvents({
'click:relay(#undo button)': function(event, element){
event.stop();
console.log(element.get('value'));
}
});
given that you inject your data there later on, this will work fine.