MVC 5, globalize, validate german date: How to bundle the js-scripts? - asp.net-mvc

In the answer to this question (MVC 5 - can not get globalisation running) I solve the problem with a bunch of "<sript src="..." declarations and some js.
What I not managed: I want to bundle the scripts. If I try it like this (excerpt from bundleConfig.cs):
bundles.Add(new ScriptBundle("~/bundles/jqueryvalDe").Include(
"~/Scripts/jquery.validate.js",
"~/Scripts/jquery.validate.unobtrusive.js",
"~/Scripts/cldr.js",
"~/Scripts/cldr/event.js",
"~/Scripts/cldr/supplemental.js",
"~/Scripts/cldr/unresolved.js",
"~/Scripts/globalize.js",
"~/Scripts/globalize/currency.js",
"~/Scripts/globalize/number.js",
"~/Scripts/globalize/date.js",
"~/Scripts/globalize/plural.js",
"~/Scripts/globalize/relative-time.js",
"~/Scripts/globalize/unit.js",
"~/Scripts/jquery.validate.globalize.js"
));
But I get an error from JavaScript: "Globalize" is undefined
It seems, the order of scrpts is changed...
At the moment I use a Workaround: I wrote an custom HTM-Helper.
public static class GermanDateValidationExtension
{
public static MvcHtmlString ScriptsForGermanDateValidation(this HtmlHelper helper)
{
return new MvcHtmlString("<script src=\"~/ Scripts / jquery.validate.js\"></script>\n" +
"<script src = \"~/Scripts/jquery.validate.unobtrusive.js\"></script>\n" +
"<script src = \"~/Scripts/cldr.js\"></script>\n" +
"<script src = \"~/Scripts/cldr/event.js\"></ script>\n" +
"<script src = \"~/Scripts/cldr/supplemental.js\"></script>\n" +
"<script src = \"~/Scripts/cldr/unresolved.js\"></script>\n" +
"<script src = \"~/Scripts/globalize.js\"></script>\n" +
"<script src = \"~/Scripts/globalize/currency.js\" ></script>\n" +
"<script src = \"~/Scripts/globalize/number.js\"></script>\n" +
"<script src = \"~/Scripts/globalize/date.js\"></script>\n" +
"<script src = \"~/Scripts/globalize/plural.js\" ></script>\n" +
"<script src = \"~/Scripts/globalize/relative-time.js\"></script>\n" +
"<script src = \"~/Scripts/globalize/unit.js\"></script>\n" +
"<script src = \"~/Scripts/jquery.validate.globalize.js\"></script>\n" +
"<script>\n" +
"$.when(\n" +
"$.get(\"/Scripts/cldr/main/de/ca-gregorian.json\"),\n" +
"$.get(\"/Scripts/cldr/main/de/numbers.json\"),\n" +
"$.get(\"/Scripts/cldr/supplemental/likelySubtags.json\"),\n" +
"$.get(\"/Scripts/cldr/supplemental/timeData.json\"),\n" +
"$.get(\"/Scripts/cldr/supplemental/weekData.json\")\n" +
").then(function() {\n" +
"return [].slice.apply(arguments, [0]).map(function(result) {\n" +
"return result[0];\n" +
"});\n" +
"}).then(Globalize.load)\n" +
".then(function() {\n" +
"Globalize.locale(\"de-DE\");\n" +
"});\n" +
"</ script > ");
}
}
And use it in the view:
...
#section Scripts {
#Html.ScriptsForGermanDateValidation()
}
...
My question is: How to bundle the scripts correctly?

