Angular material as foreignObject inside SVG - angularjs

My general purpose is to make a dynamic and very simple flowchart view. I use svg and angular material. I am trying to show angular material objects like (md-select, md-menu, md-button) inside SVG. After a quick research I saw it is possible with "foreignObject" tags.
Secondly; I want to move all these elements at once inside SVG regarding mouse panning. So I use "viewBox" property.
In my sample;
I use "foreignObject" tag to show angular material "md-select" inside a svg element.
I expect "md-select" to move when I change x and y values of viewBox property of svg element but it keeps its position while clickable area changes.
When I try same scenario with html "select" it moves as I expect. But I can't do the same with angular material objects. (they visually stay in their original position but their click area goes another where regarding viexBox x-y values.)
<div ng-controller="MyCtrl">
x: <input ng-model="vbx">
y: <input ng-model="vby">
<svg id="processDesignPanel" viewBox="{{vbx}} {{vby}} 500 500" name="processDesignPanel" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800px" height="800px">
<foreignObject width="100" height="50" x="100" y="100">
<md-select placeholder="Assign to user" ng-model="userkey" style="width: 200px;">
<md-option ng-repeat="user in formusers">{{user}}</md-option>
</md-select>
</foreignObject>
<foreignObject width="100" height="50" x="100" y="200">
<select placeholder="Assign to user" ng-model="userkey" style="width: 150px;">
<option ng-repeat="user in formusers">{{user}}</option>
</select>
</foreignObject>
</svg>
</div>
sample js
angular.module('MyApp', ['ngMaterial'])
.controller('MyCtrl', function ($scope) {
$scope.formusers=["ally","mike"];
$scope.vbx=null;
$scope.vby=null;
})
here is my fiddle.

This isn't a complete solution, but I think it's a couple steps in that direction. I cut down your fiddle to show the incorrectly-placed MD select along with the correctly-placed regular select, with a button that modifies the style of the md-select-value tag to have position:inherit and z-index:auto, which makes the MD select appear in the correct place. I don't know why it does this, yet, as I haven't delved into the lib's CSS.
document.getElementsByTagName('md-select-value')[0].setAttribute('style','z-index:auto; position:inherit')
https://jsfiddle.net/emamid/n8tr0gfk/6/

Related

How to get the selecteditem for each row based on its index? [duplicate]

I'm trying to deal with the issue of scope inside of an ng-repeat loop - I've browsed quite a few questions but have not quite been able to get my code to work.
Controller code:
function Ctrl($scope) {
$scope.lines = [{text: 'res1'}, {text:'res2'}];
}
View:
<div ng-app>
<div ng-controller="Ctrl">
<div ng-repeat="line in lines">
<div class="preview">{{text}}{{$index}}</div>
</div>
<div ng-repeat="line in lines">
<-- typing here should auto update it's preview above -->
<input value="{{line.text}}" ng-model="text{{$index}}"/>
<!-- many other fields here that will also affect the preview -->
</div>
</div>
</div>
Here's a fiddle: http://jsfiddle.net/cyberwombat/zqTah/
Basically I have an object (it's a flyer generator) which contains multiple lines of text. Each line of text can be tweaked by the user (text, font, size, color, etc) and I want to create a preview for it. The example above only shows the input field to enter text and I would like that to automatically/as-you-type update the preview div but there will be many more controls.
I am also not sure I got the code right for the looping index - is that the best way to create a ng-model name inside the loop?
For each iteration of the ng-repeat loop, line is a reference to an object in your array. Therefore, to preview the value, use {{line.text}}.
Similarly, to databind to the text, databind to the same: ng-model="line.text". You don't need to use value when using ng-model (actually you shouldn't).
Fiddle.
For a more in-depth look at scopes and ng-repeat, see What are the nuances of scope prototypal / prototypical inheritance in AngularJS?, section ng-repeat.
<h4>Order List</h4>
<ul>
<li ng-repeat="val in filter_option.order">
<span>
<input title="{{filter_option.order_name[$index]}}" type="radio" ng-model="filter_param.order_option" ng-value="'{{val}}'" />
{{filter_option.order_name[$index]}}
</span>
<select title="" ng-model="filter_param[val]">
<option value="asc">Asc</option>
<option value="desc">Desc</option>
</select>
</li>
</ul>

