angularJS dynamic login page - authentication

My code is here: http://plnkr.co/edit/2WDK0b
Is it possible that when I enter an existing username, the message in the "help-block" span will change dynamically?

Just wrap your existing checking code in a function in the controller. Like $scope.checkUsername = function() { //your existing code }
Now on your username input put ng-change="checkUsername()" and then it will work.
Before you get too much further make sure to read the validation bits from the Angular Form's guide: http://docs.angularjs.org/guide/forms
Here's a fiddle of your code working: http://plnkr.co/edit/LwMJGq?p=preview Although I think the logic for the name checking needs a bit of work.

Related

How to access value from react-native-cn-richtext-editor

I have successfully implemented react-native-cn-richtext-editor with limited toolbar functions.
I want to know that, how to get value (text that we have typed) from editor.
I am new in RN, have tried to get value but didn't get success. How can I resolve this issue, as I want to sent this text to server and then do further process.
In given example of this library there is method onValueChange on change the content object is present in value and to extract the value below example is there
onValueChanged = (value) => {
console.log(value[0].content[0].text)
}
Finally I got the solution of above question.
convert the value in HTML with convertToHtmlString write following command,
let html = convertToHtmlString(this.state.value)
for more details refer this github link

vue router: go up one (variable) level

seems nobody had this question before...? (or i just don't know the right words for it :D )
i want to have a very basic heading on every page of my app, which allows the user to go "up". simple as that.
example: user is on page.com/users/browse/, clicks on the heading, gets navigated to page.com/users/, clicks again, gets navigated to page.com. nothing more. it just has to be variable, so i can put it in a component and have it just work everywhere
how can i do that? i tried vue.$route, but there is only a string of the complete url. is there any convenient way to do it? or do i HAVE to split the url by / and build the route myself?
thanks :)
Try using this: this.$router.replace("./");
I don't know how it is working though. The single dot(./) will go up one path and double dots(../) will go up 2 paths!
This functionality has a name "Breadcrumbs".
Check this: 1, 2, 3 or look for this in your framework.
Try adding a method for going up one level by getting the route's path and then splitting it. Here's what worked for me:
upOneLevel(){
var upperPath = this.$route.path.split("/")
if(upperPath.length > 0) {
upperPath.splice(upperPath.length-1)
this.$router.push(upperPath.join("/"))
}
}
Then you can add a button that calls this method to go up by one level but no further than the root. This method will work regardless of whether or not your routes were nested properly.
this.$router.replace("./") will help if the user clicks on the heading only once, if he try to clicks again nothing is happen because vue-router avoid redundant navigation to the same location.
You can catch this error then navigate to the root, (or to a named route) if you have only two levels in your routes.
NOTE :
This function works only for two levels (see the example of this Question)
goUp() {
this.$router.replace("./").then(err =>{
if(err)
this.$router.replace("/");
// or : this.$router.replace({name:"home"}); for named routes
})
}
You can get the current path using this.$route.path and than remove the last party by splitting/splicing it:
goUp(){
var upperPath = this.$route.path.split("/")
if (upperPath.length > 2) {
upperPath.splice(upperPath.length - 1)
this.$router.push(upperPath.join("/"))
} else {
this.$router.push('/');
}
}
The already mentioned this.$router.replace("./"); will add a trailing slash.
If this is not your intention, use this.$router.replace(".");
Moreover, if you want to make a new history event, use this.$router.push(".");

Yii2 Gridview get all selected row for all pagination

I wrapped my gridview with Pjax widget like this
\yii\widgets\Pjax::begin();
gridview
\yii\widgets\Pjax::end();
in order to make the gridview make ajax request when I click on each pagination.
I also use ['class' => 'yii\grid\CheckboxColumn'], in column as well.
and I find that when I'm on first pagination I checked some rows and then go to second page and check some rows but when I go back to first page what I've checked is gone.
My question is how can I keep all checkedrow for all pagination
With current conditions (Pjax, multiple pages, yii\grid\CheckboxColumn) it's impossible because of the way it works.
When you click on the pagination links all GridView html content is replaced by new one that comes from the AJAX response.
So obviously all selected checkboxes on the previous page are gone.
Few possible ways to solve that:
1) Write custom javascript and server side logic.
As one of the options, you can send AJAX request to server with parameter meaning that user has chosen to select all data for the bulk delete operation (or use separate controller action for bulk deletion). In this case actually we don't need to get the selected data from user, because we can simply get them from database (credits - Seng).
2) Increase number of displayed rows per page.
3) Use infinite scroll extension, for example this.
4) Break desired action in several iterations:
select needed rows on first page, do action (for example, delete).
repeat this again for other pages.
You can get selected rows like that:
$('#your-grid-view').yiiGridView('getSelectedRows');
[infinite scroll] : http://kop.github.io/yii2-scroll-pager/ will work good if you do not have any pjax filters. If you have filters also in play, do not use this plugin as it does not support pjax filters with it. For rest of the applications it is perfect to use.
Update1 : it seems to be straight forward than expected, here is the how I accomplished it
Add following lines to the checkbox column
'checkboxOptions' => function($data){
return ['id' => $data->id, 'onClick' => 'selectedRow(this)'];
}
Now add following JS to the common js file you will have in your project of the page where this datagrid resides
var selectedItems=[]; //global variable
/**
* Store the value of the selected row or delete it if it is unselected
*
* #param {checkbox} ele
*/
function selectedRow(ele){
if($(ele).is(':checked')) {
//push the element
if(!selectedItems.includes($(ele).attr('id'))) {
selectedItems.push($(ele).attr('id'));
}
} else {
//pop the element
if(selectedItems.includes($(ele).attr('id'))) {
selectedItems.pop($(ele).attr('id'));
}
}
}
Above function will store the selected row ids in the global variable array
Now add following lines to pjax:end event handler
$(document).on('pjax:end', function () {
//Select the already selected items on the grid view
if(!empty(selectedItems)){
$.each(selectedItems, function (index,value) {
$("#"+value).attr('checked',true);
});
}
});
Hope it helps.
I just solved this problem and it works properly with Pjax.
You may use my CheckboxColumn. I hope this can help. The checked items are recorded with cookies.
You can read the part with //add by hezll to understand how to fix it, because I didn't provide a complete general one.
Hope it works for you.
https://owncloud.xiwangkt.com/index.php/s/dGH3fezC5MGCx4H

