Javascript: Changing DOM elements based on form values - javascript

I'm still pretty new to JavaScript programming and I'm having an issue.
JSFiddle: http://jsfiddle.net/Y4pPj/
HTML:
<form id="practiceForm" style="display:inline">
<select id="practiceList" size="1">
<option value="sampleA" selected="selected">Sample A</option>
<option value="sampleB">Sample B</option>
<option value="sampleC">Sample C</option>
</select>
</form>
<button onclick="changeSelection();">Select</button><br />
<span id="currentSelected">Nothing selected</span><br /><br />
Name: <span id="name"></span><br />
Size: <span id="size"></span><br />
Shape: <span id="shape"></span><br />
Value: <span id="value"></span>
JavaScript:
/* var stats = {
sampleA: { name: "Alpha", size: 3, shape: square, value: 1 },
sampleB: { name: "Delta", size: 1, shape: circle, value: 10 },
sampleC: { name: "Gamma", size: 25, shape, triangle, value: 200 }
}; */
function changeSelection() {
document.getElementById("currentSelected").innerHTML = practiceForm.practiceList.options[practiceForm.practiceList.selectedIndex].value;
document.getElementById("name").innerHTML = currentSelected.name;
document.getElementById("size").innerHTML = currentSelected.size;
document.getElementById("shape").innerHTML = currentSelected.shape;
document.getElementById("value").innerHTML = currentSelected.value;
}
What I'm trying to do is, have a combobox list of items with a button. When you click the button, I need to change parts of the HTML to values that I've set in variables at the start.
The code, as it stands, works in JSFiddle. But, as soon as I un-comment the variable declaration, 'stats', it messes up, which really confuses me. Also, please excuse all the undisciplined stuff, like inline styles :) This was just for debugging test.
One more thing while I'm here- is there a way to shorthand the first line in the changeSelection() function? I've seen many examples, but they are all different.

It wont work like this. you need to access the stats through the selected value.
var stats = {
'sampleA': { name: "Alpha", size: 3, shape: 'square', value: 1 },
'sampleB': { name: "Delta", size: 1, shape: 'circle', value: 10 },
'sampleC': { name: "Gamma", size: 25, shape: 'triangle', value: 200 }
};
function changeSelection() {
document.getElementById("currentSelected").innerHTML = practiceForm.practiceList.options[practiceForm.practiceList.selectedIndex].value;
document.getElementById("name").innerHTML = stats[practiceList.value].name;
document.getElementById("size").innerHTML = stats[practiceList.value].size;
document.getElementById("shape").innerHTML = stats[practiceList.value].shape;
document.getElementById("value").innerHTML = stats[practiceList.value].value;
}
look at this fiddle.
http://jsfiddle.net/9QXc4/

It's throwing a syntax error in the console due to your object.
var stats = {
sampleA: { name: "Alpha", size: 3, shape: "square", value: 1 },
sampleB: { name: "Delta", size: 1, shape: "circle", value: 10 },
sampleC: { name: "Gamma", size: 25, shape: "triangle", value: 200 }
};
The above is the correct syntax. Things needed fixing:
-Quote property values! square, circle, and triangle were unquoted.
-The "shape" property had a comma rather than a colon to declare the value
Use the console when programming, you'll see this error right away:
Uncaught SyntaxError: Unexpected token ,
Which was caused by:
sampleC: { name: "Gamma", size: 25, shape, "triangle", value: 200 }
^^

Just replace sampleC: { name: "Gamma", size: 25, shape, triangle, value: 200 } with this sampleC: { name: "Gamma", size: 25, shape: triangle, value: 200 }
You put a comma instead of a colon

Related

How to give custom color to tree map in anychart.js

