Dynamically changing a style in Polymer 2.0 - javascript

I'm writing a proof of concept Polymer 2.0 web component where I want to change the colour of a piece of text depending on the user input.
I've tried using Polymer 2.0's this.updateStyles({...}) and Polymer.updateStyles({...}) but neither is updating the text which is output.
e.g.
Polymer.updateStyles({'--tool-colour': 'green'});
I've written a plunker which demonstrates the problem here.
I'm probably missing something simple, can someone help me out?

I do it like this myself:
<template>
<style>
.green-icon {
color: var(--green-color);
}
.red-icon {
color: var(--red-color);
}
</style>
<my-element class$="[[computeIconColor(boolProp)]]"></my-element>
</template>
then in the script:
computeIconColor(boolProp) {
if (!!boolProp) return 'green-icon';
return 'red-icon';
}

The "problem" is as Jordan Running stated that your webcomponentsjs is not loading.
The real thing is that you can't use updateStyles without webcomponentsjs which is rather unfortunate as there are situations where you probably won't need it at all.
In this case you could do
this.setAttribute('style', '--tool-colour: red');
but then again this won't work in browsers needing webcomponentsjs.
what I ended up doing create an behavior that either uses setAttributes (with merging for styles) or updateStyles depending on what is available. It code looks like this.
if (!window.ShadyCSS || (window.ShadyCSS && window.ShadyCSS.nativeCss === true)) {
var newStyleString = '';
for (var key in newStyle) {
if (newStyle.hasOwnProperty(key)) {
newStyleString += key + ': ' + newStyle[key] + ';';
}
}
this.setAttribute('style', newStyleString);
} else {
ShadyCSS.styleSubtree(this, newStyle);
}
So for usage I just write this.updateStyles({'--tool-colour': 'green'}); as my behavior overwrites updateStyles.
The full code you can find here
https://github.com/daKmoR/grain-update-inline-style-behavior.
It's a little more as it also adds support for inline styles on IE11.

As Jordan Running commented, the problem was due to missing dependencies. I'd written code in an online editor (Plunker) assuming that all I needed to get polymer working was a reference to 'webcomponents-loader.js' and links to the other web components my bespoke component was using (doh!).
To get my Polymer element working I used the Polymer CLI facility provided by the Polymer team (specifically I used this for creating a Polymer element template project).
When I then used:
polymer serve
To run a local webserver to "serve" the app which was using my Polymer element, the dependencies then got resolved properly and the element worked.

Related

react external javascript integration

