Polymer 1.0 : split index.html - polymer-1.0

I want to split my index.html file as it's too long(more than 500 lines) due to many submenus like the one below.
<paper-submenu>
<paper-item class="menu-trigger">
<iron-icon icon="add-circle-outline"></iron-icon>
<span>Medical</span>
</paper-item>
<paper-menu class="menu-content">
<a data-route="medical" href="/medical">
<paper-item>
<span>Introduction</span>
</paper-item>
</a>
Is it possible to store all the submenu lines in the index.html into another file?
Thank you in advance.

<link rel="import" href="../../bower_components/polymer/polymer.html">
<!-- Make sure to add other dependencies here -->
<dom-module id="test-comp">
<template>
<paper-submenu>
<paper-item class="menu-trigger">
<iron-icon icon="add-circle-outline"></iron-icon>
<span>{{title}}</span>
</paper-item>
<paper-menu class="menu-content">
<a data-route="{{dataRoute}}" href="{{href}}">
<paper-item>
<span>{{item}}</span>
</paper-item>
</a></paper-menu>
</paper-submenu>
</template>
<script>
(function() {
'use strict';
Polymer({
is: 'test-comp',
properties: {
title: {},
dataRoute: {},
href: {},
item: {},
},
});
})();
</script>
</dom-module>
Now insert the element like so
<test-comp title="Medical" data-route="medical" href="/medical" item="Introduction"></test-comp>
Edit: The styles that affect your index.html will not affect your custom component. Add styles INSIDE your custom component to have them included

Related

Add custom fields but avoid angularjs formly wrapper when render form

