Commerce Cloud - How to override the code for the Apply button? - demandware

I'm fairly new to Commerce Cloud; I've added a custom textfield.
I want to override the form submission that takes place on the click of the Apply Button so that I can read the value from this new field.
I'm working on the sample SiteGenesis site. Any help in this regard would be very helpful.

to process a form submission you need to write a controller in server side javascript which needs to be installed in an appropriate cartridge. It seems like you are trying to create a form as a content asset. This is not the recommended approach instead you should create a controller together with some templates that manages this task.
a simple controller looks like this:
'use strict';
var server = require('server');
var cache = require('*/cartridge/scripts/middleware/cache');
server.get('World', cache.applyDefaultCache, function (req, res, next) {
res.render('helloworld', {
Message: 'Hello World! Again.'
});;
next();
});
module.exports = server.exports();

Related

Why the refresh on the model does not work?

Maybe I don't really understand the this.getView().getModel().refresh(true) or updateBindings.. Somehow it doesn't refresh the model, or my main idea is wrong. I mean; I can do a workaround to call a function that reads the odata service again, but this is not really beautiful. So, I read the Model in the onInit
onInit: function () {
var that = this;
var oViewModel = new sap.ui.model.json.JSONModel({});
this.getView().setModel(oViewModel, "detailView");
sap.ui.getCore().setModel(oViewModel,"detailView");
var oFilter = [];
var zAppFilter = new sap.ui.model.Filter("XXX", sap.ui.model.FilterOperator.EQ, "XXXX");
oFilter.push(zAppFilter);
var oModel = that.getView().getModel();
oModel.setDefaultBindingMode("TwoWay");
oModel.read("/XXXXSet", {
filters: oFilter,
success: function (oData) {
that.getView().getModel("detailView").setData(oData.results);
},
// ...
});
},
I use this "detailView"-JSONModel model in my view for bindings. This works.. Now, the add or delete function for example:
onDelete: function (oEvent) {
var that = this;
var oModel = this.getOwnerComponent().getModel();
var oSelectedItem = oEvent.getSource().getParent();
var oSourceID = oSelectedItem.getBindingContext("detailView").getObject().Zid;
oModel.remove("/XXX(XXX='XXX',XXXX='" + XXXX+ "')", {
method: "DELETE",
success: function(data) {
that.getView().getModel("detailView").refresh(true);
sap.ui.getCore().getModel("detailView").refresh(true);
},
// ...
});
},
That does not work.. but why? I mean also when I do updateBindings or something else. Am I understanding or doing something wrong?
Your JSONModel is not connected to anything. It's just a bunch of JSON data. So if you tell it to refresh, how should it know where to get the new data?
What refresh does not do is getting new data.
What refresh actually does (in a JSONModel) is telling the bindings that it has new data. One of these bindings can be the items of a sap.m.List for example. The list then knows that it needs to rerender to show the new data.
If you don't fetch new data and call refresh nothing will happen. The actual data is still the same.
i can do a workaround to call a function that reads agean the odata service but this is not really beautyfull
Well using an additional JSONModel when you already have a perfectly fine ODataModel isn't beautiful in the first place. If you just dropped your JSONModel and bound your view to your ODataModel then the view would automatically update after calling remove.
To bind the view to your ODataModel you can start with
<Table id="table0" items="{/XXXXSet}">
Don't forget to remove detailView from your cells.
You're mixing a client-side model (JSONModel) with a server-side model (ODataModel), expecting them to synchronize.
Client-side models and server-side models are two separate models serving two different purposes.
Client-side models
The main purpose of the client-side models is to provide and to sync data that are only available during the runtime of the application. If the app is gone, the data are gone. Some of the prominent use cases of client side models are:
Device model via JSONModel which provides information about user's device and its states.
ResourceModel which provides client side translatable UI texts for i18n purposes.
Synchronizing states from UI or application
The models here are not aware of any server-side data, and they shouldn't since it's not their purpose.
When dealing with a remote data provider that complies with a certain specification (e.g. OData or FHIR), the appropriate server-side model should be used instead.
Server-side models
Server-side models, such as ODataModel, have the advantage that they're server aware.
They know how to fetch, delete, update, create data, and even call functions from the backend system. They can be used to share states between the client and the server efficiently.
How? Simply use the server-side model in the binding definition directly. With OData as the default model for example:
<List items="{
path: '/MyEntitySet',
filters: [
{
path: 'ThatProperty',
operator: 'EQ',
value1: 'something'
}
]
}"> <!-- given "MyEntitySet", "ThatProperty", "EntityTitle", and "EntityDesc" are defined in $metadata -->
<StandardListItem title="{EntityTitle}" description="{EntityDesc}" />
</List>
This creates an ODataListBinding instance which will send a request to the service with the following URL:
https://....svc/MyEntitySet?$filter=ThatProperty eq 'something'
When the request succeeds, the list will show the entities accordingly. Afterwards, when calling myODataModel.remove(...);, the corresponding list will be refreshed automatically.
TL;DR
Am I understanding or doing something wrong?
Yes. Having an intermediate JSONModel in such cases is a common anti-pattern creating high maintenance costs. Try using the ODataModel only. The framework will do the work for you.

