How to set Check attribute for a radio element? - javascript

I'm trying to make a quiz app using JavaScript and jQuery, if I click on a radio button am setting an attribute as checked but if I move on to another question and click on any radio button there in the previous question radio button selects get removed how can I make sure that it is selected even if I move on to any question and select options there. I guess its happening because I have common name on the radio button Can someone help me out?
$(document).ready(function() {
$(function() {
var data = [{
"id": 1,
"question": "Which framework is best?",
"options": ["ReactJs", "AngularJs", "Vue.js", "Backbone"],
"correctanswer": "ReactJs",
"selectedanswer": ""
},
{
"id": 2,
"question": "What does MVC stands for?",
"options": ["Model View Controller", "Model view view Controller", "Model Controller view", "None of the above"],
"correctanswer": "Model View Controller",
"selectedanswer": ""
},
{
"id": 3,
"question": "Which is the best MOOC course website?",
"options": ["Coursera", "EDX", "Udacity", "Code School"],
"correctanswer": "Udacity",
"selectedanswer": ""
},
{
"id": 4,
"question": "which backend framework is not available in any of the MOOC site?",
"options": ["Ruby on Rails", "Node JS", "Metor Js", "Django"],
"correctanswer": "Django",
"selectedanswer": ""
},
{
"id": 5,
"question": "Which frontend framework is not available?",
"options": ["AngularJs", "ReactJs", "Backbone", "Knockout"],
"correctanswer": "ReactJs",
"selectedanswer": ""
}
];
var constructordata = function(data) {
this.id = data.id,
this.question = data.question,
this.options = data.options,
this.correctanswer = data.correctanswer,
this.selectedanswer = data.selectedanswer
};
var datas = [];
data.forEach(function(item) {
datas.push(new constructordata(item));
});
var controller = {
nextquestion: function() {
var currentelement = $('#app .questionsection.visible');
var nextelement = currentelement.next();
if (nextelement.hasClass('questionsection')) {
currentelement.removeClass('visible');
nextelement.addClass('visible');
}
if (!nextelement.next().hasClass('questionsection')) {
$("button").addClass('visible');
}
},
previousquestion: function() {
var currentelement = $('#app .questionsection.visible');
var previouselement = currentelement.prev();
if (previouselement.hasClass('questionsection')) {
currentelement.removeClass('visible');
previouselement.addClass('visible');
}
},
selectanswers: function(temp) {
for (var i = 0; i < datas.length; i++) {
if (datas[i].id == temp) {
datas[i].selectedanswer = $('input[name=optradio]:checked').val();
}
}
},
checkanswers: function() {
var score = 0;
datas.forEach(function(item) {
if (item.selectedanswer == item.correctanswer) {
score++;
}
});
console.log(score);
},
init: function() {
view.init();
}
};
var view = {
init: function() {
this.maintemplate = $("#app");
this.nextarrow = $("#next");
this.submit = $("button");
this.submit.on('click', function() {
controller.checkanswers();
})
this.nextarrow.on('click', function() {
controller.nextquestion();
});
this.previousarrow = $("#previous");
this.previousarrow.on('click', function() {
controller.previousquestion();
});
this.render();
},
render: function() {
var maintemplate = this.maintemplate;
for (var i = 0; i < datas.length; i++) {
maintemplate.append("<div class='questionsection'><p>" + datas[i].question + "</p></div>");
for (var j = 0; j < datas[i].options.length; j++) {
var options = "<div class='radio'><label><input type='radio' name='optradio' questionno=" + datas[i].id + " value=" + datas[i].options[j] + ">" + datas[i].options[j] + "</label></div>"
maintemplate.children('.questionsection').last().append(options);
}
}
maintemplate.children().first().addClass('visible');
var radio = $("input[name=optradio]");
radio.on('click', function() {
var temp = $(this).attr("questionno");
controller.selectanswers(temp);
$(this).attr("checked", "checked");
});
}
};
controller.init();
});
});
.questionsection {
display: none;
}
.btn {
display: none;
}
.visible {
display: block;
}
i.fa {
font-size: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<div class="col-md-2">
<i id="previous" class="fa fa-arrow-left" aria-hidden="true"></i>
</div>
<div id="app" class="col-md-8">
</div>
<div class="col-md-2">
<i id="next" class="fa fa-arrow-right" aria-hidden="true"></i>
</div>
</div>
<button class="btn">Submit</button>
</div>
CodePen http://codepen.io/kannant14/pen/peLOXG

One way to solve it is to name your radiobuttons in the render function with a question index like:
var options="<div class='radio'><label><input type='radio' name='optradio"+i+"' questionno="+datas[i].id+" value="+datas[i].options[j]+">"+datas[i].options[j]+"</label></div>"
and the same in the selectanswers function:
selectanswers:function(temp) {
for(var i=0;i<datas.length;i++) {
if(datas[i].id==temp){
datas[i].selectedanswer=$('input[name=optradio'+i+']:checked').val();
}
}
}
then you just need to keep track of the question index when checking the correct answers.

Related

Azure DevOps Server Widget don't load if configuration is added

I created a Azure DevOps Server widget. When I tried to integrate the settings, the widget suddenly stopped loading. I checked my configuration with the example from Microsoft but did not find the solution.
My vss-extension.json:
"manifestVersion": 1,
"id": "ado-report-tfs-addon",
"version": "1.0.0",
"name": "ADO Report Widget",
"description": "You can see at a glance if a team has free capacity for new features.",
"publisher": "bci",
"icons": {
"default": "img/icon.png"
},
"targets": [
{
"id": "Microsoft.VisualStudio.Services"
}
],
"tags": [
"ado-report",
"report",
"widgets",
"dashboard"
],
"screenshots": [
{
"path": "img/sampleImage1.png"
},
{
"path": "img/sampleImage2.png"
}
],
"content": {
"details": {
"path": "README.md"
}
},
"links": {
"getstarted": {
"uri": "https://rb-tfsbci.de.bosch.com/tfs/OpConDev/Nx_Base/_git/ado-widgets"
},
"learn": {
"uri": "https://rb-tfsbci.de.bosch.com/tfs/OpConDev/Nx_Base/_git/ado-widgets"
},
"license": {
"uri": "https://rb-tfsbci.de.bosch.com/tfs/OpConDev/Nx_Base/_git/ado-widgets"
},
"support": {
"uri": "https://rb-tfsbci.de.bosch.com/tfs/OpConDev/Nx_Base/_git/ado-widgets"
}
},
"repository": {
"type": "git",
"uri": "https://rb-tfsbci.de.bosch.com/tfs/OpConDev/Nx_Base/_git/ado-widgets"
},
"branding": {
"color": "87C2E1",
"theme": "light"
},
"categories": [
"Collaborate"
],
"contributions": [
{
"id": "ADOReport1",
"type": "ms.vss-dashboards-web.widget",
"targets": [
"ms.vss-dashboards-web.widget-catalog",
"bci.ado-report-tfs-addon.ADOReport.Configuration"
],
"properties": {
"name": "ADO Report Widget",
"description": "You can see at a glance if a team has free capacity for new features.",
"catalogIconUrl": "img/icon.png",
"previewImageUrl": "img/icon.png",
"uri": "widget1.html",
"supportedSizes": [
{
"rowSpan": 5,
"columnSpan": 5
}
],
"supportedScopes": [
"project_team"
]
}
},
{
"id": "ADOReport.Configuration",
"type": "ms.vss-dashboards-web.widget-configuration",
"targets": [
"ms.vss-dashboards-web.widget-configuration"
],
"properties": {
"name": "ADO Report Configuration",
"description": "Configures ADOReport1",
"uri": "configuration.html"
}
}
],
"files": [
{
"path": "widget1.html",
"addressable": true
},
{
"path": "configuration.html",
"addressable": true
},
{
"path": "styles",
"addressable": true
},
{
"path": "sdk/scripts",
"addressable": true
},
{
"path": "img",
"addressable": true
}
],
"galleryFlags": [
"Preview"
],
"scopes": [
"vso.work",
"vso.code_write",
"vso.build_execute",
"vso.test",
"vso.build",
"vso.extension.data"
]
}
My widget1.html:
<!DOCTYPE html>
<html>
<head>
<!--<meta http-equiv="refresh" content="5">-->
<link rel="stylesheet" href="styles/main-style.css" />
<script src="sdk/scripts/VSS.SDK.min.js" type="text/javascript"></script>
<script src="sdk/scripts/main.js" type="text/javascript"></script>
</head>
<body>
<div class="widget">
<div class="title-wrapper">
<h2 class="title">ADO Widget</h2>
</div>
<div class="team-select-wrapper">
<div class="team-select-wrapper-select">
<div class="dropdown">
<label>
Team auswählen:
</label>
<div class="wrapper">
<select class="team-select-selector" id="teamSelect"> </select>
</div>
</div>
</div>
<div class="team-select-wrapper-loading">
<div class="loader" id="loading-icon"></div>
</div>
</div>
<div class="feature">
<div class="feature-wrapper">
<div class="feature-name-container" id="feature-name-container"></div>
<div class="feature-time-container" id="feature-time-container"></div>
</div>
<div class="feature-split-wrapper">
<hr class="feature-splitter" />
</div>
<div class="feature-evaluation-wrapper">
<div class="feature-evaluation-summ">
Summe
</div>
<div class="feature-evaluation-value" id="feature-evaluation-value">
</div>
</div>
</div>
<div class="kappa">
<div class="kappa-wrapper">
<div class="kappa-sprint-wrapper" id="sprint-wrapper"></div>
<div class="kappa-evaluation-wrapper">
<div class="kappa-splitter">
<hr class="kappa-splitter-item" />
</div>
<div class="kappa-evaluation">
<div class="kappa-evaluation-text">
Summe:
</div>
<div class="kappa-evaluation-evaluation" id="gesKappa"></div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
My main.js:
var selectedTeam = "team1";
var teams = [];
var gesKapa = 0;
var loader;
function changeGesKapa(newVal) {
gesKapa = newVal;
var gesKapaNote = document.getElementById("gesKappa");
while (gesKapaNote.lastElementChild) {
gesKapaNote.removeChild(gesKapaNote.lastElementChild);
}
gesKapaNote.innerHTML = "";
gesKapaNote.append(document.createTextNode(gesKapa + "h"));
}
function startLoading() {
if (loader !== undefined) {
loader.classList.remove("hidden");
}
}
function stopLoading() {
if (loader !== undefined) {
loader.classList.add("hidden");
}
}
function getSelectedTeam() {
var mySelect = document.getElementById("teamSelect");
return mySelect.value;
}
function treatAsUTC(date) {
var result = new Date(date);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;
}
function daysBetween(startDate, endDate) {
var millisecondsPerDay = 24 * 60 * 60 * 1000;
return (treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay;
}
function getBusinessDatesCount(startDate, endDate) {
var count = 0;
var curDate = startDate;
while (curDate <= endDate) {
var dayOfWeek = curDate.getDay();
if (!(dayOfWeek == 6 || dayOfWeek == 0)) count++;
curDate.setDate(curDate.getDate() + 1);
}
return count;
}
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
document.addEventListener("DOMContentLoaded", () => {
loader = document.getElementById("loading-icon");
var sel = document.getElementById("teamSelect");
sel.addEventListener("change", async () => {
startLoading();
await loadOverlay();
});
});
VSS.init({
explicitNotifyLoaded: true,
usePlatformStyles: true,
usePlatformScripts: true,
});
VSS.require(["TFS/Dashboards/WidgetHelpers"], async function (WidgetHelpers) {
WidgetHelpers.IncludeWidgetStyles();
VSS.register("ADOReport1", function () {
return {
load: function () {
return WidgetHelpers.WidgetStatusHelper.Success();
},
};
});
VSS.notifyLoadSucceeded();
});
VSS.require(["TFS/Core/RestClient"], async function loadTeams(TFS_Core_WebApi) {
TFS_Core_WebApi.getClient()
.getProjects(null, null, null)
.then(async (teamList) => {
await asyncForEach(teamList, async (teamListItem) => {
teams.push({
teams: await TFS_Core_WebApi.getClient().getTeams(
teamListItem.id,
null,
null
),
project: teamListItem,
});
});
teams.sort();
teams.forEach((element) => {
element.teams.sort();
});
var select = document.getElementById("teamSelect");
teams.forEach((element) => {
element.teams.forEach((teamsItem) => {
var option = document.createElement("option");
option.classList.add("team-select-item");
option.appendChild(
document.createTextNode(
element.project.name + " : " + teamsItem.name
)
);
option.value = teamsItem.id + ";" + element.project.id;
select.appendChild(option);
});
});
await loadOverlay();
},
(error) => {
console.log(error);
});
});
async function loadOverlay() {
document.getElementById("feature-name-container").innerHTML = "";
document.getElementById("feature-time-container").innerHTML = "";
gesKapa = 0;
VSS.require(["TFS/WorkItemTracking/RestClient"], async function loadWorkItems(
TFS_WorkItemTracking_WebApi
) {
var e = document.getElementById("teamSelect");
if (
e.options[e.selectedIndex] == undefined ||
e.options[e.selectedIndex] == null
) {
return;
}
var teamId = e.options[e.selectedIndex].value.split(";")[0];
var projectId = e.options[e.selectedIndex].value.split(";")[1];
if (teamId == undefined || teamId == null) {
return;
}
VSS.require(["TFS/Work/RestClient"], async function loadTeamIterations(
TFS_Work_WebApi
) {
TFS_Work_WebApi.getClient()
.getTeamIterations({
projectId: projectId,
teamId: teamId,
})
.then((sprints) => {
TFS_Work_WebApi.getClient()
.getTeamFieldValues({
projectId: projectId,
teamId: teamId,
})
.then((resultValues) => {
// It can happen that the Path Area is null
if (resultValues.defaultValue !== null) {
TFS_WorkItemTracking_WebApi.getClient()
.queryByWiql(
{
query:
"SELECT [System.Id] FROM WorkItems WHERE [Work Item Type] = 'Feature' AND [Board Column] = 'New' AND [Area Path] = '" +
resultValues.defaultValue +
"'",
},
projectId,
teamId
)
.then((workItemIds) => {
var ids = [];
workItemIds.workItems.forEach((workItemId) => {
ids.push(workItemId.id);
});
// It can be that no WorkItems are available
if (Array.isArray(ids) && ids.length) {
TFS_WorkItemTracking_WebApi.getClient()
.getWorkItems(
ids,
[
"System.Id",
"System.Title",
"Microsoft.VSTS.Scheduling.Effort",
],
null,
null
)
.then((workItemObject) => {
var summFeature = 0;
workItemObject.forEach((elementeNew) => {
if (
elementeNew.fields[
"Microsoft.VSTS.Scheduling.Effort"
] != undefined
) {
summFeature +=
elementeNew.fields[
"Microsoft.VSTS.Scheduling.Effort"
];
}
});
var summFeatureNode = document.getElementById(
"feature-evaluation-value"
);
summFeatureNode.innerHTML = "";
summFeatureNode.appendChild(
document.createTextNode(summFeature + "h")
);
var workItemWrapper = document.getElementById(
"feature-name-container"
);
workItemWrapper.innerHTML = "";
workItemObject.forEach((idsnew) => {
var workItemNameWrapper = document.createElement(
"div"
);
workItemNameWrapper.classList.add(
"feature-name-container-item"
);
var linkItem = document.createElement("a");
linkItem.classList.add(
"feature-name-container-link",
"animated-link"
);
linkItem.appendChild(
document.createTextNode(
idsnew.fields["System.Title"]
)
);
workItemNameWrapper.appendChild(linkItem);
workItemWrapper.appendChild(workItemNameWrapper);
});
var workItemTimeWrapper = document.getElementById(
"feature-time-container"
);
workItemTimeWrapper.innerHTML = "";
workItemObject.forEach((idsnew) => {
var workItemTimeSubContainer = document.createElement(
"div"
);
workItemTimeSubContainer.classList.add(
"feature-time-container-item"
);
if (
idsnew.fields[
"Microsoft.VSTS.Scheduling.Effort"
] != undefined
) {
workItemTimeSubContainer.appendChild(
document.createTextNode(
idsnew.fields[
"Microsoft.VSTS.Scheduling.Effort"
] + "h"
)
);
} else {
workItemTimeSubContainer.appendChild(
document.createTextNode("-")
);
}
workItemTimeWrapper.appendChild(
workItemTimeSubContainer
);
});
});
}
});
}
});
var sprintWrapper = document.getElementById("sprint-wrapper");
while (sprintWrapper.lastElementChild) {
sprintWrapper.removeChild(sprintWrapper.lastElementChild);
}
sprints.forEach((sprint) => {
// load kappa
TFS_Work_WebApi.getClient()
.getCapacities(
{
projectId: projectId,
teamId: teamId,
},
sprint.id
)
.then((result) => {
var kapa = 0;
result.forEach((teamMembers) => {
teamMembers.activities.forEach((activity) => {
kapa += activity.capacityPerDay;
});
});
kapa =
kapa *
getBusinessDatesCount(
sprint.attributes.startDate,
sprint.attributes.finishDate
);
changeGesKapa(gesKapa + kapa);
// create header
var sprintItem = document.createElement("div");
sprintItem.classList.add("kappa-sprint-item");
var sprintTitle = document.createElement("div");
sprintTitle.classList.add("kappa-sprint-title");
var sprintTitleLink = document.createElement("a");
sprintTitleLink.classList.add("kappa-sprint-title-link");
sprintTitleLink.classList.add("animated-link");
sprintTitleLink.text = sprint.name;
sprintTitleLink.href = sprint.url;
sprintTitle.appendChild(sprintTitleLink);
sprintItem.appendChild(sprintTitle);
// create sprint content
var sprintcontent = document.createElement("div");
sprintcontent.classList.add("kappa-sprint-content");
var yeStart = new Intl.DateTimeFormat("en", {
year: "numeric",
}).format(sprint.attributes.startDate);
var moStart = new Intl.DateTimeFormat("en", {
month: "short",
}).format(sprint.attributes.startDate);
var daStart = new Intl.DateTimeFormat("en", {
day: "2-digit",
}).format(sprint.attributes.startDate);
var yeEnde = new Intl.DateTimeFormat("en", {
year: "numeric",
}).format(sprint.attributes.finishDate);
var moEnde = new Intl.DateTimeFormat("en", {
month: "short",
}).format(sprint.attributes.finishDate);
var daEnde = new Intl.DateTimeFormat("en", {
day: "2-digit",
}).format(sprint.attributes.finishDate);
sprintcontent.appendChild(
document.createTextNode(
daStart +
"." +
moStart +
"." +
yeStart +
" - " +
daEnde +
"." +
moEnde +
"." +
yeEnde
)
);
sprintItem.appendChild(sprintcontent);
// create sprint evaluation
var sprintEvaluation = document.createElement("div");
sprintEvaluation.classList.add("kappa-sprint-evaluation");
sprintEvaluation.append(
document.createTextNode("Kapa: " + kapa + "h")
);
stopLoading();
sprintItem.appendChild(sprintEvaluation);
sprintWrapper.appendChild(sprintItem);
});
});
});
});
});
}
My configuration.html:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="sdk/scripts/VSS.SDK.min.js" type="text/javascript"></script>
<script>
VSS.init({
explicitNotifyLoaded: false,
usePlatformStyles: true,
});
VSS.require("TFS/Dashboards/WidgetHelpers", function (WidgetHelpers) {
WidgetHelpers.IncludeWidgetConfigurationStyles();
VSS.register(VSS.getContribution().id, function () {
return {
load: function (widgetSettings, widgetConfigurationContext) {
return WidgetHelpers.WidgetStatusHelper.Success();
},
};
});
VSS.notifyLoadSucceeded();
});
</script>
</head>
<body>
<div class="container">
</div>
</body>
</html>
Can someone help me with this problem?
In main.js, you're missing the widgetSettings parameter in the load parameter, e.g.
return {
load: function (widgetSettings) {
return YourLoadFunction(widgetSettings);
},
reload: function (widgetSettings) {
return YourReloadFunction(widgetSettings);
}
}

AmChart : hide event

I'm using amChart with the plugin dataLoader to load data and eventData so I have something like this :
var defaultStockChartData = {
"dataLoader": {
"url": "urlToMyFile.csv",
"format": "csv",
"delimiter": ",",
"useColumnNames": true
},
/**
* data loader for events data
*/
"eventDataLoader": {
"url": urlToMyFile.scv,
"async": true,
"postProcess": function(data) {
for (var x in data) {
var color = "#85CDE6";
switch (data[x].Type) {
case 'A':
color = "#85CDE6";
break;
case 'B':
color = "#85C56E6";
break;
default:
color = "#cccccc";
break;
}
data[x] = {
"type": "pin",
"graph": "g1",
"backgroundColor": color,
"date": data[x].Date,
"text": data[x].Type,
"description": data[x].Description
};
}
return data;
}
}
...
}
Now what I need to do is a checkbox that shows all the event on the graph with the type 'A' when it's checked and hide all the event with the type 'A' when it's unchecked.
How I can I access the events of my chart and hide them follow their type?
A better way to do this is to modify the event data directly and toggle each element's graph property to null or the original graph to show/hide them so you don't have to hack around the charts' bullet handling on zoom and other events. For example:
HTML:
<div>
<label>Hide Event A <input type="checkbox" class="hide-event" data-event="A"></label>
<label>Hide Event B <input type="checkbox" class="hide-event" data-event="B"></label>
</div>
JS:
//show/hide events based on selected checkbox
Array.prototype.forEach.call(
document.querySelectorAll('.hide-event'),
function(checkbox) {
checkbox.addEventListener('change', function() {
var event = checkbox.dataset.event;
chart.dataSets[0].stockEvents.forEach(function(eventItem) {
if (eventItem.text === event) {
if (checkbox.checked) {
//copy graph reference to a dummy value and null out the original graph
eventItem.oldGraph = eventItem.graph;
eventItem.graph = null;
}
else {
//restore original graph and null out copy/dummy reference
eventItem.graph = eventItem.oldGraph;
eventItem.oldGraph = null;
}
}
});
chart.validateData(); //redraw the chart
});
}
);
Full demo below:
var chartData = [];
var eventData = [];
generateChartData();
//show/hide events based on selected checkbox
Array.prototype.forEach.call(
document.querySelectorAll('.hide-event'),
function(checkbox) {
checkbox.addEventListener('change', function() {
var event = checkbox.dataset.event;
chart.dataSets[0].stockEvents.forEach(function(eventItem) {
if (eventItem.text === event) {
if (checkbox.checked) {
//copy graph reference to a dummy value and null out the original graph
eventItem.oldGraph = eventItem.graph;
eventItem.graph = null;
}
else {
//restore original graph and null out copy/dummy reference
eventItem.graph = eventItem.oldGraph;
eventItem.oldGraph = null;
}
}
});
chart.validateData(); //redraw the chart
});
}
);
function generateChartData() {
var firstDate = new Date( 2012, 0, 1 );
firstDate.setDate( firstDate.getDate() - 500 );
firstDate.setHours( 0, 0, 0, 0 );
for ( var i = 0; i < 500; i++ ) {
var newDate = new Date( firstDate );
newDate.setDate( newDate.getDate() + i );
var a = Math.round( Math.random() * ( 40 + i ) ) + 100 + i;
var b = Math.round( Math.random() * 100000000 );
chartData.push( {
"date": newDate,
"value": a,
"volume": b
} );
if ((i + 1) % 8 === 0) {
eventData.push({
"date": newDate,
"type": "sign",
"backgroundColor": "#85CDE6",
"graph": "g1",
"text": (i + 1) % 5 == 0 ? "B" : "A",
"description": "Event " + ((i + 1) % 5 == 0 ? "B" : "A") + " at index " + i
})
}
}
}
var chart = AmCharts.makeChart( "chartdiv", {
"type": "stock",
"theme": "light",
"dataSets": [ {
"color": "#b0de09",
"fieldMappings": [ {
"fromField": "value",
"toField": "value"
}, {
"fromField": "volume",
"toField": "volume"
} ],
"dataProvider": chartData,
"categoryField": "date",
// EVENTS
"stockEvents": eventData
} ],
"panels": [ {
"title": "Value",
"stockGraphs": [ {
"id": "g1",
"valueField": "value"
} ],
"stockLegend": {
"valueTextRegular": " ",
"markerType": "none"
}
} ],
"chartScrollbarSettings": {
"graph": "g1"
},
"chartCursorSettings": {
"valueBalloonsEnabled": true,
"graphBulletSize": 1,
"valueLineBalloonEnabled": true,
"valueLineEnabled": true,
"valueLineAlpha": 0.5
}
} );
#chartdiv {
width: 100%;
height: 500px;
}
<script src="https://www.amcharts.com/lib/3/amcharts.js"></script>
<script src="https://www.amcharts.com/lib/3/serial.js"></script>
<script src="https://www.amcharts.com/lib/3/amstock.js"></script>
<script src="https://www.amcharts.com/lib/3/themes/light.js"></script>
<div>
<label>Hide Event A <input type="checkbox" class="hide-event" data-event="A"></label>
<label>Hide Event B <input type="checkbox" class="hide-event" data-event="B"></label>
</div>
<div id="chartdiv"></div>
I didn't find a way to do it with AmChart so I did it in javascript (not by type but just need to check the value)
First I need this function :
function hideShowGraphEvent()
{
if($("#chxEventA").prop("checked"))
{
$("g.amcharts-graph-bullet").show();
}
else
{
$("g.amcharts-graph-bullet").hide();
}
}
And call it each time you check or uncheck the box :
$("#chxEventA").change(function()
{
hideShowGraphEvent();
});
But if you use zoom (like me) it will stop working when you zoom so you need to call the function each time you zoom :
"listeners" : [
{
"event": "zoomed",
"method": function()
{
hideShowGraphEvent();
}
},
...
]

