Dialog not displaying propagated model data - data-binding

In my UI5 application, I have an i18n.properties file with keys and values:
#XMSG:
qty=Quantity
And I'm using this property value in a dialog box as title
onUpdateDialog: function() {
var that = this;
var dialog = new Dialog({
title: "{i18n>qty}",
// ...,
});
dialog.open();
},
But when I run my application, the dialog box title is not getting displayed:
When I use text values from i18n property file somewhere else it's getting displayed.

ManagedObjects, that are created by the application code imperatively outside of the framework-managed features (Such creating an instance of sap.m.Dialog in a Controller code without using the API loadFragment), have to be added to the model delegation chain manually in order to make use of the propagated models.
In order to do so, add the created instance to the parent's <dependents> aggregation. E.g.:
this.getView().addDependent(myDialog); // myDialog is now aware of the "i18n" model
From API Reference:
Special aggregation dependents is connected to the lifecycle management and databinding, but not rendered automatically and can be used for popups or other dependent controls or elements. This allows the definition of popup controls in declarative views and enables propagation of model and context information to them.

In order to use texts in the controller you need to fetch the text first, like so:
this.getOwnerComponent().getModel("i18n").getResourceBundle().getText("qty")
this will be the dialog inside the dialog, so declare a that before the dialog and change this to that..
var that = this;
that.getOwnerComponent().getModel("i18n").getResourceBundle().getText("qty")
Hope this solves your issue..

At the point of opening the Dialog, it doesn't know the i18n model. You need to provide the model to the dialog by calling dialog.setModel(this.getModel('i18n'), 'i18n') before opening the dialog.

Related

How do I edit variables and update content of a view component using a button within the same component?

