Set uiCulture automatically based on browser accept language - asp.net-mvc

How I can set the culture of the ui automatically based on the users'browser?
All I found about this is Globalize.culture("pt-BR"); But it sets pt-BR as default and I dont want set this by default! I want only set this if the user is pt-BR!
How can I do this? And the validator methods, how can I set them for a specific culture?

In a ASP.NET MVC the web.config is the right place. There is a quick summary, the first snippet shows, how could be e.g. pt-BR culture forced
<globalization
enableClientBasedCulture="false"
uiCulture="pt-BR"
culture="pt-BR" />
If application is ready to accept the culture from the client (browser), settings should be
<globalization
enableClientBasedCulture="true"
uiCulture="auto"
culture="auto" />
The above setting will take a Language selected in client browser (e.g. cs-CZ in my case). If none is defined then system settings will be used.
Final snippet shows, how to allow client to set and send intended culture, but in case that no Language is pre-selected, override the system setting with some other default value pt-BR
<globalization
enableClientBasedCulture="true"
uiCulture="auto:pt-BR"
culture="auto:pt-BR" />
Extended: culture settings for jQuery validator and numeric input
Note: I am definitely not an expert in jQuery and globalization techniques. This is example how I do adjust validator to correctly process any numeric input
razor View part (X() is a shortcut for new HtmlString()):
var defaultThousandSeprator = "#X(culture.NumberFormat.NumberGroupSeparator)";
var defaultDecimalSeprator = "#X(culture.NumberFormat.NumberDecimalSeparator)";
jQuery part (custom methods for min and max)
$.validator.addMethod("min", function (value, element, param)
{
var num = value.replace(RegExp(" ", "g"), "") // remove spaces
.replace(RegExp('\\' + defaultThousandSeprator, "g"), "") // thousand separator
.replace(RegExp("\\" + defaultDecimalSeprator, "g"), "."); // fix decimals
return this.optional(element) || num >= param;
});
$.validator.addMethod("max", function (value, element, param)
{
var num = value.replace(RegExp(" ", "g"), "") // remove spaces
.replace(RegExp('\\' + defaultThousandSeprator, "g"), "") // thousands
.replace(RegExp("\\" + defaultDecimalSeprator, "g"), "."); // decimals
return this.optional(element) || num <= param;
});
And then jQuery.validator evaluates input values for cs-CZ: 10 000,00 correctly as well as en-US: 10,000.00.

You need to write out the script from the web page (or master page):
<script type="text/javascript">
Globalize.culture("<% = CultureInfo.CurrentCulture.ToString() %>");
</script>
That's it. Mind you, that I used CurrentCulture instead of CurrentUICulture, as this is what you should be using for formatting. If you need the translations (which I wouldn't do this way as it would hurt localizability), you'll need your original CurrentUICulture.

Related

html5 input type number with regex pattern in mobile