Change Angular js charts.js chart type dynamically

everyone , Am using Angular js 1.6 and angular Chart [of chart.js] am trying to to change the type of the chart when changing the value of a HTML select input like the following but the chart type doesnt change . i found out in some FAQ that the chart needs to be destroyed and recreated again but that doesn't work with the angular version . This is my code:
The view:
<select ng-change="changeChartType(selectedType)" ng-model="selectedType" >
<option ng-repeat="t in chartType" value={{t.type}}>{{t.dispName}}</option>
</select>
<p>{{selectedType}}</p>
<div id="chartContainer">
<canvas id="doughnut" class={{selectedType}}
chart-data="data" chart-labels="labels">
</canvas>
</div>
when I use this code the class changes for example from "chart chart-pie" to "chart chart-doughnut", but the chart itself doesnt change.
Am I missing something?
You have to use the "chart-type" directive to change the chart type dynamically. They already provide it out of the box.
Check this plunker: http://plnkr.co/edit/xKrCCcEQpzEvxfUMJKzd?p=preview
<canvas id="bar" class="chart-base" chart-type="selectedType"
chart-data="data" chart-labels="labels"> chart-series="series"
</canvas>
Reference : http://jtblin.github.io/angular-chart.js/#base-chart (search for "dynamic chart")

onclick on hyperlink should add a div horizontally using angularjs

My html:
<div id="contentDiv">
<div id="headerDiv" ><div id="titleDiv"> Queries</div></div>
<div id="valuesDiv" ><div id="yearDiv"> 2015</div></div>
<div id="graphDiv" ><div id="chartDiv">graph</div></div>
</div>
Like this div, I have another div but the content in the div is different.
How to add a new div horizontally when I click on hyperlink using angularjs?
How can I do this? please help me out regarding this
Looks like what you need is a two way binding with the ng-model directive. So the idea would be that you bind the new div to a variable in your scope which is initially in an empty or undefined state (for example, there are better ways). When the hyperlink is clicked it calls the function specified by an ng-click directive which will fill your bound object, which in turn will cause the new div to be rendered.
EDIT:
Based on your comments here is a simple example.
HTML page:
<div id="newDiv" ng-repeat="item in items">
<!-- Div content -->
<!-- example -->
<input type="text" ng-model="item.name">
</div>
<input type="button" ng-click="addItem()">
Controller:
$scope.items=[];
$scope.addItem = function() {
var newItem = {};
newItem.name = "new item name";
$scope.items.push(newItem);
}
What's happening here is the data for each div is stored in an array of objects. The ng-repeat directive will repeat the div for each object in the array. You can then fill the elements in the div using the object. Adding a new div is as simple as adding a new item to the array and angular will take care of the rest for you. Please note that I have not tested this example, but hopefully it's enough to point you in the right direction.
RE aligning the divs horizontally, this will be done with CSS, using the inline-block display mode. So you could give the div a class of, for example, "horizontalDiv" and add the following class to your CSS file:
.horizontalDiv {
display: inline-block;
}

onsen-ui get and set value of ons-checkbox

