Cannot find name 'jQuery' error in controller.js - javascript

I am developing a UI5 app in VS Code.
I added a new count function to the *.controller.js file, and in order to display the count from the server, I am using jQuery like in the following code:
jQuery.each(this._mFilters, function (sFilterKey, oFilter) {
oModel.read("/portfolios/$count", {
filters: oFilter,
success: function (oData) {
var sPath = "/" + sFilterKey;
oViewModel.setProperty(sPath, oData);
}
});
});
Unfortunately, I get the following error:
Does anyone know why was the error triggered and how it can be fixed?
Any help or suggestion is much appreciated.

I assume this._mFilters is an object. In that case, try with:
Object.keys(this._mFilters).map(sFilterKey => {
const oFilter = this._mFilters[sFilterKey];
oModel.read("/portfolios/$count", {
filters: [ oFilter ],
success: function(sCount) {
const sPath = `/${sFilterKey}`;
oViewModel.setProperty(sPath, +sCount);
},
});
});
Also the parameter filters awaits an array instead of a single Filter instance.
If jQuery is still preferred, include "sap/ui/thirdparty/jquery" (formerly "jquery.sap.global") to the dependency list of the controller.
sap.ui.define([
"sap/ui/core/mvc/Controller",
// ...,
"sap/ui/thirdparty/jquery",
], function(Controller,/*...,*/ jQuery) {
// jQuery is here available
});

Related

How to process two sets from different models in one custom control

Aim:
I'd like to have two models(sets of data) passed to the custom control with a predefined search field, in which later on I can execute filtering.
I'm a newbie in OpenUi5, so I might be doing something wrong and stupid here. I've started with a simplified task of passing data from the frontend to my custom control and experiencing troubles.
Background of the simplified idea:
Create a custom control with an aggregation foo , the value to it will be provided from the view.
Also create another aggregation element _searchField which will be populated with the data provided from the view.
Fire the onSuggestTerm everytime user types in a _searchField.
Custom control code:
function (Control) {
var DropDownListInput = Control.extend('xx.control.DropDownListInput', {
metadata: {
defaultAggregation: 'foo',
aggregations: {
foo: { type: 'sap.m.SuggestionItem', multiple: true, singularName: 'suggestionItem' },
_searchField: { type: 'sap.m.SearchField', multiple: false, visibility: 'hidden' }
}
}
});
DropDownListInput.prototype.init = function () {
var that = this;
this.onSuggestTerm = function (event) {
var oSource = event.getSource();
var oBinding = that.getAggregation('foo');
oBinding.filter(new sap.ui.model.Filter({
filters: new sap.ui.model.Filter('DISEASE_TERM', sap.ui.model.FilterOperator.Contains, ' Other')
}));
oBinding.attachEventOnce('dataReceived', function () {
oSource.suggest();
});
};
this.setAggregation('_searchField', new sap.m.SearchField({
id: 'UNIQUEID1',
enableSuggestions: true,
suggestionItems: that.getAggregation('foo'),
suggest: that.onSuggestTerm
}));
};
return DropDownListInput;
}, /* bExport= */true);
I'm not providing Renderer function for control here, but it exists and this is the most important excerpt from it:
oRM.write('<div');
oRM.writeControlData(oControl);
oRM.write('>');
oRM.renderControl(oControl.getAggregation('_searchField'));
oRM.write('</div>');
Passing the data to this control from the xml frontend:
<xx:DropDownListInput
id="diseaseTermUNIQUE"
foo='{path: db2>/RC_DISEASE_TERM/}'>
<foo>
<SuggestionItem text="{db2>DISEASE_TERM}"
key="{db2>DISEASE_TERM}" />
</foo>
</xx:DropDownListInput>
The code fails to run with this error Cannot route to target: [object Object] -
and I have no idea what's wrong here..
The problem is that you forgot to provide single quotes in your path:
foo="{path: 'db2>/RC_DISEASE_TERM/'}"

Intercepting response in dojo to read cookies

I have a filter on server side which adds a cookie myCookie to every response.
I am intercepting the response in a dojo widget as below:
define("mySolution/ServerCookieWidget", [
"dojo/request/notify",
"dojo/cookie"
], function (notify, cookie) {
notify("load", function(response) {
var cookieRead = cookie("myCookie");
console.log('Cookie read is: ', cookieRead);
});
});
I want to use the value read to do some calculation on client side.
How do I share the read cookie value with other widget?
I am new to dojo and thus not aware of the syntax and not able to find any example for my scenario.
Depending on the rest of your architecture, you might want to use Dojo's pubsub module dojo/topic:
https://dojotoolkit.org/reference-guide/1.10/dojo/topic.html
So for example, changing your code to:
define("mySolution/ServerCookieWidget", [
"dojo/request/notify",
"dojo/cookie",
"dojo/topic"
], function (notify, cookie, topic) {
notify("load", function(response) {
var cookieRead = cookie("myCookie");
// console.log('Cookie read is: ', cookieRead);
topic.publish("*/cookie/value", cookieRead);
});
});
You can create widgets which subscribe to the topic:
define("mySolution/SomeOtherWidget", [
"dojo/_base/declare",
"dojo/topic"
], function (declare, topic) {
var OtherWidget = declare(null, {
constructor: function (opt) {
this.topicHandle = topic.subscribe("*/cookie/value", this._handleCookieValue.bind(this));
},
_handleCookieValue: function (cookieVal) {
console.log("Cookie value is:", cookeVal);
}
});
return OtherWidget;
});

