Shift + Click to Select a Range of Checkboxes - javascript

I have large tables being generated and each row has a checkbox, class "chcktbl".
In the table header, there is a Select All checkbox, class "chckHead".
The select/deselect all function works fine, as does the count of selected charts I have displayed in the table heading.
The function to enable shift+click capability to select a range of checkboxes also works, but in its current format, only selects 10 checkboxes before generating an error message in a popup window:
"Stop running this script? A script on this page is causing your web browser to run slowly. If it continues to run, your computer might become unresponsive."
<script type=text/javascript>
//select all button
$('#chckHead').click(function() {
if (this.checked === false) {
$('.chcktbl:checked').attr('checked', false);
}
else {
$('.chcktbl:not(:checked)').attr('checked', true);
}
countSelected();
});
//count number of boxes checked
function countSelected() {
var numCharts = $('input.chcktbl:checked').length;
$('#numCharts').html(numCharts);
}
//SHIFT+Click to select a range of checkboxes:
// this variable stores the most recently clicked checkbox
// it is used for shift-clicks
var lastClickedBox = 0;
// the checkbox functionality is default to the browser
$('.chcktbl').click(function(event) {
var clickedBox = $('.chcktbl').index(event.target);
if(event.shiftKey) {
setCheckboxes(lastClickedBox, clickedBox);
};
lastClickedBox = clickedBox;
countSelected();
});
// sets all the checkboxes between the specified indices to true
function setCheckboxes(end, start) {
if(start > end) {
var temp = start;
start = end;
end = temp;
};
for(var i = start; i < end; i++) {
$('.chcktbl').eq(i).prop('checked', true);
};
countSelected();
};
</script>
This is a really common feature for selecting a range of items with one click, but I can't find an efficient way to do it. If anyone knows a better way of approaching this or can spot some inefficiency in the code then please let me know.

How about using jquery nextUntil?
I didn't actually test this but this should give you the basic idea and it removes the for loop. I created similar functionality to this before using nextUntil/prevUntil and never got an unresponsive page.
function setCheckboxes(end, start) {
if(start > end) {
var temp = start;
start = end;
end = temp;
};
$('.chcktbl').eq(start).nextUntil(':eq('+(end+1)+')').add().prop('checked', true);
countSelected();
};

I tried you code and it worked well for me. You might want to try this jquery plugin
https://gist.github.com/DelvarWorld/3784055

Related

HTML/Javascript keypad function isn't working

I am making a page for a school project, and I am trying to make a keypad for a passcode system. However, I don't know how to get the keys to work. Looking it up, I have found multiple working keypads, however, I don't know what parts of their code I would have to add to my page to make it work.
The code that follows is currently what I have attached to the onclick part of each of the buttons:
<script>
function kpclick(){
var current = document.getElementById("tbInput").value;
var append = this.innerHTML;
if (current.length < 4) {
if (current=="0") {
document.getElementById("tbInput").value = append;
} else {
document.getElementById("tbInput").value += append;
}
}
}
</script>
The "tbInput" mentioned is a textbox underneath the keypad in the same div that later will be hidden and (hopefully) disabled. If there is no solution that allows the keypad to be used while the textbox is disabled, I will likely move it outside of the div the keypad is in.
When I press any of the buttons currently, nothing happens. What's happening here?
I'm assuming this is meant to be the button context. You can pass it with onclick="kpclick(this)".
function kpclick(target) {
var current = document.getElementById("tbInput").value;
var append = target.innerHTML;
if (current.length < 4) {
if (current == "0") {
document.getElementById("tbInput").value = append;
} else {
document.getElementById("tbInput").value += append;
}
}
}
<button onclick="kpclick(this)">0</button>
<button onclick="kpclick(this)">1</button>
<input id="tbInput">

Ext setLoading(true,true) being called too late?

