Can i use ngxErrors or something like it to display a form error? - forms

I use ngxErrors to display errors for a form control and it works great. Is there any way to get similar functionality for a form or a form group? Currently, I display a form error like this:
<div *ngIf="form.hasError('loginFailed')">
Login Failed
</div>
The bummer is, when I detect that there is a form error (e.g. after the login form is submitted) as opposed to control error, I set it like this:
this.form.setErrors({ loginFailed: true });
this.cdr.detectChanges();
Where this.cdr is an instance of ChangeDetectorRef. This is necessary because I'm using OnPush change detection strategy. So basically it's like calling $scope.$apply() from AngularJS all over again.
What I would really like to do is something more like how ngxErrors does it:
<div ngxErrors="myForm">
<div ngxError="loginFailed" [when]="['dirty', 'touched']">
The login has failed
</div>
But ngxErrors expects myForm to be a control.

This feature is not currently baked into ngxErrors, but I submitted a PR. https://github.com/UltimateAngular/ngxerrors/pull/18
The working syntax is a slight modification of the above:
<div ngxErrors>
<div ngxError="loginFailed" [when]="['dirty', 'touched']">
The login has failed
</div>
</div>
I learned that you do not have to tell child components the form, the FormGroupDirective is available to children automatically.

See this library https://www.npmjs.com/package/ng-error-messages for show error messages based on validation rules:
<input placeholder="Texto:" formControlName="text">
<div errorMessage="text" alias="Super Texto" ></div>

Related

Gorilla CSRF - Forbidden - CSRF token invalid - fails when there are two forms

I'm adding in CSRF token validation and I'm running into a problem where I have two forms on a page and one of them will submit successfully and the other will not. I'm not doing AJAX requests, I'm simply using hidden input fields. If I submit the form when it is the only one on the page, it submits without issue. If I submit it on a page with more than one form, it fails.
Below is the template code for my two forms
{{if .IsAuthenticated}}
<form action='/admin/logout' method='POST'>
<button>Logout</button>
{{.CsrfField}}
</form>
{{end}}
<form action='/admin/stuff/create' method='POST'>
{{with .Form}}
<div>
<label>Title:</label>
<input type='text' name='title' value='{{.Get "title"}}'>
</div>
<div>
<input type='submit' value='Publish stuff'>
</div>
{{end}}
{{.CsrfField}}
</form>
And this is what the generated HTML looks like. Both appear to be valid.
When I click the "Logout" button though, I get the Forbidden - CSRF token invalid error, but clicking the create input value in the second form always works.
The logout button is correctly validated when I attempt to use it on the home page which is "/admin/" but it does not work on any of the other pages "/admin/snippet/:id" or "/admin/snippet/create". The Logout button is part of a base template, so it appears on every page, so there shouldn't be anything different in how it appears on any page.
I've read other SO posts about multiple forms & CSRF tokens on a page and I understand there should be no issue with multiple forms with the same information as long as you have each one in it's own form, it should be fine. So I am not sure where I am going wrong.
I found the issue. Currently the way that gorilla/csrf works, it does not like creating the masked token from one path and then sending that token off to another path. So in my situation, going from /admin/snippet/create to /admin/logout threw an error because it was expecting the path for the token to be /admin/snippet/<something> and so it threw an error.
This issue has been addressed in this PR: https://github.com/gorilla/csrf/pull/147 and essentially the solution is to set the default path yourself to something which all of your routes will contain, so in my case that was /admin
This is what my CSRF declaration looks like now in main.go
var csrfMiddleWare = csrf.Protect(
[]byte("<put your 32 character key here>"),
csrf.Path("/admin"),
csrf.Secure(false),
)
A note, if you had this issue and then apply this fix and it doesn't resolve the problem, trying testing in a separate browser as there may be some caching issues.

How to determine that a Angular form is tried

How to determine that a Angular form is tried to submit or not to show invalid fields.
When you create a form in angular, then the form object contains a boolian property "submitted". It becomes true when user tries to submit a form.
<form #searchForm="ngForm" [ngClass]="{'FormTried':searchForm.submitted}"
(ngSubmit)="submitData(searchForm)" >
// your form fields
</form>
I used it to add a class for form tried to submit or not.
<form #empForm="ngForm" [ngClass]="{'FormTried':empForm._submitted}"
(ngSubmit)="submitData(empForm)" >
// added code here
</form>
I have used this and this works fine at my end, please try this also.

