ng-click used inside ng-grid - angularjs

I'm hoping you can help me figure out how to merge my ng-click event into my code. I've been trying to figure it out all weekend. I found this ng-click event jsfiddle: http://jsfiddle.net/nisham/09k8f5s4/97/ that I want to use inside my project.
I want users to be able to see the grid and simply click a box and have it switch between 'Y' and 'N', back and forth.
I have tried many ways of incorporating the ng-click event into my webpage. Here is a plunker I made to make it easy to share: http://plnkr.co/edit/eTf96oJLIjtM7UiB742e?p=preview
I guess I need to figure out how to define the scope differently to add my function?
Do I need to use a to call the ng-click?
Do I need to add variables into my $scope.myData? Something like:
$scope.myData = [
{ time: "8:00am", monday: val, tuesday: val,
??????????????

You can do it by using cellTemplate for a column in column defination:
{
field: 'monday',
displayName: 'Monday' ,
cellTemplate: '<div class="ngCellText"><div ng-click="onClickFn(row.entity, col.field)">{{row.getProperty(col.field)}}</div></div>',
enableCellEdit: false
}
Check this working plunker.

Related

Angular ui-grid , add custom message to editableCellTemplate

I need to add a custom error message to cell when it is in editable mode, basically i just need to add message to the editable html template as follow
<a href=\'#\' data-toggle=\'tooltip\' data-placement=\'top\' title=\'error!\' ng-show=\'!inputForm.$valid\'>errMsg - {{customMsg}}</a>
i have just bind the customMsg to the global scope just for testing purposes , but still it doesnt seems to be appearing. sample plunker added here, it would be a great help if you can tell me what i am doing wrong here
Thanks
You might want to take a look at this answer
https://stackoverflow.com/a/28127498/1585304
When you are working with the ui-grid, you are actually working in an isolated scope.
This means that you cannot access to the parent scope simply by type the name of the var into your html.
In order to access to your customMsg variable, you need to refer to the parent scope using grid.appScope.
Your column definition should look more like this.
{
field: 'company',
displayName: 'Company',
enableColumnMenu: false,
editableCellTemplate: "<div><form name=\"inputForm\">
<input type=\"INPUT_TYPE\" ng-class=\"'colt' + col.uid\"
ui-grid-editor ng-model=\"MODEL_COL_FIELD\" minlength=3
maxlength=10 required><a href=\'#\' data-toggle=\'tooltip\'
data-placement=\'top\' title=\'error!\'
ng-show=\'!inputForm.$valid\'>errMsg - {{grid.appScope.customMsg}}
</a></form></div>"
}
The only problem is that is really hard to see the message since the form is almost completely hidden by the row.
Hope this helps.

Unintended Reset of Bootstrap Datepicker when using angularjs

I'm trying to use Bootstrap Datepicker from eternicode in combination with angularjs.
see jsfiddle
var app=angular.module('myApp', [])
.controller('dateCtrl', function($scope) {
// Case 1:
$scope.datepick = '';
// Case 2:
//$scope.datepick = '25.04.1986';
$scope.setFirstDate = function() {
$scope.datepick= '13.10.1960';
};
$scope.setAnotherDate = function() {
$scope.datepick = '20.02.1967';
};
});
$(document).ready(function(){
$('.datepicker').datepicker({
autoclose: true,
format: 'dd.mm.yyyy',
clearBtn: true,
todayBtn: 'linked',
todayHighlight: true,
weekStart: '1',
calendarWeeks: true,
keyboardNavigation: false
});
});
Essentially, it works fine. But when I change the date programmatically, BS Datepicker ignores it. This shows, when you initially load the fiddle and follow these steps:
1) Click on 'First me!'
2) Select the input field, without touching the datepicker
3) Tab out, press Esc, or click anywhere but the datepicker (close it without selecting a date)
You'll see, that the input field is now empty.
This does not happen because of an invalid date-format as suggested in this question: Uncomment line 6 in the fiddle and test case 2. Repeat above steps. The datefield now shows '25.04.1986'.
Also, in both cases you can test clicking the datepicker and then repeating steps 1-3. The input field will show the last date selected by the BS Datepicker.
{{datepick}}
shows, that the ng-model is always accurate, so this question is not a duplicate of this or this question. Seeing that angularjs is always aware of the actual date, I don't see how scope.apply would solve my problem.
This tells me: BS Datepicker is keeping track of his own and will only remember the initial date or the dates selected by the datepicker itself. And when closing without picking a new one, it will reset the input field to this remembered value.
So how can I prevent this from happening?
So, I found a workaround for this problem. To keep the Datepicker from resetting the input value, add:
forceParse: false
to your Datepicker options. See updated jsfiddle.
Even though this solves the problem at hand, keep in mind, that the Datepicker will no longer parse/check/correct any inputs.
I do believe this to be a bug and will create an issue at Github.

Display date and time of record with grid cell data

