Stefan Wittmann · Nov 20, 2015 go to post

You can manually escape ">" with ">". A more generic approach is to escape your CSS with ..EscapeHTML().

Stefan Wittmann · Nov 20, 2015 go to post

I just checked this on 16.2. The compiler does not complain about the ">" character in selectors:

&html<

<style type="text/css">
        .SourceFile > div{
color: black; background: #EEEEEE; font-size: 12pt;
}
</style>
>
Stefan Wittmann · Dec 15, 2015 go to post

Hi Fabio and Bernd,

<documentView>.disableItem(id,newState);

is really just a shortcut for 

<layoutItem>.$disable(newState);

Both only work on standard control elements, and only *if* the library rendering the widget in question don't add special logic. jQueryMobile implements their own styles and behavior for disabling and enabling elements, therefore, it is the most stable approach to leverage the jQM logic.

A long discussion regarding this topic can be found here: http://stackoverflow.com/questions/5875025/disable-buttons-in-jquery-mobile

Let's walk through this in the ZM.jQM145.HomePage.cls demo and disable/enable the main button with the caption "Start demo".

var view = zen('mainView');

var button = view.getItemByKey('start-show');

var id = button.$findElement().id;

$('#'+id).button('disable');

$('#'+id).button('enable');

Line 1 retrieves the documentView component while line 2 retrieves the button layout object. This is pretty basic. 

In order to run jQM logic we have to find the HTML DOM element we want to disable/enable with the $() method from jQuery. As it requires the physical id that Zen Mojo generated for us we store that in a local variable id in line 3.

Line 4 now looks up the jQM widget and disables it with the supported jQM library call. Line 5 enables the button again.

In the future, we may add support for $disable and these special library calls as we have done for $show and $hide. $show and $hide work on any widget from any supported plugin.

HTH,

Stefan

Stefan Wittmann · Jan 15, 2016 go to post

Sure. The best way to achieve this is to build your own custom theme using the jQM ThemeRoller application:

https://themeroller.jquerymobile.com

Add a swatch with a custom letter (e.g. "f") and define your theme by setting colors, fonts and so on for all elements. When you are done you can download the theme zip file and extract it in the directory where you serve your static files from.

Include your CSS file, instead of the default jQM CSS file and finally just set the defaultTheme of your jQMPageManager to the swatch you designed (e.g. "f") and you are done.

Stefan Wittmann · Jan 22, 2016 go to post

I don't see this either. I am using Safari. Just had a quick look at the cookies, what looks like the session cookie expires for me at February 10th.

But I agree that you should be redirected to the page you looked at after you log in. 

Stefan Wittmann · Jan 22, 2016 go to post

Not sure what is going on here, as the code looks fine. What class do you extend from? The only difference I can spot is that your class method is calling ..Lookup, instead of ##class(Ens.Util.FunctionSet).Lookup

Stefan Wittmann · Jan 28, 2016 go to post

I think the Autocompile setting has to be set to false to allow what Ben is describing. The mapping of static files is done either by deploying them to "csp/broker" (making them available for all web applications) or by a proper mapping in your web server if you are using an external one.  

Stefan Wittmann · Jan 29, 2016 go to post

Functional indices are very powerful and allow you to implement additional indexing logic.  Thank you very much for composing this insightful post.

Stefan Wittmann · Feb 1, 2016 go to post

The obvious answer is to disable automatic windows updates. I guess the issue you are seeing is a troubled production after reboot? Or are there other issues?

Stefan Wittmann · Feb 3, 2016 go to post

I just had a similar problem. Currently, you have to switch to HTML mode, inject the break tag and switch back to WYSIWYG mode before you save the change. Don't save your formatted post in HTML mode. At least that worked for me.

Stefan Wittmann · Feb 4, 2016 go to post

The current architecture of Caché is process-based and I don't see an efficient way to achieve what you describe. If the set is huge enough it may pay off to start up a pool processes that can do the post processing. It does depend on the desired output: Another in-memory structure or persisted data.

Anyway, you want to make that you have a pool of processes that work on your set, you don't want to spin them up on demand as this will slow you down.

The work queue manager may be helpful to manage this.

https://community.intersystems.com/post/using-work-queue-manager-process-data-multiple-cores

Stefan Wittmann · Feb 4, 2016 go to post

Thanks for pointing this out. I totally agree and have updated the table to present all values in ms. As soon as I can upload the image (the process is not simple yet) I will update the article.

Update: I made the changes to the article.

Stefan Wittmann · Feb 6, 2016 go to post

This is a new feature, introduced in Caché 2016.2. I am currently investigating whether this is a current limitation or a bug.

Update: %Object can be mapped back to registered objects, but we are missing  a code path for composing a %Array instance into a registered object. Investigation still ongoing, but we are working on it. This code path will be supported in Caché 2016.2.

I will update this comment as soon as the functionality is available in a field test build.

Thank you very much for spotting and reporting!

Stefan Wittmann · Feb 6, 2016 go to post

Correct. That is the reason why this approach only makes sense if the processing takes a significant amount of time. Otherwise, the overhead of dumping the data twice is just not worth it.