Summary: I have a view component with buttons which need to be able to change the details displayed in the rest of the component on click, but i can't figure out how to update the components content and data using an element within the component.
I am using asp.net razor pages to make a simple UI which displays various info grabbed from a JSON file, no database connection or POST functionality necessary.
I want the block of html that displays the data to be a reusable component, so i don't have to rewrite it every time i want to show a different entry in the file. From my research, there are a few options: HTML components, tag helpers, razor components, partial views, and view components. I chose to use a view component since the other options all seemed either outdated or not capable enough to achieve what i wanted. That is, with the exception of razor components, which require blazor to function fully which would also require me to learn a whole new framework and retrofit my program to work for it.
My view component functions to the point where i can invoke it from Index.cs and the component shows all the data from the first log in the list, as desired.
My intention: the default entryNo value is 0, so the component shows the title and date from the first log entry. When a user clicks the "Next" button (inside the component), entryNo becomes 1, and the component shows the title and date of the second entry in the log file.
ViewComponent.cshtml:
#model FullLog
#{ int entryIndLocal = 0; }
<div>
<div>#Model[entryNo].Title</div>
<div>#Model[entryNo].Date</div>
<button onclick={entryNo++}>Next</button>
</div>
What i've tried:
Setting the entryNo value in the view's .cs file and including a function to increment that value when called. I couldn't figure out how to call the function from the cshtml.
Initialising the entryNo variable from within the cshtml file, with the intention of the adding onclick={#entryNo++}. This didn't work either.

Filter page datasource based on record selection

I seem to be struggling with this. I am working on a project management app in Google App Maker. I am using SQL data models. The portion of the app I am having trouble with is several project detail pages linked with a project list page. I have no trouble going from the project list page to the first project detail page.
I have a table widget in the project list page, and the onClick code for a table row is:
app.datasources.Projects.selectKey(widget.datasource.item._key);
app.showPage(app.pages.ProjectPage);
This filters the first detail page with the primary key of the record in focus. No problem here. When I want to navigate the next detail page that has a different datasource (but I still need to filter using the same primary key) I am struggling.
If someone can guide me in making a button in the first detail page that when clicked gets the _key of the project loaded in that current page and filters another detail page for the same project in focus, (using another data model, let's call it ProjectBudgetPage for example) I would really appreciate the help.
This was one my latest attempts at navigation to other detail pages within a project, this was for an onClick event:
var widgets = widget.parent.descendants;
var projectID = widgets.HiddenProjectID.text;
var projectDataSource = app.datasources.ProjectBudgetView.item;
projectDataSource = projectID;
app.showPage(app.pages.ProjectInfoPage);
which results in: (TypeError) : Cannot read property '__gwt_instance' of undefined
at HeaderProjectTabs.HeaderContainer.InfoTabButton.onClick:5:5
I am not sure if I understood properly but I suggest that you start by checking this official App Maker template available here https://developers.google.com/appmaker/templates/partner-management/ which provides a ready-to-run app you can use to manage an internal list of partners, but you can also customize it with your own needs. I recently used most of the UI and logic of this template and I was able to integrate it with SQL data models and it works really great.
I noticed that for this template they are saving the (widget.datasource.item._key) to a Page custom property which you can access afterwards. Custom properties are page-level properties that store data for a single user session. Custom properties are useful when you need to bind properties of multiple widgets to a single value. More info available here https://developers.google.com/appmaker/ui/binding#custom_properties
In your scenario, you can create a new custom property (string) inside your ProjectInfoPage and then you can add a script to the button onClick event in your ProjectPage to save the _key or any other item to a page property. For example:
app.pages.ProjectInfoPage.properties.ProjectKey = widget.datasource.item._key;
app.showDialog(app.pages.ProjectInfoPage);
Then you can get the “ProjectKey” property by adding this to the onAttach event in your ProjectInfoPage:
var key = app.pages.ProjectInfoPage.properties.ProjectKey;
…
In the onAttach event you can filter the new model or pass the property values to a server script. I believe there are other approaches but I hope this helps!

SSRS and Interactive Sorting work in MVC4

I have implemented a reporting engine in mvc using html rendering. I had to create custom paging functionality based on the metadata returned via the render method. I am now looking at implementing interactive sorting in the same fashion which is looking like a more daunting task. It seems there is a setting in the HTML Device Information Settings header for html rendering called ActionScript.
ActionScript(*)-
Specifies the name of the JavaScript function to use when an action event occurs, such as a drillthrough or bookmark click. If this parameter is specified, an action event will trigger the named JavaScript function instead of a postback to the server.
My question is has anyone used this feature? Since I lose authentication after the report is rendered I will have to somehow make authenticated callbacks in the controller. It seems to me it may be easier just to add parameters for sorting in the report, however I would like to keep the interactive sorting in the report.
--Edit Solution1---
It turns out that the * next to script name above means the ActionScript parameter is being depreciated after ssrs 2012. Thus, I decided not to pursue it. If anyone else stumbles upon this then the best way I thought of to simulate interactive sorting without post backs is detailed below:
On the Report
1. Add a parameter to the report SortField1
2. Add a Sort condition to the Tablix or group you wish to sort. Tablix-Sort Expressions
3. Set the expression of the sort to Fields(Paremeters!SortField1.Value).Value
4. Set the default value of parameter SortField1 to the default sort field
5. Set Allow Nulls of the parameter to true.
6. Add a image or label for each column you would like to sort by
7. Create a action for the element created in step 7 with code similar to
="javascript:void(reportSortRequest('ColumsFieldName'))"
NOTE: Your view or view descendant will have need to have an identical function defined to accept the action
In the View
Implement the function reportSortRequest(fieldName). This should set
Model.SortField1 and invoke the post back to the controller to
re-render the report.
In the Controller (This is for Ajax post backs that sends a model that will have a field SortField1)
Call the render with report information including SortField1.
Updated with client script that works to access the report markup wrapper.
The report element generated by the ssrs markup can be accessed in your view by its tags. I have that found the following will work using the predetermined ssrs wrapper element #oReportCell":
Loaded in iframe :
var frameContent = $("#myIFrame").contents();
var ssrsContentElement = frameContent.find("#oReportCell");
Loaded in div:
var ssrsContentElement = $("#myDiv").find("#oReportCell");
Function to load html blob into either a frame or a div. Depending how the report was configured, the content is either a url of a temp file or the html markup.
function setReportContent(content, isUrl, renderInIFrame) {
if (isUrl) {
if (renderInIFrame) {
$("#reportContent").html("<iframe id='reportFrame' sandbox='allow-same-origin allow-scripts' width='100%' height='300' scrolling='yes' onload='onReportFrameLoad();'\></iframe>");
$('#reportFrame').attr('src', content);
}
else
$("#reportContent").load(content);
}
else {
if (renderInIFrame) {
$("#reportContent").html("<iframe id='reportFrame' sandbox='allow-same-origin allow-scripts' width='100%' height='300' scrolling='yes' onload='onReportFrameLoad();'\></iframe>");
$('#reportFrame').contents().find('html').html(content);
}
else
$("#reportContent").html(content);
}
if(!renderInIFrame)
showReportWaitIndicator(false);
$("#reportContent").show();
}
Notice that if you want report images with auto-resize property set to be rendered correctly you have to turn on allow-scripts so that the ssrs resize js functions can fire, be careful.

Flex4 Right Click Spark List using ContextMenu()

I would like to add custom right clicks to a number of spark list controls.
I have tried the following as an item renderer. (as per the flex 4 cook book).
Full Render code here http://pastebin.com/Kx8tJ1cY
When I right click on the Spark List I simply get the Adobe Default Context menu.
This is the same default behaviour I had before I added any code to this.
Could anyone tell me how to add right clicks to List Items in Flex 4.
Please and Thank you.
I found the problem/solution. You cant use context menus if there are Vboxes or Tab Navigators. Which is insane because it means I cant do relative layout properly or decent variable width design.
Quoted from: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/ui/ContextMenu.html
For example, if a DataGrid control is a child of a TabNavigator or VBox container, the DataGrid control cannot have its own context menu.
Christopher Huyler posted something similar (source code available here). From the article:
Start out by grabbing the Javascript code from Google's code repository.
Step 1 – Setup custom context menu code
Create a new Flex project in Flex Builder. Copy rightclick.js and swfobject.js into the html-template folder of your project. From here, I had to make several changes…
I modified the RightClick.init() function to accept an object and container value as input. This allows me to pass in the name of the application as the object instead of having it be called the same thing every time.
I included rightclick.js and swfobject.js in the header of index.template.html.
I added a new div to the body called “flashcontent”.
I added an onload handler to the body tag to initialize RightClick
I replaced AC_FL_RunContent(…) with new SWFObject(…) making sure to maintain all template variables.
After making these changes, I verified that no right-click context menu appears in my application.
Step 2 – Listen for the rightClick event
Next I added a few lines to the main mxml file of my application to listen for the ExternalInterface event that will be dispatched when I right-click my appliction.
private function handleCreationComplete():void
{
ExternalInterface.addCallback("rightClick", handleRightClick);
}
private function handleRightClick():void
{
Alert.show("Right Click Success!");
}
Step 3 – Dispatch an event to the correct object
Getting the event to the main application is easy, but we actually want the appropriate child object to be notified when the right-click event occurs. Since I am not using any double-click events in my application I decided I would treat every right-click event like a double-click event. Users without a two button mouse (aka Mac users) can simply double-click to get the same menu while users with a two button mouse just have to right-click. Here is how I make sure the event is dispatched to the appropriate object.
private function handleRightClick():void
{
var objects:Array = systemManager.getObjectsUnderPoint(
new Point(mouseX,mouseY));
if (objects.length>0)
{
var object:Object = objects[objects.length-1];
var relatedObject:InteractiveObject;
if (object is InteractiveObject)
relatedObject = object as InteractiveObject;
else if (object.parent && object.parent is InteractiveObject)
relatedObject = object.parent;
var event:MouseEvent = new MouseEvent(
MouseEvent.DOUBLE_CLICK,true,false,mouseX,mouseY,
relatedObject);
object.dispatchEvent(event);
}
}
I hope this helps!

Creating a Pop up and setting its view state before it displays

I am a beginner developer in Flex, and I have been using viewstates lately. I had a couple of custom popup titlewindow components that are initialized using:
PopUpManager.createPopUp(this, ContentCreate, true);
They both contain view states already, and are very similar so I wanted to combione them into one popup titlewindow and change view state on initialisation of the popup to either the Create version of the popup or the Update.
I thought I was being smart haha, but I realized soon after refactoring my code that, I as far as I know I can't pass parameters to the popup to indicate which state I want, if it is created using the PopUpManager.
Does anyone know how to pass parameters to the PopupManager, or create the ContentCreate component(TitleWindow) in mxml or code so I can specify the view state?
When you create a pop up window using the createPopUp method a reference to the created window is returned.
Example:
pop = mx.managers.PopUpManager.createPopUp(this, TitleWindow, false);
You can create a public setState function to tell the new popup window which state to display.
pop = mx.managers.PopUpManager.createPopUp(this, TitleWindow, false);
pop.setDisplay('Update');
Your example would be more like:
var pop:ContentCreate;
pop = PopUpManager.createPopUp(this, ContentCreate, true) as ContentCreate;
pop.setState('Update');
This should work.
More information can be found here.
Hope this helps.

Resources