Iron-list not update after element property changed - polymer-1.0

I'm having problems re-rendering an iron-list after changing an item property.
I need iron-list to re-render to apply new classes just like it does when i push or splice items.
Already tried almost everything(notifyPath, resize, _update, ...) but still doesn't make it work.
Please help :)
Below you can find an jsfiddle to ilustrate:
work OK:
this.set('words.'+i+'.checked', true);
NOT work:
this.notifyPath('words.'+i+'.checked');
http://jsfiddle.net/s6f029j3/23/

I looked at your jsfiddle and made some changes. Try it now and see if this is what you were looking to do.
jsfiddle
I made changes to the function on the paper-list to have it see if it had been checked there, rather than in the actual function.
<iron-list id="list" items="{{words}}">
<template>
<paper-item class$='[[_computedClass(item.checked)]]'>
<div>Item: [[item.name]] checked: [[item.checked]]</div>
</paper-item>
</template>
</iron-list>
and in the function, here's what I did:
_computedClass: function(e) {
//WHY IT DOES NOT RE-RENDER AFTER CLICK????
return (e) ? 'stuff_checked' : 'stuff_notchecked';
},
By just removing the .checked it now works as intended.

Related

Add Eventlistener dynamically on vaadin combobox in Polymer Datatable

I try to listen on changes made in a vaadin combobox (value) inside an iron-data-table.
This is my complete Datatable:
<iron-data-table id="grid4" items="[[riskCombined]]" selection-enabled on-selected-items-changed="_selected" >
<data-table-column name="#" width="20px" flex="0">
<template>
<div class="index">[[item]]</div>
</template>
</data-table-column>
<data-table-column name="Risk" width="140px" flex="0">
<template>[[item.name]]</template>
</data-table-column>
<data-table-column name="State" width="100px" flex="0">
<template><vaadin-combo-box value=[[item.state]] items=[[item.settings]] on-value-change="valueChanged" id=combobox[[index]]> </vaadin-combo-box></template>
</data-table-column>
</iron-data-table>
I want to listen on value changes:
<data-table-column name="State" width="100px" flex="0">
<template>
<vaadin-combo-box value=[[item.state]] items=[[item.settings]] on-value- change="valueChanged" id=combobox[[index]]> </vaadin-combo-box>
</template>
</data-table-column>
I'm adding an eventlistener:
<script>
var combobox = document.querySelector('vaadin-combo-box');
combobox.addEventListener('value-changed', function(event) {
console.log(event.detail.value);
});
combobox.addEventListener('selected-item-changed', function(event) {
console.log(event.detail.value);
});
</script>
also tried with:
document.getElementById(...)
The problem is that the Eventlistener is just added to the first combobox. But since there are multiple boxes dynamically created, this doesn't work. How can I dynamically add the Eventlistener to multiple comboboxes? Or is there an other solution?
Edit: tried this:
valueChanged: function(event) {
console.log(event.detail.value);
}
Edit 2:
changed
on-value-change="valueChanged"
to
on-value-changed="valueChanged"
Now edit1 is working! But its firing already when the page loads the first time an sets the values of the combobox...
The correct way is to use the on-value-changed (notice the changeD) attribute inside the template. Using querySelector is unreliable since there might be new elements being added later on the the table is scrolled.
Because the elements are being recycled and reused, there's a new value being bound to the <vaadin-combo-box> elements when scrolling – hence firing value-changed events everytime a row is recycled.
Assuming you want the user to be able to change the item.state property, I suggest you instead bound that property two-way with value="{{item.state}}" and add a listener for the event item-changed.
See my example here: http://jsbin.com/heroqu/edit?html,console,output
The item-changed seems to be fired always twice, but it should still be OK to use.
Vaadin-combo-box already fires value-changed event when value changes. You can listen to value-changes event instead of creating your own event. Here's the documentation for vaadin-combo-box.
listeners:{'value-changed':'valueChanged'},
valueChanged:function(e){
//code goes here
}

Update Material Lite checkbox with Angular 2

I am trying to use Material Design Lite in Angular 2 and have trouble updating checkboxes after the state has changed. See the following Plunker example.
When the user clicks on "All" to select all boxes, only the normal checkboxes update. I have tried using componentHandler.upgradeDom() and componentHandler.upgradeAllRegistered() but it made no difference.
How can I get the data-binding to work?
Ok, so I had a similar problem like you, and after good 2 or 3 hours of Googling around, I came up with a solution (or maybe it's just a dirty hack, don't know):
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" [class.is-checked]="isChecked()">
<input type="checkbox" [(ngModel)]="checkbox.Checked" class="mdl-checkbox__input">
<span class="mdl-checkbox__label">A label</span>
</label>
I've updated the plunk you've shared so you can see it there. I hope this solves your problem, as it have solved mine.
After reading the MDL code, it seemed to me that the appearance of the MDL checkbox only changes when it sees the onchange event. But just setting "checked" in code doesn't deliver the changed event. So, after I set it, I give it a poke.
function setChecked(element, bool) {
element.checked = bool;
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
element.dispatchEvent(evt);
}
Now, I'm not saying this is the RIGHT or BEST way to do this, but it works for me.

Using contenteditable with ng-model inside ng-repeat?

