sabrio / ng2-validation-manager

Validation manager library for Angular 2 (based on Laravel Validation method)
34 stars 14 forks source link

Support multiple language #10

Open ghiscoding opened 6 years ago

ghiscoding commented 6 years ago

Hello, I found your library while trying to find something easier to implement than the official Reactive Form. Your library seems to make this bridge possible (I find the core one immensely complex for no reason).

However, I need to support at least 2 languages (French/English which I'm both fluent with, so I could help with French translation). Would you have an easier way to deal with that in the near future? I would probably use ngx-translate in my projects since it supports dynamic translation (that is without reloading the page) and loading of translations through JSON files, is that an option for you?

Side note. Your lib looks very similar to the one I made in AngularJS 1.x since I also wrote it based on the excellent Laravel implementation as you did. If you want to take a look at it, it was named Angular-Validation and it supported a lot of ways to do validation (local, remote, multiple languages, ...). I'm talking in past time since I'm not intending to rewrite it for Angular2+, though it might give you ideas for future functionalities like multiple language support (I used Angular-Translations with external JSON files, the community helped me to bring it up to 11 locales, which you can see here). You could also peek around the Wiki, it's loaded.

sabrio commented 6 years ago

@ghiscoding I am also interested to bring this feature in but I don't have a much time these days. Let's start to discuss here, make a short plan and see what can we do: I can do the coding part but in order me to not wast a lot of time investigating around, you or someone else should do some investigation how can we bring this feature in, for e.x:

  1. How can we change the existing ones(validations text)
  2. How can we support multiple languages by default
  3. What we need to change(probably the method getError()
  4. How we will know the language has been changed (probably there should a service for this in ngx-validation)
  5. How we will change the initial language at the beginning ... We need to clarify this thing in order to start coding, I can take the coding part as I said before. Your experience should help us a lot to bring this in.
ghiscoding commented 6 years ago

Yeah I'm in the same boat as to what time I have available. I also have an Angular 4+ library for a datagrid and I'm planning on adding ngx-translate but I haven't yet. So once I do, I will report back.

Anyhow, the idea that I had in mind (which I'm also planning for my own lib) is to use ngx-translate with separate JSON files for each locales and replace all your error text by a translation key and translate them with the language that is currently loaded.

In regards to some of your questions

  1. How can we change the existing ones(validations text)
    • Move the English error text into en.json file
  2. How can we support multiple languages by default
    • Build multiple JSON files for each locales, since they are separate a new locale/language can be added at any point in time
  3. What we need to change(probably the method getError()
    • You could simply return the translation key and the error will be displayed in the correct language/locale trough: {{form.getError('username') | translate}} or create a new function if you don't want to change current behavior... getErrorKey('username') would be just fine.
  4. How we will know the language has been changed (probably there should a service for this in ngx-validation)
    • I don't think you need to care if you just returning the error translation key (as mentioned in 3.)
  5. How we will change the initial language at the beginning
    • Just set a default language used as default: this.translate.setDefaultLang('en') and if the user wants to change it, he will set his own default (translate is called with DI, so it's reflected on your side too). However, if you just return the translation key, then you don't even need this at all.

Also, the translate mentioned here is a Service called by dependency injection, so if the user changes his language, it will be reflected in your lib when you run a translation. This is assuming that the user also installs ngx-translate if he wants to use translation.

Note, I did not use ngx-translate at all (I'm just starting to look at it this week) and so I could be totally wrong.

sabrio commented 6 years ago

@ghiscoding great tip for getErrorKey('username'), it will do the job for 3,4 and 5. I think it will be good if we do not include any third party library for languages like ngx-translate in order to make this library more flexible and another thing what I am thinking about is: how can we support multiple languages by default and should we support?! If we do support by default multiple languages then we will have to think about those things like changing stuff, initial language ... etc what do you say?

ghiscoding commented 6 years ago

Yeah I was thinking that if you output only the translation key with getErrorKey('username') that might be enough. You could provide external JSON file as optional, user could use whatever lib they want to load the translations. This would make it quite flexible indeed.

Nonetheless, in my lib I would still include ngx-translate and use only external JSON files, user could use whatever else in their project (like the core i18n), the lib would be independent. I just think the i18n is too complex and beefy for such simple translations. I like ngx-translate because it offers dynamic translations and simple syntax (same as AngularJS 1.x). Anyhow, I would still be ok with just a translation key, I could point to your translation files (if you want to include them) or translate them myself (if you don't provide JSON file then make a list of the translation keys in your doc somewhere accessible).

Gotta love open source community sometimes, I got lot of ideas from here and there :)

sabrio commented 6 years ago

One more thing to discuss and we will be good to go, params(dynamic text), ngx-translate uses something like: <div>{{ 'HELLO {{dynamicPart}}' | translate:param }}</div> where param is object of keys and values. In this case we will have to provide another method for params, e.x getErrorParams(), @ghiscoding what do you say about this?

ghiscoding commented 6 years ago

That could be an idea or you could return everything inside an object. So maybe instead of getErrorKey('username'), you could use getErrorObject('username') that would return an object with the key and params properties. Like this

// Validation error object returned
{ 
    key: 'BETWEEN_LENGTH',
    params: {
        minValue: 2,
        maxValue: 10
    }
}

Then in the View

<div class="text-danger">{{ 'BETWEEN_LENGTH' | translate: userErrorParams }}</div>

Component

let userError = getErrorObject('username');
let userErrorParams = userError.params

Where the translation in the JSON file could be

"BETWEEN_LENGTH": "Text must be between {{minValue}} and {{maxValue}} characters in length."