I am creating dashboard application with Gridster: https://github.com/ManifestWebDesign/angular-gridster
I would like to save my layout to database using JSON. What I do know, is that I store charts array to database and fetch it. Is it possible to store widget col,row and size to specific widget so I could then give the size-x and size-y with angular style {{chart.xsize}}. When creating widget I could then assign default size values and save only after user has resized or dragged widget. Or is this completely wrong way to do this? How else I could store the widget sizes and positions to database?
I have ng-repeat for my widgets like this:
<div ng-if="chart.type === settings.types.LINEAR_GAUGE">
<div class="panel c8y" gridster-item size-x="2" size-y="1">
<div class="panel-heading">
<h3 class="panel-title">{{chart.title}}</h3>
<button class="btn btn-danger pull-right btn-xs" ng-click="onClickDelete($index)"><span class="glyphicon glyphicon-remove"/></button>
</div>
<div class="panel-body">
<c8y-linear-gauge dp="chart.dp" measurement="chart.data[0].measurement"/>
</div>
</div>
</div>
I've actually built several angular dashboards using angular-gridster, and save the layout back to the database. Here is how I do it:
<div gridster="gridsterOpts">
<ul>
<li
gridster-item
row="element.posY"
col="element.posX"
size-x="element.width"
size-y="element.height"
ng-repeat="element in elements track by $index">
<div class="element-title">
<!--some header stuff goes here-->
</div>
<div class="element-useable-area">
<!--Main widget stuff goes here-->
</div>
</li>
</ul>
</div>
So I have an array called elements where I am storing my widget objects. Each object in the array includes properties for the height and width and size. So, something like this:
{
posY: 0,
posX: 0,
width: 100,
height: 100,
templateUrl: ...,
data: ...
}
Fortunately because of angular binding, when the user changes the gidster item size or position, it changes the property value too! Its important to note that the elements array is appended to a $sessionStorage object from the ngStorage framework I use, so that all the changes will be persisted if the page refreshes.
Eventually, when the user saves the dashboard, I write an object to the database which includes the elements array. Thus saving all the location and size info. The next time you call that object from the database, and populate the elements array with its data, you get back the same dashboard.
Related
In my angular application I have created the dashboard page In that created the map and right side placed the data to display something about the map (i.e created the circle in the map of 5km radius if the marker inside the circle show the details of the marker).
I have written the if condition for the marker comes inside the circle it should be turned to red otherwise blue.
And in Html I have created the bootstrap tabs with id (drones).
component.ts
inQuadrant(quadrant) {
var inPolygon = this.isMarkerInsidePolygon(this.droneMarker, quadrant);
if (inPolygon) {
quadrant.setStyle({color: 'red'});
const isRed=true;
} else {
quadrant.setStyle({color: '#3388ff'});
}
}
component.html
<div class="tab-pane fade " id="Drones" >
<ul class="list-group card" id="dd">
<li class="list-group-item" *ngFor="let x of datas">
<div class="row no-gutters">
<div class="col-sm-3" >
<div class="card-body">
<img src="{{drone01.iconref}}" width="90" height="90">
</div>
</div>
</div>
</li>
</ul>
</div>
So my requirement is how to show and hide the data when the drone comes in side(the data of id=drones should have to be shown) and outside (the data of id=drones have to be disappear)
Can anyone help me regarding this.I have tried multiple ways.
I'm afraid you're approaching this in a very non-angular way - it's a bit difficult to give a good answer with the limited amount of code you're providing, but here goes:
If you wish to hide things, you can either:
Use *ngIf to display or not display the item, or bind to the CSS visibility-property, eg.: [visibility]=isHidden ? 'hidden' : 'visible'.
But I might be misunderstanding your question?
Manipulating HTMLElements (quadrant.setStyle) is an anti-pattern in angular, you should instead use property bindings.
I'm guessing this has probably been answered a million times, but I don't have the right language to describe this particular issue. Essentially I can't do something like $ctrl.thing.subelement. The following works just fine:
<div class="col-md-10" ng-repeat="p in $ctrl.patient">
<!--Body content-->
<p>{{p.name}}</p>
<p>{{p.id}}</p>
</div>
This prints the patient name and id -- the behavior I want -- except I don't have the need for a repeat. I want to be able to reference specific patient elements throughout the page.
Similarly, this will print all the patient's information as JSON plaintext (that's how everything is stored).
<div class="col-md-10">
<!--Body content-->
<p>{{$ctrl.patient}}</p>
</div>
What doesn't work is the following (which is what I really want)
<div class="col-md-10">
<!--Body content-->
<p>{{$ctrl.patient.name}}</p>
<p>{{$ctrl.patient.id}}</p>
</div>
What am I missing here? Why am I able to access $ctrl.patient in a div but not $ctrl.patient.name?
Simple because $ctrl.patient is not an object representing a single patient it is an array of patients – which is why you iterate over it. So you need to know which item in the array you want to access by index and then use:
{{$ctrl.patient[0].name}}
Where 0 is the index of the record you want.
I have a internal team website build using python django and angularJS. The website works fine when there is low data/ content on it.
When the website gets scrolled and more data is loaded. It becomes slow.
The major problem occurs when we try to open any modal or try to write text in the textarea. The text lags while writing and modal open very slowly.
I have used nested ng-repeat there are 5 nested ng-repeat.
<div ng-repeat="x in xyz">
<div ng-repeat="y in xyz">
</div>
<div ng-repeat="img in xyz">
</div>
<div ng-repeat="y in xyz">
<div ng-repeat="z in xyz">
</div>
</div>
</div>
Above is the example of the structure being used in the website.
The above snippet repeat itself around 100 times thorughout the page.
These are having images, forms, text, input , user tagging like facebook.
ngCacheBuster,ui.bootstrap, ngTagsInput, ui.mention,monospaced.elastic these are the external library being used in the website.
the website is built using bootstrap.
Is there a specific reason why the website becomes heavy.
each size of the image is around 100kb on an average.
really? the page loads slow when there is alot of data? :D
anyway the most simple method to speed-up heavy data apps is to conditionally load and render parts of it, for example:
<div ng-repeat="x in bla" ng-click="showL1 = true">
<div ng-repeat="y in boo" ng-if="showL1 === true">
//more...
</div>
</div>
on the other part is double check your architecture, since there is a very limited amount of data a person can take from a page and therefor start thinking about tabs and paging
Maybe u need use some function in your controller that will load some part of all data for user.
For example:
app.constant('range' , 10);
app.controller('example', ['$scope', function($scope) {
$scope.loadRangeData = function(range) {
//your way of loading data with using range
}
}
]);
and after u can use ng-repeat as
<div ng-repeat="x in loadRangeData">
but best way it's finding answer in your django maybe
I'm dynamically creating jQuery UI sliders, using the following code in a forEach loop:
// Sets an id for the slider handles, gives them a custom class (makes them appear as circles, centers them)
$("#slideRange" + i).find(".ui-slider-handle").attr("id","slideHandle" + i).addClass("customSliderHandle");
// These two lines set the times below the slider handles.
$("#timeSlider" + i).find(".slideStartLabel").text(startTime);
$("#timeSlider" + i).find(".slideEndLabel").text(endTime);
This successfully makes the following slider, with variable times, for every iteration:
What I'd like to do, instead of showing the times below the circular handles, is have the times appear in the middle of the handles. The end result would look like this (photoshopped):
The times will then update, according to the slider values, within the "slide" event callback.
My question is: how do I assign unique id's to the two slider handles, so that I can then set their text independently in the "slide" callback? The code I wrote above gives both handles the same id. Using this id to set text to a handle will only apply to the first handle, leaving me no way to change the text of the second. Using find(), get(), or just $(".ui-slider-handle") are all ways of getting an array of the slider handles, but when I try attr("id","uniqueId") on one of the elements of that array, I get "(...).method(...) is not a method".
Or is assigning unique id's the wrong approach, here? Is there a jQuery or vanilla Js way of setting attributes of one element at a time, when searching by class and getting potentially multiple results?
Also, for context: I'm using find() because I'm using clone() on a markup shell, then appending it to a central div. Here's the shell:
<!-- This hidden div will be cloned, customized, and appended onto .modal-body -->
<div id="timeslotShell" class="timeslot row" style="display:none">
<div class="container-fluid slotContents" id="slotContents">
<span class="col-md-4"> Listing <div class="slotNumber listNum">*Listing No.*</div>: From <div class="slotNumber startNumber slotStartShell"> *Start Time* </div> until
<div class="slotNumber endNumber slotEndShell"> *End Time* </div> </span>
<div class="col-md-8">
<button type="button" class="btn btn-md btn-info slotButton">
Choose A Time From Within These Hours
</button>
</div>
<div id="timeSliderShell" class="collapse timeSlider">
<br><br>
<div id="slider-range" class="slideRange row"></div>
<div id="slideLabels" class="slideLabels slideRange row">
<div class="slideStartLabel"></div><div class="slideEndLabel"></div>
</div>
</div>
</div>
<br><br>
</div>
Cool -- as luck with have it, I found the answer shortly after posting this. Check this post if you're dealing with a similar issue:
Slider Value Display with jQuery UI - 2 handles
All that's needed, in the .find() calls, is
.find(".ui-slider-handle:first").text(value1);
for the first handle and then
.find(".ui-slider-handle:last").text(value2);
for the second.
I have a page which is similar to page builder template editor. Im using Dragula.JS as a plugin for drag and drop and used their method copy to copy elements from other container. This is what it looks like:
The problem is when I drag from right side columns and put in the left box elements are copied exactly what it is on the right columns. This is my code:
<div id="2col" class="collapse column-choices">
<a href="#" class="list-group-item">
<div class="row">
<div class="layoutBorder one-half"></div>
<div class="layoutBorder one-half"></div>
</div>
</a>
<a href="#" class="list-group-item">
<div class="row">
<div class="one-four layoutBorder"></div>
<div class="three-four layoutBorder"></div>
</div>
</a>
<a href="#" class="list-group-item">
<div class="row">
<div class="three-four layoutBorder"></div>
<div class="one-four layoutBorder"></div>
</div>
</a>
</div>
and my JS:
// the `templateContainer is the right box container`
dragula([document.getElementById('2col'), document.getElementById('templateContainer')], {
copy: true,
});
When I drag things to left box container this code will be put on:
<a href="#" class="list-group-item">
<div class="row">
<div class="layoutBorder one-half"></div>
<div class="layoutBorder one-half"></div>
</div>
</a>
That is not I want. Question is How to copy elements from right container and when put to left box container elements are going to changed this my aim. I will change elements to:
<div class="element-to-paste">
This thing will be copy on the left box. From Right.
</div>
Please point me on other drag and drop plugin that can make my objective.
The way to do what your asking is to utilize the .drop Dragula callback.
.on("drop", function(el, container, source) {}
https://github.com/bevacqua/dragula#drakeon-events
I've built one app where the 'drop zone' only had one column, so all elements would be lined-up vertically.. Similar to a sortable list. I used Angular for my project and my whole drop-zone used an ng-repeat directive, which is just a way to loop through an array of data. For an example it could be:
var data = [
{
index: 1,
type: 'image',
data: 'image.jpg'
},
{
index: 2,
type: 'textblock',
data: 'lorem ipsum, blah blah'
}]
Then in your ng-repeat directive you can read the type property, and put in some HTML for it, like
<div ng-if="mydata.type='image'">
<img src='{{ mydata.data}}'>
</div>
<div ng-if="mydata.type='text'">
<p>{{ mydata.data }}</p>
</div>
To get the correct order for your elements, you could use the ng-orderBy directive using the object's index.
This way the dropping action is a facade. You actually remove the dragged element from the DOM and replace it with a new one.
Dragula appends a .gu-transit class to elements while they're being dragged, so within your .drop callback you can loop through the DOM elements in your drop-container, find the .gu-transit, then you know the index that it's at, and can assign it a correct index property when you push it into your data array.
I'm using Angular as an example because that's what I used, and I think using it or another framework substantially helped implement this functionality. I think it'd be a lot more difficult to do with straight jQuery.