I have a grid with a good amount of data which the user can filter or show/hide groups of columns by using combo boxes. Some of the column switches take a long time to load and I want to call setLoading(true,true) on the grid or the combobox to show the user that the browser is working.
I have a listener function that is called when the user makes a selection on the combo box. I call combo.setLoading(true,true) before starting any of the code that takes a while to execute. Then I call combo.setLoading(false,false) at the very bottom of the function.
The loading only shows up for a split second after the code between the two setLoading calls has executed. If I take out the call to remove the loading icon, the icon still only shows up after the code is executed.
Anyone have an idea what is happening? This seems very odd to me.
categorycomboselect: function(combo, records){
combo.setLoading(true,true);
var panel = combo.up('panel');
console.log(panel);
var category = records[0].data.name;
var grid = Ext.ComponentQuery.query('grid')[1];
Ext.suspendLayouts();
grid.suspendedLayout=true;
var columns = grid.columns;//.getView().getGridColumns();
//slow code that shows/hides columns
grid.suspendedLayout=false;
Ext.resumeLayouts(true);
combo.setLoading(false,false);
},
UPDATE
Here is my code with Trimboli's suggestion, it still isn't working. I'm showing/hiding the columns based on a string in their ID. I did it this way because the categories I want to show/hide the columns on are dynamic and the columns are dynamic.
categorycomboselect: function(combo, records){
combo.setLoading(true,true);
setTimeout( function(){
var panel = combo.up('panel');
var category = records[0].data.name;
var grid = Ext.ComponentQuery.query('grid')[1];
Ext.suspendLayouts();
grid.suspendedLayout=true;
var columns = grid.columns;
if(category=='All grade items'){
for(var i = 0; i< columns.length; i++){
columns[i].setVisible(true);
}
}else{
for(var i = 0; i< columns.length; i++){
columns[i].hide();//setVisible(false);
if(!(typeof columns[i].itemId ==='undefined')){
if((columns[i].itemId).indexOf(category)>=0){
columns[i].show();
}
}
}
}
grid.suspendedLayout=false;
Ext.resumeLayouts(true);
combo.setLoading(false,false);
},1);
},
Also, I wasnt sure if
Ext.suspendLayouts();
grid.suspendedLayout=true;
do the same thing or not. And if not, which is better.
What you're essentially doing is this:
showMask();
for (i = 0; i < 10000000; ++i) {
// busy loop
}
hideMask();
If you show/hide a mask without giving the browser a "break" for it to update the DOM, you won't see anything because it all gets flushed out at the end once you relinquish control back to the browser.
If you wanted to let the mask actually show, you need to give a slight delay before continuing on with your busy loop:
showMask();
setTimeout(function() {
// Busy stuff
hideMask();
}, 1);

Calling a function when checking a checkbox, onclick event doesn't fire when unchecking

I should probably start by mentioning that I am using Internet Explorer 6. I am calling a JavaScript function (tabModifiedHighlight) from an onChange event. The function works perfectly other places however, I have a couple of places on the page where it works when I check the checkbox, but the event doesn't even seem to fire when I uncheck it.
Here is the JavaScript function:
function tabModifiedHighlight(){
alert("alert");
var div, i, input, inputIndex, selects, selectIndex, selectedTab, highlighted;
var tabs = new Array("admissioninformation","diet","vitalsigns","activities","nursing","ivfluids","medications1","medications2","labs","respiratory","diagnostic","consultations");
for(i=0; i<(tabs.length); i++){
selectedTab = tabs[i]+'tab';
if (document.getElementById(selectedTab).className == "selectedtab"){
div = document.getElementById(tabs[i]),
input = div.getElementsByTagName('input'),
selects = div.getElementsByTagName('select');
break;
}
}
highlighted = false;
for (inputIndex = 0; inputIndex < input.length; inputIndex++){
if (input[inputIndex].checked == true){
highlighted = true;
}
}
for (inputIndex = 0; inputIndex < input.length; inputIndex++){
if (input[inputIndex].type == 'text' && input[inputIndex].value != ""){
highlighted = true;
}
}
for (selectIndex = 0; selectIndex < selects.length; selectIndex++){
if (selects[selectIndex].value != ""){
highlighted = true;
}
}
if (highlighted == true){
document.getElementById(selectedTab).style.backgroundColor = "#FF0";
}
else {
document.getElementById(selectedTab).style.backgroundColor = "#F0F0F0";
}
}
And here is the input that is calling it:
<input name="cbMedTylenolPO" id="cbMedTylenolPO" type="checkbox" value="PO" onClick="tylenolPoShowHide(); checkBoxHighlight(this, 'MedicationsRow2'); tabModifiedHighlight();" />
This page has multiple "tabs" which are just divs that are set to visible or hidden based on which one is selected. It seems consistent in that it works everywhere except for 2 of the tabs, and nowhere on those tabs. The only other difference I can see is that the ones that are not working are also showing or hiding divs within the tab, based on whether the checkbox is checked or not. I have added the alert at the very beginning of the function to see if it is firing or not, and it does when checking the checkbox, but not when unchecking.
I hope I made this clear, and any thoughts are appreciated!
As your code is not working only for two tabs, and working for all others its not an browser compatibility issue.
onClick if checkbox you are calling these 3 methods
tylenolPoShowHide(); checkBoxHighlight(this, 'MedicationsRow2');tabModifiedHighlight()
Note tabModifiedHighlight is last one..
if any of first two methods tylenolPoShowHide or checkBoxHighlight fails... then tabModifiedHighlight will not be called.
I will suggest to add alert as first and last line in both tylenolPoShowHide and checkBoxHighlight ...
It will help you find which one is actually failing then you can add that code here and we will be able to help you further

