971-270-0003 info@singlecoilinc.com

Happy New Year!

We at Single Coil Inc wish all of you a Happy Holiday and a Happy New Year.

2014 was an exciting year for S1c, we thank our amazing customers for looking at us to provide technical expertise when/where needed.  Also, we have been working on something a bit different than the typical work we’ve been doing – we will be making an official announcement very, very soon and are looking to start the new year of with a big bang!

We hope you have a fantastic, safe and Happy New year!

– The S1c Team.

 

 

 

 

 

Using CSS Flexbox for Headache-Free Layouts

Historically, a major shortcoming of CSS has been its lack of a simple, streamlined layout mechanism. When developing a page layout of any significant complexity , the CSS can quickly devolve into endless spaghetti of “float”s and “clear”s,  and hackish, ugly mechanisms like negative margins. And the developer in question had better pray that he or she is working with some fixed-sized elements, lest there be no concrete reference point for anything on the page, and things become even more of a convoluted nightmare. In short, arranging elements in a reliable and fluid manner has been a notoriously painful task.

Thankfully, many of these concerns have been remedied with the introduction of the CSS flexbox (flexible box) model. The flexbox model is specifically designed to build scalable, fluid layouts using a straightforward, intuitive system. It is supported by all major modern browsers (even IE!), and it takes little time to learn/understand.

I will explain some of the fundamentals of the flexbox system. The flexbox layout is initiated by using the following rule on a parent container:

display: flex;

Important Note: Like many new CSS features, the “-webkit-“, “-moz-“, and “-ie-” prefixes need to be used with some versions of Webkit, Firefox, and Internet Explorer browsers, respectively. Refer to the CanIUse page for more details.

Unlike block or inline layouts, the elements within a flex container do not have to be given explicit rules to define their orientation and size in relation to one another, or in relation to their parent container. The benefit of the flex system is that the elements will automatically be sized / positioned relative to their parent. Some things to know about flexbox:

  • Floats do not apply to items in a flexbox layout.
  • Clears do not apply to items in a flexbox layout.
  • Vertical aligns do not apply to items in a flexbox layout.

With the flexbox model, some of the most headache-inducing features of CSS are eliminated entirely! Want to align something dead center (horizontally and vertically) in its parent? Just set on the child:

margin:auto;

(JSFiddle)

Want to “float” it to the right? Set on the child:

margin-left:auto;

and on the parent:

justify-content:flex-end;
flex-direction:row;
align-items:center;

(JSFiddle)

Want if you want the content to be spaced evenly to fill its parent container? Just make the following change to the previous rules:

justify-content:space-around;

(JSFiddle)

You can also specify the direction that the content will flow (i.e. horizontally or vertically) with the flex-direction rule. The following makes content flow vertically:

flex-direction: columns;

(JSFiddle)

These are just some of the many options available in the flexbox model. I’ve only scratched the surface of its power, but it’s already made my web development experience a whole lot more enjoyable.

 

Swift-ly venturing into an iOS future

Swift is the new Xcode language being promoted by Apple. I decided it was best to figure out how to use this language and learn its benefits first hand.

Why did Apple decide a new language was needed?  One major reason is that Objective-C (cocoa) has a bad reputation: hard to learn, ugly, convoluted and a plethora of [[[brackets]]].  Some of these complaints were true, some were just nit-picking. Is Objective-C hard to learn? Not in my experience, and it got much easier with the advent of ARC. Is it ugly? Yes, with arbitrary prefixes instead of namespaces (the NS in NSString originated with a company that hasn’t existed in nearly two decades!) and convention-breaking syntax (i.e. “YES”/”NO” instead of “true”/”false” or “becomeFirstResponder”/”resignFirstResponder” instead of “focus”/”blur” or even “self” instead of “this”), the average C/C++ developer would paraphrase C3PO, “I don’t know where your Mac learned to communicate but it has the most peculiar dialect.”

