Not able to set column width in angular datatables - angularjs

var app = angular.module('tableTest', ['datatables']);
app.controller('TableCtrl',function ($scope,$compile,DTOptionsBuilder, DTColumnBuilder) {
$scope.showUpdateForm = function(code,reason,startTime,endTime,transactionGroup,geoGroup,transactionGroup) {
$scope.$parent.code = code;
$scope.$parent.reason = reason;
$scope.$parent.startTime = startTime.split(' ')[1].substring(0,startTime.split(' ')[1].lastIndexOf(':'));
$scope.$parent.endTime = endTime.split(' ')[1].substring(0,endTime.split(' ')[1].lastIndexOf(':'));
$scope.$parent.startDate = startTime.split(' ')[0];
$scope.$parent.endDate = endTime.split(' ')[0];
$scope.$parent.transactionGroup = transactionGroup;
$scope.$parent.geoGroup = geoGroup;
$scope.$parent.group = transactionGroup;
$scope.$parent.getGeographyList();
$scope.$parent.getTransactionsList();
}
var vm = this;
vm.dtOptions = DTOptionsBuilder.newOptions()
.withOption('ajax', {
url: '<some url>',
type: 'GET'
})
.withDataProp('data')
.withOption('serverSide', true)
.withOption('createdRow', function(row, data, dataIndex) {
$compile(angular.element(row).contents())($scope);
})
.withOption('responsive', true).withOption('bAutoWidth', false)
.withPaginationType('full_numbers');
vm.dtColumns = [
DTColumnBuilder.newColumn('group').withTitle('Group').withOption('bSortable',true),
DTColumnBuilder.newColumn('startTime').withTitle('Start').withOption('bSortable',true),
DTColumnBuilder.newColumn('endTime').withTitle('End').withOption('bSortable',true),
DTColumnBuilder.newColumn('status').withTitle('Status').withOption('bSortable',true),
DTColumnBuilder.newColumn('reason').withTitle('Reason').withOption('bSortable',true).withOption('sWidth', '20%'),
DTColumnBuilder.newColumn('transactionGroup').withTitle('Transaction Group').withOption('bSortable',true),
DTColumnBuilder.newColumn('geoGroup').withTitle('Geo Group').withOption('bSortable',true),
DTColumnBuilder.newColumn('group').withTitle('Current Status').renderWith(function(data, type, full, meta) {
var arr = full.endTime.split(/-|\s|:/);
var endTime = new Date(arr[0], parseInt(arr[1])-1, arr[2], arr[3], arr[4], arr[5]);
arr = full.startTime.split(/-|\s|:/);
var startTime = new Date(arr[0], parseInt(arr[1])-1, arr[2], arr[3], arr[4], arr[5]);
var currentTime = new Date();
var color = ['#2196F3','#009688'];
var currentStatus = ['INACTIVE','ACTIVE']
var index;
if(startTime.getTime() <= currentTime.getTime() && currentTime.getTime() <= endTime.getTime()) {
index = 1;
} else {
index = 0;
}
return '<span style="background : '+color[index]+';color: #FFF;font-weight: 500;" class="currentStatus"> '+currentStatus[index]+' </span>';
}).notSortable(),
DTColumnBuilder.newColumn('code').withTitle('').notSortable().renderWith(function(data, type, full, meta) {
return '<div class="btn-group" > <label class="btn btn-primary"><input type="radio" name="blockedTransaction" ng-click="showUpdateForm(\''+full.code+'\',\''+full.reason+'\',\''+full.startTime+'\',\''+full.endTime+'\',\''+full.transactionGroup+'\',\''+full.geoGroup+'\',\''+full.transactionGroup+'\')" ng-model="blockedTransaction" data-toggle="modal" data-target="#updateForm" data-whatever="#getbootstrap" >EDIT</label></div>';
})
];});
The above code is my table controller. The problem is that I am not able to set the column width. When there is a lot of data for a column, the table resizes and it goes out of its page. What is wrong in the code. What is right key value pair to be put in "withOption" so that it sets the width of the column properly.
Link to Datatables plugin and
Link to Datatables + Angular plugin