TYPO3: How to use the element browser in an own backend module?

I want to have a simple input field in an own TYPO3 8.7 backend module, what should be filled with a pageid after clicking a page in the element browser.
I tried a lot in the past but the main problem is an error-alert in the element browser when clicking a page with Error - reference to main window is not set properly!
My module.js file looks like at the moment:
var setFormValueOpenBrowser;
define(['jquery', 'TYPO3/CMS/Lux/Vendor/Chart.min'], function($) {
// define(['jquery', 'TYPO3/CMS/Lux/Vendor/Chart.min', 'TYPO3/CMS/Backend/FormEngine'], function($) {
// main options
// var FormEngine = {
// formName: TYPO3.settings.FormEngine.formName
// ,backPath: TYPO3.settings.FormEngine.backPath
// ,openedPopupWindow: null
// ,legacyFieldChangedCb: function() { !$.isFunction(TYPO3.settings.FormEngine.legacyFieldChangedCb) || TYPO3.settings.FormEngine.legacyFieldChangedCb(); }
// };
var url = '/typo3/index.php?route=%2Fwizard%2Frecord%2Fbrowse&token=53b5d23e8e661e465636a96ca618426cb293d0b5&mode=db&bparams=data[pages][2][content_from_pid]|||pages|';
var popup = window.open(url, 'Typo3WinBrowser', 'height=600,width=800,status=0,menubar=0,resizable=1,scrollbars=1');
popup.focus();
});
Of course, the token is hardcoded in this example - but that's not the problem.
BTW: If I try to also load FormEngine via require.js the console throws a TypeError: TYPO3.settings.FormEngine is undefined
Has anyone a working code for the usage of the element browser (files or pages) in an own backend module? Or is there an existing extension where I can dig into the code?
Although this question is a little outdated, here's how I did it:
This is in the controller of my extension
$options = [
'renderType' => 'inputLink',
'tableName' => 'myTable',
'fieldName' => 'url',
'databaseRow' => [
'uid' => $myModel->getUid(),
'pid' => 0
],
'parameterArray' => [
'fieldConf' => [
'label' => 'URL',
'config' => [
'eval' => 'trim',
'size' => 1024,
],
],
'itemFormElValue' => $myModel->getUrl(),
'itemFormElName' => 'data[myTable][editform][url]',
'itemFormElID' => 'data[mytable][editform][url]',
'field' => 'url',
'fieldChangeFunc' => [
'TBE_EDITOR_fieldChanged' => "TBE_EDITOR.fieldChanged('mytable','editform','url','data[mytable][editform][url]');"
],
]
];
$nodeFactory = new NodeFactory();
$linkField = new InputLinkElement($nodeFactory, $options);
$urlField = $linkField->render();
$this->view->assign('renderedUrlField', $urlField['html']);
Where «mytable» is the table the controller uses, «editform» is the form-name and «url» is the database-field that's been used to store the value.
For some reason, you need to name your form «editform», since a sysext-JS refers to that.
You need to add this to your controller to make this working:
use TYPO3\CMS\Backend\Form\Element\InputLinkElement;
use TYPO3\CMS\Backend\Form\NodeFactory;
And in the fluid-template, you have to use:
<f:format.raw>{renderedUrlField}</f:format.raw>
because it returns html-code.
Regarding the javascript error: that's because the FormEngine wasn't initialized.
Add this to your Default.html in the section <f:be.container...>:
includeJsFiles="{
1:'/typo3/sysext/backend/Resources/Public/JavaScript/jsfunc.tbe_editor.js',
3:'/typo3/sysext/backend/Resources/Public/JavaScript/jsfunc.inline.js',
4:'/typo3/sysext/backend/Resources/Public/JavaScript/backend.js'
}"
includeRequireJsModules="{
0:'{f:uri.resource(path:\'JavaScript/ckeditor/ckeditor.js\')}',
4:'TYPO3/CMS/Backend/FormEngine',
5:'TYPO3/CMS/Backend/FormEngineValidation',
7:'TYPO3/CMS/Backend/ContextMenu',
8:'TYPO3/CMS/Backend/FormEngineReview',
9:'{f:uri.resource(path:\'JavaScript/main.js\')}'
}"
I included ckeditor as well here.
And now, you need to initialize the FormEngine. I did this in main.js:
TYPO3.settings.FormEngine = {"formName":"editform"};
define(['jquery', 'TYPO3/CMS/Backend/FormEngine'], function($){
'use strict';
$(function(){
TYPO3.FormEngine.initialize();
});
});
The first line is important, otherwise, the JS will throw said error.
Hope this helps somebody.

How to split up a JSON file for use in Drop Down box