Here is my issue:
I am using ng-repeat to make a list of spans.
Each span has the contenteditable attribute and ng-model directive.
Everything works as expected (including two-way data binding), until I try to add a new item to the list.
<div ng-repeat="item in list">
<span ng-model="item.text" contenteditable></span>
</div>
<button ng-click="addItemToList"></button>
The methods look like this:
$scope.addItemToList = function () {
$scope.list.push({text: 'dummy text'});
}
or
$scope.addItemToList = function () {
$scope.list.splice(1, 0, {text: 'dummy text'});
}
When adding the new item to the list (push or splice), the DOM updates, but the last item is initialised empty, with no text whatsoever. The last item in the model list also empties out, even if I specifically push an element with text in it.
After a few tests, I've noticed that this only happens if the list's length is bigger after modifying it:
if I try to replace/modify/remove (not add) an element in the list, it works well.
I believe this has to do with the way contenteditable elements initialise in the DOM (I think they initialise empty, and somehow, the model empties out as well).
Has anyone encountered this problem before? If yes, how did you solve it / what workaround have you found?
Based on the angular docs related to ngModelController, it seems that there is not built-in support for two-way data binding with contenteditable elements, seeing as in the plunkr example they wrote their own contenteditable directive. You might be able to use a modified version of that as a workaround.
It looks to be a similar problem as this question and the contenteditable directive there looks similar to the contenteditable directive in the angular docs example.
I also found this directive on github that might accomplish what you are trying to do.
Edit: I did a new version of the plunk I posted in the comment above:
https://plnkr.co/edit/v3elswolP9AgWHDIPwCk
In this version I added a contenteditable directive that appears to be working correctly. It is basically a spin off of how the input[type=text] directive is written in angular, but I took out the places where it handles different types of input (since in this case it will just be text) and the places where it handles events that contenteditable elements don't even fire. I also changed it so that the $viewValue gets updated based on element.html() instead of element.val(). You might be able to use something like this as a workaround
The issue is old but that was the same problem for me today. (angular 1.5). My workaround was to add on blur update option: <td contenteditable data-ng-model="position.value" ng-model-options="{updateOn: 'blur'}"></td> somehow then model stopped getting be empty on initialize. I like using update on blur in many places (solves some performaces issues) so this is good for me, however it's some kind of trick.

How to remove draggability from an element with Ext JS?

I have a div that I want to make draggable or not, depending on the state of some other stuff on my page. I seem to be able to easily make it draggable, but I can't seem to figure out how to best remove the draggability from the div.
I am making it draggable with:
var dd = Ext.create('Ext.dd.DDProxy', mydiv, 'myDDGroup', { isTarget: false });
And I've tried to then remove the draggability by removing the only group it's a member of
dd.removeFromGroup('myDDGroup');
and just destroying the dd object with
delete dd;
Neither of these seem to actually keep me from starting a drag on the element. I suspect I should be able to use the b4Drag override in some way to simply cancel a drag of my div before it even begins, rather than toggling the draggable state of the div at all, but I can't seem to find docs on how I might cancel the drag during the b4Drag call.
So, how can I make a div undraggable after I have already made it draggable?
Seems to be working for me.
Here is the JSFiddle http://jsfiddle.net/01gx33h0/
var dd = Ext.create('Ext.dd.DDProxy', 'test123', 'myDDGroup', { isTarget: false });
Ext.fly('btn123').on('click', function() {
dd.removeFromGroup('myDDGroup');
});
Can you give me the sample code where it is not working. And what version of ExtJs are using?
You have to unreg. Not removeFromGroup.
It just removes from group. But events are not removed on that element.
dd.unreg();
https://fiddle.sencha.com/#fiddle/1eun
When looking at something specific that needs to be dragged, you might consider that allowing dragging is something users expect, for general ease of use you might try the ondragstart="return, this could be appended to your images, or links like so:
<a ondragstart="return false" href="#link">link</a>.

jquery checkbox attr change seems not to work

Does anyone have any idea why this code seems not to work?
What am I doing wrong?
JQuery 1.5.1 is used.
JS code:
$('#search_filters #discipline a').click(function(){
var checkbox = $(this).next(':checkbox');
if (checkbox.attr('checked')) {
checkbox.attr("checked", true);
} else {
checkbox.attr("checked", false);
}
$(this).children('img').toggleClass("active");
return false;
});
HTML:
<li>
<a href="#">
<img class="inactive" alt="Football" src="/images/disciplines/e9bc7681813110c/thumb.png">
</a>
<input type="checkbox" name="search_discipline[7]" value="1" class="search_discipline">
</li>
I just ran into this myself. It seems in jQuery 1.5.1 and 1.5.2 setting the checked attribute is a bit buggy. I had better luck with $(':checkbox').val(boolean) (which is even a bit easier).
Update: after some digging, it seems the webkit inspector doesn't actually show the checked attribute in the DOM, but jQuery reads/writes it properly. Very odd. Serves me right for using the nightly webkit builds for dev.
The value of a "checked" attribute should be "checked":
if (checkbox.is(':checked'))
{
checkbox.attr("checked", "checked");
} else {
checkbox.removeAttr("checked");
}
Just two helpful ideas to check the change for attributes:
Write the plain HTML first, without Javascript. Did it work? If so, then write it with JS
If you had modified an html tag recall the attribute itself, so you can check that your code had been executed well. E. g. alert($({your target object}).attr({the attribute which added}));
That's what I do in the most cases.
Some pointers:
$('#search_filters #discipline a') will be selecting all a elements that descend from #discipline that descend from #search_filters. Is this what you indend?
Are you remembering that .next() returns a sibling.
What happens if you remove the href='#'?
Does your click event even fire?

Resources