I have created a RotatingImagesComponent and allocating banners to that component.
As per requirement , need to allow maximum 6 banners in RotatingImagesComponent.
Can someone please let me know how to achieve this ?
Do I need to create CMS restriction in this case ?
Thanks..
Hi Below are the steps to Restrict Banner Numbers.
1 Extend RotatingImagesComponent to create custom one.
<relation code="SimpleResponsiveBannerComponentToTestRotatingImagesComponent" localized="false">
<deployment table="BannerToTestRotImgRel" typecode="25003"/>
<sourceElement qualifier="rotatingComponent" type="TestRotatingImagesComponent" cardinality="many"/>
<targetElement qualifier="simpleResponsiveBanners" type="SimpleResponsiveBannerComponent" cardinality="many" collectiontype="list" ordered="true"/>
</relation>
<itemtype code="TestRotatingImagesComponent" extends="RotatingImagesComponent" jaloclass="com.company.testcore.jalo.components.TestRotatingImagesComponent">
<description>Image carousel</description>
</itemtype>
2 Create new controller to set banneers based on your custom logic.
package com.company.teststorefront.controllers.cms;
import static java.util.stream.Collectors.toList;
import de.hybris.platform.acceleratorcms.model.components.SimpleResponsiveBannerComponentModel;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.company.testcore.model.components.TestRotatingImagesComponentModel;
import com.company.teststorefront.controllers.ControllerConstants;
/**
* Controller for the TestRotatingImagesComponent{#link TestRotatingImagesComponentModel}
*/
#Controller("TestRotatingImagesComponentController")
#RequestMapping(value = ControllerConstants.Actions.Cms.TestRotatingImagesComponent)
public class TestRotatingImagesComponentController
extends AbstractAcceleratorCMSComponentController<TestRotatingImagesComponentModel> {
private static final String IMAGE_CAROUSEL_BANNERS_ATTRIBUTE = "imageCarouselBanners";
private static final int BANNERS_MAX_SIZE = 5;
#Override
protected void fillModel(HttpServletRequest request, Model model, TestRotatingImagesComponentModel component) {
//#formatter:off
List<SimpleResponsiveBannerComponentModel> limitedBannerList = component.getSimpleResponsiveBanners().stream()
.limit(BANNERS_MAX_SIZE)
.collect(toList());
//#formatter:on
model.addAttribute(IMAGE_CAROUSEL_BANNERS_ATTRIBUTE, limitedBannerList);
}
}
3 create testRotatingImagesComponent.jsp and have logic to render banners.
<%# page trimDirectiveWhitespaces="true" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%# taglib prefix="ycommerce" uri="http://hybris.com/tld/ycommercetags" %>
<%# taglib prefix="image" tagdir="/WEB-INF/tags/responsive/image"%>
<div class="owl-carousel js-owl-carousel js-owl-banner carousel-banner" data-autoplayspeed = "${component.timeout}">
<c:forEach items="${imageCarouselBanners}" var="banner" varStatus="status">
<c:if test="${ycommerce:evaluateRestrictions(banner)}">
<c:url value="${banner.urlLink}" var="encodedUrl" />
<div class="carousel__item">
<a tabindex="-1" href="${encodedUrl}"<c:if test="${banner.urlLink}"> target="_blank"</c:if>>
<image:damImgModel damAsset="${banner.media}" cssClass="carousel-banner__image"/>
</a>
</div>
</c:if>
</c:forEach>
</div>
4 control this variable BANNERS_MAX_SIZE dynamically by adding in properties and use configurationService.
I think what you need in an interceptor
Create interceptor that implements PrepareInterceptor
public class RotatingImagesComponentInterceptor implements PrepareInterceptor<RotatingImagesComponentModel> {
....
#Override
public void onPrepare(RotatingImagesComponentModel model, InterceptorContext ctx) throws InterceptorException {
if (CollectionsUtils.isNotEmpty(model.getBanners()) && model.getBanners().size() > 6)
throw new InterceptorException("Only 6 banners are allowed");
}
}
Related
I have JavaFX TextField in my code and would like to add an action to different events on the TextField.
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.text.Font;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import java.io.File;
import javafx.beans.value.ChangeListener;
/* Input from user */
weightTF = new TextField();
weightTF.setMaxWidth(36);
activeInsulinTF = new TextField();
activeInsulinTF.setMaxWidth(36);
VBox inputBox = new VBox();
inputBox.setFillWidth(false);
inputBox.setAlignment(Pos.CENTER);
inputBox.getChildren().add(weightTF);
inputBox.getChildren().add(activeInsulinTF);
inputBox.setSpacing(8);
// Add onAction for the texfields
menuHBox.getChildren().add(inputBox);
weightTF.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
double weight = Double.parseDouble(weightTF.getText());
Main.state.setWeight(weight);
System.out.println("Entered weight: " + weight);
}
});
Today I only get an action when I press enter after writing some text in the TextField. How can I add an action for handling a tab press? Also, how to react when the TextField looses focus with a mouse click?
As I read the documentation it should be possible:
https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TextField.html
Hope someone can help me :)
There are a couple of convenience methods to do exactly that, for example
weightTF.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
// do stuff
}
});
this executes whenever a key is pressed in the TextField. You might want to check if the pressed key was a specific one. This can be achieved by
if(event.getCode() == KeyCode.TAB){
// do stuff
}
for example. If you are using NetBeans or some other IDE, you can take a look at the convenience methods by pressing the autocomplete shortcut after having typed "weightTF.", which will show you all of the available methods. The methods I am talking about start with setOn...
Hope that helped :)
It sounds from your question as though you are really interested in knowing when the user moves focus from the text field to another control. This can happen typically if the user presses Tab, or clicks the mouse on another control, though technically this behavior is platform-dependent. It can also happen programmatically.
The problems with using "low-level" event handlers are (1) that in theory you would have to register a mouse listener with all other controls; (2) that you rely on the same keystrokes being used on all platforms for focus traversal; and (3) that if you were to add functionality which required programmatic focus traversal (i.e. you have code like someOtherControl.requestFocus() anywhere), your event listener will not be notified.
The sure-fire way to respond if a text field loses focus is simply to register a listener with its focusedProperty():
weightTF.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
if (! isNowFocused) {
// text field has lost focus...
System.out.println(weightTF.getText());
}
});
Note also that the Scene has a focusOwnerProperty, which is similarly observable and contains a reference to the node in the scene that currently has focus. You could potentially use this property instead for a more general listener that handled moving focus away from any text field.
I'm working with Hybris 5.6 and I'm trying to add a button in the editor area right next to the save/reload/delete buttons.
How can I add a button to the ToolBarChip like in the example below?
It's quite possible to add a new action (label) to the toolbar of HMC, however it's not so recommended as it may result some issues while the migration.
First, add the following snippet to your **/hmc.xml :
<type name="AbstractOrder" mode="append">
<organizer mode="append" >
<editor>
<tab name="payment_and_delivery" position="2" mode="append">
<section name="deliveryadministration" mode="append" >
<table>
<tr>
<td width="16px">
</td>
<td>
<!-- here is the interesting part -->
<action type="item"
classname="com.foo.bar.MyNewAction"
name="action.my_new_action"
toolbaricon="my_new_action"
icon="images/icons/my_new_action_icon.gif"
autosave="true"
showtoolbarlabel="true"
hidebutton="true"
/>
</td>
</tr>
</table>
</section>
</tab>
</editor>
</organizer>
</type>
Then, define the new action to be performed when the new label is clicked :
Add a new class called MyNewAction.java that extends from ItemAction and implement the method ActionResult perform(ActionEvent event) :
public MyNewAction extends ItemAction {
#Override
public ActionResult perform(ActionEvent actionEvent) throws JaloBusinessException {
//what the new action should do here ...
}
}
Note : you could override other interesting methods to be triggers while the action is possessing like : boolean needConfirmation() or String getConfirmationMessage() ...
The result would be like this :
I created a Servlet call ShippingDetailsServlet.java and deployed it. I need to submit a HTML form to it. I am not sure what path I should put in the form action. Below is the form.
<form action="/services/mycompany/ShippingDetailsServlet" method="post">
Country: <input type="text" name="country" value="au"><br>
Quantity: <input type="text" name="quantity" value="1">
<cq:include path="./submit" resourceType="foundation/components/form/submit" />
Please let me know what path should I give for the form action so that it can be submitted to the Servlet.
Below is the Servlet.
package mycompany.servlets;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import javax.servlet.ServletException;
import java.io.IOException;
import java.io.PrintWriter;
#SlingServlet(
paths={"/services/mycompany/"}
)
#Properties({
#Property(name="service.pid", value="mycompany.ShippingDetailsServlet",propertyPrivate=false),
#Property(name="service.description",value="Shipping details servlet", propertyPrivate=false),
#Property(name="service.vendor",value="mycompany", propertyPrivate=false)
})
public class ShippingDetailsServlet extends SlingAllMethodsServlet
{
#Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException
{
//Do something fun here
}
#Override
protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException
{
//Do something fun here
PrintWriter out = response.getWriter();
out.println("Hello");
}
}
That is not necessarily true. You can deploy servlets on custom paths, but in order to do so you need to modify the "Apache Sling Servlet/Script Resolver and Error Handler" and add the custom path to the "Execution Paths" section.
Also, if this form is going to be deployed to your publish instance, you may want to use a custom path other than /bin/ because CQ has a lot of admin servlets registered under /bin and exposing them to the public may present a security concern.
By default, servlets can be deployed only below the /bin path. Don't put trailing / to the paths and don't add any additional properties. Eg. use following annotation:
#SlingServlet(paths={"/bin/services/mycompany"})
public class ShippingDetailsServlet extends SlingAllMethodsServlet
Path in the form should be the same as in #SlingServlet:
<form action="/bin/services/mycompany" method="post">
And if you really want to create servlet outside the /bin, you need to add appropriate path to the Execution Paths property in Apache Sling Servlet/Script Resolver and Error Handler configuration page in the /system/console/configMgr console.
Got the answer to my question from the forums.adobe.com
Answer is as below.
if you have annotated your servlet like this:
#SlingServlet(methods = { "POST" }, paths = "/apps/mycompany/servlets/GenericServlet")
the form shoud post to the same same url as in paths, that is "/apps/mycompany/servlets/GenericServlet"
so if you would change you "paths" line in the servlet to "/services/mycompany/ShippingDetailsServlet"
the form would post to that one.
I'm trying to learn how to use custom events in Flex.
I'm following Oliver Merk's tutorial found here: blog
The custom event works if I implement it using MXML in the main app. But, if I use actionscript, then I get error 1119: Access of possibly undefined property ADD_PRODUCT through a reference with static type Class.
My Event:
In the events subdirectory, I've got:
package events {
import flash.events.Event;
public class AddProductEvent extends Event {
public var productName:String;
public function AddProductEvent( type:String, productName:String ) {
super( type );
this.productName = productName;
}
override public function clone():Event {
return new AddProductEvent( type, productName );
}
}
}
In the component, I've got a radioButtonGroup
<mx:RadioButtonGroup id="choicesRadioButtonGroup" itemClick="onButtonClick()"/>
private function onButtonClick():void {
var myEventObj:Event = new AddProductEvent("addProduct", "Flex T-shirt");
dispatchEvent(myEventObj);
}
This is the metadata in the component and the import statement:
<mx:Metadata>
[Event (name="addProduct", type="events.AddProductEvent")]
</mx:Metadata>
import events.AddProductEvent;
In the main app, I've got:
import events.AddProductEvent;
private function onAddProduct( event:AddProductEvent ):void {
mx.controls.Alert.show('Attached data was ' + event.productName);
}
If I implement the component in the main app like this:
<visualcomponent:PopWindow addProduct="onAddProduct(event)" />
then everything works.
If I implement the component in the main app in actionscript like this, then I get an error:
public function clickHandler2(event:MouseEvent):void {
if(event.currentTarget.selected){popWindow = new PopWindow;
queryBuilder(event.currentTarget);
PopUpManager.addPopUp(popWindow, my_view, false);
PopUpManager.centerPopUp(popWindow);
popWindow.addEventListener(AddProductEvent.ADD_PRODUCT, onAddProduct);}
}
I get the error on the addEventListener line. What am I doing wrong? Any advice?
Thank you.
-Laxmidi
Your AddProductEvent class doesn't seem to expose a public static string called ADD_PRODUCT which has the value "addProduct" which is what it looks like you are trying to do.
Is it possible to use the Flex Framework and Components, without using MXML? I know ActionScript pretty decently, and don't feel like messing around with some new XML language just to get some simple UI in there. Can anyone provide an example consisting of an .as file which can be compiled (ideally via FlashDevelop, though just telling how to do it with the Flex SDK is ok too) and uses the Flex Framework? For example, just showing a Flex button that pops open an Alert would be perfect.
If it's not possible, can someone provide a minimal MXML file which will bootstrap a custom AS class which then has access to the Flex SDK?
I did a simple bootstrap similar to Borek (see below). I would love to get rid of the mxml file, but if I don't have it, I don't get any of the standard themes that come with Flex (haloclassic.swc, etc). Does anybody know how to do what Theo suggests and still have the standard themes applied?
Here's my simplified bootstrapping method:
main.mxml
<?xml version="1.0" encoding="utf-8"?>
<custom:ApplicationClass xmlns:custom="components.*"/>
ApplicationClass.as
package components {
import mx.core.Application;
import mx.events.FlexEvent;
import flash.events.MouseEvent;
import mx.controls.Alert;
import mx.controls.Button;
public class ApplicationClass extends Application {
public function ApplicationClass () {
addEventListener (FlexEvent.CREATION_COMPLETE, handleComplete);
}
private function handleComplete( event : FlexEvent ) : void {
var button : Button = new Button();
button.label = "My favorite button";
button.styleName="halo"
button.addEventListener(MouseEvent.CLICK, handleClick);
addChild( button );
}
private function handleClick(e:MouseEvent):void {
Alert.show("You clicked on the button!", "Clickity");
}
}
}
Here are the necessary updates to use it with Flex 4:
main.mxml
<?xml version="1.0" encoding="utf-8"?>
<local:MyApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:local="components.*" />
MyApplication.as
package components {
import flash.events.MouseEvent;
import mx.controls.Alert;
import mx.events.FlexEvent;
import spark.components.Application;
import spark.components.Button;
public class MyApplication extends Application {
public function MyApplication() {
addEventListener(FlexEvent.CREATION_COMPLETE, creationHandler);
}
private function creationHandler(e:FlexEvent):void {
var button : Button = new Button();
button.label = "My favorite button";
button.styleName="halo"
button.addEventListener(MouseEvent.CLICK, handleClick);
addElement( button );
}
private function handleClick(e:MouseEvent):void {
Alert.show("You clicked it!", "Clickity!");
}
}
}
This is a very simple app that does only the basic bootstrapping in MXML. This is the MXML:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onCreationComplete()">
<mx:Script source="Script.as" />
</mx:Application>
This is the Script.as:
import mx.controls.Button;
import flash.events.MouseEvent;
import mx.controls.Alert;
import mx.core.Application;
private function onCreationComplete() : void {
var button : Button = new Button();
button.label = "Click me";
button.addEventListener(MouseEvent.CLICK, function(e : MouseEvent) : void {
Alert.show("Clicked");
});
Application.application.addChild(button);
}
NOTE: The below answer will not actually work unless you initialize the Flex library first. There is a lot of code involved to do that. See the comments below, or other answers for more details.
The main class doesn't even have to be in MXML, just create a class that inherits from mx.core.Application (which is what an MXML class with a <mx:Application> root node is compiled as anyway):
package {
import mx.core.Application;
public class MyFancyApplication extends Application {
// do whatever you want here
}
}
Also, any ActionScript code compiled with the mxmlc compiler -- or even the Flash CS3 authoring tool -- can use the Flex classes, it's just a matter of making them available in the classpath (refering to the framework SWC when using mxmlc or pointing to a folder containing the source when using either). Unless the document class inherits from mx.core.Application you might run in to some trouble, though, since some things in the framework assume that this is the case.
Yes, you just need to include the flex swc in your classpath. You can find flex.swc in the flex sdk in frameoworks/lib/flex.swc
edit: One more thing: if you're using Flex Builder you can simply create a new ActionScript project, which will essentially do the same as above.