As the releases rolled on, Apple conformed more and more to accepted conventions (You could declare arrays like “@[‘a’,’b’,’c’]” instead of “[[NSArray alloc] initWithObjects: ‘a’,’b’,’c’,nil];” and if Objective-C is allowed to develop, by Xcode 9 we’d have something approaching C#.  However in doing so, the syntax would become so complex supporting new and old conventions making code much more unreadable.  A better, cleaner approach was to create a new language using modern software coding paradigms.  Enter Swift.

My very first foray into Swift was a new simple class I intended to add to an existing project.  One of the benefits of Swift is that it can be mixed in with existing projects that were built using Objective-C. However, upon creation of the swift file, the IDE informed me that I also needed a bridging class between Objective-C and Swift; additionally, I looked into how to access from Swift extern const NSStrings defined in Objective-C and saw that also wasn’t straightforward.  I the proceeded to remove my newly created Swift class, rewrite it in Objective-C and shelve my Swift learning for another day–it’s always a good idea to learn how to walk before you learn how to run.

So now I return to Swift learning with a simple project.  I want a Swift app that allows me to fill out a form and after clicking “Submit” shows the form on the next view.

Here are my steps:

1. Create the Swift Xcode Project.
I created a new Single View project called “Swift Test”.
I chose the “Swift” language for the project.
I set the device to iPhone (simpler than universal or iPad).
Lastly, I checked the “use Core Data” checkbox. Strictly speaking, this wasn’t necessary because I have no plans to store any data.  However, I wanted to see what the generated methods looked like in Swift compared to those I am used to for Objective-C Core Data.

The files created were named similarly to their Objective-C cousins: AppDelegate.swift & ViewController.swift–but there are no headers!  Looking at the methods in the classes yielded some nice surprises–gone are the ugly “#pragma mark”s and in their place are normal(-ish)comments (“// MARK: – …”) used to delineate regions in code. Also gone were the godawful “YES” and “NO” boolean values–application:didFinishLaunchingWithOptions returns “true”!! (BTW, I know that “true” and “false” are legal in Objective-C, but they’re not the convention and the last thing I want is some Mac fanboy to think I’m a noob after looking at my code.).

The next thing I notice is the total lack of semicolons. I’m apprehensive towards this mostly because of memories of time wasted tracking down missing whitespace while debugging TCL/TK back in college.  Semicolons clearly delineate one statement from the next, but mostly I think out of habit I’m going to type them anyways–that is until I break that habit–then forget them all over the place when I return to Obj-C, C#, JavaScript, Java, PHP, and every other freaking language that uses them.

Continuing on, the next I see are “lazy var”s.  The method signature for the Managed Object Context is “lazy var managedObjectModel: NSManagedObjectContext”.  What’s a lazy var?  It is actually a very nice shorthand way to not initialize a value until it is actually used.  In Objective-C, gettermethods would often have a bit of boilerplate such as:


-(NSPropA) PropA{
if (propA == nil){
propA = [[NSPropA alloc] init];
}
return propA;
}

The above code will initialize the iVar propA the first time the property is accessed and then pass propA back for each subsequent call.

I imagine the Swift equivalent is closer to:


lazy var PropA: (NSPropA) = {
propA = NSPropA()
return propA
}()

A method body with half the internal line count!

Also, in the ViewController.swift file, I was pleased to see the keyword “override”; I always prefer to have a compiler ask me if I want to redefine some variable or method rather than just take me at my word.

2. Modify the Storyboard
After examining the code, I took to modifying the storyboard.  This was more-or-less the same as Objective-C (Although perhaps because this was my first wholly iOS 8.1 SDK project, I noticed some differences in segues and view sizes.)
I threw on a couple text fields for First and Last Name as well as a button labeled “Submit” and then segued (“present modally”) to another view where my message will be displayed.

3. Add the IBOutlets & IBActions.
Declaring IBOutlets in the Swift class file is  done like this:
@IBOutlet var firstName: UITextField!

The exclamation point (‘!’) is for required fields, but you can also use a question mark (‘?’) for optional fields–compare this to Strong and Weak Objective-C properties.

Hook the IBOutlets and IBActions up just like usual in the storyboard.

4. Write the methods (or are they functions now?)

I filled out my submit method by checking that both text fields were populated and showed a UIAlertController message if they were not.  Then I filled out the usual prepareForSegue method by getting the destinationViewController, casting to the correct view controller type and then setting the UILabel to the display message. A definite check in the “Pro” column is the native String type and concatenation with ‘+’–no more “NSString:stringWithFormat” and worrying about using %d or %@ or %ld just to build a simple string.

I then built and ran the code.  Then it crashed with the following (characteristically dismal) error message:

“unexpectedly found nil while unwrapping an optional value swift”

Unlike in Objective-C, at this point the UILabel hasn’t been initialized yet. I needed to add a property to my resultDisplayViewController class to hold the display message.  Then in ViewDidLoad (or if you want, ViewWillAppear) I assigned the message to the UILabel’s text field.  Then it worked fine.  My first Swift program is ready for the App Store! :)

Conclusion:
Swift has legs.  It’s has many advantages over Objective-C.  It will take a bit of time to get used to, but not too much and the investment in Swift will pay off.  I look forward to my next iOS application that I will start and will write it in Swift.

Displaying AX 2012 Customer Financial Dimensions

A frequent customer requirement is to display AX 2012 Financial Dimensions for different entities in row and also column format.  Reasons are typically due to some form of reporting or integration into third party systems.

One specific area that has become complex in AX 2012 is the new Financial dimension data model.  The new data model does not lend itself to easily extract all dimensions per an entity (customer, vendor, etc.) in a clean format without some more advanced sql.  Out of the box, these values are stored per name per row, this post will demonstrate how to show the Customer dimensions in a column format per customer account number.  With some minor modifications, the sql can be modified to accommodate other entities as well.

