How to change progress bar with creating dynamic checkboxes - javascript

I have looked all over and found many similar threads, but none of them really answered my question with this specific situation:
I want to, when the visitor creates dynamic Checkbox, then the visitor checks or unchecks a checkbox it will increase or decrease the value shown on the progress bar. In addition I want to show the percent of the progress bar. Like this: Image
Here is a demo
Here is the Code:
HTML:
<div id="cblist"></div>
<input type="text" id="checkBoxName" />
<input type="button" value="ok" id="btnSaveCheckBox" />
<div id="progressbar"></div>
<br/>
Jquery:
$(document).ready(function () {
$('#btnSaveCheckBox').click(function () {
addCheckbox($('#checkBoxName').val());
$('#checkBoxName').val("");
});
$(function () {
$("#progressbar").progressbar({
value: 0,
max: 100
});
});
});
function addCheckbox(name) {
var container = $('#cblist');
var inputs = container.find('input');
var id = inputs.length + 1;
$('<input />', {
type: 'checkbox',
id: 'cb' + id,
value: name
}).appendTo(container);
$('<label />', {
'for': 'cb' + id,
text: name
}).appendTo(container);
$('<br/>').appendTo(container);
}
Please HELP !!!!

You need to add a Handler to the page to determine when a Checkbox has been checked / unchecked.
To do this you can use a delegate event handler, or assign the Event handler manually when you create the checkbox.
This first example is showing you using the Delegated Event Handler :
JSFiddle
Code :
$(document).ready(function() {
$('#btnSaveCheckBox').click(function() {
addCheckbox($('#checkBoxName').val());
$('#checkBoxName').val("");
});
$(document).on('change', 'input[type="checkbox"]', updateProgress);
$("#progressbar").progressbar({
value: 0,
max: 100
});
});
function updateProgress() {
var numAll = $('input[type="checkbox"]').length;
var numChecked = $('input[type="checkbox"]:checked').length;
if (numAll > 0) {
var perc = (numChecked / numAll) * 100;
$("#progressbar").progressbar("value", perc);
}
}
function addCheckbox(name) {
var container = $('#cblist');
var inputs = container.find('input');
var id = inputs.length+1;
$('<input />', { type: 'checkbox', id: 'cb'+id, value: name }).appendTo(container);
$('<label />', { 'for': 'cb'+id, text: name }).appendTo(container);
$('<br/>').appendTo(container);
updateProgress();
}
The changes made to your code are the addition of the updateProgress(); function, which looks for all the Checkboxes on the page and determines the percentage of them that have been checked, it will then update the Progress bar with this value.
Also the call to the updateProgress function at the end of your addCheckbox function, to re-calculate the percentage done when new elements are added.
And the following line of code in the Document.Ready handler :
$(document).on('change', 'input[type="checkbox"]', updateProgress);
This line of code creates a Delegate event handler to monitor all checkboxes on the page, and any that may be added in future to determine when they have been changed, and when they have it will execute the updateProgress function.
By Manually Assigning Event Handler on Creation :
If you don't want to use a Delegated event handler and want to use a direct event handler, you can do the following.
Change the line that creates the checkbox in your addCheckbox function to the following :
$('<input />', { type: 'checkbox', id: 'cb'+id, value: name }).appendTo(container).change(updateProgress);
This adds an event handler to the change event of the element and calls the updateProgress function.
To display the Value on the Progress bar : See this answer
Basically when you set the value of the Progress bar (in the updateProgress function) change the line to be the following :
$("#progressbar").progressbar("value", perc)
.children('.ui-progressbar-value')
.html(perc.toPrecision(3) + '%')
.css("display", "block");
This will then display the value in the progress bar. You can format the text using the following CSS :
.ui-progressbar-value {
font-size: 13px;
font-weight: normal;
line-height: 18px;
text-align:center;
}

check this fiddle:
UPDATED
http://jsfiddle.net/KAALv/8/
to increment progressbar use these code:
var val = $("#progressbar").progressbar( "value" ) || 0;
$("#progressbar").progressbar( "value", val + 5 );
UPDATE Also use this to give percentage value to a textbox..
$("#progressbar").progressbar({
value: 0,
max: 100,
change: function() {
$("#txtProgressbarStatus").text( $("#progressbar").progressbar( "value" ) + "%" );
},
});

Related

Change listener in a loop - only first one works