I created two angularjs formly custom field with custom template.
formlyConfig.setType({
name: '
wrapper-init',
template:
''
});
formlyConfig.setType({
name: 'wrapper-end',
template: '</div>'
});
What I want is use them for Wrap other Angularjs formly field between this two custom fields so We can group and separate groups of fields visually by wrapping them in layers that will be given appearance with css.
But Angularjs formly render all custom field with extra div and even close my no closed tag in my custom template fields.
This is what a need to render formly:
<div class="tag-wrapper-init">
...... some AngularJs formly fields like inputs and textareas ....
</div>
How can I create custom fields in AngularJs formly so I avoid Formly Wrap them with a
<div formly-field="" ...
Is this possible?
I have tried to make clear the idea of what I need but if I have not done well or it is not understood, comment on it to improve it but please need help on this.
Hi bellow is the example
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 20px
}
.formly-field {
margin-bottom: 16px;
}
</style>
<!-- Twitter bootstrap -->
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet">
<!-- apiCheck is used by formly to validate its api -->
<script src="//npmcdn.com/api-check#latest/dist/api-check.js"></script>
<!-- This is the latest version of angular (at the time this template was created) -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>
<!-- This is the latest version of formly core. -->
<script src="//npmcdn.com/angular-formly#latest/dist/formly.js"></script>
<!-- This is the latest version of formly bootstrap templates -->
<script src="//npmcdn.com/angular-formly-templates-bootstrap#latest/dist/angular-formly-templates-bootstrap.js"></script>
<!-- bring in angular-xeditable -->
<link href="https://rawgit.com/vitalets/angular-xeditable/master/dist/css/xeditable.css" rel="stylesheet">
<script src="https://rawgit.com/vitalets/angular-xeditable/master/dist/js/xeditable.js"></script>
<title>Angular Formly Example</title>
</head>
<body ng-app="formlyExample" ng-controller="MainCtrl as vm">
<div>
<h1>angular-formly example: {{vm.exampleTitle}}</h1>
<div>
This example shows how you integrate angular-formly with angular-xeditable.
angular-xeditable does some interesting things with the forms, so there's a little bit of extra work you need to do.
</div>
<hr />
<form novalidate>
<formly-form model="vm.model" fields="vm.fields" options="vm.options" form="vm.form" editable-form onaftersave="vm.onSubmit()" root-el="form">
<!-- button to show form -->
<button type="button" class="btn btn-default" ng-click="vm.form.$show()" ng-show="!vm.form.$visible">
Edit
</button>
<!-- buttons to submit / cancel form -->
<span ng-show="vm.form.$visible">
<button type="submit" class="btn btn-primary" ng-disabled="vm.form.$waiting">
Save
</button>
<button type="button" class="btn btn-default" ng-disabled="vm.form.$waiting" ng-click="vm.form.$cancel()">
Cancel
</button>
</span>
</formly-form>
</form>
<hr />
<h2>Model Value</h2>
<pre>{{vm.model | json}}</pre>
<h2>Fields <small>(note, functions are not shown)</small></h2>
<pre>{{vm.originalFields | json}}</pre>
</div>
<div style="margin-top:30px">
<small>
This is an example for the
angular-formly
project made with ♥ by
<strong>
<span ng-if="!vm.author.name || !vm.author.url">
{{vm.author.name || 'anonymous'}}
</span>
<a ng-if="vm.author.url" ng-href="{{::vm.author.url}}">
{{vm.author.name}}
</a>
</strong>
<br />
This example is running angular version "{{vm.env.angularVersion}}" and formly version "{{vm.env.formlyVersion}}"
</small>
</div>
<!-- Put custom templates here -->
<script>
(function () {
'use strict';
var app = angular.module('formlyExample', ['formly', 'formlyBootstrap', 'xeditable']);
app.run(function (editableOptions, formlyConfig) {
editableOptions.theme = 'bs3';
formlyConfig.setType({
extends: 'input',
template: '<div><span editable-text="model[options.key]" e-name="{{::id}}">{{ model[options.key] || "empty" }}</span></div>',
name: 'editableInput'
});
});
app.controller('MainCtrl', function MainCtrl(formlyVersion) {
var vm = this;
// funcation assignment
vm.onSubmit = onSubmit;
// variable assignment
vm.author = { // optionally fill in your info below :-)
name: 'Kent C. Dodds',
url: 'https://twitter.com/kentcdodds'
};
vm.exampleTitle = 'angular-xeditable integration'; // add this
vm.env = {
angularVersion: angular.version.full,
formlyVersion: formlyVersion
};
vm.model = { text: 'This is editable!' };
vm.options = {};
vm.fields = [
{
key: 'text',
type: 'editableInput',
templateOptions: {
label: 'Text'
}
}
];
vm.originalFields = angular.copy(vm.fields);
// function definition
function onSubmit() {
debugger;
vm.options.updateInitialValue();
alert(JSON.stringify(vm.model), null, 2);
}
});
})();
</script>
</body>
</html>

How to navigate from tab to different Page and viceversa in angularJS?

If i am having One page with 2 tabs. and if from 2nd tab i am navigating to different page. then how to come back to that 2nd tab from navigated page? i am using $StateProvider.
Thanks.
Here is the example code and it works well,
index.html
----------------
<html>
<head>
<title>Tabs Directive</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0-rc.0/angular.min.js"></script>
<script src="tabController.js"></script>
</head>
<body>
<div class="container">
<section ng-app="myApp" ng-controller="TabController as tab">
<ul class="nav nav-pills">
<li ng-class="{active:tab.isSet(1)}"><a href ng-click="tab.setTab(1)">Tab 1</a></li>
<li ng-class="{active:tab.isSet(2)}"><a href ng-click="tab.setTab(2)">Tab 2</a></li>
<li ng-class="{active:tab.isSet(3)}"><a href ng-click="tab.setTab(3)">Tab 3</a></li>
</ul>
<div ng-show="tab.isSet(1)">
<h4>Tab 1</h4>
</div>
<div ng-show="tab.isSet(2)">
<h4>Tab 2</h4>
</div>
<div ng-show="tab.isSet(3)">
<h4>Tab 3</h4>
</div>
</section>
</div>
</body>
</html>
tabController.js
----------------
var app = angular.module('myApp', []);
app.controller('TabController', function () {
this.tab = 1;
this.setTab = function (tabId) {
this.tab = tabId;
};
this.isSet = function (tabId) {
return this.tab === tabId;
};
});
Thanks Atul :)
but this solution worked for me.
we can have one flag varibale ilke "this.isPageVisited=false" in APPCONTEXT.js file. so that variable will be available throughout the project. so suppose from tab of one page i am going to different page, what i do is i set isPageVisited=true via setter method in visted page . so now to come back to tab page again, we check the variable if its true or not. if it is true we put the "active" class to the tab element.
so that the we can have current tab active from where navigation started.

