Set selected of Paper-Tabs - dart

I am trying to select a paper-tab based on it's data-id attribute. I have the element but I cannot changed to selected property of the inner_tabview.
I have a Polymer:
<paper-tabs id="inner_tabview" noink="true">
<template repeat="{{item in tabNames}}">
<paper-tab data-id="{{item['id']}}"><h3>{{item['name']}}</h3></paper-tab>
</template>
</paper-tabs>
And some Dart code behind it:
selectTab(itemId) {
PaperTab item = shadowRoot.querySelector("paper-tab[data-id='" + itemId + "']");
print('Selecting: ' + itemId + ', text:' + item.text);
PaperTabs tabView = shadowRoot.querySelector('#inner_tabview');
tabView.selected = item; // This doesn't work
}
Changing the selected using an integer (index) works, but I don't know what the index should be.
Only thing I can currently think of is finding all paper-tab elements and get the index of the correct element in that List. But that sounds a bit silly to do so.
Any other way?

I don't know why querySelector doesn't work but selected expects an index by default not an element.
if you specify the valueattr attribute you can use other attributes than the index.
<paper-tabs id="inner_tabview" noink="true" valueattr="data-id">
<template repeat="{{item in tabNames}}">
<paper-tab data-id="{{item['id']}}"><h3>{{item['name']}}</h3></paper-tab>
</template>
</paper-tabs>
then
tabView.selected = itemId;
should work as well

Related

Free Text Entry in Angular Material mdAutoComplete

I want my angular material autocomplete to be a list of suggestions but not requirements. However I'm not sure how to implement as their is no clear example from the Angular Material docs.
In the example below my model is $ctrl.item.category
Clearly the example below is wrong, as my model is linked to md-selected-item, but this only works if I select an item. I want the user to be able to free enter the text if the item is not in the list. Basically how autocomplete already works in most browsers.
I see plenty of questions on how to disable this, but they are not trying to disable so much as clean up the left over text when an item is not selected. In these cases when an item is not selected then the model value is null, but text is left in the input.
I want the text left int he input to be the model value if the person does not select (or a match is not made).
md-autocomplete(
md-floating-label="Category Name"
flex="50"
md-input-name="category"
md-selected-item="$ctrl.item.category"
md-search-text="catSearch"
md-items="category in $ctrl.categories"
md-item-text="category"
md-min-length="0"
md-select-on-match=""
md-match-case-insensitive=""
required=""
)
md-item-template
span(md-highlight-text="catSearch" md-highlight-flags="^i") {{category}}
My options ($ctrl.categories) is an array of strings ['Food','Liqour'] and I wan the user to be able to use one of those or free enter Tables as their choice.
In this case you should link md-search-text to your model.
If you want to implement fuzzy search you have to write the filter method yourself. Look at this example:
template:
<md-autocomplete
md-items="item in $ctrl.itemsFilter()"
md-item-text="item.label"
md-search-text="$ctrl.query"
md-selected-item="$ctrl.selected"
>
<md-item-template>
<span md-highlight-text="$ctrl.query">{{item.label}}</span>
</md-item-template>
<md-not-found>
No item matching "{{$ctrl.query}}" were found.
</md-not-found>
<div ng-messages="$ctrl.myValidator($ctrl.query)">
<div ng-message="short">Min 2 characters</div>
<div ng-message="required">Required value</div>
</div>
</md-autocomplete>
controller:
var items = [ ... ];
ctrl.itemsFilter = function itemsFilter() {
return ctrl.query ? filterMyItems(ctrl.query) : items;
};
ctrl.myValidator = function (value) {
return {
short: value && value.length < 2,
required : value && value.length < 1,
};
};
then you just need to add filterMyItems method to filter your items
To improve the answer of #masitko, I have implemented the filter in a way, that it adds the query to the filtered list. So it becomes selectable and a valid option. So it's possible to make the autocomplete a suggestion box.
I'm using ES6 in my projects. But it should be easily adaptable to ES5 code.
myFilter() {
if (!this.query) return this.items;
const
query = this.query.toLowerCase(),
// filter items where the query is a substing
filtered = this.items.filter(item => {
if (!item) return false;
return item.toLowerCase().includes(query);
});
// add search query to filtered list, to make it selectable
// (only if no exact match).
if (filtered.length !== 1 || filtered[0].toLowerCase() !== query) {
filtered.push(this.query);
}
return filtered;
}

Jsoup returns wrong ChildNode

I would Like to parse the Metadata to a Book. Whild trying to retrieve the Booktitle, I noticed I can't access the ChildNodes from an Element that contains a TextNode. Here is my Data:
<div id="detail_content_wrapper">
<h1>
MyBookTitle 22<br>
<span class="sub">
subtext
Book 22
by Foo Bar
</span>
</h1>
I retrieve the Elements within "detail_content_wrapper" using:
Document parsedObject = Jsoup.parse(source);
Element bookNotes = parsedObject.getElementById("detail_content_wrapper");
Element h1Element = bookNotes.getElementsByTag("h1").first()
This will give me the complete content inside the h1-Tag.
When I take a look at the h1-Element ChildNodes, the first Childnode is a TextNode that holds the BookName. BUT when I try to get the Content of the First Child...
Element bookName = h1Element.children().first();
OR Element bookName = h1Element.childNode(0);
...This will, in both cases, contain the 2nd node which is the br-Element.
Is this a bug or am I using Jsoup wrong?