jquery mobile and knockout form submit binding

I stumbled on an apparent incompatibility between knockoutjs and jquery mobile when it comes to form submit behavior.
Consider the following markup:
<form data-bind="submit: myKoSubmitAction">
<!-- form fields here -->
</form>
The intention is that knockout prevents server post/get and instead calls myKoSubmitAction. jqm will also prevent standard submit behavior only for jqm the reason is that the form submit is replaced by an ajax request.
So while knockout (presumably) succeeds at preventing the standard server request, it fails to prevent jqm from sending an ajax request.
I found the answer to this problem in a google group and thought it should be on SO as well. See below
You can also add data-ajax="false" to the <form> element.
See Submitting Forms.
The best solution I have been able to find is the following custom ko binding:
//This binding fixes apparent incompatibility between knockout and jqm
ko.bindingHandlers.jqmsubmit = {
init: function (el, accessor, allbindings, vm) {
ko.bindingHandlers.submit.init(el, accessor, allbindings, vm);
$(el).submit(function (e) {
// prevent the submit behavior
e.preventDefault();
e.stopPropagation();
return false;
});
}
};
To be used in the place of the standard submit ko binding:
<form data-bind="jqmsubmit: myKoSubmitAction">
<!-- form fields here -->
</form>

grails form redirect gives 404, but url mapping works

I feel like I've entered the Twilight Zone. I have a Grails form that redirects to a URL, but gives a 404. If I go directly to that exact URL, everything works fine (that is, the URL mappings are correct).
This is an example generated form tag:
<form action="/alm/contactRefresh/itemRefreshProcess/7070" method="post">
On submit, it redirects to:
http://localhost:8080/alm/contactRefresh/itemRefreshProcess/7070
But gives this error:
HTTP ERROR 404
Problem accessing /alm/contactRefresh/itemRefreshProcess/7070. Reason:
NOT_FOUND
Powered by Jetty://
But then if I just go directly to that same URL (by focusing the browser Location bar and pressing enter), the page renders just fine, though the form params are lost because it's just a GET now. I've also tried changing the form method to GET, and that doesn't work either (throws a 404).
I've done similar forms a zillion times before with no problems. I'm sure this is some stupid user error, but I seriously can't figure out what's wrong.
Thanks for any ideas!
So, I finally started ripping parts out of the form and found out that for some reason you can’t name a Grails checkbox starting with the word "action". It must be something related to the default params["action"] entry. Though my checkbox names were a concatenation of "action_" + an id.
Anyway, there was some kind pre-processing of the checkbox form params that was blowing up before making it to the controller, and somehow that translated to a 404 instead of an actual Exception.
Originally I had this:
<g:checkBox name="action_${serviceRefreshAction.id}" value="${true}" />
Which renders this:
<input type="hidden" name="_action_7196" /><input type="checkbox" name="action_7196" checked="checked" id="action_7196" />
I changed "action" to "myAction", like this:
<g:checkBox name="myAction_${serviceRefreshAction.id}" value="${true}" />
Which renders this:
<input type="hidden" name="_myAction_7206" /><input type="checkbox" name="myAction_7206" checked="checked" id="myAction_7206" />
And now everything works fine.
Five hours of my life down the drain.
But I guess I have to forgive Grails, for the all time it saves me on a daily basis normally. :o)

How to architecture a webapp using jquery-mobile and knockoutjs