I'm using Marionette/Backbone and i have a JSON file with multiple objects, i need to populate a select box with items from this JSON file. So a drop down box for accountType, States and dates.
At the moment i only care about the accountType, but i can't find a way of splitting the JSON file up so that the drop down shows only "Full" or "Trial".
I have a JSON file which looks similar to this:
{
"accountType":["Full","Trial"],
"states": [{"state":"AL","stateDescription":"Alabama","featured":"A1"},
{"state":"AK","stateDescription":"Alaska","featured":"B1"}],
"dates":[{"dateDescription":"Jan","month":1,"year":2008},
{"dateDescription":"Feb","month":2,"year":2008}]
}
I didn't write the JSON file it's what i have to use - i access it in my .js file like so:
initialize: function () {
this.on('change', this.change);
var that = this;
$.getJSON("webapp/jsondata", function (data) {
that.set('accountType', data);});
}
But in my drop down box i basically get:
Full, Trial
[object Object], [object Object]
In that sort of format.
I think i understand why and it's because im not splitting up the JSON file but just can't work out how to do it. Read pages and pages online but nothing seems appropriate.
Any advice appreciated, please be gentle.
EDIT:---
Here's the whole code in the backbone data. This now works to populate the accountType box but when i replicate it with the other drop downs all of them turn blank.
define([ 'backbone', 'underscore', 'vent', ], function (Backbone, _, vent) {
'use strict';
return Backbone.Model.extend({
url: {},
loaded: false,
defaults: {
accountType: [],
states: [],
dates: [],
},
initialize: function () {
this.on('change', this.change);
var that = this;
$.getJSON("webapp/jsondata", function (data) {
that.set({
states: data.states,
});
});
$.getJSON("webapp/jsondata", function (data) {
that.set({
dates: data.dates,
});
});
$.getJSON("webapp/jsondata", function (data) {
that.set({
accountType: data.accountType,
});
});
},
});
});
I'm guessing it's because AccountType has only 1 attribute while "states" have State, description and featured. I want to only pick out for example "AL" and "AK". So i need a way of slicing my data (i think) and allocating it to the drop downs.
Edit--
Here's the view code:
define([ 'marionette', 'templates', 'vent', 'select'],
function (Marionette, templates, vent, select) {
"use strict";
return Marionette.ItemView.extend({
template: templates.inputView,
serializeData: function () {
return {
states: this.options.meta.get('states'),
dates: this.options.meta.get('dates'),
accountType: this.options.meta.get('accountType'),
};
},
});
});
You can use the parse method of model/collection.
Take a look at the documentation
Try this :
initialize: function () {
//this.on('change', this.change);
this.fetch();
}
A more specific question was asked here which sorted me out:
Populating data from JSON for drop downs

CouchDB list function throwing TypeError (point is undefined)

I am attempting to get a list out of my database. The documents look like:
{
"class": "lists",
"collection": "symptoms",
"order": "6",
"en": "Headache",
"_id": "9022034e7d5ecd0efab0762c5b7f0c04"
}
There are an arbitrary number of "collection"s.
A view function simply returns a bunch of objects in the class "lists":
// Emit lists
exports.viewlist = {
map: function(doc) {
if (doc.class === 'lists') {
emit(
doc.collection, {
order: doc.order,
name: doc.en
});
}
}
};
I wrote a list function to try to filter the output to just the list that I want.
exports.viewlist = function(head, req) {
var row;
start({
code: 200,
headers: {
'Content-Type': 'text/json; charset=utf-8',
}
});
while (row = getRow()) {
if (row.collection === req.l) {
send(JSON.stringify(row.value));
}
}
};
CouchDB throws an error when I visit the URL of the list:
http://localhost:5984/dev/_design/emr/_list/viewlists/viewlist?l=symptoms
{"error":"TypeError","reason":"{[{<<\"message\">>,<<\"point is undefined\">>},
{<<\"fileName\">>,<<\"/usr/share/couchdb/server/main.js\">>},
{<<\"lineNumber\">>,1500},\n {<<\"stack\">>,
<<\"(\\\"_design/emr\\\",[object Array],
[object Array])#/usr/share/couchdb/server/main.js:1500\
()#/usr/share/couchdb/server/main.js:1562\
#/usr/share/couchdb/server/main.js:1573\
\">>}]}"}
I can't figure out where I'm going wrong here.
I also ran into this error and what causes it, as hinted at by #Pea-pod here Submitting form to couchDB through update handler not working, is not defining properly your exports in the couchapp's design documents. In our case it was as list function that couldn't be called and instead displayed a 500 error with Type error and point is undefined in the couchdb log.
We use kanso and in the app.js we hadn't required the list file. We had:
module.exports = {
rewrites: require('./rewrites'),
views: require('./views'),
shows: require('./shows')
};
Changing it to the following solved the problem:
module.exports = {
rewrites: require('./rewrites'),
views: require('./views'),
shows: require('./shows')
lists: require('./lists'),
};
Can I suggest to a moderator to change the title of this question to include point is undefined which is the error that shows up in the CouchDB log when this type of error is made, in order to help others find it more easily?

Categories