I am using a single-cell grid to show notifications in my application. How do I show date and time of notification with each cell data? The data is present in the model of the associated store. I want it to be something like the phabricator https://secure.phabricator.com/
Any pointers how I may do so?
One way to accomplish this would be to use a templatecolumn. You can then specify a tpl in the config of html representing the two sources of data.
Here is a fiddle I created demonstrating and simple and more complex tpl that resembles the data on the site you referenced.
Here is a simple example of a template column:
{
xtype: 'templatecolumn',
header:'Name',
tpl:'{first_name} {last_name}'
}
And a more complex template column with similar style to the one you referenced:
{
xtype: 'templatecolumn',
header: 'Example With Date',
flex: 1,
tpl:'<span style="display:inline-table;width:50%;">{first_name}</span><span style="width: 50%;display: inline-table;text-align: right;">{myDate}</span>'
}

Bootstrap Datepicker with angular JS issue (again)

I am trying to create an editable Grid in which there is a dateField which is editable. The cell will be shown as editable only if Cell is focussed
$scope.gridOptions = {
data: 'result',
enableCellSelection: true,
enableRowSelection: false,
enableCellEditOnFocus: true,
multiSelect: false,
columnDefs: [
{ field: 'name', displayName: 'Name', enableCellEdit: false, width: 60 },
{ field: 'age', displayName: 'Age', enableCellEdit: false, width: 60 },
{ field: 'sex', displayName: 'Sex', enableCellEdit: false, width: 90 },
{ field: 'dob', displayName: 'DOB', width: 150,
editableCellTemplate: '<input type="text" datepicker-popup="dd/MM/yyyy" is-open="true" ng-input="COL_FIELD" ng-model="COL_FIELD" datepicker-append-to-body=true />',
}
]
};
In the editableCellTemplate, if i am not using is-open="true", then pop up is not coming. If i am not using ng-input="COL_FIELD", focus is not getting removed from any cell. So, datepicker is not getting hidden .But if i am using both then, value is not getting selected. In the console the error says Expression 'true' used with directive 'datepickerPopup' is non-assignable!
There are a lot of questions on stackoverflow for this. I tried almost all, but no sucess.
What can be done? How can i remove the error? Please provide me with a working plunker. I am not able to create this issue with the plunker.
Edit
I think, i could not remove the error. The error is still the same
Expression 'true' used with directive 'datepickerPopup' is non-assignable!
How can i remove it? After removing it, i am sure it will work. I tried taking it as a scope variable, and referencing it, but value is not getting replaces as true in when i am checking it using Inspect element. If i am using it as a variable and concatenating the value in template like 'is-open="' + $scope.dateFormat.opened + '"' , still the same error is there.
Edit 2
What is this is-open used for? Somewhere i see its value equlas to true, somewhere just opened. In one of the example over here in Stackoverflow its just opened1 and opened2. What is this? And how to use this?
I have removed the error using bcombs technique
Edit 3
After further debugging, i found that, datePicker is getting opened (if i am using the method mentioned by bcombs)but, it is getting closed as soon as it is opening.
$scope.$on('ngGridEventStartCellEdit', function () {
debugger;
});
Edit 4
From more manipulation what i concluded is
If ng-input is used, then it breaks the 2 way binding. i.e If u change the date value textfield, then in the datePicker it will be reflected, but if you will try to change the value using datePicker, it will not be reflected in textField.
If you remove ng-input, this 2 way binding, remain correct, so it works, but this causes ngGridEventEndCellEdit event NOT fired. so, the focus is not getting lost. Value is getting selected, datePicker is getting closed (if instead enableCellEditOnFocus:true, i use enableCellEdit:true), but focus remains on the textField..
Need help. Hope the update helps in solving the issue
I'm no expert on bootstrap directives or their angular implementations... But to directly answer the question of how to remove the bug:
I'm fairly certain that the is-open attribute cannot be a primitive value. It needs to be a variable that will hold the (boolean) state of whether this particular widget is open. In my code, I use a single object to hold these flags for all my datepickers, such as:
openDatePickers: {}
Then, in the cellTemplate string, I give it a unique id such as:
' is-open="openDatePickers[\'dob_{{row.entity.name}}\']" '
(note that I'm using the "name" property to match your example, but a unique ID is preferred).
Edit in response to comment:
The celltemplate has access to its controller scope, so the simplest approach is to simply declare:
$scope.openDatePickers={};
As for how this works, it depends a little on which codebase you are using.
I'm using angular-ui, and in ui-bootstrap-tpls-0.8.0.js at line 1140 you can see where the directive manages the "is-open" attribute.
If the attribute is not supplied, the directive manages this flag internally with a closure, but behavior is different When the attribute IS supplied. The way the assignment works is straightforward in both cases: the variable (whether the internal closure, or the one you supplied in the attribute) is simply toggled between states.
Edit in response to your debugging
As far as the focus thing: I don't use ng-input or enableCellEditOnFocus. I do use:
enableCellSelection: true
...and our client didn't want manual edits of the field to be allowed, so my input element has:
ng-readonly="true"
This should be a functional workaround for your issue as long as your use case doesn't require that you allow manual edits to the input field.

Why there is time lag when using Kendo and angular JS

I am newbie to Angular and Kendo,My case is like buttons other than edit must disappear for other users in the query screen and it should appear for the owner of the query alone.
Now it disappears after some time lag say one minute,why this lag occur?
Any help on this is greatly helpful for me....
On analysis,identified the below points:
-the function called in ng-show is not triggered immediately where ng-show is wrapped inside a template,then checked by assigning a constant value for ng-show still there is a delay in triggering the ng-show.But fixed style worked correctly example style=display:none..
-then i identified that angularjs directives are not invoked immediately after rendering kendoui grid row template, there is some delay to invoke the angularjs directives
Code:
$scope.showButton = function(userId){
if($scope.loggedInUserId == userId)
{
return true;
}
else
{
return false;
}
};
$scope.model.columns = [
{ field: "name",title:"Name", width: 300},
{ field: "userId",title:"User Id", width: 100},
{ field: "lastModified",title:"Last Modified Date", width: 200},
{ field: "visibility",title:"Visibility", width: 100},
{ template: "<img title='Edit' src='content/images/glacier/2.0.1/generic/normal/png21/d_040_edit_normal.png' onmouseover=\"this.src='content/images/glacier/2.0.1/generic/active/png21/d_040_edit_active.png'\" onmouseout=\"this.src='content/images/glacier/2.0.1/generic/normal/png21/d_040_edit_normal.png'\" ng-click='viewQuery(#=id#);disableSave(\"#=userId#\")' alt='Edit'><img title='Make Public' src='content/images/glacier/2.0.1/generic/normal/png21/d_150_team_normal.png' onmouseover=\"this.src='content/images/glacier/2.0.1/generic/active/png21/d_150_team_active.png'\" onmouseout=\"this.src='content/images/glacier/2.0.1/generic/normal/png21/d_150_team_normal.png'\" ng-click='makePublic(#=id#)' ng-show='showButton(\"#=userId#\")' alt='Public'><img title='Make Private' src='content/images/glacier/2.0.1/generic/normal/png21/d_118_user_normal.png' onmouseover=\"this.src='content/images/glacier/2.0.1/generic/active/png21/d_118_user_active.png'\" onmouseout=\"this.src='content/images/glacier/2.0.1/generic/normal/png21/d_118_user_normal.png'\" ng-click='makePrivate(#=id#)' ng-show='showButton(\"#=userId#\")' alt='Private'><img title='Delete' src='content/images/glacier/2.0.1/generic/normal/png21/d_030_delete_normal.png' onmouseover=\"this.src='content/images/glacier/2.0.1/generic/active/png21/d_030_delete_active.png'\" onmouseout=\"this.src='content/images/glacier/2.0.1/generic/normal/png21/d_030_delete_normal.png'\" ng-click='deleteQuery(#=id#)\' ng-show='showButton(\"#=userId#\")' alt='Delete'>", title: "Operations" },
];
$scope.model.gridOpts = {
columns: $scope.model.columns,
filterable: { extra: false },
scrollable: true,
height: "230%",
pageable: true,
batch: false,
reorderable: true,
sortable: true,
editable: "inline",
};
Without having a JSFiddle to analyze, it will be hard to pin down the problem. But I'll provide a possible solution that you can at least investigate.
Angular is only able to hide those buttons after it, and everything it depends on, has started up. Which means downloading the angular code, waiting for everything else to load, parsing the HTML, resolving any data dependencies, etc. At that point it will make modifications to the DOM (which is when your buttons hide).
There are several ways to handle this, from using ng-cloak, not showing anything on the screen until it's been modified appropriately, or hiding all the optional controls and just showing what the user does have access to after Angular loads.
Here is one option which I just used in a project. Add this code at the TOP of your entry file (like index.html, default.html, whatever):
.ng-hide {
display: none !important;
}
Now apply the ng-hide class to any of those buttons you don't want to show until you know what they have access to.
By placing this at the top of the default file, it won't show at all until it's told to. If you place it in a .css file, then it will sometimes appear briefly until the .css file it loaded, parsed and applied.
Another option is to look at ng-cloak. You can try out it out here: http://plnkr.co/edit/?p=preview
The fact that it's taking upwards of 60 seconds I believe you said, leads me to believe that maybe it is waiting for required data to get resolved before it can analyze permissions.
If you don't understand how the resolve statement works in routes, you can read about here:
http://www.undefinednull.com/2014/02/17/resolve-in-angularjs-routes-explained-as-story/
I'm not sure if that will fix your problem, but once you can create a jsfiddle then you'll have many more people jumping in to answer this question.

Resources