Stefan Wittmann · Feb 8, 2016 go to post

John,

I've asked documentation to look into your first question. Documatic (class documentation) is available for system methods for sure.

Your understanding of the use of the word "namespace" is correct.

Stefan Wittmann · Feb 9, 2016 go to post

In my personal opinion, this is already a case where you want to switch from a routine to a class design. This way it is so much easier to keep track of the scope of your variables by defining them as properties of your class.

Working with publiclist and %-variables in routines can introduce a couple of side-effects, especially if these are not documented properly.

Stefan Wittmann · Feb 9, 2016 go to post

I have double checked this topic with our documentation group. The documentation talks about the concept of system methods in general here:

/csp/docbook/DocBook.UI.Page.cls?KEY=GJSON_intro#GJSON_intro_dao

We do not document formally how to define system methods, as this is reserved for InterSystems. See also the following quote from the above documentation link:

Note that there is no supported mechanism for customers to create system methods.

Nevertheless, we have to introduce the concept, so that you are aware what problem system methods are solving and how you can call them (using the dot dollar syntax).

Thanks,

Stefan

Stefan Wittmann · Feb 12, 2016 go to post

Hi Tim,

$compose works with deep structures but it replaces values of key-value pairs at the top level. It does not merge sub-arrays or sub-objects by default. Consider the following code:

SAMPLES>set o1 = {"a":1,"c":2,"deep":{"f":1,"g":1}}
 
SAMPLES>set o2 = {"b":1,"c":1,"deep":{"f":3,"j":1}}
 
SAMPLES>s o3 = o2.$compose({"returnValue":o1})
 
SAMPLES>w o3.$toJSON()
{"a":1,"c":1,"deep":{"f":3,"j":1},"b":1

You can easily spot, that the path "deep" in o3 has the value from o2 and completely misses "deep.g" from o1. We just copied the path "deep" from o2 into o1. We do provide a way  to override this behavior if you want to, but in a future release, we plan to ease this by introducing compose maps. I will cover this topic in more detail in an upcoming post.

Stefan Wittmann · Feb 12, 2016 go to post

Personally, I would not go for 4) and 1).

4) Allows invalid data to be entered and a class definition helps you to query users based on user data later on. This approach just limits your options in the future.

1) I don't like this approach just because it does not separate the concerns and it requires privileges.

2) and 3) are both good approaches. 2) Includes a sanity check because of the reference, but you have to be aware of this if you want to move user data between servers in case the users are not in sync.

I guess you are asking for ways to persist user data, but just in case: If you are building a CSP/Zen/Zen Mojo application you can store session data for a user in %session.Data. As soon as a transaction is complete and you want to store it you can go with approach 2) and 3) and persist the relevant data in your own class structure. 

Stefan Wittmann · Feb 12, 2016 go to post

You have to create two CSP applications, one for REST and another for regular calls, e.g.:

  1. /csp/samples/ for websocket and others
  2. /csp/samples/rest/v1/ for REST

HTH,

Stefan

Stefan Wittmann · Feb 12, 2016 go to post

You have to create a dedicated CSP application for REST calls using the %CSP.REST architecture as all calls that match the CSP application path will be forwarded to the REST dispatcher class.

Stefan Wittmann · Feb 15, 2016 go to post

$push/$pop is already available and the other methods you mentioned are on our list for 2016.3.

A $lb conversion utility is not on our roadmap at the moment. $compose is available starting with 2016.2 and helps to convert dynamic objects into registered objects and vice versa (e.g. %ListOfDataTypes and %ArrayOfDataTypes).

Stefan Wittmann · Feb 16, 2016 go to post

What I have done in previous projects is to link the correlated records, e.g.:

 ID           CitizenRef           RelocationDate                 City                        Surname         NextLocationId
...
 48          1000                       2015-04-01                          Boston                  Smith               49
 49          1000                       2015-07-01                          Seattle                  Smith               50
 50          1000                       2015-10-01                          Boston                  Smith               51
 51          1000                       2016-01-15                          NewYork              Smith               NULL

You can quickly filter for current locations by setting your filter to "NextLocationId IS NULL". This is not very different from the other comments so far, but this approach is more flexible.

If you ask the question: "Who lived in Boston and relocated to Seattle" you can check for the case (pseudo-filter)

City="Boston" AND NextLocationId.City="Seattle"

You can even ask more complex questions like "Who relocated to Boston and stayed longer than a year after living in NewYork?"

Stefan Wittmann · Feb 16, 2016 go to post

The managed provider uses TCP/IP.

The confusion probably stems from XEP (eXtreme Event Persistence).

XEP for dotNet still has an in-memory and a TCP/IP connection mode.  As Bill indicated we are moving away from the in-memory mode, as we are improving the throughput of the TCP/IP mode. We already deprecated the in-memory connection mode for XEP for Java where the performance is already pretty much the same. The in-memory connection mode has two issues as a) crashes on the client can interfere with the server and b) it does not allow the client to run on a different machine, which is a problem for scaling up.

Stefan Wittmann · Feb 16, 2016 go to post

Java yes, fuzzy for dotNet. It depends how well we can increase the throughput of the TCP/IP mode there.