I have an input to which I wish to bind a dataAdapter for a custom query as described in https://select2.org/upgrading/migrating-from-35#removed-the-requirement-of-initselection
<input name="pickup_point">
My script:
Application.prototype.init = function() {
this.alloc('$pickupLocations',this.$el.find('[name="pickup_point"]'));
var that = this;
$.fn.select2.amd.require([
'select2/data/array',
'select2/utils'
], function (ArrayData, Utils) {
var CustomData = function($element, options) {
CustomData.__super__.constructor.call(this, $element, options);
};Utils.Extend(CustomData, ArrayData);
CustomData.prototype.query = function (params, callback) {
var data = {
results: []
};
console.log("xxx");
for (var i = 1; i < 5; i++) {
var s = "";
for (var j = 0; j < i; j++) {
s = s + params.term;
}
data.results.push({
id: params.term + i,
text: s
});
}
callback(data);
};
that.$pickupLocations.select2({
minimumInputLength: 2,
language: translations[that.options.lang],
tags: [],
dataAdapter: CustomData
});
});
}
But when I type the in the select2 search box the xxx i'm logging for testing doesn't appear in my console.
How can I fix this?
I found the solution on
https://github.com/select2/select2/issues/4153#issuecomment-182258515
The problem is that I tried to initialize the select2 on an input field.
By changing the type to a select, everything works fine.
<select name="pickup_point">
</select>
Related
I'm trying to get this canvasJS line chart to render using thymeleaf rather than JSP.
It has the following loop in jsp that I need to convert to javascript. However I'm not proficient in javascript
<c:forEach items="${dataPointsList}" var="dataPoints" varStatus="loop">
<c:forEach items="${dataPoints}" var="dataPoint">
xValue = parseInt("${dataPoint.x}");
yValue = parseFloat("${dataPoint.y}");
dps[parseInt("${loop.index}")].push({
x : xValue,
y : yValue,
});
</c:forEach>
</c:forEach>
The above $dataPointList is created in java as follows
static List<Map<Object, Object>> dataPoints1 = new ArrayList<Map<Object, Object>>();
static {
int limit = 50000;
int y = 100;
Random rand = new Random();
for (int i = 0; i < limit; i += 1) {
y += rand.nextInt(11) - 5;
map = new HashMap<Object, Object>();
map.put("x", i);
map.put("y", y);
dataPoints1.add(map);
}
list.add(dataPoints1);
}
public static List<List<Map<Object, Object>>> getCanvasjsDataList() {
return list;
}
I've tried the following however dps[parseInt(i)].push({ gives a type error. I'm not sure how to create the required data structure for canvasJS given the datalist defined in java.
<script src="http://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript" th:inline="none" class="init">
/*<![CDATA[*/
window.onload = function (e) {
var dps = [[]];
var chart = new CanvasJS.Chart("chartContainer", {
theme: "light2", // "light1", "dark1", "dark2"
animationEnabled: true,
zoomEnabled: true,
title: {
text: "Try Zooming and Panning"
},
data: [{
type: "area",
dataPoints: dps[0]
}]
});
var xValue;
var yValue;
var dataPointsList = /*[[${dataPointsList}]]*/ 'default';
for (var i = 0; i < dataPointsList.length; i++) {
var dataPoints = dataPointsList[i];
for (var j = 0; j < dataPoints.length; j++) {
dps[parseInt(i)].push({
x : dataPoints[j].x,
y : dataPoints[j].y,
});
}
}
chart.render();
}
/*]]>*/
</script>
The following adjustments have resulted in the graph displaying
<script type="text/javascript" th:inline="javascript" class="init">
/*<![CDATA[*/
window.onload = function (e) {
var dps = [];
var chart = new CanvasJS.Chart("chartContainer", {
theme: "light2", // "light1", "dark1", "dark2"
animationEnabled: true,
zoomEnabled: true,
title: {
text: "Try Zooming and Panning"
},
data: [{
type: "area",
dataPoints: dps
}]
});
var dataPointsList = /*[[${dataPointsList}]]*/ 'null';
count = 0;
for (var i = 0; i < dataPointsList.length; i++) {
var dataPoints = dataPointsList[i];
for (var j = 0; j < dataPoints.length; j++) {
dps[count++] = {
x: dataPoints[j].x,
y: dataPoints[j].y
};
}
}
chart.render();
}
/*]]>*/
</script>
I need a simple autocomplete search functionality but also allowing users to type more than one value. I'm using jQuery UI's autocomplete widget (http://jqueryui.com/autocomplete/) and so far I've set the source to only search for the first letter in the suggestions. What I'd like to add now is the ability for users to search for multiple items from the same textbox. (i.e. after a comma suggestions are shown again)
I have been trying to search on how this could be done. The only thing I've managed to find is an option that could be added multiple: true (http://forum.jquery.com/topic/multiple-values-with-autocomplete). Thing is that it's not even listed in the documentation anymore so I don't know if the option has changed or doesn't exist anymore.
This is my code:
var items = [ 'France', 'Italy', 'Malta', 'England',
'Australia', 'Spain', 'Scotland' ];
$(document).ready(function () {
$('#search').autocomplete({
source: function (req, responseFn) {
var re = $.ui.autocomplete.escapeRegex(req.term);
var matcher = new RegExp('^' + re, 'i');
var a = $.grep(items, function (item, index) {
return matcher.test(item);
});
responseFn(a);
}
});
});
What I tried:
var items = [ 'France', 'Italy', 'Malta', 'England',
'Australia', 'Spain', 'Scotland' ];
$(document).ready(function () {
$('#search').autocomplete({
source: function (req, responseFn) {
var re = $.ui.autocomplete.escapeRegex(req.term);
var matcher = new RegExp('^' + re, 'i');
var a = $.grep(items, function (item, index) {
return matcher.test(item);
});
responseFn(a);
},
multiple: true
});
});
Try this:
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$( "#search" )
.autocomplete({
minLength: 0,
source: function( request, response ) {
response( $.ui.autocomplete.filter(
items, extractLast( request.term ) ) );
},
focus: function() {
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
terms.pop();
terms.push( ui.item.value );
terms.push( "" );
this.value = terms.join( ", " );
return false;
}
});
SEE DEMO
To solve the issue of multiple strings in the same textbox AND include a regex to only show suggestions matching the start of the string I did the following:
$('#search').autocomplete({
minLength: 1,
source: function (request, response) {
var term = request.term;
// substring of new string (only when a comma is in string)
if (term.indexOf(', ') > 0) {
var index = term.lastIndexOf(', ');
term = term.substring(index + 2);
}
// regex to match string entered with start of suggestion strings
var re = $.ui.autocomplete.escapeRegex(term);
var matcher = new RegExp('^' + re, 'i');
var regex_validated_array = $.grep(items, function (item, index) {
return matcher.test(item);
});
// pass array `regex_validated_array ` to the response and
// `extractLast()` which takes care of the comma separation
response($.ui.autocomplete.filter(regex_validated_array,
extractLast(term)));
},
focus: function () {
return false;
},
select: function (event, ui) {
var terms = split(this.value);
terms.pop();
terms.push(ui.item.value);
terms.push('');
this.value = terms.join(', ');
return false;
}
});
function split(val) {
return val.split(/,\s*/);
}
function extractLast(term) {
return split(term).pop();
}
If you want to implement the focus function instead of returning false, it's:
focus: function (event, ui) {
var terms = split(this.value);
terms.pop();
terms.push(ui.item.value);
this.value = terms.join(', ');
return false;
},
If you do this though, you should probably extract commas from the values.
Also, you can replace lines 7-10 with a call to extractLast. And then you can get rid of your other extractLast because you already called it on term.
With all my changes:
$('#search').autocomplete({
minLength: 1,
source: function (request, response) {
var term = extractLast(request.term),
re = $.ui.autocomplete.escapeRegex(term),
matcher = new RegExp('^' + re, 'i'),
regex_validated_array = $.grep(items, function (item, index) {
return matcher.test(item);
}),
mapped_array = regex_validated_array.map(function (item) {
return value.replace(/,/g, '');
});
response($.ui.autocomplete.filter(mapped_array, term));
},
focus: function () {
var terms = split(this.value);
terms.pop();
terms.push(ui.item.value);
this.value = terms.join(', ');
return false;
},
select: function (event, ui) {
var terms = split(this.value);
terms.pop();
terms.push(ui.item.value);
terms.push('');
this.value = terms.join(', ');
return false;
}
});
function split(val) {
return val.split(/,\s*/);
}
function extractLast(term) {
return split(term).pop();
}
How to upload file in SAP Netweaver server using SAPUI5? I tried to upload file using FileUploader but did not get the luck if any one can help it will be very appreciated.
Thanks in Advance
Nothing was added to the manifest nor the component nor index files. It is working for me, you just need to change the number of columns to whatever you want to fit your file.
UploadFile.view.xml
<VBox>
<sap.ui.unified:FileUploader id="idfileUploader" typeMissmatch="handleTypeMissmatch" change="handleValueChange" maximumFileSize="10" fileSizeExceed="handleFileSize" maximumFilenameLength="50" filenameLengthExceed="handleFileNameLength" multiple="false" width="50%" sameFilenameAllowed="false" buttonText="Browse" fileType="CSV" style="Emphasized" placeholder="Choose a CSV file"/>
<Button text="Upload your file" press="onUpload" type="Emphasized"/>
</VBox>
UploadFile.controller.js
sap.ui.define(["sap/ui/core/mvc/Controller", "sap/m/MessageToast", "sap/m/MessageBox", "sap/ui/core/routing/History"], function(
Controller, MessageToast, MessageBox, History) {
"use strict";
return Controller.extend("cafeteria.controller.EmployeeFileUpload", {
onNavBack: function() {
var oHistory = History.getInstance();
var sPreviousHash = oHistory.getPreviousHash();
if (sPreviousHash !== undefined) {
window.history.go(-1);
} else {
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.navTo("admin", true);
}
},
handleTypeMissmatch: function(oEvent) {
var aFileTypes = oEvent.getSource().getFileType();
jQuery.each(aFileTypes, function(key, value) {
aFileTypes[key] = "*." + value;
});
var sSupportedFileTypes = aFileTypes.join(", ");
MessageToast.show("The file type *." + oEvent.getParameter("fileType") +
" is not supported. Choose one of the following types: " +
sSupportedFileTypes);
},
handleValueChange: function(oEvent) {
MessageToast.show("Press 'Upload File' to upload file '" + oEvent.getParameter("newValue") + "'");
},
handleFileSize: function(oEvent) {
MessageToast.show("The file size should not exceed 10 MB.");
},
handleFileNameLength: function(oEvent) {
MessageToast.show("The file name should be less than that.");
},
onUpload: function(e) {
var oResourceBundle = this.getView().getModel("i18n").getResourceBundle();
var fU = this.getView().byId("idfileUploader");
var domRef = fU.getFocusDomRef();
var file = domRef.files[0];
var reader = new FileReader();
var params = "EmployeesJson=";
reader.onload = function(oEvent) {
var strCSV = oEvent.target.result;
var arrCSV = strCSV.match(/[\w .]+(?=,?)/g);
var noOfCols = 6;
var headerRow = arrCSV.splice(0, noOfCols);
var data = [];
while (arrCSV.length > 0) {
var obj = {};
var row = arrCSV.splice(0, noOfCols);
for (var i = 0; i < row.length; i++) {
obj[headerRow[i]] = row[i].trim();
}
data.push(obj);
}
var Len = data.length;
data.reverse();
params += "[";
for (var j = 0; j < Len; j++) {
params += JSON.stringify(data.pop()) + ", ";
}
params = params.substring(0, params.length - 2);
params += "]";
// MessageBox.show(params);
var http = new XMLHttpRequest();
var url = oResourceBundle.getText("UploadEmployeesFile").toString();
http.onreadystatechange = function() {
if (http.readyState === 4 && http.status === 200) {
var json = JSON.parse(http.responseText);
var status = json.status.toString();
switch (status) {
case "Success":
MessageToast.show("Data is uploaded succesfully.");
break;
default:
MessageToast.show("Data was not uploaded.");
}
}
};
http.open("POST", url, true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.send(params);
};
reader.readAsBinaryString(file);
}
});
});
After researching a little more on this issue I finally solved this issue by myself I placed a file controller and a uploader in php which return the details related to files further, we can use it to upload it on server.
Here is the code I have used.
fileUpload.html
<!DOCTYPE html>
<html><head>
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
<title>Hello World</title>
<script id='sap-ui-bootstrap' src='http://localhost/resources/sap-ui-core.js' data-sap-ui-theme='sap_goldreflection'
data-sap-ui-libs='sap.ui.commons'></script>
<script>
var layout = new sap.ui.commons.layout.MatrixLayout();
layout.setLayoutFixed(false);
// create the uploader and disable the automatic upload
var oFileUploader2 = new sap.ui.commons.FileUploader("myupload",{
name: "upload2",
uploadOnChange: true,
uploadUrl: "uploader.php",
uploadComplete: function (oEvent) {
var sResponse = oEvent.getParameter("response");
if (sResponse) {
alert(sResponse);
}
}});
layout.createRow(oFileUploader2);
// create a second button to trigger the upload
var oTriggerButton = new sap.ui.commons.Button({
text:'Trigger Upload',
press:function() {
// call the upload method
oFileUploader2.upload();
$("#myupload-fu_form").submit();
alert("hi");
}
});
layout.createRow(oTriggerButton);
layout.placeAt("sample2");
</script>
</head>
<body class='sapUiBody'>
<div id="sample2"></div>
</body>
</html>
uploader.php
<?php
print_r($_FILES);
?>
It would be good if we can see your code.
This should work.
var layout = new sap.ui.commons.layout.MatrixLayout();
layout.setLayoutFixed(false);
// create the uploader and disable the automatic upload
var oFileUploader2 = new sap.ui.commons.FileUploader({
name : "upload2",
uploadOnChange : false,
uploadUrl : "../../../upload"
});
layout.createRow(oFileUploader2);
// create a second button to trigger the upload
var oTriggerButton = new sap.ui.commons.Button({
text : 'Trigger Upload',
press : function() {
// call the upload method
oFileUploader2.upload();
}
});
layout.createRow(oTriggerButton);
layout.placeAt("sample2");
Ajax function
$(function () {
$('form').submit(function () {
if ($(this).valid()) {
$.ajax({
url: this.action,
type: this.method,
data: { model: $(this).serialize(), locations: getCheckedLocation(), reports: getCheckedReports() },
beforeSend: function () {
},
complete: function () {
},
success: function (result) {
$('#user_operations_container').html(result);
setTimeout(function () { LoadAction('#Url.Action("GetAllUsers", "User")') }, 1000);
$("#widgets ul li a").removeClass("link_active");
$("#widgets ul li:first-child a").addClass("link_active");
}
});
}
return false;
});
});
functions that are using in ajax data attribute
function getCheckedLocation() {
var nodes = $('#tt_location').tree('getChecked');
var s = '';
for (var i = 0; i < nodes.length; i++) {
if (s != '') s += ',';
s += nodes[i].text;
}
return s;
}
function getCheckedReports() {
var nodes = $('#tt_reports').tree('getChecked');
var s = '';
for (var i = 0; i < nodes.length; i++) {
if (s != '') s += ',';
s += nodes[i].text;
}
return s;
}
HTML
<div> // there are html helpers for model (dropdownlistfor, textboxfor,...)
</div>
<div> // checkbox tree (#tt_location)
</div>
<div> // checkbox tree (#tt_reports)
</div>
Controller
[HttpPost]
public ActionResult _EditUser(UserViewModel model,string locations,string reports)
{
// model = null
// locations and reports are expected. (not null)
}
Question
Why model is null?
When I use ajax data attribute like this = data: $(this).serialize(), , It works model is not null.
How can I post model, with additional data (locations,reports).
I hope I can explain. Thanks...
Try like this:
data:$('this').serialize() + "&locations=" + getCheckedLocation() "&reports=" + getCheckedReports()
It will work.
Hope it helps
I have to display KendoUI splitters dynamically depending upon the records in the database.
If i have n records in my database,I have to display "n-1" splitters.and in each partition I have to display KendoGrid with different dataSource.
I have implemented ajax to get the records from database,In the success function depending upon the length I am able to display required number of splitters.
In each splitter I put a grid like,
success: function (json) {
for (var i = 0; i < json.length; i++) {
var div = document.createElement('div');
var griddatSource = new kendo.data.DataSource({
transport: {
read: {
url: "/Home/splitter",
type: "POST",
dataType: "json"
}
},
batch: false,
schema: {
model: {
id: "iD",
fields: {
iD: { type: "number" },
name: { type: "string" },
email: { type: "string" }
}
}
}
});
$('<div id = ' + json[i].name + '>').appendTo("#splitter");
$("#" + json[i].name).kendoGrid({
dataSource: griddatSource,
selectable: "multiple",
columns: [{ field: "name", title: "Name" },
{ field: "email", title: "Email"}],
editable: false
}).data("kendoGrid");
}
$("#splitter").kendoSplitter({
orientation: "horizontal"
});
}
Now,I am able to display splitters dynamically and in each splitters I am able to load the grid,but I want to know how to use different different dataSources for different grids.
Thanks
Just use a variable :
var div = $('<div/>');
div.appendTo('#splitter');
div.someStuff();
I think you can get a short idea from this.
<script type="text/javascript">
function fnc()
{
el=document.createElement('div');
el.style.backgroundColor="red";
el.innerHTML="aaa";
document.getElementById("adiv").appendChild(el);
//document.getElementById("adiv").innerHTML=var1;
}
</script>
<div id="adiv">
qwerty
</div>
<input type="button" value="click me" onclick="fnc();">
I think this is what you mean?
function (json) {
for (var i = 0; i < json.length ; i++) {
//alert(json[i].name);
var divTag = document.createElement('div');
divTag.setAttribute('id', json[i].name);
var newAddedDiv = $('<div>').appendTo("#splitter");
newAddedDiv.html('fooooo');
}
}
In the success of ajax function,I have implemented like
success: function (json) {
for (var i = 0; i < json.length; i++) {
var j = i+1;
var div = document.createElement('div');
$('<div id = ' + json[i].prj '>').appendTo("#splitter");
----------------code for loading grid with different datasource--------------
}
$("#splitter").kendoSplitter({
orientation: "horizontal"
});
**code for loading grid with different datasource**
In the datasource read I gave like
transport: {
//passing values to the controller to display grid with different dataSource
read: {
url: function (options) {
return kendo.format("/Project/Display?selectedId=" + j + "");
}
}
}