Implementing textarea Drag and drop

(function() {
'use strict';
var data = JSON.stringify({
"tags": [{
"id": 1,
"name": "HELPDESKPHONE",
"value": "{{helpdeskphone}}",
"description": null
}, {
"id": 3,
"name": "HELPDESKEMAIL",
"value": "{{helpdeskemail}}",
"description": null
}, {
"id": 4,
"name": "CODE",
"value": "{{code}}",
"description": null
}, {
"id": 7,
"name": "CALLBACKURL",
"value": "{{callbackurl}}",
"description": null
}],
"templates": [{
"id": 1,
"key": "securitycode",
"description": null,
"content": "<p>Your credentials have been identified in the system and a request to authenticate your account by email has been made.</p><p>To continue the 2-Factor Authentication process, enter this single-use code on the verification page.</p>{{code}}<p>PLEASE NOTE THAT THIS CODE EXPIRES WITHIN 1 HOUR OF SENDING THIS EMAIL.</p><p>If you did not initiate this request, please contact the Helpdesk via email at {{helpdeskemail}} or by calling (toll-free) {{helpdeskphone}}</p>",
"subject": "Security Code"
}, {
"id": 3,
"key": "resetpassword",
"description": null,
"content": "<p>A request to change your password has been made. To continue the password change process, click on the link below.</p>Click here to reset your password.</p>\n<p>PLEASE NOTE THAT THIS LINK EXPIRES WITHIN 1 HOUR OF SENDING THIS EMAIL.</p><p>If you did not initiate this request, please contact the Helpdesk via email at {{helpdeskemail}}; or by calling (toll-free) {{helpdeskphone}}</p> ",
"subject": "FWIMS Password Change Request"
}]
});
var Tag = function(id, name, value, description) {
var self = this;
self.id = ko.observable(id);
self.name = ko.observable(name);
self.value = ko.observable(value);
self.description = ko.observable(description);
};
var Template = function(id, key, description, content, subject, tags) {
var self = this;
self.id = ko.observable(id);
self.key = ko.observable(key);
self.description = ko.observable(description);
self.content = ko.observable(content);
self.subject = ko.observable(subject);
};
var ViewModel = function(data) {
var self = this;
self.templates = ko.observableArray(data.templates.map(function(item) {
return new Template(
item.id,
item.key,
item.description,
item.content,
item.subject
);
}));
self.tags = ko.observableArray(data.tags.map(function(item) {
return new Tag(
item.id,
item.name,
item.value,
item.description
);
}));
self.makeDraggable = function() {
$("li").draggable({
helper: 'clone'
});
};
self.makeDroppable = function(elements) {
$(".txtDropTarget").droppable({
accept: "li",
drop: function(ev, ui) {
$(this).insertAtCaret(ui.draggable.text());
}
});
};
$.fn.insertAtCaret = function(myValue) {
return this.each(function() {
//IE support
if (document.selection) {
this.focus();
sel = document.selection.createRange();
sel.text = myValue;
this.focus();
}
//MOZILLA / NETSCAPE support
else if (this.selectionStart || this.selectionStart == '0') {
var startPos = this.selectionStart;
var endPos = this.selectionEnd;
var scrollTop = this.scrollTop;
this.value = this.value.substring(0, startPos) + myValue + this.value.substring(endPos, this.value.length);
this.focus();
this.selectionStart = startPos + myValue.length;
this.selectionEnd = startPos + myValue.length;
this.scrollTop = scrollTop;
} else {
this.value += myValue;
this.focus();
}
});
};
};
var viewModel = new ViewModel(ko.utils.parseJson(data) || []);
ko.applyBindings(viewModel);
}());
.move-pointer {
cursor: move;
}
<div data-bind="foreach: {data: templates, afterRender: makeDroppable } ">
<div class="card">
<div class="d-flex justify-content-between align-content-center">
<textarea rows="10" style="height: auto" aria-label="Content" class="txtDropTarget form-control m-3" aria-describedby="Template Content" data-bind="textInput: content"></textarea>
<div data-bind="html: content" class="m-3"></div>
</div>
<div class="d-flex justify-content-between align-content-center">
<ul class="dragList nav" data-bind="foreach: { data: $parent.tags, afterRender: $root.makeDraggable }">
<li data-bind="text: value" class="nav-item m-3 h5 move-pointer"></li>
</ul>
</div>
</div>
</div>
I'm designing a UI for editing and creating email template content using knockout.
I've implemented this:
I have a textarea and a preview div. when text is add in the text area it shows up in the preview area. under the textarea are acceptable tags which acts has placeholders. this placeholders will be replaced at runtime with actual values.
The problem I'm having right now is, If a tag is dragged into the textarea, the content observable is not updated immediately, I have to type in the text area to trigger an observable update.
<textarea rows="10" style="height: auto" aria-label="Content" class="txtDropTarget form-control m-3" aria-describedby="Template Content" data-bind="textInput: content"></textarea>
I've tried the textInput binding and valueUpdate: 'input' event, none of that worked
do this
$(this).insertAtCaret(ui.draggable.text()).change();
after drag.
I edited your example - https://jsfiddle.net/qskxzh0e/3/
self.makeDroppable = function(elements) {
$(".txtDropTarget").droppable({
accept: "li",
drop: function(ev, ui) {
$(this).insertAtCaret(ui.draggable.text()).change();
}
});
};