I am creating this tree map and I have different values What I want is different shades of colors(green for postive and red for negative) on different ranges of points. The issue is in my callback function I am accessing the value parameter but points is not available.
Also the second issue is I want the font size according to the size of the box. As there are some boxes which are very big but the font size looks very small. I think If i get that color part fix I can set the fontsize on my own
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.anychart.com/releases/v8/js/anychart-core.min.js"></script>
<script src="https:/cdn.anychart.com/releases/v8/js/anychart-treemap.min.js"></script>
<title>My First JavaScript Treemap Chart</title>
<style>
html,
body,
#container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="container"></div>
<style>
span {
color: #fff;
font-size: 14px;
}
</style>
<script>
anychart.onDocumentReady(function () {
var chart = anychart.treeMap(getData(), "as-tree");
chart.maxDepth(2);
chart.hintDepth(1);
chart.hintOpacity(0.7);
chart.labels().useHtml(true);
chart.labels().format(
"<span style='font-weight:bold; color: #fff;'>{%name}</span><br>{%points}"
);
chart.tooltip().useHtml(true);
chart.tooltip().format(
"COMPANY : {%name}%<br>PERCENTAGE CHANGE: {%points}%<br>MARKET CAP: {%points}<br>VOLUME: {%points}<br>"
);
chart.container("container");
chart.draw();
var customColorScale = anychart.scales.linearColor();
customColorScale.colors(["green", "red",]);
console.log(chart)
chart.colorScale(customColorScale);
// chart.colorRange().enabled(true);
chart.colorRange().length("100%");
chart.fontColor = 'white'
chart.fill(coloringFunction);
function coloringFunction(value, points, name) {
console.log(value)
if (this.value < 0) {
return 'red'
}
else if (this.value > 0) {
return 'red'
}
}
/*chart.title().useHtml(true);
chart.title(
"<span style='font-size:18; font-style:bold'>PSX TREE MAP </span><br><i><span style='font-size:14; font-style:italic'>UPDATED(7:11 PM)</i>"
);*/
});
// get data
function getData() {
// create data
var data = [
{
name: "PAKISTAN STOCK EXCHANGE",
children: [
{
name: "TECH ",
children: [
{
name: "HUMNL",
value: 24,
points: 0.26
},
{
name: "TRG",
value: 6,
points: 2.3
,
points: 0.26
},
{
name: "SYS",
value: 55,
points: 4.26
}
]
},
{
name: "SUGAR & ALLIED INDUSTRIES ",
children: [
{
name: "AGSML",
value: 12,
points: 2.26
},
{
name: "MIRKS",
value: 14,
points: 3.26
,
},
{
name: "ALNRS",
value: 15,
points: 0.26
}
]
},
]
}
];
return data;
}
</script>
</body>
</html>
To achieve the coloring you should provide ABS value for the "size" field in the data. But the "value" field may reflect positive/negative values.
Like this:
{name: "Point 1", value: -11443830, size: 11443830}
Exactly the "value" field is used for linear and ordinal coloring. The treemap supports both, you can learn more about it in the documentation article.
In your case, you can create and adjust linear scale like this:
// create and configure a color scale.
var customColorScale = anychart.scales.linearColor();
customColorScale.minimum(-100000000).maximum(100000000);
customColorScale.colors(["red", "green"]);
// set the color scale as the color scale of the chart
chart.colorScale(customColorScale);
Min/max apply as you need or do not apply it to calculate them automatically.
To adjust label fontsize for every item simply enable adjustFontSize() setting:
chart.labels().adjustFontSize(true);
For details, check the sample we prepared.
anychart.onDocumentReady(function () {
// create data
var data = [
{name: "European Union", children: [
{name: "Belgium", value: -11443830, size: 11443830},
{name: "France", value: 64938716, size: 64938716},
{name: "Germany", value: 80636124, size: 80636124},
{name: "Greece", value: -10892931, size: 10892931},
{name: "Italy", value: 59797978, size: 59797978},
{name: "Netherlands", value: -17032845, size: 17032845},
{name: "Poland", value: 38563573, size: 38563573},
{name: "Romania", value: -19237513, size: 19237513},
{name: "Spain", value: 46070146, size: 46070146},
{name: "United Kingdom", value: 65511098, size: 65511098}
]}
];
// create a chart and set the data
var chart = anychart.treeMap(data, "as-tree");
// create and configure a color scale.
var customColorScale = anychart.scales.linearColor();
customColorScale.minimum(-100000000).maximum(100000000);
customColorScale.colors(["red", "green"]);
// set the color scale as the color scale of the chart
chart.colorScale(customColorScale);
// add a color range
chart.colorRange().enabled(true);
chart.colorRange().length("80%");
chart.labels().adjustFontSize(true);
// set the container id
chart.container("container");
// initiate drawing the chart
chart.draw();
});
html, body, #container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
<script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-bundle.min.js"></script>
<div id="container"></div>

Is it possible to both select and create the same value in react-select?

I'm trying to have a multi Creatable in which the user can both select a preset value, and "create" the same value by himself, both in the same interaction.
For example, my render look
import CreatableSelect from 'react-select/creatable';
function test(){
render(
<CreatableSelect
isMulti
onChange={this.handleChange}
options = [{ value: 'Blue', label: 'Blue'}, { value: 'Red', label: 'Red'}]
/>
);)
}
I want to let the user both choose 'Blue' as an option, and create the value 'Blue' as well. Namely, I want to output of handleChange to be:
[{ value: 'Blue', label: 'Blue'}, { value: 'Blue', label: 'Blue', __isNew__: true}]
It's not a UI problem for me, as I'm coloring selected values differently based on whether it was created or selected from the list.
Is it possible? I tried having isValidNewOption={() => true} as a prop, but it didn't work.
Found a workaround, which I would not prefer to use if there's a better way:
I can add a special character (or a string) as a prefix to all values (leaving the labels aas is). For example- transforming [{ value: 'Blue', label: 'Blue'}, { value: 'Red', label: 'Red'}]
into [{ value: '$Blue', label: 'Blue'}, { value: '$Red', label: 'Red'}]
Now, it lets my create a new value "Blue", and selecting the value "$Blue". As the label of "$Blue" is still "Blue", the user won't notice the difference.
Lastly, I need to remove the prefix in my onChange function.
It's not a very elegant solution, but better than nothing.

vis.js change node color also affect edge color