web2py SQLFORM accepting too fast

I have a web2py SQLFORM that gets generated and returned by an AJAX call and the form is put in a DIV I defined.. I want that SQLFORM to be an update form, not an insert form. The problem is the form immediately runs it's accept function once it is written to that DIV. This doesn't happen if the form is for inserting, only updating. That initial accept fails and hitting the submit button does not allow for a second accept.
I don't know why the accept fails or why it happens immediately.
heres the JavaScript function that makes the AJAX call
function displayForm(currID){
//Remove everything from the DIV we want to use
$('#window').empty();
//Call the ajax to bring down the form to update the series
ajax('{{=URL('newForm')}}/'+currID,
[], 'window');
}
And here is the newForm controller
def newSerForm():
record = db.myTable(request.args[0])
form = SQLFORM(db.myTable, record, fields=['series_name','image_thumbnail'])
if form.accepts(request.vars,session):
print 'Series update successful!'
else:
print 'Series update Failed...'
return form
displayForm is fired by clicking a button and once you do the form accepts and fails and the submit button doesn't work again. Is there a way to make an SQLFORM do this? The weird thing is if I change this to make inserts into myTable, it works fine. It behaves exactly as it should. But doing it this way doesn't work.
Ok now this is where it gets weird.
I tried to achieve the same functionality here with a totally different approach, an iFrame. I made new functions in my controllers that create the form based on request.args[0]. looks like this
def editEntry():
print request.args[0]
record = db.myTable(request.args[0])
form = SQLFORM(db.CC_user_submission, record, fields=['series_name', 'image_thumbnail']).process()
return dict(form=form)
And then a corresponding HTML page that just displays form. What could be simpler right? I go to that page based on a link that gives the correct argument. Take me to a page with a form for updating. Updating works perfect. Great, now lets put it in an iFrame instead of linking to it. I put it in an iFrame on the original page. Open up the iFrame. Doesn't work. I have no idea what is going is there any part of an explanation to this?
By using the iFrame method I actually got this one to work. Since it required an iFrame to be appended with jQuery which needs quotes and the iFrame URL which also needs quotes, the notation got pretty confusing but it's doable. Looked like this:
var myURL = "{{=URL('editEntry')}}/"+idArg.toString();
$('#window').append("<iframe src = " + myURL + " width='450' height='400'> </iframe>");
It's not pretty but it works.

Ng-grid with external data and TypeScript: compile error "Cannot set property 'gridDim' of undefined"