Display item of same category from array list in html page

I have a array that hold the list of category and its details.
I am trying to display all the content of the same category.
For example, when the user click on the "Wholesome fun for the family" button it will then display all the data that is under the category of "Wholesome fun for the family".
How can I go about doing it?
HTML
<body>
<!-------------------------------------------------------- Home Page - List of activity category -------------------------------------------------------->
<nav class='current'>
<h1>FUNpedia</h1>
<a class='button' id="goto-new-note">New</a>
</nav>
<article id="home" class="current">
<section>
<ul class="list" id="home-category-list">
</ul>
</section>
</article>
<!-------------------------------------------- Selected Activity Page - List of activities within the category -------------------------------------------->
<nav class='next'>
<!-- <a class='button backTo' id="goto-home">Back</a> -->
<a id="goto-home" style="margin-top:10px;"><img src="img/backBtn.png" width="30" height="30"></a>
<h1>Attractions</h1>
</nav>
<article id="category-view" class="next">
<section>
<ul class='list'>
<li class='comp'>
<!-- <h3 class='category-title'></h3>
<p class='category-content'></p> -->
<aside>
<img title='Imagine Dragons' src="../images/music/Imagine Dragons.png" height="80px">
</aside>
<div>
<h3 class='category-title'></h3>
<h4 class='category-categoryName'></h4>
<p class='category-content'></p>
</div>
<aside>
<span class='show-detail'></span>
</aside>
</li>
</ul>
</section>
</article>
</body>
Javascript
/* ----------------------------------------------------------- Array of category and detail ----------------------------------------------------------- */
var category = [
{
categoryName: "Wholesome fun for the family",
imageName: "attraction.jpg",
content: "Number 1"
},
{
categoryName: "Wholesome fun for the family",
imageName: "attraction.jpg",
content: "Number 2"
},
{
categoryName: "Adventure for the family",
imageName: "themePark.jpg",
content: "Hihihihi"
},
{
categoryName: "For the young and curious",
imageName: "youngExplorer.jpg",
content: "Hihihihi"
},
{
categoryName: "A city of greenery",
imageName: "parkNgarden.jpg",
content: "Hihihihi"
},
{
categoryName: "Get ready to experience explosive sporting action",
imageName: "extremeSG.jpg",
content: "Hihihihi"
},
{
categoryName: "Fun in the water",
imageName: "wetAdventure.jpg",
content: "Hihihihi"
}
];
for (var i = 0; i < category.length; i++) {
listNode(i);
}
/* ----------------------------------------------------------- Display the list of category ----------------------------------------------------------- */
function listNode(id) {
$("#home-category-list").append("<li class='nav' data-id='" + id + "'>" +
"<img src=img/" + category[id].imageName + ">" +
"</li>");
}
/* -------------------------------------------------- Show the list of activities within the category -------------------------------------------------- */
$("#home-category-list").on("singletap", "li", function() {
var id = $(this).data("id");
listActivities(id);
});
function listActivities(id) {
$("#category-view").data("id", id);
$("#category-view .category-title").text(category[id].categoryName);
$("#category-view .category-content").html(category[id].content);
$("#category-view .category-categoryName").html(category[id].categoryName);
$.UIGoToArticle("#category-view");
}
SOLUTION (updated)
I changed a lot of your HTML for clarity purpose. I'm not sure it's the result you want but I'm pretty sure you will figure it all out from here.
The javascript magic:
var category = [...];
//generate a category list without repeated categories
function newCategoryList(){
var categoryList = [];
for(var a=0; a<category.length; a++){
var unique = true;
for(var b=0; b<categoryList.length; b++){
if(category[a].categoryName == categoryList[b].name) unique = false;
}
if(unique) categoryList.push({
name: category[a].categoryName,
img: category[a].imageName
});
}
return categoryList;
}
//add category to home list
function listCategories(id) {
$('#home-category-list').append('<li class="nav" data-id="'+id+'"><img src="http://placehold.it/50x50/&text='+categoryList[id].img+'"/>'+categoryList[id].name+'</li>');
}
//list all activities in the respective category
function listActivities(id){
$('#home-activity-list').html('');
var cat = categoryList[id];
for(var a=0; a<category.length; a++){
if(category[a].categoryName == cat.name){
newActivity(a);
}
}
}
//add new Activity to the list
function newActivity(id){
var img = $('<img src="http://placehold.it/150x50/&text='+category[id].imageName+'">');
var title = $('<h3>'+category[id].categoryName+'</h3>');
var content = $('<p>'+category[id].content+'</p>');
var li = $('<li>').append(img, title, content).appendTo($('#home-activity-list'));
}
//generate the list of categories
var categoryList = newCategoryList();
//list all categories
$.each(categoryList, listCategories);
//attach category click event
$("#home-category-list").on("click singletap", "li", function(){
var id = $(this).data("id");
listActivities(id);
$("html, body").animate({ scrollTop: $(document).height() }, "slow");
});
//populate the Activity list
newActivity(0);
Change singletap event to click event. I do that and now the category information appears (JSFiddle file).
This is the code I use to test (I commented $.UIGoToArticle("#category-view") because I don't have a reference to UIGoToArticle):
var category = [
{
categoryName: "Wholesome fun for the family",
imageName: "attraction.jpg",
content: "Number 1"
},
{
categoryName: "Wholesome fun for the family",
imageName: "attraction.jpg",
content: "Number 2"
},
{
categoryName: "Adventure for the family",
imageName: "themePark.jpg",
content: "Hihihihi"
},
{
categoryName: "For the young and curious",
imageName: "youngExplorer.jpg",
content: "Hihihihi"
},
{
categoryName: "A city of greenery",
imageName: "parkNgarden.jpg",
content: "Hihihihi"
},
{
categoryName: "Get ready to experience explosive sporting action",
imageName: "extremeSG.jpg",
content: "Hihihihi"
},
{
categoryName: "Fun in the water",
imageName: "wetAdventure.jpg",
content: "Hihihihi"
}
];
$( document ).ready(function() {
for (var i = 0; i < category.length; i++) {
listNode(i);
}
$("#home-category-list").on("click", "li", function() {
var id = $(this).data("id");
listActivities(id);
});
});
function listNode(id) {
$("#home-category-list").append("<li class='nav' data-id='" + id + "'>" + "<img src=img/" + category[id].imageName + ">" + "</li>");
}
function listActivities(id) {
$("#category-view").data("id", id);
var aux = $("#category-view .category-title");
$("#category-view .category-title").text(category[id].categoryName);
$("#category-view .category-content").html(category[id].content);
$("#category-view .category-categoryName").html(category[id].categoryName);
//$.UIGoToArticle("#category-view");
}
UPDATE:
To display the content of all the categories with same name you need to do something like this (JSFiddle file):
function listActivities(id) {
$("#category-view").data("id", id);
var aux = $("#category-view .category-title");
$("#category-view .category-title").text(category[id].categoryName);
$("#category-view .category-content").empty();
var selectedName = category[id].categoryName;
$.each(category, function()
{
if(this.categoryName == selectedName)
$("#category-view .category-content").append(this.content);
});
$("#category-view .category-categoryName").html(category[id].categoryName);
//$.UIGoToArticle("#category-view");
}
The .html() replace the HTML element inner content, so in this case you need to use .append() or .attach() to append the categories content one by one, or join all in a variable and then do something like .html(variable ).

How to build a tree control with JSON and jQuery

I have a web page on which I would like to display dynamically a tree based on a JSON array with the help of jQuery. Each node of my tree has a checkbox associated to it. When I click a node which has children, I would like all of them to be checked. I’ve already taken care of printing the tree and the checkboxes and I am now trying to select children nodes and I am not able.
Below is the code (simplified) that I have so far. Does anybody has an idea how I could automatically check the children checkboxes when a checkbox is checked with jQuery?
Thanks!
<html>
<head>
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript">
var myJSON = {
"d": {
"__type": "Branch",
"Name": "$",
"FullPath": "$\\$",
"SubBranch": [
{
"__type": "Branch",
"Name": "System",
"FullPath": "$\\System",
"SubBranch": [
{
"__type": "Branch",
"Name": "Library",
"FullPath": "$\\System\\Library",
"SubBranch": [
]
},
{
"__type": "Branch",
"Name": "Configuration",
"FullPath": "$\\System\\Configuration",
"SubBranch": [
{
"__type": "Branch",
"Name": "Reimage",
"FullPath": "$\\System\\Configuration\\Reimage",
"SubBranch": [
]
},
{
"__type": "Branch",
"Name": "Installation",
"FullPath": "$\\System\\Configuration\\Installation",
"SubBranch": [
]
}
]
},
]
}
]
}
}
var output;
var indentationLevel = 0;
function GetSpacing(numberOfSpaces) {
var tabs = '';
for (i = 0; i < numberOfSpaces; i++) {
tabs += ' ';
}
return tabs;
}
function GetHtmlForFeaturePath(featurePath) {
return '<div>' + GetSpacing(indentationLevel) + '<input type="checkbox" id="' + featurePath.FullPath + '" class="featureTreeCheckbox" />' + featurePath.Name + "</div>";
}
function GetHtmlForFeaturePaths(node) {
output += GetHtmlForFeaturePath(node);
indentationLevel++;
jQuery.each(node.SubBranch, function() {
GetHtmlForFeaturePaths(this);
});
indentationLevel--;
}
String.prototype.startsWith = function(str) {
return this.match("^" + str) == str;
}
window.onload = function() {
GetHtmlForFeaturePaths(myJSON.d);
document.writeln(output);
/* How do I tell a node to check its children? */
$('input').click(function(event) {
var clickedControlId = this.id;
alert(clickedControlId);
/* alert($.grep(myJSON.d, function (a) { return a.FullPath == clickedControlId })); */
});
}
</script>
</head>
<body>
jQuery
</body>
</html>
It is not a good practice to distinguish levels with spaces. Instead you should use a class or an id. This helps both the appearance (you can use css) and your code, since it defines logical levels.
Edit your code to produce a DOM like that:
<div class="level1">
<input id="$\$" class="featureTreeCheckbox" type="checkbox">$
<div class="level2">
<input id="$\System" class="featureTreeCheckbox" type="checkbox">System
<div class="level3">
<input id="$\System\Library" class="featureTreeCheckbox" type="checkbox">Library
</div>
<div class="level3">
<input id="$\System\Configuration" class="featureTreeCheckbox" type="checkbox">Configuration
<div class="level4">
<input id="$\System\Configuration\Reimage" class="featureTreeCheckbox" type="checkbox">Reimage<br/>
<input id="$\System\Configuration\Installation" class="featureTreeCheckbox" type="checkbox">Installation
</div>
</div>
</div>
</div>
Each "levelx" class defines a level. You can easily style it like this:
<style>
.level1 { margin-left: 0px; }
.level2 { margin-left: 10px; }
.level3 { margin-left: 20px; }
.level4 { margin-left: 30px; }
</style>
Then you can use code like this:
<script type="text/javascript">
$(function() {
$('div.level1 input').change(function(event) {
if ($(this).is(":checked")) {
$(this).parent().find("input").attr("checked", "checked");
}
});
$('div.level2 input').change(function(event) {
if ($(this).is(":checked")) {
$(this).parent().find(".level3 input").attr("checked", "checked");
$(this).parent().find(".level4 input").attr("checked", "checked");
}
});
$('div.level3 input').change(function(event) {
if ($(this).is(":checked")) {
$(this).parent().find(".level4 input").attr("checked", "checked");
}
});
});
</script>
I'd simplify what kgiannakakis did:
$(function() {
$('div input:first').change(function(event) {
if ($(this).is(":checked")) {
$(this).next("div").find("input").attr("checked", "checked");
} else {
$(this).next("div").find("input").removeAttr("checked");
}
});
});
This should work for any number of levels.

Categories