I would like to build a mobile app, brewed from nothing more but html/css and JavaScript. While I have a decent knowledge of how to build a web app with JavaScript, I thought I might have a look into a framework like jquery-mobile.
At first, I thought jquery-mobile was nothing more then a widget framework which targets mobile browsers. Very similar to jquery-ui but for the mobile world. But I noticed that jquery-mobile is more than that. It comes with a bunch of architecture and let's you create apps with a declarative html syntax. So for the most easy thinkable app, you wouldn't need to write a single line of JavaScript by yourself (which is cool, because we all like to work less, don't we?)
To support the approach of creating apps using a declarative html syntax, I think it's a good take to combine jquery-mobile with knockoutjs. Knockoutjs is a client-side MVVM framework that aims to bring MVVM super powers known from WPF/Silverlight to the JavaScript world.
For me MVVM is a new world. While I have already read a lot about it, I have never actually used it myself before.
So this posting is about how to architecture an app using jquery-mobile and knockoutjs together. My idea was to write down the approach that I came up with after looking at it for several hours, and have some jquery-mobile/knockout yoda to comment it, showing me why it sucks and why I shouldn't do programming in the first place ;-)
The html
jquery-mobile does a good job providing a basic structure model of pages. While I am well aware that I could have my pages to be loaded via ajax afterwards, I just decided to keep all of them in one index.html file. In this basic scenario we are talking about two pages so that it shouldn't be too hard to stay on top of things.
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<link rel="stylesheet" href="libs/jquery-mobile/jquery.mobile-1.0a4.1.css" />
<link rel="stylesheet" href="app/base/css/base.css" />
<script src="libs/jquery/jquery-1.5.0.min.js"></script>
<script src="libs/knockout/knockout-1.2.0.js"></script>
<script src="libs/knockout/knockout-bindings-jqm.js" type="text/javascript"></script>
<script src="libs/rx/rx.js" type="text/javascript"></script>
<script src="app/App.js"></script>
<script src="app/App.ViewModels.HomeScreenViewModel.js"></script>
<script src="app/App.MockedStatisticsService.js"></script>
<script src="libs/jquery-mobile/jquery.mobile-1.0a4.1.js"></script>
</head>
<body>
<!-- Start of first page -->
<div data-role="page" id="home">
<div data-role="header">
<h1>Demo App</h1>
</div><!-- /header -->
<div data-role="content">
<div class="ui-grid-a">
<div class="ui-block-a">
<div class="ui-bar" style="height:120px">
<h1>Tours today (please wait 10 seconds to see the effect)</h1>
<p><span data-bind="text: toursTotal"></span> total</p>
<p><span data-bind="text: toursRunning"></span> running</p>
<p><span data-bind="text: toursCompleted"></span> completed</p>
</div>
</div>
</div>
<fieldset class="ui-grid-a">
<div class="ui-block-a"><button data-bind="click: showTourList, jqmButtonEnabled: toursAvailable" data-theme="a">Tour List</button></div>
</fieldset>
</div><!-- /content -->
<div data-role="footer" data-position="fixed">
<h4>by Christoph Burgdorf</h4>
</div><!-- /header -->
</div><!-- /page -->
<!-- tourlist page -->
<div data-role="page" id="tourlist">
<div data-role="header">
<h1>Bar</h1>
</div><!-- /header -->
<div data-role="content">
<p>Back to home</p>
</div><!-- /content -->
<div data-role="footer" data-position="fixed">
<h4>by Christoph Burgdorf</h4>
</div><!-- /header -->
</div><!-- /page -->
</body>
</html>
The JavaScript
So let's come to the fun part - the JavaScript!
When I started to think about layering the app, I have had several things in mind (e.g. testability, loose coupling). I'm going to show you how I decided to split of my files and comment things like why did I choose one thing over another while I go...
App.js
var App = window.App = {};
App.ViewModels = {};
$(document).bind('mobileinit', function(){
// while app is running use App.Service.mockStatistic({ToursCompleted: 45}); to fake backend data from the console
var service = App.Service = new App.MockedStatisticService();
$('#home').live('pagecreate', function(event, ui){
var viewModel = new App.ViewModels.HomeScreenViewModel(service);
ko.applyBindings(viewModel, this);
viewModel.startServicePolling();
});
});
App.js is the entry point of my app. It creates the App object and provides a namespace for the view models (soon to come). It listenes for the mobileinit event which jquery-mobile provides.
As you can see, I'm creating a instance of some kind of ajax service (which we will look at later) and save it to the variable "service".
I also hook up the pagecreate event for the home page in which I create an instance of the viewModel that gets the service instance passed in. This point is essential to me. If anybody thinks, this should be done differently, please share your thoughts!
The point is, the view model needs to operate on a service (GetTour/, SaveTour etc.). But I don't want the ViewModel to know any more about it. So for example, in our case, I'm just passing in a mocked ajax service because the backend hasn't been developed yet.
Another thing I should mention is that the ViewModel has zero knowledge about the actual view. That's why I'm calling ko.applyBindings(viewModel, this) from within the pagecreate handler. I wanted to keep the view model seperated from the actual view to make it easier to test it.
App.ViewModels.HomeScreenViewModel.js
(function(App){
App.ViewModels.HomeScreenViewModel = function(service){
var self = {}, disposableServicePoller = Rx.Disposable.Empty;
self.toursTotal = ko.observable(0);
self.toursRunning = ko.observable(0);
self.toursCompleted = ko.observable(0);
self.toursAvailable = ko.dependentObservable(function(){ return this.toursTotal() > 0; }, self);
self.showTourList = function(){ $.mobile.changePage('#tourlist', 'pop', false, true); };
self.startServicePolling = function(){
disposableServicePoller = Rx.Observable
.Interval(10000)
.Select(service.getStatistics)
.Switch()
.Subscribe(function(statistics){
self.toursTotal(statistics.ToursTotal);
self.toursRunning(statistics.ToursRunning);
self.toursCompleted(statistics.ToursCompleted);
});
};
self.stopServicePolling = disposableServicePoller.Dispose;
return self;
};
})(App)
While you will find most knockoutjs view model examples using an object literal syntax, I'm using the traditional function syntax with a 'self' helper objects. Basically, it's a matter of taste. But when you want to have one observable property to reference another, you can't write down the object literal in one go which makes it less symmetric. That's one of the reason why I'm choosing a different syntax.
The next reason is the service that I can pass on as a parameter as I mentioned before.
There is one more thing with this view model which I'm not sure if I did choose the right way. I want to poll the ajax service periodically to fetch the results from the server. So, I have choosen to implement startServicePolling/stopServicePolling methods to do so. The idea is to start the polling on pageshow, and stop it when the user navigates to different page.
You can ignore the syntax which is used to poll the service. It's RxJS magic. Just be sure I'm polling it and update the observable properties with the returned result as you can see in the Subscribe(function(statistics){..}) part.
App.MockedStatisticsService.js
Ok, there is just one thing left to show you. It's the actual service implementation. I'm not going much into detail here. It's just a mock that returns some numbers when getStatistics is called. There is another method mockStatistics which I use to set new values through the browsers js console while the app is running.
(function(App){
App.MockedStatisticService = function(){
var self = {},
defaultStatistic = {
ToursTotal: 505,
ToursRunning: 110,
ToursCompleted: 115
},
currentStatistic = $.extend({}, defaultStatistic);;
self.mockStatistic = function(statistics){
currentStatistic = $.extend({}, defaultStatistic, statistics);
};
self.getStatistics = function(){
var asyncSubject = new Rx.AsyncSubject();
asyncSubject.OnNext(currentStatistic);
asyncSubject.OnCompleted();
return asyncSubject.AsObservable();
};
return self;
};
})(App)
Ok, I wrote much more as I initially planned to write. My finger hurt, my dogs are asking me to take them for a walk and I feel exhausted. I'm sure there are plenty things missing here and that I put in a bunch of typos and grammer mistakes. Yell at me if something isn't clear and I will update the posting later.
The posting might not seem as an question but actually it is! I would like you to share your thoughts about my approach and if you think it's good or bad or if I'm missing out things.
UPDATE
Due to the major popularity this posting gained and because several people asked me to do so, I have put the code of this example on github:
https://github.com/cburgdorf/stackoverflow-knockout-example
Get it while it's hot!
Note: As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live().
I'm working on the same thing (knockout + jquery mobile). I'm trying to write a blog post about what I've learned but here are some pointers in the meantime. Remember that I'm also trying to learn knockout/jquery mobile.
View-Model and Page
Only use one (1) view-model object per jQuery Mobile-page. Otherwise you can get problems with click-events that are triggered multiple times.
View-Model and click
Only use ko.observable-fields for view-models click-events.
ko.applyBinding once
If possible: only call ko.applyBinding once for every page and use ko.observable’s instead of calling ko.applyBinding multiple times.
pagehide and ko.cleanNode
Remember to clean up some view-models on pagehide.
ko.cleanNode seems to disturb jQuery Mobiles rendering - causing it to re-render the html. If you use ko.cleanNode on a page you need to remove data-role’s and insert the rendered jQuery Mobile html in the source code.
$('#field').live('pagehide', function() {
ko.cleanNode($('#field')[0]);
});
pagehide and click
If you are binding to click-events - remember to clean up .ui-btn-active. The easiest way to accomplish this is using this code snippet:
$('[data-role="page"]').live('pagehide', function() {
$('.ui-btn-active').removeClass('ui-btn-active');
});