The problem seems originated from bundling order which rendered jquery.validate.globalize.js before globalize.js, which uses "dependency tree" established in favor of well-known libraries & their custom extensions will rendered before others. Hence, in order to set load order as you want, create a class which implements IBundleOrder interface & its corresponding extension method:
// from Sebastián Rojas (/a/26602075)
class UnorderedBundleOrderer : IBundleOrderer
{
public IEnumerable<BundleFile> OrderFiles(BundleContext context, IEnumerable<BundleFile> files)
{
return files;
}
}
static class BundleExtensions
{
public static Bundle UnorderedBundling(this Bundle bundle)
{
bundle.Orderer = new UnorderedBundleOrderer();
return bundle;
}
}
Then you can use custom bundling order above in BundleConfig.cs file:
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jqueryvalDe")
.UnorderedBundling()
.Include(
"~/Scripts/jquery.validate.js",
"~/Scripts/jquery.validate.unobtrusive.js",
...
...
"~/Scripts/globalize.js",
...
...
"~/Scripts/jquery.validate.globalize.js"
));
}
Related issue:
ASP.NET MVC - Bundle Config order
Ordering of Files within a bundle - What are the known libraries?

The solution is - how Tetsuya Yamamoto says: Write your own orderer.
public IEnumerable<BundleFile> OrderFiles(BundleContext context, IEnumerable<BundleFile> files)
{
return files;
}
and use it:
var qvDeBundle =new ScriptBundle("~/bundles/jqueryvalDe").Include(
"~/Scripts/jquery.validate.js",
"~/Scripts/jquery.validate.unobtrusive.js",
"~/Scripts/cldr.js",
"~/Scripts/cldr/event.js",
"~/Scripts/cldr/supplemental.js",
"~/Scripts/cldr/unresolved.js",
"~/Scripts/globalize.js",
"~/Scripts/globalize/currency.js",
"~/Scripts/globalize/number.js",
"~/Scripts/globalize/date.js",
"~/Scripts/globalize/plural.js",
"~/Scripts/globalize/relative-time.js",
"~/Scripts/globalize/unit.js",
"~/Scripts/jquery.validate.globalize.js"
);
qvDeBundle.Orderer=new UnorderBundleOrderer();
bundles.Add(qvDeBundle);

Related

how to display a WebView only after a javascript code is done?

I'm trying to force WebView to 'skip' images by using javascript. (like here: https://stackoverflow.com/a/31848599/13174607).
The problem is that the images are disappeared only after the WebView finished loaded. I want to display the WebView only after the javascript is finished.
This is my code:
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(webView, url);
webView.loadUrl("javascript:(function(){ var imgs=document.getElementsByTagName('img');" + "for(i=0;i<imgs.length;i++) { imgs[i].style.display='none'; } })()");
}
});
}
I tried to use setVisibility() method, like this:
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
webView.setVisibility(View.INVISIBLE);
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(webView, url);
webView.loadUrl("javascript:(function(){ var imgs=document.getElementsByTagName('img');" + "for(i=0;i<imgs.length;i++) { imgs[i].style.display='none'; } })()");
webView.setVisibility(View.VISIBLE);
}
});
}
but it didn't help.
Thanks!
EDIT:
By using the proposed solution and the #mustansir comments I wrote this code on 'onPageFinished':
webView.loadUrl("javascript:" + "function taskOne() {" +
"var imgFlag = 0;" + //will sign when the for loop ended
"var imgs = document.getElementsByTagName('img');" +
"if (imgs==0){imgFlag=1;} " +
"for (i = 0; i < imgs.length; i++) {" +
"imgs[i].style.display = 'none';" +
"if (i==imgs.length-1)" +
"{" +
"imgFlag=1;" +
"}"+
"}}" +
"taskOne();" +
"function taskTwo () {" +
"if(imgFlag==1){" +
"window.visibility.changeVisibility(); }" +
"else {" +
"setTimeout(taskTwo(),100);}}" +
"taskTwo();");
but the the webview doesn't become visible. Any idea why?
You can try injecting a JavaScript interface and call that interface method when you reach at the last image in the loop to change WebView visibility.
Something like this:
webview.addJavascriptInterface(this, "visibility");
and call this interface from your JavaScript like this:
var imgs = document.getElementsByTagName('img');
for (i = 0; i < imgs.length; i++) {
imgs[i].style.display = 'none';
if (i == imgs.length-1) {
visibility.changeVisibility();
}
}
Now define changeVisibility() with #JavascriptInterface annotation in that activity in which you have added javascriptInterface like this:
#JavascriptInterface
public void changeVisibility() {
runOnUiThread(() -> webview.setVisibility(View.VISIBLE));
}