AngularJS and jqueryUI apply new index of list elements

I'm currently finishing a feature with list reordering and I'm stuck with a probably very simple thing, but I'm really sorry that I can't figure out how to solve it .... ( possibly my brain just ignores this logic :) )
The purpose is simple :
I have a list of items with a "position" data (different from $index).
I drag and drop items to change their order.
When the drag stops, all items in the list should have a new position, that'll be updated with a $resource object.
For example, after dragging I have this:
$index elem.position
0 2
1 1
2 3
should automatically change position 2->1, 1->2 and 3->3.
The problem :
With angularUI I can have the current item index but not the others in the list. So I can't change the whole list index after stopping the drag. And it's frustrating because on view, I can catch easily $index but not in controller.
Code :
in controller.js
$scope.updateSortable = {
stop: function(e, ui) {
for (var i=0; i<$scope.list.length; i++) {
var elem = $scope.list[i];
// here's don't know how to update elem.position
//elem.position = ui.item.index; // bad one, I know :)
//elem.$update();
}
},
placeholder: "xp-hightlight",
axis: 'y'
};
in html page :
<div ng-repeat="el in list">
<div>
<span class="position" ng-bind="el.position"></span>
</div>
</div>
The json items look like that :
{ id: 47, description: "my text in the list", position: 1}
Would this work for you, or do you have to have the position variable set?
<div ng-repeat="el in list">
<div>
<span class="position">{{$index + 1}}</span>
</div>
</div>
I added this to your controller 'testCtrl'. You can update the position element within the callback of this watch:
var _list;
$scope.$watch(function() {
return JSON.stringify($scope.items)
},function(_l) {
if(typeof _l !== 'undefined') {
_list = JSON.parse(_l);
console.log(_list)
}
});
I just solved the issue, and thanks to koolunix I managed the update of position directly inside the controller with this plunkr :
http://plnkr.co/edit/kDkNLSjoHbnaumk2uaOF?p=preview
The main fact was just to manage the position with the loop in list items.
elem.position=i+1;

Retrieving g:select value from within gsp - No form

How does one pass the value of the g:select box in a link action:
<g:select name="sel.n" from="${personList}" value="" />
<g:link action="addValue" params="${[personID: personInstance.id, selectionVal: sel.n.value]}">Add</g:link>
How do I retrieve the value of the selection box sel.n to pass in that action link?
This is NOT a form.
You'll want to use jQuery for something like this. Below is a sample that should get you started down the right path.
var val = "";
$('#sel\\.n').change(function() {
val = $(this).text();
 $("a").attr('href', function(i, h) {
      return h + (h.indexOf('?') != -1 ? "&" : "?") + "selectValue="+val;
});
});
The above code will catch when the select box changes and then alters the query string of the href link. If your unfamiliar with jQuery you'll need to run through some basics it's an essential tool for things like this. Good luck and enjoy!

Display index of list item using jQuery

I have an unordered list like so:
<ul class="foo">
<li id="asdf">
<span class="indexnumber"></span>
<span class="description">whatever</span>
</li>
<li id="asdfasdf">
<span class="indexnumber"></span>
<span class="description">whatever</span>
</li>
</ul>
I want to display the index number of the list item in the indexnumber span (i.e., the first item will display 1, the second will display 2, and so on). My users will have the ability to sort the list items (using jquery ui sortable). I would like to be able to show my users a number in the list item that indicates where the list item is (and the value can change as the user re-orders the list).
How can I simply display the index position in the array using jquery? Alternately, is there an easy way to do this with the sortable events (i.e., once the list is sorted, increment or decrement the indexnumbers in all other list items as appropriate)?
I guess you could add the DOM elements to an array using something like
var arr = jQuery.makeArray(document.getElementsByTagName("span"));
Then get their index using jQuery.inArray( value, array ) which returns an int.
Not very pretty though
I ended up doing the following:
$(function() {
$(".foo").sortable({
stop: function(event, ui) {
var itemID = $(ui.item).attr("id");
var items = $("li#" + itemID).parent(".foo").children();
var updateditems = new Array();
for (var i = 0; i <= items.length - 1; i++) {
var singleitemID = $(items[i]).attr("id");
var loc = i + 1;
$("#" + singleitemID).text(loc);
updateditems.push([singleitemID, loc]);
}
}
});
});
index_list = function() {
$(".foo li").each(function(i){
$(this).find(".indexNumber").html((i+1));
});
}
you can call this function on document ready and on the change attribute of the sortable object

Resources