Update #1: after the fix I commented about, now my app starts but the grid is not rendered except for its bounding box and filter button and popup. Yet, I get no error from the console, and as far as I can arrive with the debugger, I can see that data got from the server are OK. If I use Batarang, I can see the scope corresponding to my model, correctly filled with items. I updated the downloadable repro solution accordingly. Could anyone explain why ng-grid is not updating here?
I'm starting to play with ng-grid and TypeScript and I'm finding issues as soon as my test app starts up. See the bottom of this post for a link to a full test solution. Surely I have made tons of errors even in these few files, but I'd like to have something to start with and learn more step by step.
The MVC app has two client-side applications:
app.js for the default view (Home/Index). No typescript here, and the whole code is self-contained in this single file. The code is derived from the paging example in the ng-grid documentation and tries to stay as simplest as possible.
MyApp.js for the more realistic sample in another view (Home/Model). This sample uses services, models and controllers and its JS code is compiled from TypeScript. To keep things simple, I'm just storing these components under Scripts/App, in folders for Controllers, Models and Services, and each file contains just a single class or interface. The generated JS files are manually included in the view.
app.js works, except that it has issues with filtering. I posted about these here:
Server-side filtering with ng-grid: binding issue?
MyApp.js has startup issues with ng-grid. As soon as the app starts, a TypeError is thrown in the grid binding:
TypeError: Cannot set property 'gridDim' of undefined
at ngGridDirectives.directive.ngGridDirective.compile.pre (http://localhost:55203/Scripts/ng-grid-2.0.7.js:2708:37)
at nodeLinkFn (http://localhost:55203/Scripts/angular.js:4392:13)
at compositeLinkFn (http://localhost:55203/Scripts/angular.js:4015:15)
at nodeLinkFn (http://localhost:55203/Scripts/angular.js:4400:24)
at compositeLinkFn (http://localhost:55203/Scripts/angular.js:4015:15)
at publicLinkFn (http://localhost:55203/Scripts/angular.js:3920:30)
at resumeBootstrapInternal (http://localhost:55203/Scripts/angular.js:983:27)
at Object.$get.Scope.$eval (http://localhost:55203/Scripts/angular.js:8057:28)
at Object.$get.Scope.$apply (http://localhost:55203/Scripts/angular.js:8137:23)
at resumeBootstrapInternal (http://localhost:55203/Scripts/angular.js:981:15) <div ng-grid="gridOptions" style="height: 400px" class="ng-scope"> angular.js:5754
The only similar issue I found by googling is https://github.com/angular-ui/ng-grid/issues/60, but it does not seem to be related to my case as there the grid options were setup too late.
The server side just has an API RESTful controller returning server-paged, sorted and filtered items.
You can find the full repro solution here (just save, unzip and open; all the dependencies come from NuGet); see the readme.txt file for more information:
http://sdrv.ms/167gv0F
Just start the app and click MODEL in the upper right corner to run the TypeScript app throwing the error. The whole app is composed of 1 controller, 1 service and 1 model.
For starters like me, it would be nice to have a simple working example like this one. Could anyone help?
This error means gridOptions has not yet been defined by the time that Angular attempts to parse ng-grid="yourArray", where yourArray is the same array supplied to gridOptions. I had the same problem after refactoring a previously working ng-grid.
So gridOptions must be defined before the element which has ng-grid="yourArray" attribute applied to it (rather than within that element's own controller).
I resolved this by defining gridOptions in an outer element somewhere (on global/app scope, for instance).
P.S. Maybe there is a better way, but this has worked for me.
Where you are adding data to your grid?
If you are writing $scope.myGrid={data:"someObj"}; in a success call then it won't work.
See the below reason:(which is listed in https://github.com/angular-ui/ng-grid/issues/60)
You can't define the grid options in the success call. You need to define
them on the scope in your controller and then set the data or column
definitions, etc... from the success call.
What you have to do?, First is to see how this made ​​your project and revizar if your queries or data access, the beams through a service, if so this I must add the file that manages routes app, the client side.
remain so.
'use strict';
angular.module('iseApp', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute',
**'ngGrid',**
'campaignServices',
'dialinglistServices',
'itemServices'
])
.config(function ($routeProvider, $locationProvider, $httpProvider) {
$routeProvider
As you are adding your ng-grid in a directive, you have to make sure the grid options are loaded before it tries to parse your html.
You could set a boolean in your link function :
scope.isDirectiveLoaded=true;
And then, in your template, use a ng-if :
<div ng-if="isDirectiveLoaded">
<div ng-grid="myGrid"/>
</div>
I got to the same issue, empty grid was rendered.
The way I got to it in the end was to setup my this.gridOptions in the constructor of the controller, within the component. In the options everything is referenced with $ctrl like this. So the data references $ctrl.gridData. gridData is specified as a property in my component controller. $ctrl is not defined as a property.
This was done in the constructor before the data was loaded. this.gridData was defined after in the constructor and then populated later in another function. The options were defined first, I think this is important from some things I read.
For the event hooks pass null instead of $scope.
this.gridOptions = {
enableGridMenu: true,
minRowsToShow: 25,
rowHeight: 36,
enableRowHashing: true,
data: '$ctrl.gridData',
rowTemplate: this.$rootScope.blockedRowTemplate,
onRegisterApi: ($ctrl) => {
this.gridApi = $ctrl;
this.gridApi.colMovable.on.columnPositionChanged(null, (colDef, originalPosition, newPosition) => {
this.saveState();
});
this.gridApi.colResizable.on.columnSizeChanged(null, (colDef, deltaChange) => {
this.saveState();
});
this.gridApi.core.on.columnVisibilityChanged(null, (column) => {
this.saveState();
});
this.gridApi.core.on.sortChanged(null, (grid, sortColumns) => {
this.saveState();
});
this.gridApi.core.on.filterChanged(null, (grid, sortColumns) => {
this.saveState();
});
}
};
In the row template I was referencing functions defined in my component. Before conversion to a component I referenced functions like this:
ng-click="grid.appScope.jumpToExport(row.entity);"
After conversion to the component I needed to add the $ctrl before the function name like this
ng-click="grid.appScope.$ctrl.jumpToExport(row.entity);"
And this is how the component is referenced in the html
<div ui-grid="$ctrl.gridOptions" ng-if="$ctrl.gridData.length != undefined && $ctrl.gridData.length > 0" class="data-grid" ui-grid-save-state ui-grid-resize-columns ui-grid-move-columns></div>