Polymer-Data binding with DOM - polymer-1.0

I have a polymer component defined as below:
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="add-money">
<template>
<style></style>
<paper-dialog id="add-money-dialog" modal >
<h2>Add money</h2>
<paper-dialog-scrollable>
<div>
<span>{{account.name}}</span>
</div>
</paper-dialog-scrollable>
<div class="buttons">
<paper-button dialog-dismiss>Cancel</paper-button>
<paper-button dialog-confirm autofocus>Add</paper-button>
</div>
</paper-dialog>
</template>
<script>
var AddMoney = Polymer({
is: 'add-money',
properties: {
account: {
type: Object,
notify: true,
}
},
factoryImpl: function(acc) {
this.account=acc;
},
showPopup:function(){
console.log(JSON.stringify(this.account));
var dialog = document.getElementById("add-money-dialog");
if (dialog) {
dialog.open();
}
}
});
</script>
</dom-module>
Now, I instantiates it and add to body on click of a button from another component.
addMoney:function(e){
var button = e.target;
var dialog = new AddMoney(e.model.item);
document.body.appendChild(dialog);
dialog.showPopup();
}
While doing that, I am able to see that data available in showPopup method, but the same does not reflect on the DOM.
Curious, what could be the problem and what is the fix for it. I am a newbee to this and trying to write some component based code to understand polymer. Please advice on this. Thanks in advance.

It was infact an issue with the styles. I thought the value is not coming up since there was nothing displayed. But it was actually hidden and I could not see it. I added some styles ot the paper-dialog-scrollable and now I can see the values.

Related

How to implement mouse on-RightClick into list item of Material UI with ReactJS

I am developing React js app with Material UI.
I have implemented onClick in List and List Item.
enter image description here
I want to implement onRightClick event as well.
Please help me.
Use onContextMenu event where you want to show your default context menu, not browser context menu.
there is onContextMenu event in react defined events. if you want to change the rightClick action on your component or part of your component you need to write a custom eventHandler for onContextMenu event.
<div onContextMenu={this.someEvenetHandler}></div>
someEventHandler = (e) => {
"Do stuff here"
}
or something like that.
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react-dom.min.js"></script>
<html>
<head>
<title>Test</title>
</head>
<body>
<div id="app"></div>
<script type="text/jsx">
var App = React.createClass({
handleClick: function(e) {
if (e.type === 'click') {
console.log('Left click');
} else if (e.type === 'contextmenu') {
console.log('Right click');
}
},
render : function(){
return <p onClick={this.handleClick} onContextMenu={this.handleClick} >Something </p>
}
});
React.render(<App />, document.getElementById('app'));
</script>
</body>
</html>
Try running above snippet you will be able to identify left and right click respectively.
According to the react docs, onContextMenu is the correct prop to pass. To prevent the standard functionality, you probably need to add e.preventDefault(); to your callback function.

attaching template content from within a polymer element

I am trying to have certain content of a polymer element procedurally added, at a time later than its creation. I am trying to avoid a <template is="dom-if"> element.
Instead I am trying to have a nested <template> element inside the polymer element's template and have its content attached on the execution of a method, like so:
<dom-module id="simple-element">
<template>
<content id="content"></content>
<div id="display">display</div>
<template id="t">
template content
<script>console.log("template added!")</script>
</template>
</template>
<script>
var simpleElement = {
is: "simple-element",
attached : function(){
this.init();
},
init : function(){
var t = document.importNode(this.$.t.content,true);
this.$.display.appendChild(t);
},
}
Polymer(simpleElement);
</script>
</dom-module>
See it also in this jsbin http://jsbin.com/zudituvuli/edit?html,js,console,output
Is there a way to accomplish this?

polymer 1.0 select element in dom-if template

I am having what seems to be a common issue with Polymer 1.0: accessing nodes inside a dom-if template, but none of the proposed solutions seem to work in my case (?!)..
Here is a simple example:
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="my-test">
<template>
<div>
<template is="dom-if" if="{{show}}" id="tplId">
<p id="message">hello</p>
</template>
</div>
<a on-tap="tapEvent">click me!</a>
</template>
<script>
(function() {
'use strict';
Polymer({
is: 'my-test',
show: false,
ready: function() {
},
tapEvent: function() {
// show the template
this.show = true;
// How may I access #message since the template is inhert ?
// this finds the template by id
console.log(Polymer.dom(tplId));
// this won't find the #message element inside it
console.log(Polymer.dom(tplId).querySelector('#message'))
// this neither
console.log(Polymer.dom(this.root).querySelector('#message'))
// this neither
console.log(Polymer.dom(this).querySelector('#message'))
// this neither .. Should I even be using this.shadowRoot in 1.0?
console.log(Polymer.dom(this.shadowRoot).querySelector('#message'))
// this neither
console.log(this.$$('#message'))
// this cannot work because #message is not a statically created DOM element
console.log(this.$.message)
}
});
})();
</script>
</dom-module>
I'm new to Polymer, and I feel the solution might be right under my nose..?
If this
// this neither
console.log(this.$$('#message'))
doesn't work then you probably try to query the element while it doesn't exist. When show is false the <p id="message"> element doesn't exist at all. If you need this then bind to hidden instead of using dom-if
<p id="message" hidden$="{{show}}">hello</p>
then
console.log(this.$.message);
will work as well.