I'm tring to merge 2 projects i found:
https://github.com/danxfisher/MeetEasier
and
this page https://tympanus.net/Development/Interactive3DMallMap/
i've done the changes in the react project meeteasier and included the html parts from interactivemallmap(with my little react abd nodejs knowledge) . I have problems on calling the javascript from main.js(interactivemallmap).
Here is the problem:
The first time i load the page with the chromedev i see that in the main.js it gets the values but when i recall the functions that values are null:
original main.js start like this and dot work:
;(function(window) {
...
mall = document.querySelector('.mall'),
...
pins = [].slice.call(mallLevelsEl.querySelectorAll('.map__space')),
....
pins.forEach(function(pin) {
var contentItem = contentEl.querySelector('.content__item[data- space="' + pin.getAttribute('data-space') + '"]');
pin.addEventListener('mouseenter', function() {
//if( !isOpenContentArea ) {
classie.add(contentItem, 'content__item--hover');
//}
});
....
})(window);
i've tried with the $(document).ready(function(){ instead of ;(function(window) {
but it is not working or better: in the first page load the it gets its value, but after when i pass over with the mouse and the event mouseenter triggers all the values are undefined
I think this is not the right approach but how do i make it work?
I do not have enough code to fully understand what is going on, but seeing that you're trying to merge two big projects with different codebases, if I were you I should take it slow, and take some steps back.
Your problem:
The main problem is that, to use React, you should first have a fundemental understanding of what it is doing under the hood.
You're trying to implement jQuery (a DOM library) with React, however, this will not work this easily, because React works with something that's called a virtual DOM, and it does not have access to the regular DOM nodes unless specifically ordered to do so (using findDOMNode from the react-dom package handles this for example).
What you should do:
Please read the docs first:
https://reactjs.org/docs/hello-world.html
Then, after you understand React, try implementing the SVG maps in it, step by step.
Just a small insight:
Rendering SVG in your render method, or try rebuilding it with D3 (https://d3js.org/) for example, just a suggestion on how to handle complex SVG.
You should handle most logic that's from main.js in the componentDidMount lifecycle, assuming you're going to need to access the map nodes.

Custom Unobtrusive Validation Method Not Firing as Per Documentation

I've been attempting to implement a ASP.NET MVC custom validation method. Tutorials I've used such as codeproject explain that you add data-val-customname to the element. Then jQuery.validate.unobtrusive.js then uses the third segment of the attribute
data-val-<customname>
as the name of the rule, as shown below.
$.validator.addMethod('customname', function(value, element, param) {
//... return true or false
});
However I just can't get the customname method to fire. By playing around I have been able to get the below code to work, but according to all the sources I've read Unobtrusive validation should not work like this.
$.validator.addMethod('data-val-customname', function(value, element, param) {
//... return true or false
});
I've posted an example of both methods
jsfiddle example
Any help would be much appreciated
I've updated my question hopefully to make clearer.
I have finally found got there in the end, but still feels like too much hard work and therefore I've probably got something wrong. Initial I was scuppered by a bug in Chrome Canary 62 which refused to allow the adding of a custom method.
My next issue was having to load jQuery, jQuery.validate and jQuery.validate.unobtrusive in the markup and then isolate javascript implementation in a ES6 class. I didn't want to add my adaptors before $().ready() because of my class structure and loading of the app file independent of jQuery. So I had to force $.validator.unobtrusive.parse(document);.
Despite this I was still having issues and finally debugged the source code and found that an existing validator information that is attached to the form was not merging with the updated parsed rules, and essentially ignoring any new adaptors added.
My final work around and admit feels like I've done too much, was to destroy the initial validation information before my forced re-parse.
Here is the working jsfiddle demo
Here is some simplified code
onJQueryReady() {
let formValidator = $.data(document.querySelector('form'), "validator" );
formValidator.destroy();
$.validator.unobtrusive.adapters.add("telephone", [], function (options) {
options.rules['telephone'] = {};
options.messages['telephone'] = options.message;
});
$.validator.unobtrusive.parse(document);
$.validator.addMethod("telephone", this.handleValidateTelephoneNumber);
}

Vaadin 8 Html Imports Javascript

I am trying to use Vaadin 8 's "Html Import" feature
i followed instructions here : What's New In Vaadin 8
you can check it at 10th feature.
i am also sure that i installed both polymer-cli and bower.As GameCard creator mantioned at his own github.
But when run the application "the cards" are loading but not the way as it should.Mines have no flipping animation and kind a looks bad.
Screenshot :
Update After Gerald's Solution.
Finally Works with the Right Version of Polymer.
Seems to be a problem with the game-card element and the latest version of Polymer. I opened an issue on GitHub. Try with the version I used when I developed the demo. Find it here. Just replace your bower_components directory with the one in my demo.
initialize rank and symbol in different order (set rank first):
GameCard = function () {
var element = this.getElement();
this.setCard = function (symbol, rank) {
element.set("rank", rank);
element.set("symbol", symbol);
};
};

Setting up JSFiddle with CoffeeScript + React?

How can I set up JSFiddle to work with CoffeeScript and React?
I would like to code React examples using CoffeeScript and expect it to run.
I've tried setting the language to CoffeeScript on the left sidebar, and including the React libs, but that does not work.
Any pointers on how I could get Coffee+React to work with JSFiddle?
From <script src="https://facebook.github.io/react/js/jsfiddle-integration.js"></script>, which is included in the playground:
(function() {
var tag = document.querySelector(
'script[type="application/javascript;version=1.7"]'
);
if (!tag || tag.textContent.indexOf('window.onload=function(){') !== -1) {
alert('Bad JSFiddle configuration, please fork the original React JSFiddle');
}
tag.setAttribute('type', 'text/jsx;harmony=true');
tag.textContent = tag.textContent.replace(/^\/\/<!\[CDATA\[/, '');
})();
The reason is that you are using the playground with jsx, and as FB restricted the setting to JS 1.7 I guess they are using Babel to compile it down to js.
So if you use the non-jsx link, and change the syntax to Coffee and modify the JS/CS file, you are good to go.
Here is a working copy: https://jsfiddle.net/9gnkLgex/

Windows Phone App in JavaScript with AngularJS

I am developing a Windows Phone Application in JavaScript. I am using the AngularJS library. The problem is that I cannot add a dynamic content because of security reasons.
The error I get: HTML1701: Unable to add dynamic content '<div id="view_login" class="view"> <div id="view_login_container"> <img class="logo" src="http://oi60.tinypic.com/okwifa.jpg"> <input type="text" placeholder="Username" ng-model="loginUsername"> <input type="password" placeholder="******" ng-model="loginPassword"> <button ng-click="doLogin()">Login</button> <button ng-click="changeView('/signup')" class="link">... or sign up now</button> </div> </div>'. A script attempted to inject dynamic content, or elements previously modified dynamically, that might be unsafe. For example, using the innerHTML property to add script or malformed HTML will generate this exception. Use the toStaticHTML method to filter dynamic content, or explicitly create elements and attributes with a method such as createElement. For more information, see http://go.microsoft.com/fwlink/?LinkID=247104.
I changed one line in AngularJS library which should fix the problem:
append:function(a,c){
**MSApp.execUnsafeLocalFunction(function () {**
r(new N(c),function(c){
1!==a.nodeType&&11!==a.nodeType||a.appendChild(c)
})
});
}
Unfortunately it did not work.
I spent several hours trying to find a solution, but I did not manage it. I would appreciate any suggestions how to make working the Windows Phone App written in JavaScript with AngularJS.
Microsoft Open Technologies recently released a shim which will prevent this exact problem for Windows Store apps using AngularJS, as well as many other popular JavaScript libraries.
Simply download the JavaScript Dynamic Content shim off of GitHub, then reference the file towards the beginning of your app before any other scripts are run. You should no longer see a dynamic content error.
Let me know if this solves your problem!
I encountered this issue when using Angular in a Windows Store App. The solution I came up with was to monkey patch the DOM manipulation functions that were unsafe, rather than having to hack up Angular or jQuery because I still wanted to be able to update using bower.
var patch = {
methods: [
'appendNode',
'cloneNode',
'insertBefore',
'removeChild',
'replaceChild'
],
properties: [
'innerHTML',
'outerHTML'
]
};
patch.methods.forEach(function (name) {
proxyUnsafeMethod(HTMLElement.prototype, name);
});
patch.properties.forEach(function (name) {
proxyUnsafeProperty(HTMLElement.prototype, name);
});
function proxyUnsafeMethod(object, name) {
var _unsafe = object[name];
object[name] = function () {
var context = this;
var args = arguments;
return MSApp.execUnsafeLocalFunction(function () {
return _unsafe.apply(context, args);
});
};
}
function proxyUnsafeProperty(object, prop) {
var descriptor = Object.getOwnPropertyDescriptor(object, prop);
proxyUnsafeMethod(descriptor, 'set');
Object.defineProperty(object, prop, descriptor);
}
Angular dynamically puts HTML comment tags <!-- --> for ng-repeat and other directives. Unfortunately, Microsoft considers these to be unsafe when put in from javascript using element.innerHTML, and thus is not allowed.
The workaround is to modify the actual angular.js file and wrap all element.innerHTML calls in MSApp.execUnsafeLocalFunction();
In the version of Angular that I'm using, this is line 2539 and line 2162
Line 2539:
MSApp.execUnsafeLocalFunction(function() { element.innerHTML = value; });
Line 2162:
MSApp.execUnsafeLocalFunction(function() { div.innerHTML = '<div> </div>' + element });
The best method would be to search the angular.js file for all instances of innerHTML and wrap it.
In a lot of cases where you run into issues with dynamic content Winstore-jsContrib might help. Simply add the .js file at the beginning of your app and you're good to go.

Categories

Resources