Boilerplate.js Programmatically navigate to a component - boilerplatejs

I have a component declared in a module and added as a route:
var controller = new Boiler.UrlController($(".appcontent"));
controller.addRoutes( {
'artists': new ArtistsComponent(context),
'clubs': new ClubsComponent(context)
});
controller.start();
I need to navigate to a component like 'clubs' programmatically. What is the exact syntax, please

You may see how this is done to navigate from list view to details view in the sample code in:
https://github.com/ectechno/boilerplatejs/blob/master/src/modules/sampleModule2/employeeList/viewmodel.js
The method call to navigate programmatically is:
Boiler.UrlController.goTo("artists");

Related

Display custom product association data in a new tab

I wrote an extension to add data to the ProductEntity in Shopware 6 and used the following tutorial:
https://developer.shopware.com/docs/guides/plugins/plugins/framework/data-handling/add-complex-data-to-existing-entities
I also used another tutorial (https://developer.shopware.com/docs/guides/plugins/plugins/administration/add-new-tab) to add a new tab to the product detail view. Everything works so far.
In the product detail view I added a text field in my custom tab. But my problem is: how to get my data into the view? I want to add my new association to the product when the detail view is loaded. Therefore I tried to override the component from Shopware as follows:
Shopware.Component.override('sw-product-detail', {
template,
mounted() {
const criteria = this.productCriteria;
criteria.addAssociation('myNewAssociation');
this.productCriteria =criteria;
},
});
This does not work because productCriteria has no setter (original component can be found here: https://github.com/shopware/platform/blob/6.4.1.0/src/Administration/Resources/app/administration/src/module/sw-product/page/sw-product-detail/index.js)
Does anyone know how I can add a custom association to an existing one in vue.js in Shopware 6? What's the correct way to inject a custom association to the product detail view so I can use data from that in my new custom tab? The documentation always stops when it becomes interesting...
I would suggest to overwrite the productCriteria method and call the parent to not need to fully copying the existing code, like this:
Shopware.Component.override('sw-product-detail', {
template,
computed: {
productCriteria() {
const criteria = this.$super('productCriteria');
criteria.addAssociation('myNewAssociation');
return criteria;
},
},
});
Let me know if it works.
I believe also you don't need to mention the template in the override (when I did this last time, the template was displayed twice)
EDIT: All good with the template.

Auto-collapse any item in PrimeFaces PanelMenu on page loading

I'm writing a Primefaces 5.1 portlet.
It consists in a unique page containing a panelMenu, and I need that it starts with any panel collapsed everytime a user change page (on page loading).
But, if I open a panel, then change page, it will start showing that panel still opened.
I wasn't able to find any option to achieve this goal (e.g. collapsed=true, ignoreCookie=true or something similar).
The only solution I found was the following Javascript code:
PrimeFaces.widgets.myPanelMenu.collapseRootSubmenu(PrimeFaces.widgets.myPanelMenu.headers);
The problem is that this code will collapse any opened panel (so on page loading user is able to see panel menu collapsing animation) but it seems it doesn't store this state in its cookie/localstorage... the result is that on any page loading user can see this animation.
I'm sure it doesn't save its state, because the only way to "solve" the problem is to manually re-open and re-collapse the panels... then, on following page change, these menus start closed (and there is no animation).
I also tried to use PrimeFaces.widgets.sideMenuPanel.saveState() after collapsing, but with no success.
Do you have any idea about?
Thank you...
I found a solution to the problem.
If you read my discussion with Kukeltje (comments on my question), you will find that latest Primefaces' versions will solve the problem.
Otherwise, if you want to avoid upgrade or modify sources, and you need a quick fix based on Javascript only please read the following part of the answer.
It directly works on the component's state using JavaScript.
First of all you need to have a variable reference to your component:
<p:panelMenu model="#{menuBackingBean.menuModel}" widgetVar="sidePanelMenu" />
Then you should add the following JS code on document ready:
var panelMenu = PrimeFaces.widgets.sidePanelMenu;
// 1. On page loading collapses possible opened panels
panelMenu.collapseRootSubmenu(panelMenu.headers);
// following line is commented because it never should be necessary is not necessary (unless unexpected situation I never verified)
//clearSidePanelMenuPreferences();
// 2. Call the "clear preferences" actions on click on two tpe of links: first level are the panel link (used to open/close the menu) and second level are the destination links
// We need to fork also on the first level links to be sure it works after user clicks there then exit from the page in another way
panelMenu.headers.children("a").click(function(){setTimeout(clearSidePanelMenuPreferences, 500)}); // setTimeout is necessary because this event should be fired after preferences are written
panelMenu.headers.siblings().find("a").click(function(){clearSidePanelMenuPreferences();});
The function called to clear preferences are the following:
function clearSidePanelMenuPreferences() {
var panelMenu = PrimeFaces.widgets.sidePanelMenu;
panelMenu.expandedNodes = []; // clear the opened panels lists
panelMenu.saveState(); // store this information
}
Hope it helps
Please check this block of code
PF('myPanelMenu').headers.each(
function(){
var header = jQuery(this);
PF('myPanelMenu').collapseRootSubmenu(header);
header.removeClass('ui-state-hover');
}
);
I prefer to do this in order to execute this method only once and keep the menu option selected.
$(document).ready(function() {
if(location.pathname == "/cotizador/" || location.pathname == "/cotizador/faces/login.xhtml"){
var panelMenu = PrimeFaces.widgets.sidePanelMenu;
// 1. On page loading collapses possible opened panels
panelMenu.collapseRootSubmenu(panelMenu.headers);
panelMenu.expandedNodes = []; // clear the opened panels lists
panelMenu.saveState();
}
});

Custom View WIth Part Orchard

Anyone knows if there is anyway to show the build editor of an espefic part, inside a custom view.
I'm creating profesional, but not in the standard way orchard propose, I have a custom view, but that profesional has a DomicilioPart witch i created, that part has a driver with the overriden method BuildEditor. Is there any way of displaying that especific editor in my custom view?
You have to use the method _contentManager.BuildEditor(contentItem) to create the corresponding Edit template.
public ActionResult Example(int id) {
var ci = _contentManager.Get(id);
var editShape = _contentManaget.BuildEditor(ci);
// more code
viewModel.Edit = editShape;
return View(viewModel);
}
#Template
<div>#Display(Model.EditShape)</div>
This training module will teach you about the creation/edit and delete of ContentItems.

Overriding editor template in theme affects admin view

I created a form using the CustomForms module and need to control the markup of the input fields I've included on the form (to add bootstrap specific classes). I added a view to my theme at the location /Views/EditorTemplates/Fields/Input.Edit.cshtml and that allowed me to update the markup for the input fields.
My problem is that the view in my theme is also being picked up in the admin views. I didn't expect this behavior but it's happening. I tried scoping the view override to the url (Input.Edit-url-contact.cshtml) and content type (Input.Edit-ContactRequest.cshtml) using the alternate naming conventions but they do not appear to work in this case.
Is there a way to scope the Input.Edit.cshtml view in my theme so it only applies to the front-end of the site? Or is there a better way to achieve what I'm trying to do?
I ended up working around this issue by implementing a shape table provider (based on Bertrand's suggestion) to specify different template names in my theme so they weren't picked up in the admin. Here's what it looks like:
public class EditorFieldShapeProvider : IShapeTableProvider
{
public void Discover(ShapeTableBuilder builder)
{
builder.Describe("EditorTemplate")
.OnDisplaying(displaying =>
{
var shape = displaying.Shape;
if (shape.ContentField is InputField) {
shape.TemplateName = "CustomInputField";
}
});
}
}
Just drop that class somewhere in your theme and create your view at /ThemeName/Views/EditorTemplates/CustomInputField.cshtml

Xpage Component using UIDialog, UIDialog does not render its children

I am trying to develope a component for my company wich should have an integrated dialog. Creating the component was easy until i hit the point with the Dialog. I want to use the com.ibm.xsp.extlib.component.dialog.UIDialog for my component because it has some nice features wich i want to use so creating my own dialog with a ClientSideDojo is not an option.
Normaly when adding a component to another i use component.getChildren().add(MyNewComp),but when i try this Code:
public class myComponentWithADialog extends UIComponentBase implements FacesComponent {
//...other Code...
public void buildContents(FacesContext context, FacesComponentBuilder builder)
throws FacesException {
UIDialog dialog = new UIDialog();
TypedUtil.getChildren(container).add(dialog);
dialog.setStyleClass("dlgUserPref");
dialog.setTitle("titelxyz");
dialog.setId("TagDialog");
UIPanelEx panel = new UIPanelEx();
panel.setTagName("div");
panel.setStyle("border:2px solid red;");
panel.setStyleClass("lotusList lotusTags lotusRelatedTags");
dialog.getChildren().add(panel);
this.getChildren.add(dialog);
}
//....
}
My Panel does not display inside the dialog when calling XSP.openDialog('dialogClientId') in my browser the dialog is shown but empty.
I already tried several other methods like dialog.getPopupContent.getChildren().add() but then i get the error: javax.faces.component.UIPanel incompatible with com.ibm.xsp.extlib.component.dialog.UIDialog$PopupContent.
Also i tried to find a solution on google but i only found a entry at openNTF from someone with the same problem but also without any solution.
Note: I also tried to 'inject' some content to a standard <xe:dialog> and to a <px:panel> inside the <xe:dialog> via a button with SSJS like keithstric does in his blog. Code:
var dialog:com.ibm.xsp.extlib.component.dialog.UIDialog =
getComponent('extlibdialog');
if(dialog.getChildren().size() > 0) {
dialog.getChildren().clear();
}
var TextField:com.ibm.xsp.component.xp.XspOutputText = new com.ibm.xsp.component.xp.XspOutputText();
TextField.setTitle("test");
TextField.setId("testTextField");
TextField.setValue("<p>This is the new Content</p>");
dialog.getChildren().add(TextField);
This code works fine for a standard <xp:panel> outside a dialog but not on the dialog itself or a panel inside it.
The dialogue is not pre - rendered when the page is loaded, but when you actually call for it in XSP.openDialog(...)
So you need to get your code run in that event (mobile now, can't check if it is exposed).
Plan B: do use a Dojo dialogue that is backed by a rest control, so you can transport whatever data you need back and forth.
A word of caution: popup dialogs are a UI concept transplanted from desktop apps. They are alien to Web apps and mostly not working in mobile. Consider and Inline form instead (or a wizard)

Resources