I used this function to change the node color from it's id however i found that the edge that start with that node also change color
example
If i changed node 2 to red
edge 8,7,6 that is connect from: 2, to: 1,4,5 also changed to red
function draw() {
nodes.add([
{id: 1, label: 'Node 1'},
{id: 2, label: 'Node 2'},
{id: 3, label: 'Node 3'},
{id: 4, label: 'Node 4'},
{id: 5, label: 'Node 5'}
]);
edges.add([
{id:9, from: 3, to: 1},
{id:8, from: 2, to: 1},
{id:7, from: 2, to: 4},
{id:6, from: 2, to: 5}
]);
Here is my code:
network.on( 'click', function(params) {
idnode = params.nodes;
idedge = params.edges;
});
function red() {
idnode2 = idnode;
nodes.update({id: idnode2, color: "red"});
}
We need to disable the inherit property in the global options , like :
var options = {
nodes: {
shape: 'dot',
scaling: {
customScalingFunction: function (min,max,total,value) {
return value/total;
},
min:20,
max:100
}
}
,
edges:{
scaling: {
customScalingFunction: function (min,max,total,value) {
return value/total;
},
min:1,
max:200
},
color: {
//color:'#848484',
highlight:'#848484',
hover: '#d3d2cd',
inherit: false,
opacity:1.0
}
}
};
And then while adding the edge , we should include the color as :
edges.add({from: 1, to: 2, value:10,color:{color:'#ff383f'}});
Or you can update the edge with color :
edges.update({id:10,color:{color:'#ff383f'}});
My understanding is that this is exactly how vis.js works: the edge color by default is the color of the (border of) the origin node (you could of course change it, just like you did with the node).
For details on this, see the documentation for the option: color.inherit in http://visjs.org/docs/network/edges.html
Disable inherit attribute in options.edges.color.inherit :
let options = {
edges: {
color : {
inherit: false
}
}
}
I found that if i set the edges color in options. The edge color won't change anymore.

Dynamical view according to data

For a object have multiple attributes, for example, a shoe may have different color, size and etc.
Now when we tried to display the shoe, and make the customer can choose different attributes, we use radio(the simplest): https://jsfiddle.net/mwqy6217/
But how to make the availability of the view according to the data?
For example, when the red shoes are sold out, the red radio should be un-checkable. So are different sizes.
We can use this data structure to represent the shoe: {shoe:{name:'',available:['red','black','40','41']}}.
However different attributes may have relationship with each other, for example, red shoes with 40 size have been sold out, while black shoes with 40 size have not.
I think this data structure:
{shoe:{name:'',available:{color:{red:[40,41,42]},black:[42,43]}}}
As the shoe may have other attributes like 'weight', and an attributes may have 10+ options.
So how to represent this kind of relationship in the database and make them readable by the front engineer to build the view?
Update:
https://jsfiddle.net/xqtgqzt2/
See the live demo, all the available options is pre-defined as:
var options= [
["A1","B1","C1","D1"],
["A1","B3","D2"],
["A2","B1","C3","D2"]
];
Now how to make the radio button state changed according to the options? For example, when A1 is checked, only B1 B3 can be checked(enabled), when A1 B1 are checked, only C1 D1 can be checked.
To display your radio buttons regarding the option multidimensionnal array, you can do something like :
var options = [
["A1", "B1", "C1", "D1"],
["A1", "B3", "D2"],
["A2", "B1", "C3", "D2"]
];
var firstLevel = [];
var selectedList = [];
//Enable first options, disable the others
$("input[type=radio]").each(function (indexInput) {
var that = this;
that.disabled = true;
$.each(options, function (index, value) {
firstLevel.push(value[0]);
if (value[0] == that.value) {
that.disabled = false;
}
});
});
//on check radio, change states
$("input[type=radio]").on("click", function () {
var thatClicked = this;
if (firstLevel.indexOf(thatClicked.value) !== -1) {
$('input[type=radio]').removeAttr('checked');
$(thatClicked).prop('checked', true);
}
var possibleOptions = [];
selectedList.push(thatClicked.value);
$.each(options, function (index, value) {
possibleOptions = possibleOptions.concat(value[0]);
var posInArray = value.indexOf(thatClicked.value);
if (posInArray !== -1 && typeof value[posInArray + 1] !== 'undefined') {
//check previous options
$.each(selectedList, function (indexSelectedList, valueSelectedList) {
if (value.indexOf(valueSelectedList) !== -1) {
possibleOptions = possibleOptions.concat(value[posInArray + 1]);
}
});
}
});
$("input[type=radio]").each(function (indexInput) {
if (possibleOptions.indexOf(this.value) !== -1) {
this.disabled = false;
} else {
this.disabled = true;
}
});
});
.section {
padding: 10px;
overflow: hidden;
}
label {
float: left;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class="section">
<label>
<input type="radio" value="A1" /> <span>A1</span>
</label>
<label>
<input type="radio" value="A2" /> <span>A2</span>
</label>
</div>
<div class="section">
<label>
<input type="radio" value="B1" /> <span>B1</span>
</label>
<label>
<input type="radio" value="B2" /> <span>B2</span>
</label>
<label>
<input type="radio" value="B3" /> <span>B3</span>
</label>
</div>
<div class="section">
<label>
<input type="radio" value="C1" /> <span>C1</span>
</label>
<label>
<input type="radio" value="C2" /> <span>C2</span>
</label>
<label>
<input type="radio" value="C3" /> <span>C3</span>
</label>
</div>
<div class="section">
<label>
<input type="radio" value="D1" /> <span>D1</span>
</label>
<label>
<input type="radio" value="D2" /> <span>D2</span>
</label>
</div>
</div>
<div id="info">var options= [ ["A1","B1","C1","D1"], ["A1","B3","D2"], ["A2","B1","C3","D2"] ];</div>
I would set my data up similar to your second option, however because the first thing they are going to care about is size (you can't change your shoe size), I would show available colours for a size, rather than available sizes for a colour. You would first of all list all availability because if a customer knows that a size 9 green "happy shoe" is potentially available, they might come back later to buy it. You would then loop through the available options to change whether that size or colour is available.
Here's the data set up:
var objShoes = [{
name: 'Happy Shoe',
sizes: [9,10,11,12,13],
colours: ['red','blue','green'],
available: [{
size: 9,
colours: ['red']
},{
size: 10,
colours: ['red', 'blue']
},{
size: 11,
colours: ['blue']
},{
size: 12,
colours: ['red', 'blue']
},{
size: 13,
colours: ['red']
}]
}, {
name: 'Scary Shoe',
sizes: [8,9,10,11,12],
colours: ['black','grey'],
available: [{
size: 8,
colours: ['black']
}]
}];
Here's an example of how that could work, although I used select boxes instead of radio buttons. They're neater :).
The easier way IMHO is to separate the data itself from the definition of an attribute, and not having a hierarchy between attributes. To do this you'll need every attribute value to have a unique id.
In this example I use the index of every attribute in the array as an id to reference it from the availability object.
{
attributes: [
{value: "red", type: "colour"}, // 0
{value: "green", type: "colour"}, // 1
{value: "black", type: "colour"}, // 2
{value: "brown", type: "colour"}, // 3
{value: 40, type: "size"}, // 4
{value: 41, type: "size"}, // 5
{value: 42, type: "size"}, // 6
{value: 43, type: "size"}, // 7
{value: 44, type: "size"}, // 8
{value: true, type: "with_shoelace"}, // 9
{value: false, type: "with_shoelace"}, // 10
],
products: [
{
name: 'some random shoe',
availability: {
0: [4, 7, 8, 9], // red is compatible with 40, 43 and 44, only with shoelace
1: [4, 5, 9, 10], // green is compatible with 40, 43 and 44, with or without shoelace
...
6: [2, 3, 9, 10], // 42 can be black or brown, with or without shoelace
7: [0, 1, 10], // 43 can be red or green, without shoelace
...
10: [1, 4, 6, 7, 8], // ...
}
},
{
name: 'another shoe',
availability: {
...
}
}
]
}
On the GUI, you'll have to intersect the availability arrays from each checked attribute in order to determine which option is usable.

How to add an element at first of object

I have an object:
TICKET_PRIORITIES: {
LOW: 'low',
NORMAL: 'normal',
HIGH: 'high',
VERY_HIGH: 'very high'
}
In client side I have to add select at first.
Result I wanted to be
TICKET_PRIORITIES: {
SELECT: 'select',
LOW: 'low',
NORMAL: 'normal',
HIGH: 'high',
VERY_HIGH: 'very high'
}
<select ng-model="selectedPriority" ng-options="key as key | translate for (key, value) in priorities" class="form-control m-b"> </select>
In this select I wanna select "select" option and select option should be at the first of drop down.
var TICKET_PRIORITIES = {
LOW: 'low',
NORMAL: 'normal',
HIGH: 'high',
VERY_HIGH: 'very high'
};
TICKET_PRIORITIES['SELECT']='select';
alert(JSON.stringify(TICKET_PRIORITIES));
Demo
Object properties order are not concerned while creating object but you can create new properties like:
TICKET_PRIORITIES = {
LOW: 'low',
NORMAL: 'normal',
HIGH: 'high',
VERY_HIGH: 'very high'
}
TICKET_PRIORITIES.SELECT='select';
This is not possible. Javascript does not care about or enforce the order of properties in objects (see this question for reference). Or, to quote the ECMAscript standard (emphasis mine):
4.3.3 Object
An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function. A function stored in a property of an object is called a method.
If order is important to you, you will need a different data structure using arrays, e.g. something like this:
TICKET_PRIORITIES: [
{id: "LOW", label: "low"},
{id: "NORMAL", label: "normal"},
{id: "HIGH", label: "high"},
{id: "VERY_HIGH", label: "very high"}
]
This allows you to do something like this (unshift adds an element to the beginng of an array):
TICKET_PRIORITIES.unshift({id: "SELECT", label: "select"})

Categories