Since your test is using a long word without any space, you will need to use the word-break.
See this pen for example:
.dataTable td {
word-break: break-all;
}

Related

passing variable value from controller to view in AngularJS

I am developing an application where i popup a window and when it gets popup the next time i will try to open it should not be opened. Next time it should open When i will close the popup then it should open.
Now for that i am using count variable and whenever it will be 1 the popup opens and whenever it is greater than or equal to 2 it shows alert. But now when i close the popup it is not resetting the value of count to 0 in view.
In JSfiddle i tried using var self = this; it works fine but when i tried it on my code it says Uncaught Exception Typeerror cannot find property 'count' defined at line self.count = 0;
How to achieve this? or any alternate solution for this?
<a ui-sref-active="active" ng-click="count=count+1; connectMachine(machine, count)" ng-init="count=0" ><span><i class="fa fa-desktop fa-5x"></i></span></a>
$scope.connectMachine = function(machine, count) {
var promise = restAPIService.connectMachineService(
$scope.thisStudentThisBatch.guacProfileId,
machine.connectionId, $stateParams.batchID).get();
promise.$promise.then(function(response) {
var json = JSON.parse(response.data);
console.log(json.id);
var dnsUrl = $location.absUrl().split('/');
dnsUrl = dnsUrl[0] + '//' + dnsUrl[2];
var apiUrl = dnsUrl + $rootScope.apiUrl + "guacamole/disconnect/"
+ json.id;
var conn_params = $http.defaults.headers.common.Authorization
+ "++" + apiUrl;
$scope.machineURL = response.headers.url + "&conn_params="
+ conn_params;
var params = "height=" + screen.availHeight + ",width="
+ screen.availWidth;
var NewWin;
var self = this;
if ($scope.count == 1) {
NewWin = window.open($scope.machineURL);
} else if ($scope.count >= 2) {
alert("Back Off Back Off");
}
function checkWindow() {
if (NewWin && NewWin.closed) {
window.clearInterval(intervalID);
self.count = 0;
}
}
var intervalID = window.setInterval(checkWindow, 500);
}, function(error) {
dialogs.error("Error", error.data.error, {
'size' : 'sm'
});
});
}
You can use a variable defined on $scope to trigger the value of button instead of using ng-init
HTML:
<div ng-app="myApp">
<ul ng-controller="TodoCtrl">
<li class="list-group-item" ng-repeat="todo in todos">{{todo.text}}
<button class="btn btn-default" ng-click="addLike($index)">value- {{count[$index]}}</button>
</li>
</ul>
</div>
JS:
var myApp = angular.module('myApp', []);
function TodoCtrl($scope) {
$scope.todos = [{
text: 'todo one'
}, {
text: 'todo two',
done: false
}];
$scope.count = [0, 0];
$scope.addLike = function(index) {
var NewWin;
$scope.count[index] ++;
if ($scope.count[index] == 1) {
NewWin = window.open('https://www.google.com');
} else if ($scope.count >= 2) {
alert("Back Off Back Off");
}
function checkWindow() {
if (NewWin && NewWin.closed) {
window.clearInterval(intervalID);
$scope.count[index] = 0;
$scope.$apply();
}
}
var intervalID = window.setInterval(checkWindow, 500);
};
};
JS Fiddle :https://jsfiddle.net/p41dLjmn/

Validate CSV file in angularJs