The SQL PIVOT command comes in very handy for this type of data manipulation.

The customer we are using is ‘US-013′ from the AX 2012 Demo Data Contoso company and has been updated as follows:

AX 2012 Contoso Customer

If we want to show a Customer and it’s financial dimension – a simple query will show us each dimension with it’s value on a separate row.

SELECT CUSTTABLE.ACCOUNTNUM, DEFAULTDIMENSIONVIEW.NAME, DEFAULTDIMENSIONVIEW.DISPLAYVALUE
FROM DEFAULTDIMENSIONVIEW
INNER JOIN CUSTTABLE
ON DEFAULTDIMENSIONVIEW.DEFAULTDIMENSION = CUSTTABLE.DEFAULTDIMENSION
where CUSTTABLE.DATAAREAID = 'usmf' and CUSTTABLE.ACCOUNTNUM = 'US-013'
Regular AX Financial Dimension Result

AX 2012 financial Dimensions per row

with results looking something like this:

However if we have requirements where the financial dimensions are to be show in column format we need to rewrite the query as show below
select AccountNum, BusinessUnit,CostCenter,Department,ItemGroup from
 (
 select CUSTTABLE.AccountNum, Name,CUSTTABLE.DefaultDimension, CUSTTABLE.dataareaid, DimensionAttributeValueSetItem.DisplayValue from CUSTTABLE
 join DimensionAttributeValueSet on DimensionAttributeValueSet.RecId = CUSTTABLE.DefaultDimension
 join DimensionAttributeValueSetItem on DimensionAttributeValueSetItem.DIMENSIONATTRIBUTEVALUESET = DimensionAttributeValueSet.RecID
 join DimensionAttributeValue on DimensionAttributeValue.RECID = DimensionAttributeValueSetItem.DIMENSIONATTRIBUTEVALUE
 join DimensionAttribute on DIMENSIONATTRIBUTE.RecId = DimensionAttributeValue.DIMENSIONATTRIBUTE
 where CUSTTABLE.DATAAREAID = 'usmf' and CUSTTABLE.ACCOUNTNUM = 'US-013' ) d
PIVOT
(
 MAX(DisplayValue)
 FOR Name
 IN (BusinessUnit,CostCenter,Department,ItemGroup)
)
AS PivotTable

with results looking like this:

Financial Dimensions Row

That’s it for today’s post. Happy AX report writing!

Transitioning Your App to iOS 7

With the introduction of iOS 7, Apple made some controversial design decisions which affect not only the end-user, but the developer as well. This may have unwelcome consequences for the look and layout of your app. Today I’ll provide a few tips and tricks for maintaining some of the iOS 6 conventions while building for iOS 7.

 

1.) Prevent iOS 7 Status Bar from overlaying the window content

In iOS 6, the status bar was confined to a discrete, 20-pixel-high section of the screen that floats directly above the app’s main window. In iOS 7, the status bar now overlays that window. This can throw off the UI layout of the entire app.

Apple provides an official fix for those using Autolayout: simply add a “vertical space” constraint equal to 0 to the top-most view, and do this for each view in the storyboard.

If you’re not using Autolayout, however, things are a bit trickier. Apple does provide another “official” solution of sorts. Using a feature called “iOS 6/7 Deltas”, you can specify a positional offset to be used in iOS 7, which can be utilized to push content down and clear up space for the status bar.

To do this, navigate to the Interface Builder. You’ll first want to open your view’s File Inspector (the left-most icon in the Utilities pane). Under the “Interface Builder Document” section, you’ll want to make sure that you’re viewing as iOS 6.1 and earlier.

blog-screenshot1

Next, switch to the Size Inspector. Directly under the Autosizing pane, there will be a section to adjust your deltas. Set the Y delta to -20. In many cases, you’ll also want to adjust the height delta to -20 to account for this offset.

blog-screenshot2

You can now switch back to the File Inspector and choose to view as iOS 7.0 and later. You should be able to see the change in positioning previewed on your storyboard.

 

2.) Change table view cell selected background gradient

In iOS 6, table view cells had a blue gradient background when selected. In iOS 7, this has been replaced with a solid white background. Some designers may have intended for the blue gradient to be integrated as part of the app’s overall color scheme, so preserving this look may be desirable. While Apple doesn’t provide a way to revert to the iOS 6 visual style, this is relatively simple to re-implement manually.

First we’ll create a utility method to draw the gradient:

/**

* Creates a view with the size of the given frame, colored with a vertical gradient

* that starts at #068bf5 and ends at #015ee6 (same colors that were used by the UITableViewCell

* in iOS6)

*/

+(UIView *)gradientBackgroundWithFrame:(CGRect)frame

