Git Product home page Git Product logo

Comments (32)

stephanrauh avatar stephanrauh commented on July 30, 2024

The error message that AngularJS doesn't know about the CalculatorController. Usually that's because the Javascript file hasn't been loaded. By default, the file "main.js" in the folder of the XHTML file is loaded automatically.

Another problem is that there's a breaking change in AngularJS 1.3. Many examples of mine still are based on AngularJS 1.2. The first few lines of the Controller have to look like so:

angular.module("AngularTetris", [ "angularfaces" ])
.controller('AngularTetrisController', ['$scope', function($scope) {

The old way seens to be broken:

function AngularTetrisController($scope) { old syntax - doesn't work with AngularJS 1.3

from angularfaces.

DimaSol avatar DimaSol commented on July 30, 2024

Thank you for the fast answer.
It did seems to solve the previous issue but i now getting a new one:
(It seems that the way JSF concatenate IDs is problematic for angular?)
Any ideas?

angular.js.xhtml?ln=AngularJS:11594 Error: [$parse:syntax] Syntax Error: Token ':' is an unexpected token at column 14 of the expression [myform.j_idt5:firstNumberID.$error] starting at [:firstNumberID.$error].
http://errors.angularjs.org/1.3.9/$parse/syntax?p0=%3A&p1=is%20an%20unexpected%20token&p2=14&p3=myform.j_idt5%3AfirstNumberID.%24error&p4=%3AfirstNumberID.%24error
at REGEX_STRING_REGEXP (http://dimas_w7_64:8181/Bennu/javax.faces.resource/angular.js.xhtml?ln=AngularJS:63:12)
at Parser.throwError (http://dimas_w7_64:8181/Bennu/javax.faces.resource/angular.js.xhtml?ln=AngularJS:11998:11)
at Parser.parse (http://dimas_w7_64:8181/Bennu/javax.faces.resource/angular.js.xhtml?ln=AngularJS:11951:12)
at $parse (http://dimas_w7_64:8181/Bennu/javax.faces.resource/angular.js.xhtml?ln=AngularJS:12660:39)
at Scope.$get.Scope.$watchCollection (http://dimas_w7_64:8181/Bennu/javax.faces.resource/angular.js.xhtml?ln=AngularJS:14002:30)
at link (http://dimas_w7_64:8181/Bennu/javax.faces.resource/angularfaces-directives.js.xhtml?ln=AngularFaces:39:21)
at http://dimas_w7_64:8181/Bennu/javax.faces.resource/angular.js.xhtml?ln=AngularJS:8207:44
at invokeLinkFn (http://dimas_w7_64:8181/Bennu/javax.faces.resource/angular.js.xhtml?ln=AngularJS:8213:9)
at nodeLinkFn (http://dimas_w7_64:8181/Bennu/javax.faces.resource/angular.js.xhtml?ln=AngularJS:7722:11)
at compositeLinkFn (http://dimas_w7_64:8181/Bennu/javax.faces.resource/angular.js.xhtml?ln=AngularJS:7075:13) angular.js.xhtml?ln=AngularJS:11594 (anonymous function)angular.js.xhtml?ln=AngularJS:8544 $getangular.js.xhtml?ln=AngularJS:8215 invokeLinkFnangular.js.xhtml?ln=AngularJS:7722 nodeLinkFnangular.js.xhtml?ln=AngularJS:7075 compositeLinkFnangular.js.xhtml?ln=AngularJS:7078 compositeLinkFnangular.js.xhtml?ln=AngularJS:7078 compositeLinkFnangular.js.xhtml?ln=AngularJS:7078 compositeLinkFnangular.js.xhtml?ln=AngularJS:7078 compositeLinkFnangular.js.xhtml?ln=AngularJS:7717 nodeLinkFnangular.js.xhtml?ln=AngularJS:7075 compositeLinkFnangular.js.xhtml?ln=AngularJS:7717 nodeLinkFnangular.js.xhtml?ln=AngularJS:7075 compositeLinkFnangular.js.xhtml?ln=AngularJS:6954 publicLinkFnangular.js.xhtml?ln=AngularJS:1451 (anonymous function)angular.js.xhtml?ln=AngularJS:14384 $get.Scope.$evalangular.js.xhtml?ln=AngularJS:14483 $get.Scope.$applyangular.js.xhtml?ln=AngularJS:1449 bootstrapApplyangular.js.xhtml?ln=AngularJS:4182 invokeangular.js.xhtml?ln=AngularJS:1447 doBootstrapangular.js.xhtml?ln=AngularJS:1467 bootstrapangular.js.xhtml?ln=AngularJS:1361 angularInitangular.js.xhtml?ln=AngularJS:26054 (anonymous function)jquery-1.11.1.js.xhtml?ln=jQuery:3119 jQuery.Callbacks.firejquery-1.11.1.js.xhtml?ln=jQuery:3231 jQuery.Callbacks.self.fireWithjquery-1.11.1.js.xhtml?ln=jQuery:3443 jQuery.extend.readyjquery-1.11.1.js.xhtml?ln=jQuery:3474 completed

from angularfaces.

DimaSol avatar DimaSol commented on July 30, 2024

I've found a solution of putting prependId="false" on the form tag.
Is there any other better solutions?

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

Yes, unfortunately there's a nasty incompatibilty between AngularJS, jQuery and JSF. You can work around it by adding prependId="false" to the form.

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

I've spent a couple of days finding a better solution - to no avail. You could configure a different separator character in the web.xml. But every character is either illegal in JSF, forbidden by AngularJS or doesn't work in jQuery. So the only solution is to add prependId="false" or to reort a bug to the AngularJS project.

from angularfaces.

DimaSol avatar DimaSol commented on July 30, 2024

another maybe better workaround maybe to put in the web.xml:

<context-param>
    <param-name>javax.faces.SEPARATOR_CHAR</param-name>
    <param-value>-</param-value>
</context-param>

This will replace the ":" to "-" or any other pre-defined char.

from angularfaces.

DimaSol avatar DimaSol commented on July 30, 2024

using prependId="false" will cause issues with jsf dataTables I think, Am I mistaken?

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

It's funny you find the solution at the same time I jot them down :).

I tried the separator char, but ran into difficulties, too. Until now, I didn't find problems with prependId="false" - but maybe that's because I prefer PrimeFaces datatables or it's AngularJS counterparts (such as ngTable). BalusC reports somewhere on StackOverflow that prependId does cause problems (but I don't remember which ones).

from angularfaces.

DimaSol avatar DimaSol commented on July 30, 2024

How does PrimeFaces dataTable different from any other JSF dataTable?
If you'll put a component (such as inputText) inside a column the ID is seperated with ":" - look at the attached screenshot for "form:cars1:2:j_idt105" as a name.
(I've checked in: with http://www.primefaces.org/showcase/ui/data/datatable/edit.xhtml)
image

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

Ah, so that's the problem. AFAIK the Angular team believe that the colon is invalid in ids, so they don't support it (yet).

Maybe using a client side table is the better alternative. I've prepared a ngTable implementation:
https://github.com/stephanrauh/AngularFaces/blob/master/AngularFaces_2.0/AngularFaces-2.0-examples/src/main/webapp/carshop/ngtable.xhtml

Live demo of the both the PrimeFaces datatable and ngTable: http://angularfaces.net/showcase2.1/carshop/index.jsf

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

Hi @DimaSol,

I've got an idea how to solve the problem. Would you like to test my solution when I've finished programming?

Thanks in advance
Stephan

from angularfaces.

DimaSol avatar DimaSol commented on July 30, 2024

Sure. What is your approach / solution to this?

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

I thought of a kind of cheating. Or post-processing. It's possible to grab the HTML code and modify it before sending it to the browser (as I did in my BabbageFaces project). The idea is to replace the colons by - say - a string like "COLON". AFAIK the client side code of JSF doesn't really care about the colons, so this should be OK. However, the names of the input fields in subsequent requests don't match the expectations of the JSF framework. But I suppose it suffices to modify the ids, which aren't sent back to the server. The names can keep their colons, because they aren't processed by jQuery or AngularJS.

If this theory is wrong, AngularFaces also has to intercept the request before it's request. In fact, it already does, but I'm not sure if it's possible to modify the request parameters, so my idea might fail.

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

Oh, I forgot to say "Thanks!" for your offer to test!

from angularfaces.

DimaSol avatar DimaSol commented on July 30, 2024

I'm afraid this kind of solution could be problematic because you can't know if the client (javascript) components implementation using the ":" seperator to identify cells in the grid.
I already developed few features to a grid that were based on the ":" separator on client side.
Any way what you are proposing is to change the seperator so why not to use javax.faces.SEPARATOR_CHAR? Am I missing somthing?

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

According to http://stackoverflow.com/questions/12615434/is-there-a-common-replacement-for-javax-faces-separator-char,
"ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

"Next to the colon, the only sensible choices are the hyphen, the underscore and the period. As the period is at its own also a special character in CSS selectors, it would have the same problem as the colon. So logically you don't have much other choice than the hyphen - and the underscore _."

As far as I remember, AngularJS doesn't accept the hyphen, and JSF itself has problems with the underscore. But I've forgotten the details.

from angularfaces.

DimaSol avatar DimaSol commented on July 30, 2024

I think using "-" should do the work, I was trying to find an issue with it in angularJS and did find anything yet... Any way I don't sure we should eliminate others (like ".") becasue it is a selector in jQuery as it can be easily escaped.

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

I wonder if it's enough to add the hyphen to the regular expression AngularJS complains about in your second stacktrace. I suspect line 175 of Angular.js explicitly forbids special characters - but I'm not sure, I can't wrap my head around this expression. I always thought that (.+) amounts to "any string consisting of at least one character":

var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/;

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

AngularJS doesn't accept the colon because it considers it a token - and it doesn't accept tokens in ids of $watchCollection objects:

Lexer.prototype = {
  constructor: Lexer,

  lex: function(text) {
    this.text = text;
    this.index = 0;
    this.tokens = [];

    while (this.index < this.text.length) {
      var ch = this.text.charAt(this.index);
      if (ch === '"' || ch === "'") {
        this.readString(ch);
      } else if (this.isNumber(ch) || ch === '.' && this.isNumber(this.peek())) {
        this.readNumber();
      } else if (this.isIdent(ch)) {
        this.readIdent();
      } else if (this.is(ch, '(){}[].,;:?')) {
        this.tokens.push({index: this.index, text: ch});
        this.index++;
      } else if (this.isWhitespace(ch)) {
        this.index++;
      } else {
        var ch2 = ch + this.peek();
        var ch3 = ch2 + this.peek(2);
        var op1 = OPERATORS[ch];
        var op2 = OPERATORS[ch2];
        var op3 = OPERATORS[ch3];
        if (op1 || op2 || op3) {
          var token = op3 ? ch3 : (op2 ? ch2 : ch);
          this.tokens.push({index: this.index, text: token, operator: true});
          this.index += token.length;
        } else {
          this.throwError('Unexpected next character ', this.index, this.index + 1);
        }
      }
    }
    return this.tokens;
  },

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

Yesterday I remembered what precisely is the issue with using special characters in AngularJS. I've created a demo on Plunkr to illustrate the point (http://plnkr.co/edit/RsaJNTK1VxJJkPAv22X9 - but be patient, Plunkr needs 3-5 minutes for some reason unknown). The name of the input field must not contain any special character other than the underscore. Otherwise, validation errors aren't reported by AngularJS. The same restriction seems to apply to any field you want to set a watch on.

image

<!doctype html>
<html ng-app="MyApp">
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-animate.min.js"></script>
<script type="text/javascript" src="angularjs-1.2.0-animate-app.js"></script>
</head>
<body>
  <h1>Using special characters in field names of AngularJS</h1>
  This demo shows that AngularJS only accepts the underscore as special character in input field names. In
  particular, the colon which is used in JSF is rejected.<br />
  <br />
<form name="userForm">
  This version uses an underscore within the field's name:<br />
  <div class="field">
    <label for="email_Address">Enter your email address:</label>
    <input type="email" name="email_Address" ng-model="data.email1" required />

    <!-- this stuff is WAY too complex -->
    <div ng-if="userForm.email_Address.$error.required" class="error">
      You forgot to enter your email address...
    </div>

  </div>

  <hr>
  This version uses a hyphen within the field's name:<br />

  <div class="field">
    <label for="email-Address">Enter your email address:</label>
    <input type="email" name="email-Address" ng-model="data.email2" required />

    <!-- this stuff is WAY too complex -->
    <div ng-if="userForm.email-Address.$error.required" class="error">
      You forgot to enter your email address...
    </div>

  </div>

  <hr>
  This version uses a colon within the field's name:<br />

  <div class="field">
    <label for="email:Address">Enter your email address:</label>
    <input type="email" name="email:Address" ng-model="data.email3" required />

    <!-- this stuff is WAY too complex -->
    <div ng-if="userForm.email:Address.$error.required" class="error">
      You forgot to enter your email address...
    </div>

  </div>

  <hr>
  This version doesn't use any special character in the field's name:<br />

  <div class="field">
    <label for="email:Address">Enter your email address:</label>
    <input type="email" name="emailAddress" ng-model="data.email4" required />

    <!-- this stuff is WAY too complex -->
    <div ng-if="userForm.emailAddress.$error.required" class="error">
      You forgot to enter your email address...
    </div>

  </div>


  <input type="submit" />
</form>

</body>
</html>

from angularfaces.

DimaSol avatar DimaSol commented on July 30, 2024

I'm getting errors for all the inputs you have created in your example.
I've also noticed that the errors seems to appear only when i'm defining the module like angular.module("calculatorApp", [ "angularfaces" ]) but if it will be without the angularfaces dependancy like angular.module("calculatorApp", []) erros won't appear. notice that the ids still contains the ":"...
I was hoping to debug it in my free time in the next days. Have any Idea why it can be?

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

Which example do you refer do? The Plunkr or the JSF Calculator app?

I've uploaded a version of my Tetris demo using the underscore (see http://www.bootsfaces.net/AngularTetrisOnBootsFaces/). The ids look a bit odd (j_idt16_j_idt29 instead of j_idt16:j_idt29, but so far everything works. But I don't use a serverside JSF dataTable in the demo, so maybe that doesn't mean anything :(.

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

without the angularfaces dependancy like angular.module("calculatorApp", []) erros won't appear

AngularFaces 2.1 renders error messages on the client side (using the AngularJS components pui-message and pui-label). Probably that's why you need the dependency. You can suppress client-side messages by defining a standard JSF h:message tag. In this case, error messages are rendered on the server, and colons aren't a problem at all.

from angularfaces.

DimaSol avatar DimaSol commented on July 30, 2024

In the Plunkr demo you have created, the validation works fine for all 4 fields so I still missing the problem with using other separator instead of ":". The "_" is really looks a bit odd but i still think "-" can do the job pretty good (unless I'm still missing a point).

from angularfaces.

DimaSol avatar DimaSol commented on July 30, 2024

I understand that without using "angularfaces" dependency the errors are rendered in the server but the thing is that the IDs of the components still contains the ":" separator so I would expect to get the same errors in javascripts so I can only assume it somehow related to the dependency of "angularfaces" and this is what I want to figure out...

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

I start to suspect the problem isn't the id, but the name of the field.
But then, I couldn't set a watch on an id containing a ":", so ids seem
to be problematic, too.

Hm... do we have the same Plunkr demo? The error message I'm referring
to is the line "You forgot to enter your email address". The second and
third example don't show it. The red border and the HTML view in the F12
tool show that AngularJS does detect the errors correcty, but it doesn't
put the error messages into the form. In other words, the
ng-if="userForm.email-Address.$error.required" condition is always false.

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

Here's the screenshot belonging to the previous comment:
image

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

Hi Dima,

is there any progress on your side?

Cheers,
Stephan

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

AngularFaces 2.2-SNAPSHOT now copes with colons. I re-implemented the label and the message component. However, several AngularJS components or functions don't allow colons, so application developers may run into problems.

from angularfaces.

stephanrauh avatar stephanrauh commented on July 30, 2024

AngularFaces 2.1.3 has been published.

from angularfaces.

DimaSol avatar DimaSol commented on July 30, 2024

Hi Stephan,
I had a pretty busy time so didn't yet had a chance to check it out.

from angularfaces.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.