I have built a form and there is a part where there is an "add row" button which adds another row of inputs (if the user needs it).
However on this row there is a select input that needs a change handler. So what I have done, is every time the button to add a new row is clicked, each of the select inputs (which have the same name attribute) are given a unique id like so
let creditorInputs = $('select[name="creditors"]');
console.log(creditorInputs);
creditorInputs.map(i => {
$(creditorInputs[i]).attr('id', `creditorSelect${i}`);
This gives them an id of "creditorSelect0, creditorSelect1" etc
But further down the loop I have added a change listener and when I click on the select input an change its value, it only seems to affect the first one on the page.
Here is the full script:
$('#addrowothermort').click(() => {
let creditorInputs = $('select[name="creditors"]');
console.log(creditorInputs);
creditorInputs.map(i => {
$(creditorInputs[i]).attr('id', `creditorSelect${i}`);
$(`#creditorSelect${i}`).change(() => {
console.log("Changed");
});
});
});
EDIT:
$('#tabs-6').click(event => {
event.preventDefault();
if(event.target.name == 'creditors') {
let rightInput = event.target;
rightInput.addEventListener('change', () => {
console.log(rightInput.value);
})
}
})
embeding event to each select in a loop will attach again and the again the event ,
so wether using event delegation outside the loop , or attach event to dreclyt created input withot loop ,
What a suggest is bit changing the logic , create function that creates input and
and embed the click to it , after that calculate the number of creator input and set the id for the newly create depending on number of inputs .
See below snipet :
var arr = [{
val: 1,
text: 'One'
},
{
val: 2,
text: 'Two'
},
{
val: 3,
text: 'Three'
}
];
function createSelect(arr) {
var select = $('<select>').appendTo('#container');
$(arr).each(function() {
select.append($("<option>").attr('value', this.val).text(this.text));
});
return select;
}
$('#addrowothermort').click(() => {
let $select = createSelect(arr);
$select.attr("name", "creditors");
let selectLength = $('select[name="creditors"]').length - 1 | 0;
$select.attr("name", "creditors");
$select.attr("id", selectLength);
$select.on("change", function() {
console.log("Change in ", $(this).attr("id"));
});
});
select {
margin: 5px 20px 0px 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="addrowothermort">add row </button>
<div id="container"></div>

Fire an event when user move to next input field or release input field

This code is in foreach loop of php
$('input[name="<?=$value?>"]').on('change',function(){
spanval = $(".formscore").text();
width = $(".formProgressbar").width() / $('.formProgressbar').parent().width() * 100;
width = Math.round(width);
var currentval = $(this).val();
if(currentval != ''){
$(".formscore").text(parseInt(spanval) + <?=$sql123->score?> + '%' )
$(".formProgressbar").width(parseInt(width) + <?=$sql123->score?> + '%' )
}else{
$(".formscore").text(parseInt(spanval) - <?=$sql123->score?> + '%' )
$(".formProgressbar").width(parseInt(width) - <?=$sql123->score?> + '%' )
}
});
this code changes progress-bar as input field changes.
now the problem is that It changes every time when field is changed.
I tried Following Handler of jquery
change
blur
keyup
keydown
focusout/in
I want to Fire an event when user move to next input field or release input field. I am open to any other suggestions.
If you're trying to add event listener to dynamically generated element, instead of
$('input').on(event, function(e){
// won't work for dynamically generated element
});
you should use next code:
$('form').on(event, 'input', function(e){
// will work for dynamically generated element
});
This code is for next html:
<form>
<input type="text" name="">
</form>
Where input is dynamically generated element, event is your event (change, blur, etc.)
$('input[name="<?=$value?>"]').on('blur',function(e){
//Do something
});
You should probably add a class to your input when the user triggers the blur event. Then use this class to block the next trigger of the event.
(You can also use jQuery's .data () method instead of a class)
Or better, use an each loop triggered by the blur event to count all inputs filled to increase or decrease the progress bar.
See JS fiddle example
var total = $('input').length
$('input').on('blur', function() {
var counter = 0;
$('input').each(function() {
if($(this).val()) {
counter += 1;
}
})
console.log('Progress : '+counter+'/'+total+'. Percent : ' + (counter*100/total)+ '%')
})

domConstruct place button not firing

I am creating table rows dynamically using dojo domConstruct. One of the column contains a button for delete function.But i dont know how to connect onclick event for the delete button. Below is my js code for creating the row.
domConstruct.place("<tr class='test'><td>" +
" Account name"+ XXXX+" "+" Account number is is $" + data1 +
"</td><td><input type ='button' onclick='deleteFunction(this);' value='remove' id=" +
buttonId + "/></td></tr>","tradeInValue","");
So now how i connect it to
on(dom.byId("buttonId"),"click",function(){
// my code goes in here
});
I have no clue here. Basically i need to remove the row from a table on click of a button.
I am using dojo in javascript file.
Updated.
o
n(dom.byId("submitButton"), "click", function(evt){
var name=registry.byId("name").get('value');
var detail = registry.byId("manufacturer").get('value');
var id=registry.byId("model").get('value');
var make=registry.byId("shaft").get('value');
var xhrArgs={
url:"./name/getValue",
content:{name:name,detail:detail,id:id,make:make},
handleAs:"json",
load:function(data){
var data1=data/100;
var row=domConstruct.create("tr",null,"tradeInValue");
domConstruct.create("td",{innerHTML:" Name
"+ detail+" "+id+" Value is $"+data1},row);
var actions=domConstruct.create("td",null,row);
var btn=domConstruct.create("input",{
id:idRow,
type:"button",
value:"Remove"
},actions);
btn.addEventListener("click", function(evt) {
console.log("Deleting");
console.log(evt.target.parentNode.parentNode.idRow);
domConstruct.destroy(evt.target.parentNode.parentNode);
});
var test={
"name" : name,
"detail" : detail,
"id" :id,
"tradePrice" :data,
"make":make
};
tradeDetails.clubDetails.push(test);
}
}
var deferred=dojo.xhrPost(xhrArgs);
}
});
The easiest way is to create your DOM nodes individually, for example:
var row = domConstruct.create("tr", null, "myData");
domConstruct.create("td", { innerHTML: person.id }, row);
domConstruct.create("td", { innerHTML: person.name }, row);
var actions = domConstruct.create("td", null, row);
var btn = domConstruct.create("input", {
type: "button",
value: "Remove"
}, actions);
This allows you to easily attach event handlers to btn, while still preserving context and still having access to the data you're working with, for example:
btn.addEventListener("click", function() {
console.log("Deleting", person);
});
To delete the row itself you could use the Event.target property, which gives you access to the button node itself. If you use the Node.parentNode property, you can eventually access the row itself, and then you can remove it using dojo/dom-construct::destroy()
For example:
btn.addEventListener("click", function(evt) {
domConstruct.destroy(evt.target.parentNode.parentNode);
});
A full example can be found on JSFiddle.

Problems with click function in JQuery

When I add a comment, and hit the click-able text "Edit" the alert box doesn't pop up. First when I add the second comment, I'm able to hit the "edit" on the first one comment, and the alert box pop up.
Why that??
Live Demo
function addComment(name1) {
var container = $('#divComments');
var inputs = container.find('label');
var id = inputs.length + 1;
var div = $('<div />', {
class: 'CommentStyle'
});
$('<label />', {
id: 'comment' + id,
text: name1
}).appendTo(div);
var d = new Date();
var $fulaDate = $('<div class="floatleft">' + d.getFullYear() + "-" + monthNames[d.getMonth()] + "-" + d.getDate() + "T" + d.getHours() + ":" + d.getMinutes() + '</div>').appendTo(div);
var $edit = $('<p />', { class: 'edit', text: 'Edit' }).addClass('edit').appendTo(div);
$('.edit').click(function () {
alert('Hallo');
});
div.appendTo(container);
}
You need to use event delegation for dynamically created elements:
$('#divComments').on('click','.edit',function () {
alert('Hallo');
});
Also, as suggested by #Archer, you need to move the click handler outside of your function to avoid nested click events from firing multiple times.
Updated Fiddle
Problem with your implementation is that when you are attaching event like
var $edit = $('<p />', { class: 'edit', text: 'Edit' }).addClass('edit').appendTo(div);
$('.edit').click(function () {
alert('Hallo');
});
Edit element which you created just now is not added to DOM it is appeded to div only, which is not added to DOM. thus in short it doesn't exists in DOM, thus event is not binded with the button.
So to fix the issue instead of binding event to $('.edit') you need to bind event with $edit.
var $edit = $('<p />', { class: 'edit', text: 'Edit' }).appendTo(div);
$edit.click(function () {
alert('Hallo');
});
DEMO
However I would recommend you to use Event Delegation as
Event delegation allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future.
Code
function addComment(name1) {
}
$('#divComments').on('click', '.edit', function () {
alert('Hallo');
});
DEMO with event delegation

Suppressing a Kendo UI Grid selectable event when clicking a link within a cell

I have a Kendo grid that has links, which I also set to selectable, snippet here:
columns: [{
field: 'link', title: 'Link',
template: 'Click Here'
}],
...
selectable: 'row',
change: function(e) {
var rowUid = this.select().data('uid');
rowDs = this.dataSource.getByUid(rowUid);
console.log('Went (1): ' + rowDs);
return false;
}
When I click on the external link <a>, I also select the row. Is there any way to suppress the selectable event?
You can also detect what element triggered the click by giving the column a CSS class. Then you would put an if-statement in the change event to detect if the column was clicked or not:
columns: [
{
title: ' ',
command: {
text: 'My Button',
click: function (e) {
e.preventDefault();
//GET SELECTED DATA
var data = this.dataItem($(e.currentTarget).closest('tr'));
//DO SOMETHING
}
},
attributes: {
'class': 'actions'
}
}
]
Then in the change you would have this:
change: function (e) {
//GET TRIGGER SOURCE TO DETERMINE IF ACTION CLICKED
var eventTarget = (event.target) ? $(event.target) : $(event.srcElement);
var isAction = eventTarget.parent().hasClass('actions');
//SELECT ITEM IF APPLICABLE
if (!isAction) {
var grid = e.sender;
var dataItem = grid.dataItem(this.select());
if (dataItem) {
//DO SOMETHING
}
}
}
I just stumbled across a forum post by a Kendo UI dev stating that "the selection of the grid cannot be prevented" (link). I guess that means I will have to work around this.
Edit: I actually just want to get the row's uid attribute so I can select the selected dataItem from the dataSource. I've discovered that you can get it while you're defining your columns template,
columns: [{
field: 'link', title: 'Link',
template: 'Manual Edit Link'
}],
And use it to retrieve the selected row's dataItem.
var selectedRow = $('#gridId').data('kendoGrid').dataSource.getByUid(rowUid);
Will close this question in a while, in case anyone else can help.

Categories

Resources