-
Notifications
You must be signed in to change notification settings - Fork 378
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Live localization #158
Comments
Hi Yohan, I've had a few stabs at trying to get what you're asking for working without changing the library itself. Ideally, applying localisation would happen live and only update the messages currently shown, but maybe the above will be enough for your needs. I think anything more would require a code change. Hope that helps |
Hi Ian, Thanks for your response. Your jsfiddle doesn't seem to work as I would have expected. When the Toggle method is called, the validation message is changed but the observable isn't re-validated so the text doesn't change. You have to change the text inputs and re-validate the controls to get the new message. |
Interesting. I only have IE8 at work (don't get me started), and the button causes the displayed messages to update immediately... I'll take another look at home where I have some sensible browsers. |
Sorry about reviving a zombie, but I'm having the same type of issue described above. @IanYates83 I hope you made it home ;) I'm running ko.validation.localize() to switch the output text when I click the localize button. But my text is never changing either live or on revalidate. I noticed in the validator:
The second time I run the localize function, the "obsv.error" always returns the first one. |
@Kikketer You need to revalidate the observable. You might achieve this with |
This might land in some future version if more people will ask for it. Add your 👍 in the comments if you find this feature needed. |
👍 |
We need this for the koco project & koco-i18next module. We might try to fork + pull request if we find the time to do it. |
👍 |
Hello Guys.
I think the ko.extenders.required messages are stick to the first assigned text on page load. It doesn't support live validation. Here a example of the code i'm using : <span data-bind="text: Resource.helloText">Hello default value</span> // Works
<input type="radio" value="1" data-bind="checked: Person.GenderId, checkedValue: 1" />
<input type="radio" value="2" data-bind="checked: Person.GenderId, checkedValue: 2" />
<span class="text-danger" data-bind="validationMessage: Person.GenderId">Please this field is required</span> // Doesn't switch the text function ViewModel() {
self.Person = {
genderId : ko.observable(false)
}
[...]
/* // Resource.json English file
* 'helloText' : 'Hello',
* 'pageTitle' : 'My Application',
* 'genderRequired': 'Please this field is required'
* // Resource.json french file
* 'helloText' : 'Bonjour',
* 'pageTitle' : 'Mon application ',
* 'genderRequired': 'Svp ce champ est requis'
*/
$.getJSON("server/ressource." + Globalize.culture().name.toString() + ".json", function (data) {
ko.mapping.fromJS(data, {}, self.Resource);
});
// Language switcher
self.SwitchLanguage = function () {
var activeLang = 'en-CA';
if (self.LanguageAppId() == 1) {
self.LanguageAppId(2);
}
else {
self.LanguageAppId(1);
activeLang = 'fr-CA';
}
Globalize.culture(activeLang);
$.getJSON("server/ressource." + Globalize.culture().name.toString() + ".json", function (data) {
ko.mapping.fromJS(data, {}, self.Resource);
});
}
[...]
self.Person.GenderId.extend({ required: { message: self.Resource.genderRequired() } });
} Source : https://github.com/jquery/globalize |
I'm a lurker on here as I use KO extensively but don't yet use the validation plugin. However, from what I can see in the code given by @Guerson, if the message parameter was updated such that it could take an observable as well as a static string then you'd be gold. That is, the final line could be
Note that the genderRequired observable is not being evaluated. Knowing very little about the code of this library it doesn't seem like it'd be too big an imposition or change to have the message renderer to use ko.unwrap to grab the message. Actually, for all I know it already does that - give it a try @Guerson |
Each time the observable is not being evaluated, i have this traceback. Uncaught TypeError: message.replace is not a function
with a traceback of :
ko.validation.formatMessage @ knockout.validation.debug.js:279validateSync @
knockout.validation.debug.js:877ko.validation.validateObservable @
knockout.validation.debug.js:947(anonymous function) @
knockout.validation.debug.js:831computedFn.evaluateImmediate_CallReadThenEndDependencyDetection @ knockout
3.4.0.debug.js:2142computedFn.evaluateImmediate_CallReadWithDependencyDetection @ knockout
3.4.0.debug.js:2114computedFn.evaluateImmediate @ knockout
3.4.0.debug.js:2078computedFn.evaluatePossiblyAsync @ knockout
3.4.0.debug.js:2044ko_subscribable_fn.notifySubscribers @ knockout-
[...] |
My guess is that being not evaluated, the code that's calling ko.validation.formatMessage function which is not anymore a string but something not evaluated. |
Is there a way to remove the validation and re-apply it without refreshing the page? |
@Guerson You can remove validation of an observable using the // Set up validation
var obs = ko.observable().extend({required: true, email: true});
// Remove validation
obs.extend({validatable: false}); |
Thank you for your quick answer. Finally, since all extenders messages are evaluated immediately, I'll change them through a function later and notify all subscribers directly. Only problem is (valueHasMutated/notifySubscribers()) will trigger an form validation. self.myExtend = self.Person.GenderId.extend({
required: { message: self.Resource.genderRequired()},
customExtender: { message: self.Resource.extenderRequired()}
}); [...] var obsv = self.myExtend;
obsv.rules()[0].message = self.Resource['genderRequired'](); // required
obsv.rules()[1].message = self.Resource['extenderRequired'](); // customExtender
if (obsv.name == 'observable' && typeof obsv.valueHasMutated === "function") {
obsv.valueHasMutated();
} else if (observ.name == 'computedObservable' && typeof observ.notifySubscribers === "function") {
obsv.notifySubscribers();
} It seems that is the only way for me right now to support my Single-page application. |
We have override the validation template and use a custom binding that uses the validation "message" as a key to look up a localised version of the display message. The localisation is tied to the current culture via a computed and will update all strings on a page without having to re-evaluate the validation conditions if the language is updated. The use the jQuery Globalize library based on Unicode/CLDR, to load and query |
I've tried numerous ways of doing what you say you are @slaneyrw . Whatever I try to manipulate the element with, it's overriden by the validation plugin and unsuccessful in doing so. Even this simple thing; and if I were to make that span's text-data-binding a ko.computed it won't ever be overwritten. It's always the validation message from the plugin. I can't even get it to update the message with the proper localization bundles. if I have loaded english and swedish, and try to switch with ko.validation.locale("en") and ("se"), having populated the localization with "en" and "se" before attempting to do so and the javascript files for the localization are loaded, it won't update the DOM when doing ko.validation.locale() . If I check the global scope, it has changed for instance ko.validation.rules.required to the appropriate locale, but the DOM is not updated. |
For what it's worth, I fixed this. See the above link. Unzip and load page.html in a browser for the demo. I modified knockout.validation.js and saved as knockout.validation.modified.js. My changes are marked "// Dan". I changed the error message object to a knockout observable. I also added some hooks in knockout.validation.fix.js to handle updating error messages when the bounded language changes. Finally local.js contains a small localization API and the localized strings are stored in localModel.js. |
Hi Eric,
Thanks for your great contribution.
Here's my issue:
I need to localize the validation message (i.e.: Field is required) when clicking a "localize" button. My application needs to be able to switch languages (fr-en) in a "live" fashion.
How would you proceed to accomplish this using your plugin?
Thanks!
Yohan
The text was updated successfully, but these errors were encountered: