Select2 v4.0 make optgroups selectable - jquery-select2

I'm using the latest version of select2 (4.0.0) and I can't find the option to make optgroups selectable.
An optgroup is used to group different options of the dropdown, as shown in their basic examples:
I need this optgoup to be selectable too! It was possible in 3.5.1 but it isn't the default setting in 4.0.0 anymore.
My Code Looks like this:
$(document).ready(function() {
$('#countrySelect').select2({
data: [{
text: "group",
"id": 1,
children: [{
"text": "Test 2",
"id": "2"
}, {
"text": "Test 3",
"id": "3",
"selected": true
}]
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://select2.github.io/dist/js/select2.full.js"></script>
<link href="https://select2.github.io/dist/css/select2.min.css" rel="stylesheet" />
<select id="countrySelect" style="width: 380px;" placeholder="Select regions..."></select>

I manage to achieve this by using the templateResult property and attaching click events to the optgroups in this way:
$('#my-select').select2({
templateResult: function(item) {
if(typeof item.children != 'undefined') {
var s = $(item.element).find('option').length - $(item.element).find('option:selected').length;
// My optgroup element
var el = $('<span class="my_select2_optgroup'+(s ? '' : ' my_select2_optgroup_selected')+'">'+item.text+'</span>');
// Click event
el.click(function() {
// Select all optgroup child if there aren't, else deselect all
$('#my-select').find('optgroup[label="' + $(this).text() + '"] option').prop(
'selected',
$(item.element).find('option').length - $(item.element).find('option:selected').length
);
// Trigger change event + close dropdown
$('#my-select').change();
$('#my-select').select2('close');
});
// Hover events to properly manage display
el.mouseover(function() {
$('li.select2-results__option--highlighted').removeClass('select2-results__option--highlighted');
});
el.hover(function() {
el.addClass('my_select2_optgroup_hovered');
}, function() {
el.removeClass('my_select2_optgroup_hovered');
});
return el;
}
return item.text;
}
});
And the associated css:
.my_select2_optgroup_selected {
background-color: #ddd;
}
.my_select2_optgroup_hovered {
color: #FFF;
background-color: #5897fb !important;
cursor: pointer;
}
strong.select2-results__group {
padding: 0 !important;
}
.my_select2_optgroup {
display: block;
padding: 6px;
}

This was requested over on GitHub, but realistically it is not actually possible. It was previously possible with a <input />, but the switch to a <select> meant that we now explicitly disallow a selectable <optgroup>.
There is a technical barrier here that Select2 will likely never be able to tackle: A standard <optgroup> is not selectable in the browser. And because a data object with children is converted to an <optgroup> with a set of nested <option> elements, the problem applies in your case with the same issue.
The best possible solution is to have an <option> for selecting the group, like you would have with a standard select. Without an <option> tag, it's not possible to set the selected value to the group (as the value doesn't actually exist). Select2 even has a templateResult option (formatResult in 3.x) so you can style it as a group consistently across browsers.

Well, I came across this issue and I found that every time the select2 (Select2 4.0.5) opens it adds a span element before the closing body element. In addition, inside the span element adds a ul with the id: select2-X-results, where X is the select2 id.
So I found the following workaround (jsfiddle):
var countries = [{
"id": 1,
"text": "Greece",
"children": [{
"id": "Athens",
"text": "Athens"
}, {
"id": "Thessalonica",
"text": "Thessalonica"
}]
}, {
"id": 2,
"text": "Italy",
"children": [{
"id": "Milan",
"text": "Milan"
}, {
"id": "Rome",
"text": "Rome"
}]
}];
$('#selectcountry').select2({
placeholder: "Please select cities",
allowClear: true,
width: '100%',
data: countries
});
$('#selectcountry').on('select2:open', function(e) {
$('#select2-selectcountry-results').on('click', function(event) {
event.stopPropagation();
var data = $(event.target).html();
var selectedOptionGroup = data.toString().trim();
var groupchildren = [];
for (var i = 0; i < countries.length; i++) {
if (selectedOptionGroup.toString() === countries[i].text.toString()) {
for (var j = 0; j < countries[i].children.length; j++) {
groupchildren.push(countries[i].children[j].id);
}
}
}
var options = [];
options = $('#selectcountry').val();
if (options === null || options === '') {
options = [];
}
for (var i = 0; i < groupchildren.length; i++) {
var count = 0;
for (var j = 0; j < options.length; j++) {
if (options[j].toString() === groupchildren[i].toString()) {
count++;
break;
}
}
if (count === 0) {
options.push(groupchildren[i].toString());
}
}
$('#selectcountry').val(options);
$('#selectcountry').trigger('change'); // Notify any JS components that the value changed
$('#selectcountry').select2('close');
});
});
li.select2-results__option strong.select2-results__group:hover {
background-color: #ddd;
cursor: pointer;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/css/select2.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/js/select2.full.min.js"></script>
<h1>Selectable optgroup using select2</h1>
<select id="selectcountry" name="country[]" class="form-control" multiple style="width: 100%"></select>

Had the same problem today. This is certainly not my nicest solution, but beggars can't be choosers:
$(document).on('click', '.select2-results__group', function(event) {
let select2El = $('#mySelect2');
var setValues = [];
//Add existing Selection
var selectedValues = select2El.select2('data');
for ( var i = 0, l = selectedValues.length; i < l; i++ ) {
setValues.push(selectedValues[i].id);
}
//Add Group Selection
$(this).next('ul').find('li').each(function(){
let pieces = $(this).attr('data-select2-id').split('-');
setValues.push(pieces[pieces.length-1]);
});
select2El.val(setValues).trigger('change').select2("close");
});

$(document).ready(function() {
$('#countrySelect').select2({
data: [{
text: "group",
"id": 1,
children: [{
"text": "Test 2",
"id": "2"
}, {
"text": "Test 3",
"id": "3",
"selected": true
}]
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://select2.github.io/dist/js/select2.full.js"></script>
<link href="https://select2.github.io/dist/css/select2.min.css" rel="stylesheet" />
<select id="countrySelect" style="width: 380px;" placeholder="Select regions..."></select>

Related

How to prevent the creation of a port from spreading to all objects, in GoJS?

When user interaction creates a port in an object (right click on the object then "add left port"), all objects get the same port added, the same for the object in the palette.
How can I prevent the creation of a port from spreading to all objects?
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>LLDynp</title>
<meta name="description" content="Nodes with varying lists of ports on each of four sides." />
<!-- Copyright 1998-2017 by Northwoods Software Corporation. -->
<meta charset="UTF-8">
<script src="../release/go-debug.js"></script>
<span id="diagramEventsMsg" style="color: red"></span>
<span id="changeMethodsMsg" style="color: red"></span>
<span id="BackgroundDoubleClicked" style="color: red"></span>
<p>
<script id="code">
function init() {
var $ = go.GraphObject.make; //for conciseness in defining node templates
myDiagram =
$(go.Diagram, "myDiagramDiv",
{
allowDrop: true, // from Palette
mouseDrop: function(e) { finishDrop(e, null); },
"commandHandler.archetypeGroupData": { isGroup: true, category: "OfGroups" },
"undoManager.isEnabled": true
});
// this function is used to highlight a Group that the selection may be dropped into
function highlightGroup(e, grp, show) {
if (!grp) return;
e.handled = true;
if (show) {
// cannot depend on the grp.diagram.selection in the case of external drag-and-drops;
// instead depend on the DraggingTool.draggedParts or .copiedParts
var tool = grp.diagram.toolManager.draggingTool;
var map = tool.draggedParts || tool.copiedParts; // this is a Map
// now we can check to see if the Group will accept membership of the dragged Parts
if (grp.canAddMembers(map.toKeySet())) {
grp.isHighlighted = true;
return;
}
}
grp.isHighlighted = false;
}
function finishDrop(e, grp) {
var ok = (grp !== null
? grp.addMembers(grp.diagram.selection, true)
: e.diagram.commandHandler.addTopLevelParts(e.diagram.selection, true));
if (!ok) e.diagram.currentTool.doCancel();
}
// LL
function showMessage(s) {
document.getElementById("diagramEventsMsg").textContent = s;
}
// To simplify this code we define a function for creating a context menu button:
function makeButton(text, action, visiblePredicate) {
return $("ContextMenuButton",
$(go.TextBlock, text),
{ click: action },
//{showMessage( "button: " + myDiagram.lastInput.button);
// don't bother with binding GraphObject.visible if there's no predicate
visiblePredicate ? new go.Binding("visible", "", function(o, e) { return o.myDiagram ? visiblePredicate(o, e) : false; }).ofObject() : {});
//}
}
var nodeMenu = // context menu for each Node
$(go.Adornment, "Horizontal",
makeButton("Add left port",
function (e, obj) { addPort("left"); }),
makeButton("Add right port",
function (e, obj) { addPort("right"); }),
); //Leon end nodeMenu
// Add a port to the specified side of the selected nodes.
function addPort(side) {
myDiagram.startTransaction("addPort");
myDiagram.selection.each(function(node) {
// skip any selected Links
if (!(node instanceof go.Node)) return;
// compute the next available index number for the side
var i = 0;
while (node.findPort(side + i.toString()) !== node) i++;
// now this new port name is unique within the whole Node because of the side prefix
var name = side + i.toString();
// get the Array of port data to be modified
var arr = node.data[side + "Array"];
showMessage ("node: " + node + ";name: " + name + ";arr: " + arr + ";node.data: " + node.data + "; node.data[side=" + node.data[side + "Array"]);
if (arr) { console.log("arr is true")
// create a new port data object
var newportdata = {
portId: name,
portColor: "rgb(180, 0, 0)" //go.Brush.randomColor()
// if you add port data properties here, you should copy them in copyPortData above
};
// and add it to the Array of port data
myDiagram.model.insertArrayItem(arr, -1, newportdata);
}
});
myDiagram.commitTransaction("addPort");
}
var portSize = new go.Size(10, 10);
myDiagram.linkTemplate =
$(go.Link,
{
routing: go.Link.Orthogonal, corner: 5,
relinkableFrom: true, relinkableTo: true
},
$(go.Shape, { stroke: "gray", strokeWidth: 2 }),
$(go.Shape, { stroke: "gray", fill: "gray", toArrow: "Standard" })
);
////////////// groupTemplateMap ///////////////////////////////////
myDiagram.groupTemplateMap.add("OfGroups",
$(go.Group, "Table",// left ports+ placeHolder+right ports
{ locationObjectName: "BODY",
selectionObjectName: "PH",
resizable: true,
resizeObjectName: "PH",
contextMenu: nodeMenu,
background: "transparent",
mouseDragEnter: function(e, grp, prev) { highlightGroup(e, grp, true); },
mouseDragLeave: function(e, grp, next) { highlightGroup(e, grp, false); },
computesBoundsAfterDrag: false,
mouseDrop: finishDrop,
handlesDragDropForMembers: true // don't need to define handlers on member Nodes and Links
},
new go.Binding("background", "isHighlighted", function(h) { return h ? "rgba(255,0,0,0.2)" : "transparent"; }).ofObject(),
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
// the body
$(go.Panel, "Auto",
{ row: 1, column: 1, name: "BODY"
//stretch: go.GraphObject.Fill
},
$(go.Shape, "Rectangle",
{ fill: null, stroke: "rgb(0, 0, 200)", strokeWidth: 3,name: "PH",
minSize: new go.Size(56, 56) }),
$(go.Panel, "Vertical", // title above Placeholder
{alignment: go.Spot.Top},
$(go.Panel, "Horizontal", // button next to TextBlock
{ stretch: go.GraphObject.Horizontal, background: "#FFDD33" },
$("SubGraphExpanderButton",
{ alignment: go.Spot.Right, margin: 5 }),
$(go.TextBlock,
{
alignment: go.Spot.Left,
editable: true,
margin: 5,
font: "bold 18px sans-serif",
opacity: 0.75,
stroke: "#404040"
},
new go.Binding("text", "text").makeTwoWay())
), // end Horizontal Panel
$(go.Placeholder,
{ padding: 5
, alignment: go.Spot.TopLeft // no change
},
new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify))
) // end Vertical Panel
), // end Auto Panel body
// the Panel holding the left port elements, which are themselves Panels,
// created for each item in the itemArray, bound to data.leftArray
$(go.Panel, "Vertical",
new go.Binding("itemArray", "leftArray"),
{ row: 1, column: 0,
itemTemplate:
$(go.Panel,
{ _side: "left", // internal property to make it easier to tell which side it's on
fromSpot: go.Spot.Left, toSpot: go.Spot.Left,
fromLinkable: true, toLinkable: true, cursor: "pointer"},
new go.Binding("portId", "portId"),
$(go.Shape, "Rectangle",
{ stroke: null, strokeWidth: 0,
desiredSize: portSize,
margin: new go.Margin(1,0) },
new go.Binding("fill", "portColor"))
) // end itemTemplate
}
), // end Vertical Panel
// the Panel holding the right port elements, which are themselves Panels,
// created for each item in the itemArray, bound to data.rightArray
$(go.Panel, "Vertical",
new go.Binding("itemArray", "rightArray"),
{ row: 1, column: 2,
itemTemplate:
$(go.Panel,
{ _side: "right",
fromSpot: go.Spot.Right, toSpot: go.Spot.Right,
fromLinkable: true, toLinkable: true, cursor: "pointer"},
new go.Binding("portId", "portId"),
$(go.Shape, "Rectangle",
{ stroke: null, strokeWidth: 0,
desiredSize: portSize,
margin: new go.Margin(1, 0) },
new go.Binding("fill", "portColor"))
) // end itemTemplate
}
), // end Vertical Panel
)
); // end groupTemplateMap.add("OfGroups"
var nodeDataArray = [];
var linkDataArray = [];
myDiagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
// initialize the Palette and its contents
myPalette =
$(go.Palette, "myPaletteDiv",
{
groupTemplateMap: myDiagram.groupTemplateMap
// ,layout: $(go.GridLayout, { wrappingColumn: 1, alignment: go.GridLayout.Position })
});
myPalette.model = new go.GraphLinksModel([
{ //key: 101,
text: 'UNIT',
leftArray: [], rightArray: [],
isGroup: true, isSubProcess: true,
category: "OfGroups", isAdHoc: true,
loc: '0 0' },
]);
}
</script>
</head>
<body onload="init()">
<!-- LL -->
<body onload="goIntro()">
<div id="container" class="container-fluid">
<div id="content">
<div id="sample">
<div style="width: 100%; display: flex; justify-content: space-between">
<div id="myPaletteDiv" style="width: 100px; margin-right: 2px; background-color: whitesmoke; border: solid 1px black"></div>
<div id="myDiagramDiv" style="flex-grow: 1; height: 480px; border: solid 1px black"></div>
</div>
</div>
</div>
</body>
</html>
Please read the code for the Dynamic Ports sample at https://gojs.net/latest/samples/dynamicPorts.html. Note the comments in the load function.
function load() {
myDiagram.model = go.Model.fromJson(. . .);
// When copying a node, we need to copy the data that the node is bound to.
// This JavaScript object includes properties for the node as a whole, and
// four properties that are Arrays holding data for each port.
// Those arrays and port data objects need to be copied too.
// Thus Model.copiesArrays and Model.copiesArrayObjects both need to be true.
// Link data includes the names of the to- and from- ports;
// so the GraphLinksModel needs to set these property names:
// linkFromPortIdProperty and linkToPortIdProperty.
}
And notice in the JSON representation of the model how it sets those properties:
{ "class": "go.GraphLinksModel",
"copiesArrays": true,
"copiesArrayObjects": true,
"linkFromPortIdProperty": "fromPort",
"linkToPortIdProperty": "toPort",
"nodeDataArray": [
{"key":1, "name":"Unit One", "loc":"101 204",
. . .
So when you create a GraphLinksModel programmatically, be sure to set those same properties to the values that are appropriate for your data.

Bind Quill to asp net core model

I am using ASP.Net Core form to pass data from user to server with code:
#model SomeModel
#using(Html.BeginForm(...))
{
#Html.TextBoxFor(s => s.PropertyName);
}
which works fine but now i have field which need to be populated from quill editor. Quill request me to pass him div container for his job and i do not know how to bind that container to my model property. I have tried giving that div id and name just as property name but it didn't work. Also tried adding runat = server but still not working.
Here is my full code:
#model ClanakModel
#{
ViewData["Title"] = "New story";
}
<style>
#Naslov {
width: 80%;
margin-bottom: 20px;
}
#GrupaID {
height: 30px;
width: 18%;
margin-left: 2%;
}
input {
border: 1px solid gray;
background-color: whitesmoke;
padding: 5px;
border-radius: 20px 20px 20px 20px;
}
#Tekst {
width: 100%;
max-width: 100%;
min-width: 100%;
}
#Publish_btn {
float: right;
border: 2px solid black;
background-color: white;
margin-top: 20px;
border-radius: 20px;
padding: 5px 15px 5px 15px;
}
#Publish_btn:hover {
background-color: deepskyblue;
}
</style>
<h2>Write new story</h2>
#using (Html.BeginForm("CreateNew", "Story", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.TextBoxFor(c => c.Naslov, new { #placeholder = "Title" });
#Html.DropDownListFor(c => c.GrupaID, new SelectList(GrupaModel.List(), "GrupaID", "Naziv"));
<div id="Tekst" name="Tekst"></div>
<button id="Publish_btn">Publish</button>
}
<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
<script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
<script>
var toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['image'],
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }], // custom button values
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
[{ 'script': 'sub' }, { 'script': 'super' }], // superscript/subscript
[{ 'indent': '-1' }, { 'indent': '+1' }], // outdent/indent
[{ 'direction': 'rtl' }], // text direction
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
[{ 'font': [] }],
[{ 'align': [] }],
['clean'] // remove formatting button
];
var options = {
theme: 'snow',
placeholder: 'Start writing here!',
modules: {
toolbar: toolbarOptions
}
};
var quill = new Quill('#Tekst', options);
</script>
Since DIVs are not input elements, you could add a hidden input which accepts the content of the editor when you submit the form.You could get Editor content in js using quill.getContents().
Assuming that your model has a Description field, below is a simple demo:
#model SomeModel
<h2>Write new story</h2>
<form id="form" method="post">
<input asp-for="Description" name="Description" type="hidden" class="form-control" />
<div id="Tekst" name="Tekst"></div>
<input type="submit" id="Publish_btn" value="Publish" />
</form>
<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
<script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>
<script>
var toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['image'],
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }], // custom button values
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
[{ 'script': 'sub' }, { 'script': 'super' }], // superscript/subscript
[{ 'indent': '-1' }, { 'indent': '+1' }], // outdent/indent
[{ 'direction': 'rtl' }], // text direction
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
[{ 'font': [] }],
[{ 'align': [] }],
['clean'] // remove formatting button
];
var options = {
theme: 'snow',
placeholder: 'Start writing here!',
modules: {
toolbar: toolbarOptions
}
};
var quill = new Quill('#Tekst', options);
var form = document.querySelector('form');
form.onsubmit = function () {
// Populate hidden form on submit
var description = document.querySelector('input[name=Description]');
description.value = quill.getContents();
};
</script>

Highcharts one input of the three not working

I have created three input boxes that should filter the chart. The second option seems not to be working. I have not found any problem in the code so far.
//JSON query
var json_data = [
{
"mip": {
"id": 125,
"name": "One",
"code": "One"
},
"briefNetSpendInEuro": 2200,
"postNetSpendInEuro": 0,
"proposalSpendInEuro": 3530
},
{
"mip": {
"id": 125,
"name": "Two",
"code": "Two"
},
"briefNetSpendInEuro": 12052,
"postNetSpendInEuro": 2516,
"proposalSpendInEuro": 5358
},
{
"mip": {
"id": 531,
"name": "Three",
"code": "Three"
},
"briefNetSpendInEuro": 5391,
"postNetSpendInEuro": 9812,
"proposalSpendInEuro": null
}
]
var categories = [];
var series = [];
var brief = [];
var post = [];
var proposal = [];
//JSON manipulation to prepare the data for the highchart
json_data.forEach(function(element) {
categories.push(element.mip.code);
brief.push(element.briefNetSpendInEuro = element.briefNetSpendInEuro || 0);
post.push(element.postNetSpendInEuro = element.postNetSpendInEuro || 0);
proposal.push(element.proposalSpendInEuro = element.proposalSpendInEuro || 0);
});
//Filter creation
$(function() {
var chart = new Highcharts.Chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Spend per Media Group'
},
xAxis: {
categories: [{
"class": "One",
"name": "One"
}, {
"class": "Two",
"name": "Two"
}, {
"class": "Three",
"name": "Three"
}],
labels: {
formatter: function() {
return this.value.name;
},
useHTML: true
}
},
yAxis: {
min: 0,
title: {
text: 'Spend (EUR)'
}
},
tooltip: {
headerFormat: '<span style="font-size:10px">{point.key.name}</span><table>',
pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
'<td style="padding:0"><b>{point.y:.,0f} </b></td></tr>',
footerFormat: '</table>',
shared: true,
useHTML: true
},
plotOptions: {
},
series: [{
name: 'Brief Net',
data: brief
}, {
name: 'Post Net',
data: post
}, {
name: 'Proposal',
data: proposal
}]
}, function() {
$('input[type=checkbox]').bind('click', function() {
togglePointsByClass(this.value, $(this).is(':checked'), chart)
});
});
var visibleArr = [0, 1, 2];
function togglePointsByClass(className, shouldShow, chart) {
var isChartDirty = false;
if (shouldShow) {
chart.xAxis[0].userOptions.categories.forEach(function(category, i) {
if (category.class === className) {
visibleArr.push(i);
}
});
} else {
chart.xAxis[0].userOptions.categories.forEach(function(category, i) {
if (category.class === className && visibleArr.indexOf(i) > -1) {
visibleArr.splice(visibleArr.indexOf(i), 1);
}
});
}
if (visibleArr.length) {
chart.xAxis[0].update({
min: Math.min.apply(null, visibleArr),
max: Math.max.apply(null, visibleArr)
})
}
}
$('#container').highcharts().redraw();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div class="row">
<div class="col-xs-12">
<div class="box-first box-container">
<div class="row">
<div class="col-xs-4">
<input type="checkbox" name="One" value="One" checked> One
</div>
<div class="col-xs-4">
<input type="checkbox" name="Two" value="Two" checked> Two
</div>
<div class="col-xs-4">
<input type="checkbox" name="Three" value="Three" checked> Three
</div>
</div>
</div>
</div>
</div>
<div id="container" style="min-width: 310px; max-width: 800px; height: 400px; margin: 0 auto"></div>
The concept is to recalculate your series each time and determine which to show.
I took your initial calculation of data and turned it to a function like this, calling each time with the visibleArr.
const calcData = (arr) => {
const brief = [];
const proposal = [];
const post = [];
json_data.forEach((element, i) => {
if (arr.includes(i)) {
brief.push(element.briefNetSpendInEuro || 0);
post.push(element.postNetSpendInEuro || 0);
proposal.push(element.proposalSpendInEuro || 0);
}
});
return [{ name: 'Brief Net', data: brief },
{ name: 'Post Net', data: post },
{ name: 'Proposal', data: proposal }];
};
Take a look at this jsfiddle: http://jsfiddle.net/ueso3bc6/1/

Ext.Ajax.request not working

![
this is the project structure I am using. On adding a local URL like this below code is not working. url:'data/showStudentInfo.html']3I am using Ext Js version 4.1.1
In my application , I am having a grid, which uses a store.
On clicking "click me" button I want to redirect to the server, for test purpose I am using a basic google url,
But the class Ext.Ajax.Request is not working I think
Please help , as I am new to Ext js, I am not aware of the mistake I am making.
I am trying this in notepad++, as well as in eclipse ide (indigo version).
both with same output, Ext.Ajax.Request part not working.
It will of great help if anyone have suggestion as if I want to send
Thanking in advance
Below is my html and js file
practiseCellEditEx.js
Ext.require([
'Ext.data.*',
'Ext.Ajax.',
'Ext.grid.*'
]);
function getRandomDate() {
var from = new Date(1900, 0, 1).getTime();
var to = new Date().getTime();
var date = new Date(from + Math.random() * (to - from));
return Ext.Date.clearTime(date);
}
function createFakeData(count) {
var firstNames = ['Ed', 'Tommy', 'Aaron', 'Abe'];
var lastNames = ['Spencer', 'Maintz', 'Conran', 'Elias'];
var data = [];
for (var i = 0; i < count ; i++) {
var dob = getRandomDate();
var firstNameId = Math.floor(Math.random() * firstNames.length);
var lastNameId = Math.floor(Math.random() * lastNames.length);
var name = Ext.String.format("{0} {1}", firstNames[firstNameId], lastNames[lastNameId]);
data.push([name, dob]);
}
return data;
}
Ext.onReady(function(){
Ext.define('Person',{
extend: 'Ext.data.Model',
fields: ['Name', 'dob']
});
var store = Ext.create('Ext.data.Store', {
model: 'Person',
autoLoad: true,
proxy: {
type: 'memory',
data: createFakeData(10),
reader: {type: 'array'}
},
sorters: [{
direction:'ASC'
}]
});
Ext.create('Ext.grid.Panel', {
store: store,
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit : 1
})
],
columns: [
{
text: "Name",
width:120,
dataIndex: 'Name',
editor : {
xtype: 'textfield',
allowBlank:false
}
},
{
text: "DOB",
width: 120,
dataIndex: 'dob',
renderer: Ext.util.Format.dateRenderer('M d, Y'),
editor: {
xtype: 'datefield',
format: 'M d, Y',
minValue: '01/01/1900',
maxValue: new Date()
}
},
{
xtype: 'actioncolumn',
width: 30,
sortable: false,
menuDisabled: true,
items: [{
icon: 'http://etf-prod-projects-1415177589.us-east-1.elb.amazonaws.com/trac/docasu/export/2/trunk/client/extjs/shared/icons/fam/delete.gif',
handler: function(grid, rowIndex, colIndex) {
store.removeAt(rowIndex);
}
}]
}
],
renderTo:'example-grid',
width: 280,
height: 280
});
Ext.create('Ext.Button', {
text: 'Click me',
// renderTo: Ext.getBody(),
renderTo:'myBtn',
handler: getName
});
function getName (btn)
{
alert("hello");
var records = store.getAt(1);
alert('the name at index 1 is:'+records.get('Name'));
Ext.Ajax.request({
url : 'https://www.google.co.in/'
});
};
/*
function buttonClicked() {
Ext.MessageBox.confirm( 'Delete this part ? :' );
}*/
});
practiseCellEditEx.html
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>ExtJS Samples</title>
<link rel="stylesheet" type="text/css" href="../resources/css/ext-all.css" />
<script type="text/javascript" src="../adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../ext-all.js"></script>
<script type="text/javascript" src="practiseCellEditEx.js"></script>
</head>
<body>
<h2> <b>Helllo , today's Date is 02.12.2015 </b></h2>
<div id="example-grid"></div>
<!--<button id="myBtn"></button>-->
<div id="myBtn"></div>
</body>
</html>
The problems seems to be simply the request going to google.com. In my browser it is blocked because it is a cross-origin request (an ajax request to another domain), see also here for further information: https://en.wikipedia.org/wiki/Same-origin_policy.
The same code with a request to a local URL works fine.

