sap.uxap.ObjectPageLayout: How to set default section page on load? - sapui5

I am using the sap.uxap.ObjectPageLayout with a bunch of ObjectPageSections. I would like to have the first section being displayed whenever I open the view containing the ObjectPageLayout. I have seen that there is association selectedSection but it needs a value of type sap.uxap.ObjectPageSection. Settings the ID of the first section does not help. So what am I supposed to enter there?

I guess you'll need to set it when you enter the route again of your ObjectPageLayout. Then this.byId("objectPageLayout").setSelectedSection(this.byId("sectionId")) should work.

You can pass the ID of the section in the XMLView as well, despite the API reference saying that the association awaits an object of type sap.uxap.ObjectPageSection.
<uxap:ObjectPageLayout selectedSection="firstSection">
<uxap:ObjectPageSection id="firstSection">
selectedSection: The section that is selected by default on load.

Related

How to dynamically change dialog with select field

I'm new to Magnolia, and I'm making my own module.
I have a dialog box when adding a component and I want to change next fields below dynamically using a select field.
Example:
Select field with {"type 1", "type 2", ...}
IF "type 1" is selected
->show a text field below
ELSE
->show a basicUpload field below
Thanks in advance.
I believe same was already discussed here and few other places if you look over questions tagged "magnolia".
Long story short, fields are atomic, independent entities. They do not know about each other. So the only way to create such dynamic connection is over "parent" form. You need to extend form presenter and field factory (if you want select that would be SelectFieldFactory) and in there, when field is created, attach value changed or similar listener to it so when value is changed in the field, you can inform presenter to make some other field visible or hide it.
IIRC you can see example of that done in External Forms module (if you have access to enterprise code). Not sure if any of the community modules show the same.

AEM DefaultValue written to JCR

I noticed that when I set my defaultValue for a dropdown, altho it is correctly selected in the drop down when I first add my component to the page it does not write the defaultValue to the corresponding JCR until I edit the component and save it. Even if I just open the corresponding dialog and click OK now my component works as expected because the values have been added to the JCR.
I am sure there is an important piece that I am missing here, does anyone knows how defaultValues that are required in order for the component to render properly can be added to the JCR when they are first added to the page?
Like Shwan say's that's the way it works. The default values or empty texts are only for the dialog. They aren't persisted until the dialog is authored. The properties have to be set by a different method. CQ already ships with this feature and you can do it without any custom code.
Under your component , create a node called cq:template[nt:unstructured] . If all the data is stored on the component node itself , add the default values as properties to cq:template node with name same as the ones in your dialog. In case the data is stored in a child node add a similar node under cq:template node.
Source : http://blogs.adobe.com/experiencedelivers/experience-management/defaults-in-your-component/
I believe that is simply the way it works. The default value specified in a dialog does not get used until the dialog is loaded/saved, so until that happens the node on the JCR repository that is being authored won't have the default value.
We got around this on a project by adding back-end code that was tied to the component (a tag) so that when the component was loaded, if the property did not exist, it would be written with the default the first time. Ex:
if (wcmMode == WCMMode.EDIT )
{
if(!currentNode.hasProperty("SomePropertyThatWillAlwaysExistIfTheDialogHasBeenSaved")) {
currentNode.setProperty("PropertyThatShouldHaveDefault", GlobalConstants.TRUE);
currentNode.getSession().save();
}
}
Like Sharath Madappa say's that's the way it works fine if component name and jsp name same. If you dont have componentname.jsp under component or page, cq:template won't work.(Reference:http://labs.6dglobal.com/blog/2014-07-08/using-the-cq-template/)
If you hava componentname.html under your component, changed the node [cq:template] type to [cq:Template] instead of [nt:unstructured]. In this case, defaultValues can be added to the JCR when they are first added to the page.

Find CURRENTLY selected <option> with XPath