File Read-Write Error in iOS

I have used following code for file reading and writing.
private void StorePuzzleData ()
{
FileInfo fileInfo = new FileInfo (Application.persistentDataPath + "\\" + difficultyLevel + puzzleId + ".txt");
if (fileInfo.Exists)
fileInfo.Delete ();
string fileData = string.Empty;
foreach (CellInformation cellInfo in cellInfoList)
fileData += cellInfo.RowIndex + "#" + cellInfo.ColIndex + "#" + cellInfo.number + "#" + cellInfo.CellColor + "#" + cellInfo.CellDisplayColor + "#" + (cellInfo.IsGroupComplete ? 1 : 0) + ",";
StreamWriter streamWriter = fileInfo.CreateText ();
streamWriter.WriteLine (fileData);
streamWriter.Close ();
DataStorage.StorePuzzleTimePassed (difficultyLevel, puzzleId, GameController.gamePlayTime);
}
private void ReadPuzzleData ()
{
// format: rownumber, colnumber, number, cellcolor, celldisplaycolor, isgroupcomplete
StreamReader streamReader = File.OpenText (Application.persistentDataPath + "\\" + difficultyLevel + puzzleId + ".txt");
string fileData = streamReader.ReadLine ();
}
But I am getting following error in actual iOS device running. This code working correct in iMac as well in android device.
Please give me some suggestion what changes I need to do to make this correct.
It seems you're using Windows-style paths in a Unix-like (Apple Mac OS) environment. Notice that on windows you have paths with a backslash like
C:\Users\Maxi\Desktop
On Unix-like system however something like
/var/mobile/Containers
You notice that in your faulty path you have mixed forward and backward slashes, which makes the path invalid.
/var/mobile/Containers/Data/Application/2.....\debutan1.txt
The correct way to always generate the correct path is to use the Path.Combine(string, string) function. This will combine two paths using the correct directory path seperator, which can also be seperatly accessed through Path.DirectorySeparatorChar.
So, in order to make your code correct, you would do
using System.IO; /* must be imported */
private void StorePuzzleData ()
{
FileInfo fileInfo = new FileInfo (Path.Combine(Application.persistentDataPath, difficultyLevel + puzzleId + ".txt"));
if (fileInfo.Exists)
fileInfo.Delete ();
string fileData = string.Empty;
foreach (CellInformation cellInfo in cellInfoList)
fileData += cellInfo.RowIndex + "#" + cellInfo.ColIndex + "#" + cellInfo.number + "#" + cellInfo.CellColor + "#" + cellInfo.CellDisplayColor + "#" + (cellInfo.IsGroupComplete ? 1 : 0) + ",";
StreamWriter streamWriter = fileInfo.CreateText ();
streamWriter.WriteLine (fileData);
streamWriter.Close ();
DataStorage.StorePuzzleTimePassed (difficultyLevel, puzzleId, GameController.gamePlayTime);
}
private void ReadPuzzleData ()
{
// format: rownumber, colnumber, number, cellcolor, celldisplaycolor, isgroupcomplete
StreamReader streamReader = File.OpenText (Path.Combine(Application.persistentDataPath, difficultyLevel + puzzleId + ".txt"));
string fileData = streamReader.ReadLine ();
}
If this still gives an "Access denied" error it must be because of filepermissions. Post the output of ls -la <thatpath> then.

in mvc4 return html file from different directory