bind controller on dynamic HTML

I have a HTML page with different sections, which are loaded with AJAX. I have created a controller for each of the sections.
How is possible to bind the controller on a section which has been dynamically added on HTML?
I have found very complicated solutions, which i don't even know if they apply.
I need the most basic, easiest solution, something similiar with ko.applyBindings($dom[0], viewModel) for the ones who worked with KnockoutJs.
Index html
<div class="row" ng-app="app">
<div class="col-xs-3">
<ul class="nav nav-pills nav-stacked">
<li>
Profile
</li>
</ul>
</div>
<div class="col-xs-9">
<div id="container"><!-- load dynamic HTML here --></div>
</div>
</div>
Dynamic HTML
<div ng-controller="profile">
First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}
</div>
Javascript:
var app = angular.module('app', []);
app.controller('profile', function ($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
// load new HTML
// normally this is triggered by a link / button
$(function () {
$.get("/EditProfile/Profile", function (data, status) {
$("#container").html(data);
});
});
Don't use jQuery to embed html to your container. If you use jQuery, AngularJS can't track DOM manipulations and trigger directives. You can use ng-include directive of AngularJS.
In index.html file:
...
<div id="container">
<div ng-include="'/EditProfile/Profile'"></div>
</div>
...
If you want you can make that conditional:
...
<div id="container">
<div ng-if="profilePage" ng-include="'/EditProfile/Profile'"></div>
</div>
...
With that example, if you set profilePage variable to true, profile html will be load and render by ng-include.
For detailed info take a look to ngInclude documentation.
By the way, best practice to include views to your layout by triggering same link clicks is using routers. You can use Angular's ngRoute module or uiRouter as another popular one.
If you use ngRoute module, your index.html looks like that:
<div class="row" ng-app="app">
<div class="col-xs-3">
<ul class="nav nav-pills nav-stacked">
<li>
Profile
</li>
</ul>
</div>
<div class="col-xs-9">
<div id="container" ng-view><!-- load dynamic HTML here --></div>
</div>
</div>
And with a router configuration like below, profile html will be automatically loaded and rendered by ngRoute inside ngView directive:
angular.module('myapp', []).config(function($routeProvider) {
$routeProvider
.when('/profile', {
templateUrl: '/EditProfile/Profile',
controller: 'ProfileController'
});
});

Polymer 1.0 paper-tabs addEventListener stops binding tabs dynamically

I am trying very basic tab switching and tab content. Here is my code:
A Custom element I built to generate Tab Strips dynamically
<dom-module id="tab-generator">
<template>
<paper-tabs selected="{{defaultindex}}" id="tabstrip">
<template is="dom-repeat" items="{{tabitems}}">
<paper-tab>{{item.name}}</paper-tab>
</template>
</paper-tabs>
</template>
<script>
(function () {
'use strict';
var pages = document.querySelector("#plantContent");
var tabs = this.$.tabstrip;
tabs.addEventListener('iron-select', function () {
pages.selected = tabs.selected;
});
Polymer({
is: 'tab-generator',
properties: {
tabitems: {
type: Array,
notify: true
},
defaultindex: {
type: String,
notify: true
}
}
});
})();
</script>
</dom-module>
From index.html I am referencing this as follows:
<paper-card heading="Dynamic Tabs">
<div class="card-content">
<tab-generator selected="0" tabitems='[{"name": "Plant Genus"}, {"name": "Plant Series"}, {"name": "Plant Species"}]'></tab-generator>
<!-- iron pages to associate tabs as contents -->
<iron-pages selected="0" id="plantContent">
<div>Content - Tab 1</div>
<div>Content - Tab 2</div>
<div>Content - Tab 3</div>
</iron-pages>
</div>
</paper-card>
Tabs bind fine before I added the following snippet in my custom element:
<script>
var pages = document.querySelector("#plantContent");
var tabs = document.querySelector("paper-tabs");
tabs.addEventListener('iron-select', function () {
pages.selected = tabs.selected;
});
</script>
But when I remove the event listener snippet i.e.
tabs.addEventListener('iron-select', function () {
pages.selected = tabs.selected;
});
tabs are back again.
I am referring to this post. What is wrong in my code?
Thanks in advance.
Hmm, I would re-write your code to the following:
tab-generator.html:
<dom-module id="tab-generator">
<template>
<paper-tabs selected="{{selectedTab}}">
<template is="dom-repeat" items="{{tabItems}}">
<paper-tab>{{item.name}}</paper-tab>
</template>
</paper-tabs>
</template>
<script>
Polymer({
is: 'tab-generator',
properties: {
tabItems: {
type: Array,
notify: true
},
selectedTab: {
type: String,
notify: true
}
}
});
</script>
</dom-module>
index.html:
<paper-card heading="Dynamic Tabs">
<div class="card-content">
<tab-generator selected-tab="{{selectedTab}}" tab-items='[{"name": "Plant Genus"}, {"name": "Plant Series"}, {"name": "Plant Species"}]'></tab-generator>
<!-- iron pages to associate tabs as contents -->
<iron-pages selected="{{selectedTab}}" id="plantContent">
<div>Content - Tab 1</div>
<div>Content - Tab 2</div>
<div>Content - Tab 3</div>
</iron-pages>
</div>
</paper-card>
You should in your index.html also have property named selectedTab. What happens now is that, when you change selectedTab inside the tab-generator.html it is propogated to the property selectedTab inside index.html and will update the UI accordingly. No javascript is needed. :)

In AngularJS, how do I generate a piece of content from template and insert it in the DOM when a link is clicked

I have a number of links on the page, dynamically generated like so:
<a href="#" class="more-info-item" ng-click="showStats(item, $event)">
More information
</a>
I also have a simple custom template that should show an item's name:
<script type="text/ng-template" id="iteminfo.html">
<div class="item-name">
{{item.name}}
</div>
</script>
What I would like to do is: when the link is clicked, to dynamically compile the template, and insert it in the DOM right after the link. I tried using $compile within showStats method to compile the template, but I got an error that $compile wasn't found. How would I go about doing this (and also provide item as part of the scope for the newly generated template)?
Here is a solution using a custom directive which injects the item dynamically using ng-if:
View Solution with Plunker
html:
<script type="text/ng-template" id="iteminfo.html">
<div class="item-name" ng-if="item.visible">
{{item.name}}
</div>
</script>
<div ng-repeat="item in items" >
<a href="#" class="more-info-item" more-info="item" ng-click="item.visible =!item.visible">
More information
</a>
</div>
script:
angular.module('app', [])
.controller('ctrl', function($scope) {
$scope.items = [{name:'apples', visible:false},{name:'pears', visible:false},{name:'oranges', visible:false}];
})
.directive('moreInfo', function($compile,$templateCache) {
return {
restrict: 'A',
scope: '=',
link: function(scope, element, attr) {
var itemInfo = angular.element($templateCache.get('iteminfo.html'));
var lfn = $compile(itemInfo);
element.parent().append(itemInfo);
lfn(scope);
}
};
});
You can use the built-in ngInclude directive in AngularJS
Try this out
Working Demo
html
<div ng-controller="Ctrl">
<a href="#" class="more-info-item" ng-click="showStats(item, $event)">
More information
</a>
<ng-include src="template"></ng-include>
<!-- iteminfo.html -->
<script type="text/ng-template" id="iteminfo.html">
<div class="item-name">
{{item.name}}
</div>
</script>
</div>
script
function Ctrl($scope) {
$scope.flag = false;
$scope.item = {
name: 'Manu'
};
$scope.showStats = function (item, event) {
$scope.item = item;
$scope.template = "iteminfo.html";
}
}

Resources