I have a csv file which contains two columns store_id and store_name.When the user uploads a csv file I need to validate the file i.e check if first column is Integer(store_id) and second column is String(store_name).Can you help how to read and retrieve the content and validate the file?
Thanks
Try this code
my csv file
store_id,store_name
01,"First point"
02,"Second point"
03,"Third point"
var demo = angular.module('demo', []);
demo.controller('loadData', function($scope,$rootScope,$http){
$scope.uploadData = function() {
var uploaded=$scope.fileContent;
$scope.processData(uploaded);
};
$scope.processData = function(allData) {
var filteredData = allData.split(/\r\n|\n/);
var headers = filteredData[0].split(',');
var final = [];
for ( var i = 0; i < filteredData.length; i++) {
if (!filteredData[i]=="") {
var data = filteredData[i+1].split(',');
if (isNaN(data[0])==false && isNaN(data[1])==true) {
final.push(data);
console.log("Valid CSV");
}
else{
console.log("Not Valid CSV");
}
}
}
$scope.data = final;
};
});
demo.directive('fileReader', function() {
return {
scope: {
fileReader:"="
},
link: function(scope, element) {
$(element).on('change', function(changeEvent) {
var files = changeEvent.target.files;
if (files.length) {
var r = new FileReader();
r.onload = function(e) {
var contents = e.target.result;
scope.$apply(function () {
scope.fileReader = contents;
});
};
r.readAsText(files[0]);
}
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.min.js"></script>
<div ng-app='demo'>
<div ng-controller='loadData'>
<input type="file" file-reader="fileContent" />
<button ng-click='uploadData($event)' >upload</button>
<div>{{fileContent}}</div>
<table>
<tr ng-repeat="x in data">
<td ng-repeat="y in x">{{ y }}</td>
</tr>
</table>
</div>
</div>
document.getElementById('csvUpload').onchange = function(){
var file = this.files[0];
var storeId = [],storeName = [],line,flag = 1;
var reader = new FileReader();
reader.onload = function(progressEvent){
var lines = this.result.split('\n');
for(var iterator = 0; iterator < lines.length-1; iterator++){
line = lines[iterator].split(',');
storeId.push(line[0]);
storeName.push(line[1]);
}
var result = !storeId.some(isNaN);
for(var iterator = 0; iterator < storeName.length; iterator++) {
console.log(typeof storeName[iterator]);
if(typeof storeName[iterator] !== "string"){
flag = 0;
break;
}
}
if(result === false || flag === 0) {
var alert = mdDialog.alert({
textContent: 'Please select a valid csv file',
ok: 'Close'
});
mdDialog.show( alert );
}
};
reader.readAsText(file);
}
you may try this component
https://www.import-javascript-angular-xlsx-csv-validator.com/
it validates that and more

Controller function not applying to ng-include file

I am trying to use the "minisCtrlOverall" controller in my ng-include file, but none of the functionality in my controller works for the included file unless I put ng-controller in the actual overall.html file. What I am trying to do is access the "ring-fill" class that is in my overall.html file from my controller. I want to add the class "active" too all "ring-fills" but its not working. I'm guessing this isn't working because the included files comes after the controller runs? Anyone know how I can fix this?
Controller:
angular.module('ciscoImaDashboardAdmin',[])
.controller('minisCtrlOverall', function ($scope, $rootScope, dummyData) {
$scope.overallOn = true;
$scope.switchView = function(element) {
var value = element.target.attributes['value'].value;
if(value == "overall") {
$scope.overallOn = true;
$scope.swimlaneOn = false;
}
else if(value == "swimlane") {
$scope.swimlaneOn = true;
$scope.overallOn = false;
}
};
var totalRings = 9;
var maxScore = 10;
var data_overall = {
average_score: 6
}
var ringToHighlight = Math.floor((data_overall.average_score/maxScore)*totalRings); //round down
var i = 0;
var rings = [];
var ringClass = 'path.ring-fill:not(.ring-border)';
$(ringClass).each(function(){
rings.push($(this)[0]);
});
while( i < ringToHighlight) {
fillPath(i);
i = i + 1;
}
function fillPath(i) {
if(i < ringToHighlight) {
var selectedRing = $(rings[i]);
selectedRing.attr("class", "ring-fill active");
}
}
});
HTML:
<div class="row mini" ng-show="overallOn" ng-controller="minisCtrlOverall">
<div class="col-sm-3">
<div ng-include="'svgs/overall.html'"></div>
</div>
</div>

how to update a scope after removing element from ng-repeat in angular?

what i am trying to achieve is that when i am double clicking and item in my grid i traverse inside it, according to it my breadcrumbs is updating. but when i am clicking back in breadcrumbs then breadcrumbs previous value is removed but when i am moving inside again by double click it show previous removed value also. i am attaching my code and also a image to better understand.
<div id="breadCrumb"><div ng-click="breadCrumbFilter('^/xyz/$')" style="float:left;">xyz</div>
<div ng-repeat="bCrumb in bCrumbs" id="{{bCrumb.name}}" style="float:left;
" ng-click="breadCrumbFilter(bCrumb)">{{ bCrumb.name }}</div></div>
var app = angular.module('myApp', ['ngGrid']);
app.controller('MyCtrl', function($scope) {
$scope.filterOptions = {
filterText: '^/xyz/$'
};
$scope.breadCrumbFilter = function(bCrumb) {
var filterText = bCrumb.path;
if(filterText == null){
filterText = bCrumb;
}
var active = $scope.filterOptions.filterText;
if ($scope.filterOptions.filterText === filterText) {
$scope.filterOptions.filterText = filterText;
}
else if ($scope.filterOptions.filterText !== '' ) {
$scope.filterOptions.filterText = filterText;
}
$scope.resetBreadcrumbs(filterText,active);
};
$scope.resetBreadcrumbs = function(fText,rActive){
var reset = fText;
var activeBreadcrumbs = rActive;
activeBreadcrumbs = activeBreadcrumbs.substring(reset.length -1, activeBreadcrumbs.lastIndexOf("/"));
var myEl = angular.element(document.getElementById('/ '+activeBreadcrumbs));
myEl.remove();
};
$scope.filterFpath = function(row) {
var fileName = row.entity.name;
var folderPath = row.entity.Full_Path;
var newPath = folderPath+fileName+'/';
var filterText = '^'+newPath+'$';
if ($scope.filterOptions.filterText ==='^'+folderPath+'$') {
$scope.filterOptions.filterText = filterText;
}
else if ($scope.filterOptions.filterText === filterText) {
$scope.filterOptions.filterText = '';
}
$scope.addname('/ '+fileName,filterText);
};
$scope.bCrumbs = [] ;
$scope.addname=function(name,path)
{
obj={};
obj['name'] = name;
obj['path'] = path;
$scope.bCrumbs.push(obj);
};
var rowTempl = '<div ng-dblClick="filterFpath(row)" ng-style="{ \'cursor\': row.cursor }" ng-repeat="col in renderedColumns" '+'ng-class="col.colIndex()" class="ngCell{{col.cellClass}}"><div ng-cell></div></div>';
$scope.myData = [{name: "Moroni", Full_Path: "/xyz/"},
{name: "Tiancum", Full_Path: "/xyz/Moroni/"},
{name: "Jacob", Full_Path: "/xyz/"},
{name: "Nephi", Full_Path: "/xyz/Moroni/Tiancum/"},
{name: "Nephiss", Full_Path: "/xyz/"}];
$scope.gridOptions = {
data: 'myData',
filterOptions: $scope.filterOptions,
rowTemplate: rowTempl,
};
});
what happening right now:
1st image when data loaded in breadcrumbs 'xyz' displayed by default
when double click on moroni it is traversed inside and breadcrumbs updated.
when i click on xyz come back again:
Again if i traverse inside moroni its displays something like this:
What is the issue i am not able to figure it out.
By seeing your code i found out that you are removing dom element but you are not deleting it from array so try finding index of the desired remove file and then use 'slice' in that.
Try something like this:
<div id="breadCrumb"><div ng-click="breadCrumbFilter('^/xyz/$')" style="float:left;">xyz</div>
<div ng-repeat="bCrumb in bCrumbs" id="{{bCrumb.name}}" style="float:left;
" ng-click="breadCrumbFilter(bCrumb,$index)">{{ bCrumb.name }}</div></div>
$scope.breadCrumbFilter = function(bCrumbs,$index) {
$scope.bCrumbs.splice($index+1);
var d = $scope.bCrumbs.length -1;
path = bCrumbs[d].path;
var filterText = path;
if(filterText == null){
filterText = bCrumb;
}
var active = $scope.filterOptions.filterText;
if ($scope.filterOptions.filterText === filterText) {
$scope.filterOptions.filterText = filterText;
}
else if ($scope.filterOptions.filterText !== '' ) {
$scope.filterOptions.filterText = filterText;
}
};
try this out.

how to wrap text in angularjs and save the position

I would like to wrap text with span tag and save the position.
I know how to do it with JS but i dont know how to do it with angularjs
Here is what i have done:
http://jsfiddle.net/ymeaL06j/1/
This function gives me the position of the text in the DIV
function getSelectionPosition() {
var range = window.getSelection().getRangeAt(0);
var preSelectionRange = range.cloneRange();
preSelectionRange.selectNodeContents(document.getElementById("code"));
preSelectionRange.setEnd(range.startContainer, range.startOffset);
var start = preSelectionRange.toString().length;
return {
start: start,
end: start + range.toString().length
}
};
I take the start and end positions and insert them as an attribute in the span tag
After this i would like to save all the marked positions and load it later, i have a function that select text and then i can wrap it (i hope that there is a better solution)
function setSelection(savedSel) {
var charIndex = 0, range = document.createRange();
range.setStart(document.getElementById("code"), 0);
range.collapse(true);
var nodeStack = [containerEl], node, foundStart = false, stop = false;
while (!stop && (node = nodeStack.pop())) {
if (node.nodeType == 3) {
var nextCharIndex = charIndex + node.length;
if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
range.setStart(node, savedSel.start - charIndex);
foundStart = true;
}
if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
range.setEnd(node, savedSel.end - charIndex);
stop = true;
}
charIndex = nextCharIndex;
} else {
var i = node.childNodes.length;
while (i--) {
nodeStack.push(node.childNodes[i]);
}
}
}
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
You can use the same code that you illustrated above and put it inside of your angularjs controller.
Refer to my plunker code; it is a simple angularjs version of your jsfiddle code.
For example, suppose that a snippet of the index.html looks like this:
<body ng-controller="MainCtrl">
<div id="code">This is <b>some text</b> bla bla bla</div>
<br />
<input type="button" value="Mark!" ng-click="markText()" />
<input type="button" value="Remove marks!" ng-click="removeMarks()" />
</body>
Then the example angularjs controller, MainCtrl, could look like this:
app.controller('MainCtrl', function($scope) {
var getSelectionPosition = function () {
var range = window.getSelection().getRangeAt(0);
var preSelectionRange = range.cloneRange();
preSelectionRange.selectNodeContents(document.getElementById("code"));
preSelectionRange.setEnd(range.startContainer, range.startOffset);
var start = preSelectionRange.toString().length;
return {
start: start,
end: start + range.toString().length
}
}
$scope.markText = function() {
var currPosition = getSelectionPosition();
var selection = window.getSelection().getRangeAt(0);
var selectedText = selection.extractContents();
var span = document.createElement("span");
span.className = "Mark";
span.setAttribute("PosStart", currPosition.start);
span.setAttribute("PosEnd", currPosition.end);
span.appendChild(selectedText);
selection.insertNode(span);
};
$scope.removeMarks = function() {
$(".Mark").each(function () {
$(this).contents().unwrap();
});
};
});
Notice that the MainCtrl is the angularjs controller for the body. The ng-click on the buttons reference the markText and removeMarks functions in the controller's scope. The logic in the functions are exactly the same as you referenced in your question (and jsfiddle).
None of your JS code changed other than moving the functions inside of the controller. Again, check out the plunker above to see the actual code working.

Resources