Here is my code, actually i am trying to return a html file from other directory, and my code return the html page, but it doesn't return the Image of that page, can anyone suggest me how to do the same. Mean how to return the html page with image from different directory.
public ActionResult GetHtml()
{
//var encoding = new System.Text.UTF8Encoding();
//var htm = System.IO.File.ReadAllText(ConfigurationManager.AppSettings["ServerFilePath"].ToString()
+ "CPL\\" + "CPLPolicy\\" + "IMS.htm", encoding);
//byte[] data = encoding.GetBytes(htm);
//Response.OutputStream.Write(data, 0, data.Length);
//Response.OutputStream.Flush();
//Response.AddHeader("Content-Disposition", new System.Net.Mime.ContentDisposition { Inline = true, FileName = "index.htm" }.ToString());
//return File(ConfigurationManager.AppSettings["ServerFilePath"].ToString() + "CPL\\" + "CPLPolicy\\" + "IMS.htm", "text/plain");
//return File(ConfigurationManager.AppSettings["ServerFilePath"].ToString() + "CPL\\" + "CPLPolicy\\" + "IMS.htm", "text/html");
var result = new FilePathResult(ConfigurationManager.AppSettings["ServerFilePath"].ToString()
+ "CPL\\" + "CPLPolicy\\" + "IMS.htm", "text/html");
return result;
}
Based on your comments, it looks like your HTML pages use relative URLs like this:
<img src="testImage.jpg">
<img src="~/images/testImage.jpg">
The best thing to do is to update your HTML pages to absolute URLS like this:
http://www.yoururl.com/images/testImage.jpg
If you can't modify your HTML pages, then you need HTML Agility Pack. Then you can return the HTML like this in your controller:
string fileLocation = ConfigurationManager.AppSettings["ServerFilePath"].ToString() + "CPL\\" + "CPLPolicy\\" + "IMS.htm";
string html = System.IO.File.ReadAllText(fileLocation);
StringWriter writer = new StringWriter();
string websiteUrl = "http://www.yoursite.com";
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
foreach (var img in doc.DocumentNode.Descendants("img"))
{
img.Attributes["src"].Value = new Uri(new Uri(websiteUrl), img.Attributes["src"].Value).AbsoluteUri;
}
doc.Save(writer);
string content = writer.ToString();
return File(content, "text/html");

externalize properties in grails

I am trying to just externalize some custom properties in grails.
I cannot find a clear way on how to externalize some string properties and use them in my code.
Can any one please help me out.
You have to specify the location of the external configuration file in the config.groovy.
For example like this:
if (!grails.config.locations || !(grails.config.locations instanceof List)) {
grails.config.locations = []
}
// Internal Jetty: config-files are locates inside the /web-app/WEB-INF directory
if( GrailsUtil.isDevelopmentEnv() ) {
def dir = System.properties["base.dir"]
def f1 = "${dir}" + File.separator + "web-app" + File.separator + "WEB-INF" + File.separator + "${appName}-config.groovy"
grails.config.locations << "file:${f1}"
}
// TIER Tomcat: config-files are locates inside Tomcat's conf-directory
else if( System.properties["catalina.home"] ) {
def dir = System.properties["catalina.home"]
def f1 = "${dir}" + File.separator + "conf" + File.separator + "${appName}-config.groovy"
grails.config.locations << "file:${f1}"
}
// JBOSS, Glassfish etc
else {
//
}
// Further choices: command line argument (-D{$appName}.config.location=xxx)
if( System.properties["${appName}.config.location"] ) {
grails.config.locations << "file:" + System.properties["${appName}.config.location"]
}
So on local development the config file is locate under the WEB-INF directory.
While going life you have various choices of where to put your configuration file.
You can adapt, if needed, the code to works for config.properties in the same way.

Blackberry: Command line build and application auto-start