I'm trying to get regex pattern in input type number to show only numbers and dots.
I tried something like this.
<input type="number" pattern="[0-9.]*">
<input type="tel">
Both are showing only numbers (0-9), but not displaying . (dot). I need to use dot in input field.
Is it possible thru html5? Or Shall I go with javascript?
Note: This is working fine in Android, but . (dot) not displaying in iphones
I need to display mobile keypad like this..
Any help regarding this?
If you only specify "type=number" it will display keypad on iPhone like:
And if you specify pattern like <input type="number" pattern="\d*"/> or <input type="number" pattern="[0-9]*" />, then keypad on iPhone will be like :
Still it cannot display dot(.), currently there is no pattern to handle such case.
So you may opt for <input type="tel" /> which will provide keypad like:
Please refer to below links for more details on inputs for iOS:
http://bradfrost.com/blog/mobile/better-numerical-inputs-for-mobile-forms/
http://blog.pamelafox.org/2012/05/triggering-numeric-keyboards-with-html5.html
https://about.zoosk.com/nb/engineering-blog/mobile-web-design-use-html5-to-trigger-the-appropriate-keyboard-for-form-inputs/
http://mobiforge.com/design-development/html5-mobile-web-forms-and-input-types
http://www.petefreitag.com/item/768.cfm
http://html5tutorial.info/html5-contact.php
Hope this will help you. :)
Updates for customization (reference: https://stackoverflow.com/a/20021657/1771795)
You can do some customization using javascript.
Lets take example of currency input with decimals pattern in which e.which to read CharCode entered and then push it into an array (before) which represents digits before decimal mark and another array (after) to move values from (before) array past the decimal mark.
complete fiddle link
HTML:
<input type="tel" id="number" />
JS
Variables and functions:
// declare variables
var i = 0,
before = [],
after = [],
value = [],
number = '';
// reset all values
function resetVal() {
i = 0;
before = [];
after = [];
value = [];
number = '';
$("#number").val("");
$(".amount").html("");
}
// add thousand separater
function addComma(num) {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
Main code:
// listen to keyup event
$("#number").on("keyup", function (e, v) {
// accept numbers only (0-9)
if ((e.which >= 48) && (e.which <= 57)) {
// convert CharCode into a number
number = String.fromCharCode(e.which);
// hide value in input
$(this).val("");
// main array which holds all numbers
value.push(number);
// array of numbers before decimal mark
before.push(value[i]);
// move numbers past decimal mark
if (i > 1) {
after.push(value[i - 2]);
before.splice(0, 1);
}
// final value
var val_final = after.join("") + "." + before.join("");
// show value separated by comma(s)
$(this).val(addComma(val_final));
// update counter
i++;
// for demo
$(".amount").html(" " + $(this).val());
} else {
// reset values
resetVal();
}
});
Reset:
// clear arrays once clear btn is pressed
$(".ui-input-text .ui-input-clear").on("click", function () {
resetVal();
});
Result:
Not every input type and attribute is supported in all browsers. In general, most modern browsers from IE10+ include basics such as email and number.
The browser will revert to a standard text input when a specific type and ignore attributes when those values are not supported.
So you should use a good regular expression pattern.
for example
<input type="tel" name="tel" pattern="^(?:\(\d{3}\)|\d{3})[- . ]?\d{3}[- . ]?\d{4}$" />
1234567899
123 456 7899
123-456-7899
123.456.7899
supported
Browser support for 'tel' type
Android (yes)
iOS (yes)
IE (yes)
Mobile (yes)
Opera (yes)
Mobile (yes)
Opera (yes)
Classic (yes)
Opera Mini (no)
Firefox (yes)
Mobile (yes)
Chrome for Android (yes)
(Sources: caniuse.com, DeviceAtlas, mobilehtml5.org)
Browser support for pattern attribute
But the pattern attribute is supported in Internet Explorer 10, Firefox, Opera, and Chrome.
And is not supported in Internet Explorer 9 and earlier versions, or in Safari.
For iOS use the input attribute type="number", inputmode="decimal".
This will show the number pad with the “dots” on iOS 12.3+.
I had a similar scenario whereby I needed to support both comma and point as both the decimal mark and digit grouping [see here]
E.g.
1.00 / 1,00
1,000,000.00 / 1.000.000,00
At the same time the scenario required that the number keypad was displayed on mobile devices.
The initial implementation combined the 'number' type with the pattern attribute.
<input type="number" pattern="^(0*[,.]*[0-9][0-9]*([,.][0-9]+)*|[0-9]?[,.][0-9]*[1-9][0-9]*)$" required />
However the number validation failed inputs that the pattern would allow. This meant the field and thus form were marked as invalid.
The solution was to change the type to 'tel'.
<input type="tel" pattern="^(0*[,.]*[0-9][0-9]*([,.][0-9]+)*|[0-9]?[,.][0-9]*[1-9][0-9]*)$" required />
Mobile users would now see a number keypad by default, and the pattern validation would be used to validate the input.
Unfortunately it's not possible to achieve the exact functionality that you're looking for is not possible. However there is a kind of "hack" available which will give similar functionality:
http://www.brownphp.com/2011/05/iphone-currency-input-web-apps/ (Link broken)
It's a bit of JS which fills in the decimal automatically when the user starts typing, like this: 0.01 -> 0.12 -> 1.23 -> 12.34 . So this can be used for similar effect.

How to access leftover text in ng-tags-input

Is the left over text in input accessible programatically? If so, how?
I only allow tags from autocomplete (to use as search filters), and want to use the left over text as additional keywords, meaning I want to know if it's bound to anything so I can pass it to a search function.
Thanks for the help
That's not directly possible, but you can hack into the directive and make it work by using a helper directive:
app.directive('bindInternalInputTo', function() {
return function(scope, element, attrs) {
var property = attrs.bindInternalInputTo,
input = element.find('input'),
inputScope = input.scope();
inputScope.$watch('newTag.text', function(value) {
scope[property] = value;
});
};
});
Now you can bind some variable in the outer scope to the inner input by doing the following:
<tags-input ng-model="tags" bind-internal-input-to="variable"></tags-input>
Working Plunker
Please note that this solution isn't guaranteed to work with future versions of ngTagsInput since it relies on internal implementation details.

Insert dynamic text into Sitecore Rich Text field

I've been spending a bit of time with Sitecore recently, and I noticed the site I am working on has a copyright date in a Rich Text field. Unfortunately, it is 2012. Now, the easy way to fix this problem is to simply go in and change the Rich Text field which has the copyright information, but I don't want to have to worry about changing it in 2014.
Is there a way to insert dynamic text into the Text control? Even if I could have a sigil which I could manually replace in C# that would be preferable to either switching the Text for a Literal or force manual updates every year.
You can add your own processor to the renderField pipeline, check whether current field is RichText field and replace a token (e.g. __YEAR__) with current year:
<renderField>
<!--... other processors -->
<processor type="My.Assembly.Namespace.ReplaceTokenProcessor, My.Assembly" />
<!--... other processors -->
</renderField>
and the code of the processor:
namespace My.Assembly.Namespace
{
public class ReplaceTokenProcessor
{
public virtual void Process(RenderFieldArgs args)
{
if (args.FieldTypeKey != "rich text")
return;
args.Result.FirstPart = (args.Result.FirstPart == null) ? null : args.Result.FirstPart.Replace("__YEAR__", DateTime.Now.Year.ToString());
args.Result.LastPart = (args.Result.LastPart == null) ? null : args.Result.LastPart.Replace("__YEAR__", DateTime.Now.Year.ToString());
}
}
}
The solution Maras proposed works, but to me it sounds like a bit overkill for just one date in a RTE field.
Besides that, every RTE field that is rendered on every single page in your website is processed.
If it is only for one Year-value I would use a Literal and fill and replace the Text property of the Literal in Codebehind:
Literal.Text = FieldRenderer.Render(Context.Item, "RTE_FieldName")
.Replace("__YEAR__", DateTime.Now.Year.ToString());
Then add caching to the sublayout and it is only rendered once after the cache has been cleared.

All of a sudden, CultureInfo.CurrentUICulture does not reflect IE9 language preference in view?

Previously, I had no problem with this code in my view, and, it always properly reflected the user's language preference set in IE9:
#using (Html.BeginForm("Edit", "Revision", FormMethod.Post, new { id = "RevisionMain" }))
{
#Html.Hidden("UICultureLanguage", CultureInfo.CurrentUICulture.Name)
...
}
I recently added this code, and was also working for me previously. However, in between the last time this seemed to work, and the time it broke, the only thing my company did, was upgrade to Telerik Kendo; I don't see how that could have affected this, but the problem is that the above code and the below code, no longer properly reflect the user's language settings as chosen in IE9...
I have a code block in my view uses CultureInfo.CurrentUICulture.Name, but it appears to always be set to en-US, regardless of what I set my IE9 language preferences to. Note: this code is embedded in a #section:
**#section JQueryScripts** {
<script src="#Url.Content("~/Scripts/jquery-1.7.2.min.js")" type="text/javascript"> </script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"> </script>
<script src="#Url.Content("~/Scripts/jquery.validate.1.9.js")" type="text/javascript"> </script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"> </script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"> </script>
#* Language support for numerics that use ',' instead of '.' for decimal separator *#
<script src="#Url.Content("~/Scripts/jquery.validate.globalized.number-mvc4.js")" type="text/javascript"> </script>
#* Language support for jQuery datepicker *#
#{
var currentUiCultureName = CultureInfo.CurrentUICulture.Name;
var scriptFile = #Url.Content("~/Scripts/jquery/ui/1.8.1/i18n/jquery.ui.datepicker-" + currentUiCultureName + ".js");
// var scriptFile = #Url.Content("~/Scripts/jquery/ui/1.8.1/i18n-minified/jquery.ui.datepicker-" + currentUiCultureName + ".min.js");
// Note: If we have a language other than english (en/en-US), include the appropriate .js file to
// support the jquery datepicker. Nothing needed to include for english because A) english is
// the default language supported by the jquery datepicker and B) there is no physical .js file for
// english because it is not needed (see A).
//
// Attention: If a language is not supported, let the javascript error come up, so we know that the
// language needs to be supported.
//
if (!currentUiCultureName.Equals("en", StringComparison.OrdinalIgnoreCase) &&
!currentUiCultureName.Equals("en-US", StringComparison.OrdinalIgnoreCase))
{
<script type="text/javascript" src="#scriptFile"> </script>
}
}
}
My web.config currently has the following settings in globalization:
<globalization enableClientBasedCulture="true" uiCulture="auto" culture="auto" requestEncoding="utf-8" responseEncoding="utf-8" fileEncoding="utf-8" />
I also set CultureInfo.CurrentCulture to CultureInfo.CurrentUICulture in my controller, so that my model binds correctly for dates and my numeric values:
protected override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
// For model binding.
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture;
}
Very important to note: For some reason, if I set break points in both the OnAuthorization AND the code block in the jQueryScripts #section, OnAuthorization gets hit 3 times (I do have some ajax calls that may be causing this ($(document).ready(...), but have to verify, never noticed this before) - but Thread.CurrentThread.CurrentUICulture seems to only reflect the user's language preference properly on the LAST call, and the break point that I placed in the jQueryScripts #section, which queries CultureInfo.CurrentUICulture, gets hit on AFTER THE FIRST call to OnAuthorize. I know that OnAuthorize is not setting CurrentUICulture, but just pointing out that it seems that the user's language settings are being recognized in the controller, but not in the view. Very perplexying...any thoughts?
ANSWER
Would you believe that in my case, it appears to have been a Group Policy issue, which prohibited IE9 language changes being from being recognized by the web application on my local machine. Very odd, although the AD profile I had been using has had various issues since I first picked it up.