Kendo UI and angular - no widget in $scope

I'm using Kendo UI version 2014.2.716 with AngularJS version 1.2.27, and I made a grid using a directive
<div ng-controller="MyController as ctrl">
<div id="myGrid" kendo-grid k-options="{some options}"></div>
<button ng-click="ctrl.doSomething()"></div>
</div>
I read that if you give a name to the grid (like this: kendo-grid="myGridOnScope"), you can access the widget in the controller scope in this way:
myModule.controller('MyController', function($scope) {
this.doSomething = function() {
console.log($scope.myGridOnScope);
}
}
The console.log should log a widget object, but in my case it's undefined. What am I doing wrong? Thanks for the help
I have found out the problem myself, so I'm going to post an answer if someone has the same problem. If you use the controllerAs syntax in AngularJS, you can't just write the name of the widget - you have to prefix it with your controller alias.
Take a look at this example:
<div ng-controller="MyController as ctrl">
<div kendo-grid="myGridName"></div>
</div>
This will not give you the grid object on the $scope - for that you need to add the ctrl prefix:
<div ng-controller="MyController as ctrl">
<div kendo-grid="ctrl.myGridName"></div>
</div>
Now you have access to the widget in your controller like this:
angular.module('MyModule',['kendo.directives'])
.controller('MyController', function($scope){
// this gives you the widget object
console.log(this.myGridName);
// however, this doesn't work
console.log($scope.myGridName);
});
I hope I helped someone with this post.
Cheers,
Try waiting for the event that Kendo emits.
Html
<div kendo-grid="grid" options="gridOptions"></div>
Javascript
$scope.$on("kendoWidgetCreated", function(event, widget){
if (widget === $scope.grid) {
console.log($scope.grid);
}
});
Edit: See this Plunker
It is because angular is too fast and the kendo element doesn't exist when you try to set the options.
I solved this with a watch.
This is my html code:
<div kendo-grid="ListDesign"></div>
And this is my angular code
$scope.$watch('ListDesign', function () {
if ($scope.ListDesign != undefined) {
var gridOptions = {
columns: columns,
sortable: {
mode: 'multiple',
allowUnsort: true
}
};
$scope.ListDesign.setOptions(gridOptions);
$scope.ListDesign.setDataSource(dataSource);
}
});
Does this answer your question?

Hide element outside the ng-view DOM based on route

Question:
How can I add a "Login" view/route to my angular app that hides an element that is outside the ng-view DOM?
Situation:
In my Angular page, I have a navigation tree view on the left and the main view in the center:
<div ng-app="myApp">
<div class="col-sm-3" ng-controller="TreeController">
<div treeviewdirective-here>
</div>
</div>
<div class="col-sm-9 content" ng-view="">
</div>
</div>
Each node in the treeview changes the location using something like window.location.hash = '#/' + routeForTheClickedItem;.
Using the standard routing, this works great, i.e. the tree is not reloaded each time, but only the main "window".
Problem:
I want to add a login functionality with a login view. For this view, the treeview should not be visible - only after the login. To achieve this with the normal routing, I know I could move the ng-view one level up, i.e. embed the treeview into each view - but this would result in the treeview being reloaded with every route change.
Is there an easy alternative that allows me to check what page is displayed in the ng-view? Or check some other variable set during the routing? Then I could use something like:
<div class="col-sm-3" ng-controller="TreeController" ng-show="IsUserLoggedIn">
You could listen for a routeChangeSuccess outside ng-view
$scope.$on('$routeChangeSuccess', function (event, currentRoute, previousRoute) {
//do something here
});
hope that helps, you can catch me on angularjs IRC - maurycyg
You could define a controller at the top div level.
Something like:
<div ng-app="myApp" ng-controller="MainController">
and in MainController inject a Session. Something like Session is enough to decide whether to show the tree.
Here's an example of MainController:
_app.controller('MainController', function ($scope, SessionService) {
$scope.user = SessionService.getUser();
});
Here's an example of SessionService:
_app.factory('SessionService', function() {
var user = null;
return {
getUser : function() {
return user;
},
setUser : function(newUser) {
user= newUser;
}
};
});
Of course, when you login you must set the user to the SessionService. Therefore, a SessionService has to be injected into your LoginController, too.
And finally, your html:
<div ng-app="myApp" ng-controller="MainController">
<div class="col-sm-3" ng-controller="TreeController">
<div ng-hide="user == null" treeviewdirective-here>
</div>
</div>
<div class="col-sm-9 content" ng-view="">
</div>
</div>

Resources