I am having trouble using javascript to get and set the value of ons-checkbox elements. I have read through the docs and am stuck. Any advice or direction would be much appreciated.
Sean
If you want to use pure JavaScript for your OnsenUI app, I suggest you use Onsen CSS component. In other words, you will have OnsenUI style for your app by just adding the css of the Onsen CSS component you want. Then, use JavaScript to access those components just like how you do it with any HTML components. For example in this case a checkedbox. Please see the example here about how to set/get the value as well as check status.
However, if you still wanna use OnsenUI's elements. There are 2 ways to do it:
1. Directly in the html page:
<!--Set the value directly in the tag-->
<section style="padding: 10px;">
<ons-checkbox
ng-model="answer"
ng-true-value="YES"
ng-false-value="NO">
Yes or No?
</ons-checkbox>
<br>
<!--Get the value directly-->
<span>{{answer}}</span>
</section>
2. Via AngularJS
page.html
<ons-page class="center" ng-controller="Test_Ctrl">
<h1>Checkbox Value</h1>
<section style="padding: 10px;">
<ons-checkbox ng-model="answer">
Yes or No?
</ons-checkbox>
<br>
<!--Get the value directly-->
<span>{{answer}}</span>
</section>
<!--Get the value by the script-->
<ons-button ng-click="check()">Result</ons-button>
</ons-page>
app.js
angular.module('myApp', ['onsen.directives']);
function Test_Ctrl($scope) {
$scope.check = function (){
if($scope.answer) //If the checkbox is checked.
$scope.answer="YES";
else //If the checkbox is unchecked.
$scope.answer = "NO";
alert($scope.answer);
}
}

jQuery Mobile & AngularJS checkboxes horizontal

Using jQuery Mobile and AngularJS together, without a plug-in but having read about it, loading jQuery first, and the two frameworks are mostly playing very nicely and quite powerful having both.
Trying to render jQuery Mobile checkboxes with
<div data-role="fieldcontain">
<legend>Showing more lodges slows the display</legend>
<fieldset data-role="controlgroup" data-type="horizontal">
<label ng-repeat-start="(lodgekey, lodge) in data.lodges" for="chooser_{{lodgekey}}">{{lodge.lodgetitle}}</label>
<input ng-repeat-end id="chooser_{{lodgekey}}" type="checkbox" ng-model="lodge.selected" />
</div>
</fieldset>
</div>
Problem is that jQuery Mobile finishes setting up the checkbox as a button prior to Angular doing the repeat. So the repeated checkboxes stack up vertically even though I have used data-type="horizontal" in the fieldset, and each show as first/last orphan - which they are before AngularJS does its ngRepeat. Viewing the code example at http://demos.jquerymobile.com/1.0a4.1/docs/forms/forms-checkboxes.html and looking at the rendered DOM shows the way it should render.
My solution so far has been to reproduce the jQuery Mobile form using Angular, but this is not ideal, here is my code:
<div data-role="fieldcontain" id="lodge-chooser">
<legend>Showing more lodges slows the display</legend>
<fieldset data-role="controlgroup" data-type="horizontal" class="ui-corner-all ui-controlgroup ui-controlgroup-horizontal">
<div class="ui-checkbox" ng-repeat="(lodgekey, lodge) in data.lodges">
<label ng-class="{'ui-btn-active':lodge.selected, 'ui-corner-left':$first, 'ui-corner-right':$last}" for="{{lodgekey}}">{{lodge.lodgetitle}}</label>
<input id="{lodgekey}}" type="checkbox" ng-model="lodge.selected" />
</div>
</fieldset>
</div>
and CSS:
/* remove incorrect rounded corners which appear on all buttons*/
div#lodge-chooser label.ui-btn.ui-corner-all {
border-radius:0!important;
}
/* reinstate rounded corners in correct places */
div#lodge-chooser label.ui-btn.ui-corner-left {
border-bottom-left-radius:inherit!important;
border-top-left-radius:inherit!important;
}
div#lodge-chooser label.ui-btn.ui-corner-right {
border-bottom-right-radius:inherit!important;
border-top-right-radius:inherit!important;
}
This works, noting that the div.ui-checkbox is nested redundantly because jQuery Mobile still adds it in but my addition provides the styles needed and the extra nested div doesn't appear to do any harm.

Resources