{
    UIColor *startColor = [UIColor colorWithRed:6/255.f green:139/255.f blue:245/255.f alpha:1];
    UIColor *endColor = [UIColor colorWithRed:1/255.f green:94/255.f blue:230/255.f alpha:1];

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];

    CAGradientLayer *gradient = [CAGradientLayer layer];
    gradient.frame = view.bounds;
    gradient.colors = @[(id)[startColor CGColor], (id)[endColor CGColor]];

    [view.layer insertSublayer:gradient atIndex:0];

    return view;
}

Then in the appropriate table view delegate, we’ll use this method like so:


-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // ..snip...
    cell.selectedBackgroundView = [MyUtils gradientBackgroundWithFrame:cell.frame];
    // ..snip..
}

Run your app and select a table cell. It will look just as it did in iOS 6.

iOS Simulator Screen shot Jun 16, 2014, 11.47.36 AM

 

Customizing AX 2012 Released Product ListPage Filter using X++

In Microsoft Dynamics AX 2012, ListPages are more restricted from customization than in prior versions of AX.  Primary reason for the restriction is so that the list pages maintain compatibility with Enterprise Portal.  Recently a customer had a requirement where the filter needs to be available on the list page and only on the client side.  I spent quite some time searching for a solution and thought I’d share my workaround here – This post will outline how to create a customized filter on the Released Product list page.

The Requirement: quickly find Released Product by External Item number and display the Released Product Number(s) on the Released Products List page.

The Solution: Since we are looking for data not part of any DataSource on the original query – and due to some join complexities, customizing the existing query was also not an option, X++ became the last option. (As you may or may not know, external item data is stored in the CustVendExternalItem Table.)  Microsoft specifies for developers to change the *LPInteraction class, however I have to date not found any concrete examples for using the class to manipulate the list pages.  For this example we will modify the Released Product List Page by overriding the modified method on a filter field.

Here is how:

1. We need to allow overriding of methods on fields on the form (which by default is not allowed on Forms of FormTemplate: ListPage).  Navigate to the AOT –> Forms –> EcoResProductPerCompanyListPage –> Designs –> Design –> Group:Filter –>  Properties –> Display Target and select “Client”. Note this means that the filters will only be visible in the AX client and not  via EP.  This will also allow us to actually override the “modified” method on the filter form.  Ensure that the filter is Visible, DisplayTarget is set to Client and the Caption, FrameOptionButton and OptionValue can be set as needed/desired.

EcoResProductPerCompanyListPage

2. Create a new field under the filter section, ensure that AutoDeclaration is set to “Yes” and that the proper data type is selected.  In this case the ExtendedDataType should be “ExternalItemId”

ExternalItem

3.  Override the “modified” method on the Field.  Note if you are unable to override any method then you have not completed step number 1 above.

RightClickOverrideMethod

3. Paste code below to filter by the external customer/vend ItemId.  Note: there are many different ways to create the desired result other than below, notably the “QueryFilter” object is another alternative.

</pre>
public boolean modified()
{
boolean ret;
QueryBuildRange qbr;
QueryRun queryRun;
Query query;
QueryBuildDataSource qbds;
SysTableLookup lookup;
ItemId itemId;
CustVendExternalItem custVendExternalItem;

ret = super();
if (this.valueStr())
{
query = new query();
qbds = query.addDataSource(tableNum(CustVendExternalItem));
qbr = qbds.addRange(fieldNum(CustVendExternalItem, ExternalItemId));
qbr.value(queryValue(this.valueStr()));
queryRun = new QueryRun(query);
while (queryRun.next())
{
custVendExternalItem = queryRun.get(tableNum(custVendExternalItem));
itemId = custVendExternalItem.ItemId;
break;
}
// if we found a match in the external item table show it
if (itemId)
{
InventTable_ds.queryBuildDataSource().addRange(fieldNum(InventTable, ItemId)).value(itemId);
InventTable_ds.executeQuery();
}
}
else{
InventTable_ds.queryBuildDataSource().clearRanges();
InventTable_ds.executeQuery();
}

return ret;
}

4. One nice thing about the filter Group is that it  includes a display type, I have selected “Hide” which allows a user to hide it if they do not want to see/use the specific filter with minimal screen real-estate being consumed.  Run an X++ compile on the form and Incremental CIL compile and the Released Product form should look like below.

NewFilter1

5.  For our example I have added a an external item Id “S1CTestItem” in the Contoso environment.  Let’s see what product this item corresponds to.  Just type in the External Item Id and hit Tab or enter.

Filter2

 

The form runs the query and displays the result.

6.  Just to confirm, we go to the “External Item Description” form and as you can see everything checks out.

FilterConfirmation

 

That’s it!   As you can see this is the basic framework for customizing the list page form if you cannot change the Query object or are not able to pass the necessary parameters to the LPInteraction class.