Show a popup on redirect from old to new domain

I need to show a popup when the old domain is redirected to new domain in the nuxt js.
I have modified the . htaccess file and have a modal in the index.vue.
mounted() {
const modal = document.getElementById('modal')
if (document.referrer.indexOf('https://olddomain.com') > -1) {
alert('Previous domain redirected')
modal.style.display = 'block'
}
}
But there is no popup displayed. Is there a better way to do this using nuxt.
You can try the following:
Create a middleware in middleware/popupCheck.js name is up to you..
when you are creating middleware in Nuxt you should export default function, like this:
export default function(context) {
if (context.req.headers['your-custom-header']) {
// Use vuex store to dispatch an action to show a popup or set a cookie
// to listen to. Here the logic should be defined by the implementation.
}
}
The point here is to listen for a header in the request, could be a cookie also, that you have to send from your old site for every request, so make sure it's not something generic, but instead something that you cannot hit easily by mistake..
After you create your middleware you can use it on pages or layouts views, and you should add it in the default object you export:
export default {
middleware: 'popupCheck',
}
Without importing the middleware you just call it by name, this could also be an array if you wish to add multiple middlewares, and the order in that array is important.
There might be a better way to solve this, but this is the first one that came to my mind..

Hook for REST validation with sailsjs

I need to create a validation layer for my REST services, I'm using sailsjs.
Someone know how can I do that?
I tried to create a hook but I cant access routes definitions and the hook is called before start policies :'(
The way is something like picture below.
It is perfectly fine to use policies to pre-process requests before they are passed to the controllers. Policies are not just for authentication and acl. They are so versatile you can use them for anything.
E.g.
policies/beforeUpdateTicket.js
module.exports = function(req, res, ok) {
TicketService.checkTicket(req.params.id, null, true).then(function(ticket) {
# You can even modify req.body
req.body.checked = true;
return ok();
}).fail(function(err) {
# Don't go to the controller, respond with error
return res.send(JSON.stringify({
message: 'some_error'
}), 409);
});
};

How can I show a maintenance page?

I'd like to show a maintenance page on my site. I plan on saving a Boolean value to the db in order to control when to show the page or not. How can I have the maintenance page show for just my controller routes? I'd like to continue to have sails serve scripts, stylesheets, and images normally.
You could use a policy to achieve this.
// api/policies/inMaintenance.js
module.exports = function(req, res, next) {
var maintenanceMode = ... // get the value
if (maintenanceMode) return res.view('maintenance');
next();
}
// config/policies.js
module.exports.policies = {
'*': 'inMaintenance',
...
}
In your views folder add maintenance.ejs.
All the assets will still be available.
There is one drawback to this approach though, if in config/routes.js you have a route pointing directly to a view it will not go through the policy. Thus, you need all routes to be handled by controllers.
You can check the Sails documentation on policies to better understand how they work.

Why when I upload of file-list the server-side code get an empty list?

First of all here's my jsFiddle, so you can see what I'm talking abuout.
I'm using blueimp/jQuery-File-Upload to manage files in the GUI of my asp-net application (server-side code is OK). If I manage the upload one-by-one I am able to upload that file successfully but as I try to submit the whole list the server does not recognize data and get only an empty list.
Here's the piece of code where my issue is:
//initialize fileupload()
$('#fileupload').fileupload({
//I call this function when I add file(s) to the list
add: function (e, data) {
//I do some more actions here
//Then I define this function when the submit button is clicked
$('#submitButton').click(function () {
//fix this?
data.submit();
});
}
)};
So, what am I doing wrong?
Your server should support multipart forms!
A solid handler for ASP.NET is Backload