What's the correct XPath syntax to check if an option element is currently selected, or just to get the selected option element from a select element, on an open page with which the user, and JavaScript, may have interacted? Is this even possible with XPath, or does it lack the ability to look at DOM properties?
I can't find any documentation on this, and have (speculatively) tried:
//option[#selected=true]
//option[#selected="selected"]
//option[#selected]
but none of these work; they simply don't match any elements.
(In case it matters, I've tried this both using the $x function in the Chrome developer console, and using the find_elements_by_xpath method in Selenium for Python.)
Short answer: it's not possible.
Longer answer: XPath can look at HTML attributes, but it can't look at DOM properties. Selecting an <option> element in a <select> changes the selected property of the <option> to true, and also changes the value property of its parent <select> element, but it doesn't affect the attributes of either, so it is invisible to XPath.
To find <option> elements that have the selected attribute set, which is often how a page author might determine which option is initially selected, you can use //option[#selected]. But this does not find the currently selected <option>; changes that the user makes to the selection are invisible to XPath. There's no guarantee it will even find the initially selected option, since it's possible that the page author didn't put the selected attribute on any elements and either let the browser select the first option by default or had some JavaScript select the initial option via the selected property.
The multiple other answers here claiming that a selector like //option[#selected] can detect selection changes made by the user after the page loads are simply completely wrong.
Of course, if you're able to use CSS selectors instead of XPath selectors, then option:checked will do the job.
The problem could be the " (double quotes).
//select/option[#selected='selected'] - Will match the selected option, i am using this successfully.
//select/option[#selected='selected' and #value='specific value'] - Will only match the selected option if it has a 'specific value', i'm also using this.
If you are still having trouble, it could be an entirely different problem, perhaps there is no option node. I hope this helps.
I think we can use a knowledge from #Mark's answer and account that. Let's just find a node which HAS desired attribute:
tree.xpath('//select/option[#selected]/text()')[0].strip()
I tried "//option[#selected=''] and it has worked for me.
it is able to highlight the selected option within Page objects model.
I would try //option[#selected='true']
i.e. driver.findElements(By.xpath("//option[#selected='true']")).getText();

ExtJS 4 - How to load grid store with its params carrying latest values from a form?

I have a window with a search form at the top and grid at the bottom.
User can enter values in the search form and click button - Get Records.
At the click of this button, I load the store of the grid by passing the values in form fields as parameters in following way:
store.load({
params:{
key1:Ext.getCmp('field1').getValue();
}
});
I tried giving parameters in the store proxy itself, but it unfortunately always takes up initial values (values when the form is rendered) and not the latest one entered by the users in the form fields. Following is the method I used for assigning values to params while creating the store:
extraParams:{
key1:Ext.getCmp('field1').getValue();
}
I wanted to seek guidance at two things:
a. While defining a store, can I ensure that store takes latest/current values from the form fields before querying server, so that I don't have to provide these values while calling load function?
This becomes more necessary as I have a paging toolbar at the bottom which carries a refresh button (along with next, last, previous, first icons for navigation).
Now, whenever user clicks at refresh (or any navigation icon), the store gets loaded without the query parameters.
Thus the second thing is:
b. If the answer of 'a' is that - Pass the latest values to parameters manually when calling load function - then how can I write the handler for 'refresh' button and navigation icons (that is, next, last, previous and first) in the paging toolbar, so that I can pass the latest form values to load function.
Thanks for any help in advance.
PS: I am using ExtJS 4.
yourStore.on('beforeload',function(store, operation,eOpts){
operation.params={
status:cmbStatus.getValue(),
value:txtBuscarPor.getValue(),
empresa:'saasd',
app:'dsads'
};
},this);
Related to your question (b) (and because you especially asked for this in the comments section):
I see only one standard way to hook into the PagingToolbar button handlers which is very limited.
Ext.toolbar.Paging fires a 'beforechange' event before it actually changes the current page. See API docs. A listener that returns false will stop the page change.
All other methods require extending Ext classes which wouldn't be a problem if the ComboBox would make it easier to use your own implementation of BoundList (which is the class that renders the dropdown) or pass through config parameters to BoundList resp. the paging toolbar.
I tried to bring this lack of flexibility up on the Ext message board once but was pretty much ignored.
A possible solution for this is to use 'beforeload' event of the store and provide the list of parameters in it. This way, whenever the store is loaded, then its beforeload event is fired and the values picked up are always the latest. Hope this helps someone looking for something similar.

MVC Html.textbox/dropdown/whatever won't refresh on postback

OK, let's start with the Html.Textbox. It is supposed to contain text read from a file. The file read is based on what the user picks from a dropdown list.
The first time it is fine. The user picks a value from the dropdown list. The controller uses that value to read some text from a file, and returns that text to the view via the view model. Everything is fine.
THen the user picks another value from the dropdown list. The controller reads a new value from a file and returns it via the view model. Debugging to the LINE BEFORE THE HTML.TEXTBOX is set in the view shows that the model contains the correct value. However, the textbox itself still shows the PREVIOUS value when the page displays!
If I switch from Html.Textbox to a plain input, type="text" html control, everything works fine. That's not so hard, but the same thing happens with my dropdown list -- I can't set the selected value in code. It always reverts to whatever was chosen last. Rendering a "select" tag with a dynamically-generated option list is a pain. I would love to be able to use Html.Dropdown.
What am I missing here?? This is such a simple thing in webforms!
When you post a form, the values that are posted are put into ModelState. When the HtmlHelper renders an html iunput element, e.g. Html.TextBoxFor(x => x.FirstName), it'll search various locations to get the value for the textbox... ModelState is before ViewData.Model in the list of locations. So there for, the previously posted value will appear in your textbox.
To fix this you could clear the ModelState value or update the ModelState value. BUT I would kinda view that as a hacky way of getting around the problem.
The real issue has more to do with the flow of the posts and requests. I would personally look into that and maybe implement the PRG (Post Redirect Get) pattern.
HTHs,
Charles
Following on from what Charles/Charlino said:
Model binding updates the ModelState object, which contains validation and model binding errors that are collected during model binding.
Inside an action method, model binding has occurred already to update the model, and generated the ModelState object. If you now update the value on the model inside the action, you must also manually update the model state (since the helpers use it to generate their HTML). Below is an example:
model.CaptchaIsValid = CaptchaService.ValidateAndExpireCaptcha(model.CaptchaAttempt);
if (!model.CaptchaIsValid)
{
ModelState.AddModelError("CaptchaAttempt", "Incorrect - please try again");
}
// I'll clear the value on each attempt, to force them to re-enter a CAPTCHA.
model.CaptchaAttempt = string.Empty;
// Since I updated the model, I must create a new ValueProvider result...
ValueProviderResult clearedValue = new ValueProviderResult(
model.CaptchaAttempt,
model.CaptchaAttempt,
CultureInfo.CurrentCulture);
// ... and update the ModelState's value.
ModelState.SetModelValue("CaptchaAttempt", clearedValue);
The biggest issue I see here is that you are trying to do a postback within MVC. That model is really not supported, and is actually way more trouble than it is worth (as it seems you are finding out). I would recommend using Ajax to update the contents of the dropdown dynamically.