Getting ID for row on resourceLabelDidMount - fullcalendar-5

I'm trying to get the ID for each row.
data.event.id isn't working. Any suggestions?
resourceLabelDidMount: function(data) {
var icon = document.createElement('strong');
icon .innerHTML = ' < a type="button" href="javascript:;" onclick="editReourceModal(1)" style="color: #0c0c0c"> ';
data.el.querySelector('.fc-datagrid-cell-main') .appendChild(icon );
},

Related

How to add child nodes to a Kendo Treeview without multiple parent selection in angularjs?

I am using the following to add a child node to a kendo treeview , it works if i dont try to select the first node. Once i select the first node , it doesnt add a child node and it stays selected even if i select other nodes.
But if i dont select the first node all seems to work as expected.
Any ideas as to whey this may be happening ?
Html:
<div ng-show="selectedItem">
<h4>Selected: {{selectedItem.Service}}</h4>
<button class="k-button" ng-click="addAfter(selectedItem)">Add item below</button>
<button class="k-button" ng-click="addBelow(selectedItem)">Add child item</button>
<button class="k-button" ng-click="remove(selectedItem)">Delete</button>
</div>
<div id="xmlFileDestinationModalTreeView"
kendo-tree-view="tree"
k-options="treeOptions"
k-on-change="selectedItem = dataItem"
style="border: 1px solid lightgrey; height: 300px; overflow: auto;">
<span k-template>
{{dataItem.Service}} <button class='k-button k-button-solid-base k-button-solid k-button-md k-rounded-md' ng-click='click(dataItem)'>+</button>
<i class="fa fa-plus" aria-hidden="true" ng-click="addBelow($event)"></i>
<i class="fa fa-trash" aria-hidden="true" ng-click="selectedItem=dataItem;remove(selectedItem, $event)"></i>
</span>
</div>
Javascript:
$scope.treeViewDataSource = new kendo.data.HierarchicalDataSource({
data: [],
schema: {
data: "json",
model: {
hasChildren: true,
children: "ChildServices"
}
}
});
$scope.treeOptions = {
loadOnDemand: true,
dataSource: $scope.treeViewDataSource,
dataTextField: "Service",
expandAll: false,
//checkboxes: {
// checkChildren: true
//}
};
$scope.click = function (dataItem) {
alert(dataItem.Service);
};
$scope.addAfter = function (item) {
var array = item.parent();
var index = array.indexOf(item);
var newItem = makeItem();
array.splice(index + 1, 0, newItem);
};
$scope.addBelow = function ($event) {
var newItem = $scope.testservice[0];
$scope.tree.append(newItem, $scope.tree.select());
};
$scope.remove = function (item) {
var array = item.parent();
var index = array.indexOf(item);
array.splice(index, 1);
$scope.selectedItem = undefined;
};
It seems as if the first Parent in the treeView stays as selected and focused once it is selected.Not sure how to clear that.
Here is what the newItem will look like :
This is the newItem object being added

angularJS how to calculation for ng-repeat data shown in input element