Kendo UI Conditional Button in ClientTemplate

I'm trying to get a conditional client template to work in a Kendo Grid that will call into my controller with a simple userName string as a parameter but I cannot figure out the syntax to get this working correctly.
My template is in my view like this:
columns.Bound(user => user.IsLockedOut).ClientTemplate(
"# if (IsLockedOut == true) { #" +
"<input type='button' value='Unlock Acc' onclick='location.href=" + #Url.Action("UnlockAccount", "Administration", new { userName = "#= UserName #" + }) + "/>" +
"# } else { #" +
"Unlocked" +
"# } #"
);
And the action method of the controller looks like:
public void UnlockAccount(string userName)
{
}
At the moment the error generated is:
CS1525: Invalid expression term '}'
I've been looking at this for a couple of hours now and I cannot see the wood for the trees now.
You have some '+' plus symbol that you do not actually need. Also you do not need the 'at' sign # in front of the helper.
new { userName = "#= UserName #" + }) //<- that last plus
This method worked for me.
const string ShowUpdateButton = "#if (IsNetReversal == false) {#<a class='k-button k-button-icontext k-grid-edit' href='\\#'><span class='k-icon k-edit'></span>Update</a>#}#";
const string ShowReverseButton = "#if (IsNetReversal == false) {#<a class='k-button k-button-icontext k-grid-reverse' href='/JournalDetail/Reverse/#: ID #' ><span class='k-icon k-reverse'></span>Reverse</a>#}#";
const string ShowDeleteButton = "#if (IsAdjustment == true) {#<a class='k-button k-button-icontext k-grid-delete' href='\\#'><span class='k-icon k-delete'></span>Delete</a>#}#";
You can do the template inline but I find it easier (particularly for multiple buttons) if you declare constants and then use string.format to concatenate them.
col.Template(o => o).ClientTemplate(string.Format("{0}{1}{2}", ShowUpdateButton, ShowDeleteButton, ShowReverseButton));
The upside is it will work with popup editor whereas jquery hacks will ignore the conditional status when a user cancels out of edit. A cancel from the popup editor will restore the grid row from the viewmodel or wherever Kendo stores it which results in button states from before any jquery/javascript hack. The method above will also auto-wire the standard commands since I copied their HTML output for the client template.
The downside is that if Kendo changes their pattern for command buttons the client template may fail. I tired several other methods besides this one and the downside to this method seems better than the other methods.
Note on Kendo Forums: As of the date of this post, they do not appear to allow people who do not pay for support to post to the forums so I would suggest posting questions here instead. They monitor Stack Overflow and in my experience they seem to answer questions more quickly here.
I've gotta a bit further but only by manually writing the URL like this:
"<input type='button' value='Unlock Acc' onclick='location.href=/Administration/TryUnlockAccount?userName=#= UserName #'/>"
Still doesn't call my controller method though but it does have the right parameter value ...

Resources