jQuery UI Sortable: no changing order of items while sorting

By default, while sorting, items are replaced (for example, if I take the third element and move it to the first, than the first and the second elements will move down)
I do not need this behaviour. I'd like elements not to change order while I finish sorting (release mouse).
I need this because I want to ask user if he want to change element or to re-order?
P.S. option tolerance have only 2 options, and they don't help in this situation.
I meant something like this (sortable list with option of replacing elements):
$(function() {
var
/**
* Sortable List, that can insert or replace elements
*/
SortableList = (function() {
var
// Configuration of Sortable list
// css classes of separator and sortable elements
// jQuery UI droppable and sortable init configuration
CONFIG = {
'confirm-message': 'Insert? Element will be removed',
'separator-class': 'sortable-separator',
'sortable-class': 'sortable-elem',
// Initialization of jQuery UI Droppable
'separators-droppable-init': {
drop: function(e, ui) {
// Insertation
var drag = ui.draggable,
drop = $(this),
a = drop.prev(),
b = drop.next();
Separators.clean();
Elements.insert(a, b, drag);
Separators.init();
},
over: function(e, ui) {
$(this).css({
'background-color': 'lightgreen'
});
},
out: function(e, ui) {
$(this).css({
'background-color': 'white'
});
}
},
'sortable-droppable-init': {
drop: function(e, ui) {
// Replace
var drag = ui.draggable,
drop = $(this);
if (Elements.replace(drop, drag)) {
Separators.init();
}
}
},
'sortable-draggable-init': {
revert: true,
start: function(e, ui) {
$(this).css({
'z-index': '999',
'cursor': 'move'
});
},
stop: function(e, ui) {
$(this).css({
'z-index': '1',
'cursor': 'default'
});
}
}
},
getSeparators = function() {
return $('.' + CONFIG['separator-class']);
},
getSortables = function() {
return $('.' + CONFIG['sortable-class']);
},
/**
* Separators Handler
*/
Separators = (function() {
var
// create separator html element
_create = function() {
return $('<div />').addClass(CONFIG['separator-class']);
},
// create all separators and insert them
createAll = function() {
getSortables().each(function() {
$(this).before(_create());
}).last().after(_create());
return Separators;
},
// remove all separators
clean = function() {
var s = getSeparators();
if (s.length) {
s.remove();
}
return Separators;
},
// init jQuery UI Droppable interface
initDroppable = function() {
getSeparators().droppable(CONFIG['separators-droppable-init']);
return Separators;
},
// Initialization of separators
init = function() {
if (getSeparators().length) {
Separators.clean();
}
return Separators.createAll().initDroppable();
};
// Return result
Separators = {
clean: clean,
createAll: createAll,
init: init,
initDroppable: initDroppable
};
return Separators;
}()),
Elements = (function() {
var
init = function() {
getSortables().droppable(CONFIG['sortable-droppable-init']).draggable(CONFIG['sortable-draggable-init']);
return Elements;
},
// replaces element A with element B
replace = function(A, B) {
if (!confirm(CONFIG['confirm-message'])) {
return false;
}
B.draggable("option", "revert", false).css({
top: 0,
left: 0
});
A.replaceWith(B);
return Elements;
},
// insert element C between elements A and B
insert = function(A, B, C) {
C.draggable("option", "revert", false).css({
top: 0,
left: 0
});
if (!A.length) {
B.before(C);
} else {
A.after(C);
}
return Elements;
},
// result to return
Elements = {
init: init,
replace: replace,
insert: insert
};
return Elements;
}()),
init = function() {
Separators.init();
Elements.init();
};
return {
init: init
};
}());
SortableList.init();
});
.sortable-elem {
width: 32px;
height: 32px;
background-color: darkred;
border: 1px solid brown;
color: white;
}
.sortable-separator {
width: 100px;
height: 16px;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script>
<link href="//code.jquery.com/ui/1.8.16/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="//code.jquery.com/ui/1.8.16/jquery-ui.min.js"></script>
<div class="sortable-elem" data-order="1">1</div>
<div class="sortable-elem" data-order="2">2</div>
<div class="sortable-elem" data-order="3">3</div>
<div class="sortable-elem" data-order="4">4</div>
<div class="sortable-elem" data-order="5">5</div>
<div class="sortable-elem" data-order="6">6</div>
<div class="sortable-elem" data-order="7">7</div>
<div class="sortable-elem" data-order="8">8</div>
<div class="sortable-elem" data-order="9">9</div>
<div class="sortable-elem" data-order="10">10</div>
View on JSFiddle

Resources