I have JSON data of items=[]; displayed in <tables> (1st table) using ng-repeat. The user then can add this row using the ng-repeat $index to another array itemsPOS=[] by using push() function, this array then is displayed in another <table> (2nd table) using ng-repeat. So of itemsPOS=[] data are displayed in input fields such as item#, itemDescription, price. What am I trying to do after that, I added fields qty, discount and Total That if I try putting values in qty, it will recalculate the Total just like this plunker: http://plnkr.co/edit/R3LON9?p=preview. But on my version, it's in a table.
What I am facing now is if I added two rows for itemsPOS=[], if I edit the 1st-row qty, it calculates the 2nd row Total. **Just like image below **
My Code to put items at itemsPOS=[];
$scope.passItem = function(index) {
var itemNu = $scope.itemLoad[index].itemNo;
var descrptn = $scope.itemLoad[index].desc;
var cashPrice = $scope.itemLoad[index].cash;
var qty = 1;
var totalSum = cashPrice*qty;
console.log(totalSum)
$scope.presyo = cashPrice;
$scope.itemsPOS.push({'code':itemNu, 'name':descrptn, 'price': cashPrice, 'qty': qty, 'dscnt': 0, 'subTotal': totalSum});
console.log($scope.itemsPOS)
$scope.counter = $scope.itemsPOS.length;
Code for calculation of Total
$scope.changeQty = function(qty) {
$scope.qnty = qty;
if($scope.qnty>0){
$scope.totalAmount = $scope.presyo*$scope.qnty;
}
console.log($scope.totalAmount)
}
UPDATE
The 1st table
<tbody>
<tr dir-paginate="it in itemLoad|orderBy:sortKey:reverse|filter:search|itemsPerPage:10">
<td><button type="button" class="btn btn-primary btn-sm" title="Add to POS tab" ng-click="passItem($index)"><i class="fa fa-plus-circle"></i> Add</button></td>
<td>{{it.itemNo | ifEmpty: 'Item No.'}}</td>
<td>{{it.desc | ifEmpty: 'Item Name.'}}</td>
<td>{{it.Available | ifEmpty: '0'}}</td>
<td>{{it.OnOrder | ifEmpty: '0'}}</td>
<td>₱{{it.cash|currency:''| ifEmpty: '0.00'}}</td>
<td>₱{{it.charge|currency:''| ifEmpty: '0.00'}}</td>
<td>₱{{it.str|currency:''| ifEmpty: '0.00.'}}</td>
<td>₱{{it.ins|currency:''| ifEmpty: '0.00'}}</td>
</tr>
</tbody>
2nd table
<tbody>
<tr ng-repeat="so in itemForPOS|filter:search">
<td><button type="button" class="btn btn-danger btn-sm" title="Add to POS tab" ng-click="remItem($index)"><i class="fa fa-times-circle-o"></i> remove</button></td>
<td>{{so.code | ifEmpty: 'Item No.'}}</td>
<td>{{so.name | ifEmpty: 'Item Name.'}}</td>
<td><a><input type="text" value="{{so.price|currency:'₱'}}" style="text-align: center; border: 0;width: 100px" ></a></td>
<td><a><input type="text" ng-validate="integer" ng-model="qty" ng-change="changeQty(qty)" placeholder="0" style="text-align: center; border: 0;width: 100px"></a></td>
<td><a><input type="text" ng-validate="integer" ng-model="dscnt" style="text-align: center; border: 0;width: 100px" placeholder="0"></a></td>
<td><b>{{totalAmount|currency:'₱'}}</b></td>
</tr>
</tbody>
Instead of passing the qnty to changeQty function you have to pass the entire row. Just put the indexing variable used in ng-repeat in the argument, so that you can edit any column in that particular row.
For Eg, consider the sample code,
<div ng-repeat="x in records">
<button ng-click="changeQty(x)">
</div>
When ng-repeat is used with filter, then a $index is different than what is expected.
In your case, you are using a search filter with ng-repeat. So when the item is filtered from the list/table then $index is also changed according to the new filtered list.
You can use the workaround of ng-hide where row will be hidden but $index will be maintained or you can pass something unique or complete single object to the function instead of $index.
Not sure if I understand your case but here is a JsFiddle trying to ask your question: Working example. I hope this help you.
You can pass the whole collection and the modified item to the onChange function, then find the element by its id and make your action (calculate total). The same is posible just passing the element index.
It is jus an example, you can do this in few ways.
$scope.onChange = function(collection, item){
collection.forEach(function(prod){
if(prod.id === item.id){
prod.total = prod.qty * prod.price;
}
});
}
You can try like this below code and also check this plunker link for you example working scenario.
Template:
<tr ng-repeat="so in itemForPOS">
<td><button type="button" class="btn btn-danger btn-sm" title="Add to POS tab" ng-click="remItem($index)"><i class="fa fa-times-circle-o"></i> remove</button></td>
<td>{{so.code}}</td>
<td>{{so.name}}</td>
<td><a><input type="number" value="{{so.price}}" style="text-align: center; border: 0;width: 100px" ></a></td>
<td><a><input type="number" ng-model="so.qty" ng-change="changeQty(so)" placeholder="0" style="text-align: center; border: 0;width: 100px"></a></td>
<td><a><input type="number" ng-model="so.dscnt" style="text-align: center; border: 0;width: 100px" placeholder="0"></a></td>
<td><a><input type="number" ng-model="so.subTotal" style="text-align: center; border: 0;width: 100px" placeholder="0"></a></td>
</tr>
Controller:
$scope.changeQty = function(item) {
if(item.qty>0){
item.subTotal = parseInt(item.price*item.qty);
}
getTotal();
};
function getTotal(){
var tot=0;
for (var i = 0; i < $scope.itemForPOS.length; i++) {
tot = tot + $scope.itemForPOS[i].subTotal;
}
$scope.totalAmount= tot;
}
There are many solutions given by others already, so I'm going to point out your mistakes here.
As you show in the screen shot, you have a total amount for each row, so assigning many total amounts into a single variable $scope.totalAmount is going to create problem. Same to $scope.presyo.
A simple way to fix this issue is to assign all variables into their respective row object, so each row can have their own total amount.
ng-model for each inputs should also be bound to row object as well, so changing quantity 1 row wouldn't update quantity on other rows.
And an improvement, you can pass the whole item instead of index only in the other function.
// instead of
$scope.passItem = function(index) {
var itemNu = $scope.itemLoad[index].itemNo;
var descrptn = $scope.itemLoad[index].desc;
var cashPrice = $scope.itemLoad[index].cash;
// do this
$scope.passItem = function(item) {
var itemNu = item.itemNo;
var descrptn = item.desc;
var cashPrice = item.cash;
This can be achieved by changing the signature of the changeQty method
FROM
$scope.changeQty = function(qty) {
$scope.qnty = qty;
if($scope.qnty>0){
$scope.totalAmount = $scope.presyo*$scope.qnty;
}
console.log($scope.totalAmount) }
TO
/*The new method now works on the item that is edited and not just the quantity. This method will execute after the ng-model for the control is updated. Hence, item.qty will contain the updated quantity.*/
$scope.changeQty = function(item) {
// This step is not necessary
// $scope.qnty = qty;
if(item.qty>0){
item.subTotal = item.price*item.qty;
} else {
// #TODO Write code to remove item from the itemsPOS
}
// Now we can recaculate the total
reCalculateTotal();
// console.log($scope.totalAmount)
}
function reCalculateTotal() {
$scope.counter = $scope.itemsPOS.length;
$scope.totalAmount = 0;
$scope.itemsPOS.forEach(function(item){
$scope.totalAmount += item.subTotal;
});
}
you can send 'it' into passItem function
<button type="button" ng-click="passItem(it)"><i class="fa fa-plus-circle"></i> Add</button>
and in js funcation:
$scope.passItem = function(item) {
var itemNu = item.itemNo;
var descrptn = item.desc;
var cashPrice = item.cash;
var qty = 1;
var totalSum = cashPrice*qty;
console.log(totalSum)
$scope.presyo = cashPrice;
$scope.itemsPOS.push({'code':itemNu, 'name':descrptn, 'price': cashPrice, 'qty': qty, 'dscnt': 0, 'subTotal': totalSum});
console.log($scope.itemsPOS)
$scope.counter = $scope.itemsPOS.length;
$scope.passItem = function(index) {
var seletectedItem = JSON.parse(JSON.stringify($scope.itemLoad[index]));
var itemNu = seletectedItem.itemNo;
var descrptn = seletectedItem.desc;
var cashPrice = seletectedItem.cash;
var qty = 1;
var totalSum = cashPrice*qty;
console.log(totalSum)
$scope.presyo = cashPrice;
$scope.itemsPOS.push({'code':itemNu, 'name':descrptn, 'price': cashPrice, 'qty': qty, 'dscnt': 0, 'subTotal': totalSum});
console.log($scope.itemsPOS)
$scope.counter = $scope.itemsPOS.length;

How to get distinct value using lodash in ReactJS?

How to get distinct value using lodash in ReactJS? Now I'm getting all the data. But how to avoid printing duplicate data? Actually it is a filter box. So data repetition I've to avoid. Can anyone help me out?
Function:
comboClick () {
var apiBaseUrl = "http://api.eventsacross-stage.railsfactory.com/api/";
var input = this.state.search_event;
let self = this;
axios.get(apiBaseUrl+'v1/events/?on_dashboard=false'+input)
.then(function (response) {
let events = response.data.events;
self.setState({events: events});
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
Jsx Part:
<div className="dropdown text-center">
<button
className="btn btn-default dropdown-toggle"
type="button"
data-toggle="dropdown"
style={{width: "50%"}}
onClick={this.comboClick.bind(this)}>
Place
<span className="caret"></span>
</button>
<ul className="dropdown-menu">
{this.state.events.map(function (event, i) {
return (
<div key={i}>
{event.locations.map(function (locations, j) {
return (
<li key={j}><p>{locations.city}</p></li>
)
})}
</div>
)
})}
</ul>
</div>
You can use _.uniqBy, as per documentation:
This method is like _.uniq except that it accepts iteratee which is
invoked for each element in array to generate the criterion by which
uniqueness is computed. The order of result values is determined by
the order they occur in the array. The iteratee is invoked with one
argument: (value).
I've added an example:
var locations =
[
{city:"city1"},
{city:"city2"},
{city:"city3"},
{city:"city1"},
];
var locationsUnique = _.uniq(locations, 'city');
console.log(locationsUnique);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
UPDATE:
From the method shared in the comments I'm guessing that what you want to do is something like:
comboClick() {
var apiBaseUrl = "api.eventsacross-stage.railsfactory.com/api/";
var input = this.state.search_event;
let self = this;
axios.get(apiBaseUrl + 'v1/events/?on_dashboard=false' + input).then(function(response) {
let events = response.data.events;
for (var i = 0; i < response.data.events_count; i++) {
var obj = response.data.events[i];
console.log(obj.locations);
//Assuming that obj.locations has the locations that you want to display
var locationsUnique = _.uniq(obj, 'city'); //Added this line
console.log(locationsUnique); //Added this line
}
for (var j = 0; j <= obj; j++) {}
self.setState({events: events});
}).catch(function(error) {
console.log(error);
});
}

Bound AngularJS template not changing in angular datatable

I am using angular data table from below link
http://l-lin.github.io/angular-datatables/archives/#!/bindAngularDirective
I am using the defer rending concept here.
I have 2 button
Active (Show when user status is 1)
Inactive (Show when user status is 0)
As 2 way data binding not working here. I am unable to show Inactive button after clicking on active & viceversa
Below is my code
$scope.setCustomers = function (s, dto, dtc, f, c, h, t) {
s.dtInstance = {};
s.actions = {};
//dtOptions - Makes the ajax request to get the customer records, also builds the buttons to copy,csv,excel..etc
s.dtOptions = dto.fromSource('customers/showCustomers.json')
.withPaginationType('full_numbers')
.withDisplayLength(25)
.withOption('createdRow', createdRow)
.withDOM('<"html5buttons"B>lTfgitp').withDisplayLength(25);
// dtColumns - Builds the columns and renders the rows for each column
s.dtColumns = [
dtc.newColumn('name').withTitle('Name'),
dtc.newColumn('email').withTitle('Email'),
dtc.newColumn('phone').withTitle('Phone'),
dtc.newColumn('status').withTitle('Status')
.renderWith(function (data) {
return "<div style=text-align:center;>" + (data == 1 ? 'Accepted' : data == 2 ? 'Declined' : 'Pending') + "</div>";
}),
dtc.newColumn(null).withTitle('Actions').notSortable()
.renderWith(actionsHtml)
];
function createdRow(row, data, dataIndex) {
c(angular.element(row).contents())(s);
}
function actionsHtml(data, type, full, meta) {
s.actions[data.id] = data;
var actions = '<button ladda="loadingDemo' + data.customer_id + '" class="ladda-button ladda-button-demo btn btn-primary btn-xs" data-style="zoom-in" ng-click="resetPassword(actions[' + data.id + '])" uib-tooltip="Reset Password" tooltip-placement="top"><i class="fa fa-key"></i></button> '
+ '<i class="fa fa-money"></i></button> '
+ '<i class="fa fa-files-o"></i></button> '
+ '<i class="fa fa-eye"></i></button> '
+ '<i class="fa fa-pencil"></i></button> ';
if (data.is_active == 1) {
actions += '<button class="btn btn-success btn-xs" data-is_active="' + data.is_active + '" ng-click="setStatus(actions[' + data.id + '])" tooltip-placement="top" uib-tooltip="Inactive"><i class="fa fa-thumbs-up"></i></button> ';
} else {
actions += '<button class="btn btn-danger btn-xs" data-is_active="' + data.is_active + '" ng-click="setStatus(actions[' + data.id + '])" tooltip-placement="top" uib-tooltip="Active"><i class="fa fa-thumbs-down"></i></button> ';
}
return actions;
}
}
$scope.setCustomers($scope, DTOptionsBuilder, DTColumnBuilder, $filter, $compile, $http, toaster);
Thanks

ui-grid button in cell

So I have been struggling with this for like 2 days and still no clue on what to do...
First of all I'm very new to angular and javascript in general so everything I wrote can (and may) be extremely wrong.
sample data:
{
'title' : 'awesome title',
'date' : '19-05-2015',
'place' : 'nice place',
'person' : 'Juliet Peterson',
'status' : 'OK'
}
What I need is, in an existing ui-grid, add a column containing either
if myData.person contains only one persone, this person
if myData.person is empty the text 'No person'
if myData.person contains multiple persons the text 'Choose from' wich on click will popup a list for selection.
My problem is that I am curently unable to get that working. the 2 first cases work fine but i'm struggling for the last one.
We are using bootstrap so my heart goes for either a dropdown list or a popover button
here is my current code:
html:
<div id="grid_post_id" ui-grid="gridPostOpts" ui-grid-edit class="grid"></div>
js:
$scope.choosePerson = function(a) {
if (a.length == 0) {
return 'No person';
} else {
var split = a.split(',');
if (split.length > 1) {
var res = '<button type="button" class="btn btn-default" data-container="body" data-toggle="popover" data-placement="right" data-content="';
for (var i = 0; i < split.length; i++) {
res = res + split[i];
}
res = res + '">Choose from</button>'
return res;
} else {
return a;
}
}
}
$scope.gridPosteOpts = {
columnDefs : [
{
name : 'Title',
field : 'title',
enableCellEdit : false
},
[...]
{
name : 'Person',
cellTemplate : '<div class="ui-grid-cell-contents">{{grid.appScope.choosePerson(row.entity.person)}}</div>',
enableCellEdit : false
}
this code is almost working as i got the rigth data in my cell but it is displayed instead of being interpreted as html (ie my cell contains the string '<button type="bu...')
Use
cellTemplate : `
<div class="ui-grid-cell-contents">
<button type="button" class="btn btn-default" data-container="body"
data-toggle="popover" data-placement="right"
data-content="{{grid.appScope.choosePerson(row.entity.person)}}">
Choose from
</button>
</div>`
and have choosePerson() just return the data.
You can't inject elements into the DOM using angulars {{}}. It will always be text-only
Finnaly managed to do it by myself using a mix of differents approaches found on SO!
I used #j2L4e template for the case "button needed" and just the text for the othercases; i choose between the two with an ng-if
here is the "final" code:
$scope.containsComma = function(a) {return a.contains(',')};
$scope.choosePersonBis = function(a) {
if (a.length == 0) {
return 'No person';
} else {
var split = a.split(',');
if (split.length > 1) {
var res = '';
for (var i = 0; i < split.length; i++) {
res = res + split[i];
}
return res;
} else {
return a;
}
}
;
$scope.gridPosteOpts = {
columnDefs : [
{
name : 'Title',
field : 'title',
enableCellEdit : false
},
[...]
{
title : 'Person',
cellTemplate : `
<div ng-if="grid.appScope.containsComma(row.entity.person)"
class="ui-grid-cell-contents">
<button type="button" class="btn btn-default"
popover="{{grid.appScope.choosePersonBis(row.entity.person)}}"
popover-placement="right"
popover-trigger="focus">
Choose person
</button>
</div>
<div ng-if="grid.appScope.notContainsComma(row.entity.person)"
class="ui-grid-cell-contents">
{{grid.appScope.choosePersonBis(row.entity.person)}}
</div>`
}
};
try replace this code
<div class="ui-grid-cell-contents">{{grid.appScope.choosePerson(row.entity.person)}}</div>
with
<div class="ui-grid-cell-contents" ng-bind-html="grid.appScope.choosePerson(row.entity.person)"></div>

Resources