looping through elements in jquery

I've got a page with bunch of drop downs and each drop down has a button next to it. When the page initially loads I want all the buttons to be disabled and if there is a change to a specific drop down then its corresponding button shall be enabled.
I've got the following code down for this but I need to know how to loop through all the drop downs and buttons so I can generalize it.
$(document).ready(function () {
//disable all buttons
function disableAllButtons () {
$(':input[type=button]').attr("disabled", "true");
}
disableAllButtons();
//enable button when drop down changes
$(':input[name=sNewPKvalue1]').focus(function() {
disableAllButtons();
$(':input[name=Update0]').removeAttr("disabled");
})
//enable button when drop down changes
$(':input[name=sNewPKvalue2]').focus(function() {
disableAllButtons();
$(':input[name=Update1]').removeAttr("disabled");
})
////.....question?
});
Question
If I have 12 dropdowns and 12 buttons
How do I loop through all the drop downs with name sNewPKvalue[1-12] and all the buttons with name Update[0-11]
I would not recommend a loop. Just use a selector that selects the elements you want and perform the appropriate action. My first thought is to assign a CSS class to the buttons and drop down lists you are talking about. Then you can simply do something like this:
$('.dropDown').focus(function(){
$(".ddlButton").attr("disabled", "true");
$(this).closest('.ddlButton').removeAttr("disabled");
});
I would do something like:
$.each([1, 12], function(index, value) {
var valmin = val - 1;
$(':input[name=sNewPKvalue'+value+']').focus(function() {
disableAllButtons();
$(':input[name=Update'+valmin+']').removeAttr("disabled");
})
});
I didn't test this one, but you should get the idea ;)
You can do it that way.
for (var i = 0; i < 12; i++)
{
$(':input[name=sNewPKvalue'+(i+1)+']').focus(function() {
disableAllButtons();
$(':input[name=Update'+i+']').removeAttr("disabled");
})
}
Or
$(':input[name^=sNewPKvalue]').focus(function() {
disableAllButtons();
$(':input[name=Update'+(Number(this.name.match(/[0-9]+/))-1)+']').removeAttr("disabled");
})
What you could do is to make a for loop.
for(var i = 1; i <= 12; i++) {
$("select[name='sNewPKvalue"+i+"']").doSomething();
}
for(var i = 1; i <= 11; i++) {
$(":button[name='Update"+i+"']").doSomething();
}

jQuery submit form IF

Hey guys,
I have this great scripts someone on stack overflow helped me out with, except the one major function I need is missing.
This is a game where the user picks a number (by entering that number in a text field) then hits a play button. After they hit the play button a series of numbers will appear, they then have to click on the number that matches their number.
The query script I'm using counts how many times they hit the number and how many times they missed the number. Take a look at the script in action here. link text
now what I need it to do, is send the score (hits and misses ) to a database after 3 misses, so I can keep high score. Any ideas? Here's the script.
var hitCount = 0,
missCount = 0;
function IsNumeric(n) {
return !isNaN(n);
}
$("#getit").click(function() {
var li = [],
intervals = 0,
n = parseInt($('#MyNumber').val());
if (IsNumeric(n)) {
setInterval(function() {
li[intervals++ % li.length].text(Math.random() > .1 ? Math.floor(Math.random() * (10 + n) + (n / 2)) : n).attr('class', '');
}, <?php echo $time ?>);
}
$('#randomnumber').empty();
for (var i = 0; i < 5; i++) {
li.push($('<li />').click(function() {
var $this = $(this);
if (!$this.hasClass('clicked')) {
if (parseInt($this.text(), 10) === n) {
$this.addClass('correct');
$('#hitcount').text(++hitCount);
} else {
$this.addClass('wrong');
$('#misscount').text(++missCount);
}
}
$this.addClass('clicked');
}).appendTo('#randomnumber'));
}
return false;
});
I've updated your problem here.
After updating the status Check for the missCount if it is greater than or equal to 3 then stop the play(clear the interval and unbind the event), then save the value using an ajax request.
I've changed the event handling to use event delegation instead of direct click event on the <li> elements. Event delegation is better in cases where there are lot of elements to which we have to bind a particular event.
I updated your fiddle with the solution. Check http://jsfiddle.net/DHPQT/2/.
I marked all the new stuff with a comment in the form of
//new ....
The main thing to do is checking after
$('#misscount').text(++missCount);
if missCount is 3 and if yes stop the game and send something

Categories

Resources