I have an application which is built from command line (ANT) using J2ME Polish. As such, this application is defined through a build.xml, not from Blackberry JDE project files.
What I need to do is have this application auto-start. This is easy enough to do once the application has been run for the first time (example). However, this does require the application to be manually run by the user (which I want to avoid).
The JDE provides options which you can check to enable auto-start, and from ANT:
<cldc runonstartup=="true"...
Will do the trick. The question is, how do I integrate this into a Polish buiild (i.e. into a Polish build.xml which is also building for other platforms)?
Anyone know what the auto-start option in the JDE actually does / what it changes?
So, the way to do this is, unfortunately, to change the J2ME-Polish source! As outlined in this bug report the J2ME Polish build framework (at version 2.1.4) doesn't pass on the RIM-MIDlet-Flags-x JAD attribute to RAPC.
The changes are relatively simple - merely passing on the RIM-MIDlet-Flags-1 value if defined in the JAD, otherwise setting it to zero (as the original 2.1.4 source does).
The diff (from 2.1.4) source:
Index: /enough-polish-build/source/extensions/de/enough/polish/blackberry/JarToCodFinalizer.java
===================================================================
--- /enough-polish-build/source/extensions/de/enough/polish/blackberry/JarToCodFinalizer.java (revision 315)
+++ /enough-polish-build/source/extensions/de/enough/polish/blackberry/JarToCodFinalizer.java (revision 316)
## -36,6 +36,7 ##
import java.util.Calendar;
import java.util.Locale;
import java.util.Map;
+import java.util.List;
import java.util.Properties;
import org.apache.tools.ant.BuildException;
## -185,6 +186,13 ##
}
}
File iconFile = null;
+ Map jadProperties;
+ try {
+ jadProperties = FileUtil.readPropertiesFile( jadFile, ':' );
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new BuildException("Unable to read JAD file " + e.toString() );
+ }
if (mainClassName != null) {
try {
/*
## -230,12 +238,26 ##
"MicroEdition-Configuration: CLDC-1.1",
//"MIDlet-1: Demo," + iconUrl + ",",
"MIDlet-1: " + env.getVariable("MIDlet-Name") + "," + iconUrl + ",",
- //"MIDlet-Icon: " + iconUrl,
- "RIM-MIDlet-Flags-1: 0"
+ //"MIDlet-Icon: " + iconUrl
};
+ /* Ensure that if RIM-MIDlet-Flags is defined in the JAD, it is
+ * passed on to RAPC to create the COD file.
+ * See https://developer.berlios.de/bugs/?func=detailbug&group_id=1246&bug_id=16901
+ * for details.
+ */
+ ArrayList newEntriesList = new ArrayList(Arrays.asList(newEntries));
+ final String flagsKey = "RIM-MIDlet-Flags-1";
+ String flagString = (String)jadProperties.get(flagsKey);
+ if (flagString == null) {
+ flagString = "0";
+ }
+ flagString = flagString.trim();
+ System.out.println("JarToCodFinalizer setting " + flagsKey + ": " + flagString);
+ newEntriesList.add(flagsKey+ ": " + flagString);
+
File rapcFile = new File( jadFile.getParent(), codName + ".rapc");
- FileUtil.writeTextFile( rapcFile, newEntries );
+ FileUtil.writeTextFile( rapcFile, newEntriesList );
} catch ( IOException e ) {
// this shouldn't happen
e.printStackTrace();
## -367,7 +389,6 ##
// now rewrite JAD file so that it is ready for OTA download:
// (first backup JAD file:)
//FileUtil.copy(jadFile, new File(jadFile.getParent(), jadFile.getName() + ".bak") );
- Map jadProperties = FileUtil.readPropertiesFile( jadFile, ':' );
Object[] keys = jadProperties.keySet().toArray();
for (int i = 0; i < keys.length; i++) {
String key = (String) keys[i];
Another polish user :)
Take a look at BB forums the 2nd post. Then using what we know about polish and jad attributes
Add this to your jad section of your build.xml
<jad>
<attribute name="RIM-MIDlet-Flags"
value="1"
if="polish.vendor == BlackBerry" />
</jad>
I haven't tested this but the logic seems to be valid :) Let me know if it works or not.

Resources