spit items into different arrays and retrieving it back - javascript

this related to my previous question asked and thanks to every one here who is helping me to learn coding :D
i was previously working on an undo button which kind of works but not there yet :(
here is what i have done click here. But the problem is since it goes step by step backwards it has to wait till the item where the previous color was applied in the same part. Is there a way i can split something like this click here will this idea work out?
here is the test html code:
<div id="colour">
<input type="submit" name="r1" id="r1" value="1" />
<input type="submit" name="r2" id="r2" value="2" />
<input type="submit" name="r3" id="r3" value="3" />
<input type="submit" name="r4" id="r4" value="4" />
<input type="submit" name="r5" id="r5" value="5" />
<input type="submit" name="r6" id="r6" value="6" />
</div>
<div id="map">
<input type="radio" name="radio" id="layer_a" value="a" />
<label for="layer">layer_a</label>
<input type="radio" name="radio" id="layer_b" value="b" />
<label for="layer">layer_b</label>
<input type="radio" name="radio" id="layer_c" value="c" />
<label for="layer">layer_c</label>
<input type="radio" name="radio" id="layer_d" value="d" />
<label for="layer">layer_d</label>
</div>
<input name="selected" id="selected" type="hidden" value="" />
<input type="submit" name="undo" id="undo" value="undo" />
<div id="result"></div>
here is the test jQuery code:
$("#colour input").click(function() {
$("input[name='selected']").val(this.id);
});
var arraymap = [];
var array_a = [];
var array_b = [];
var array_c = [];
var array_d = [];
$("#map input").click(function() {
var mape = $(this).attr('id');
var ccurrent = $("input[name='selected']").val();
arraymap.push(mape);
// trying to split it into diffrent arrays //
if (mape == "layer_a") {
array_a.push(ccurrent);
var araycurrent = array_a;
} else if (mape == "layer_b") {
array_b.push(ccurrent);
var araycurrent = array_b;
} else if (mape == "layer_c") {
array_c.push(ccurrent);
var araycurrent = array_c;
} else if (mape == "layer_d") {
array_d.push(ccurrent);
var araycurrent = array_d;
};
var mapid = arraymap[arraymap.length - 1];
var colid = arraycurrent[arraycurrent.length - 1];
var loca = mapid + colid;
$("#result").append(mapid);
});
$("#undo").click(function() {
arraymap.pop();
var remover_map = arraymap[arraymap.length - 1];
// trying get it back from split arrays //
if (remover_map == "layer_a") {
array_a.pop();
var remover_col = array_a[array_a.length - 1];
} else if (remover_map == "layer_b") {
array_b.pop();
var remover_col = array_b[array_b.length - 1];
} else if (remover_map == "layer_c") {
array_c.pop();
var remover_col = array_b[array_c.length - 1];
} else if (remover_map == "layer_d") {
array_d.pop();
var remover_col = array_a[array_d.length - 1];
};
var remove = remover_map + remover_col;
$("#result").append(remove);
});

You can store you layer arrays in an object to use it as an associative array. That way you can easily reference them by the layer name.
Here's my version of your example: (Working demo: http://jsfiddle.net/qbdyp/)
var step_layer = []; // layers affected by each step
var step_colour = { // selected colours by layer
"a": [],
"b": [],
"c": [],
"d": []
};
var $map = $("#map"), $result = $("#result"); // cache
$("#colour > input").click(function() {
var layer = $map.find("input[name='radio']:checked").val(); // current layer
var colour = this.value; // selected colour
step_layer.push(layer);
step_colour[layer].push(colour);
$result.append("Added " + colour + " to layer " + layer + "<br/>");
});
$("#undo").click(function() {
var layer = step_layer.pop(); // get most recently changed layer
if (typeof layer === "undefined") {
$result.append("(Nothing to undo)<br />");
return;
}
var colour = step_colour[layer].pop(); // get latest change in that layer
$result.append("Removed " + colour + " from layer " + layer + "<br/>");
});
And here's a more elaborate example, one that's hopefully closer to what you're trying to achieve: http://jsfiddle.net/uWUve/

Related

How to show values from a .js file previously executed from a webpage to another webpage?

This is the webpage that will execute calculations in JS there are other personalityType I just didn't include them
<div class="question">
<div>40. It is easy for me to identify how I feel and why. </div>
<div> <input class="radiobutton" type="radio" name="m40" value="0" personalityType="intrapersonal"> Never <input class="radiobutton" type="radio" name="m40" value="1" personalityType="intrapersonal"> Rarely <input
class="radiobutton" type="radio" name="m40" value="2" personalityType="intrapersonal"> Often
<input class="radiobutton" type="radio" name="m40" value="3" personalityType="intrapersonal"> Always
</div>
<div class="question">
<div>35. English is/was one of my favorite subjects in school. </div>
<div> <input class="radiobutton" type="radio" name="m35" value="0" personalityType="verbal"> Never <input class="radiobutton" type="radio" name="m35" value="1" personalityType="verbal"> Rarely <input class="radiobutton"
type="radio" name="m35" value="2" personalityType="verbal">
Often
<input class="radiobutton" type="radio" name="m35" value="3" personalityType="verbal"> Always
</div>
<div>
<a class="myButton" onclick=calculateScores() href=results.html>Get Results</a>
</div>
This is the .js
var bodilyScore = 0;
var mathematicalScore = 0;
var naturalistScore = 0;
var interpersonalScore = 0;
var visualScore = 0;
var verbalScore = 0;
var intrapersonalScore = 0;
var musicalScore = 0;
function calculateScores() {
var button = document.getElementsByClassName("radiobutton");
var buttonLength = button.length;
musicalScore = 0;
bodilyScore = 0;
mathematicalScore = 0;
naturalistScore = 0;
interpersonalScore = 0;
visualScore = 0;
verbalScore = 0;
intrapersonalScore = 0;
for (var i = 0; i < buttonLength; i++) {
if (button[i].type === 'radio' && button[i].checked) {
var value = Number(button[i].value);
var type = button[i].getAttribute("personalityType");
switch (type) {
case "musical":
musicalScore += value;
break;
case "bodily":
bodilyScore += value;
break;
case "mathematical":
mathematicalScore += value;
break;
case "naturalist":
naturalistScore += value;
break;
case "interpersonal":
interpersonalScore += value;
break;
case "visual":
visualScore += value;
break;
case "verbal":
verbalScore += value;
break;
case "intrapersonal":
intrapersonalScore += value;
break;
}
}
}
showResults();
}
function showResults() {
console.log(musicalScore);
console.log(bodilyScore);
console.log(mathematicalScore);
console.log(naturalistScore);
console.log(interpersonalScore);
console.log(visualScore);
console.log(verbalScore);
console.log(intrapersonalScore);
document.getElementById('musicalResult').innerText = musicalScore;
document.getElementById('bodilyResult').innerText = bodilyScore;
document.getElementById('naturalistResult').innerText = naturalistScore;
document.getElementById('interpersonalResult').innerText = interpersonalScore;
document.getElementById('visualResult').innerText = visualScore;
document.getElementById('intrapersonalResult').innerText = intrapersonalScore;
document.getElementById('verbalResult').innerText = verbalScore;
document.getElementById('mathematicalResult').innerText = mathematicalScore;
}
I wanted to get the value of the 3 highest scores among musicalScore, verbalScore, etc.). after clicking the "Get Results" button and display it on another webpage. How could I also attach a text to the Score with the highest value to be displayed also?
If you want to pass your result to another page you can store them in LocalStorage.
highestResults = {mathematicalScore: 4, naturalistScore: 6, verbalScore: 5};
localStorage.setItem('calculationResults', highestResults);
And on result page.
localStorage.getItem('calculationResults');
If you want to add text to highest result:
document.getElementById('mathematicalResult').innerText = mathematicalScore + ' - highest result';

can't add elements from form, using getElementByID

I can't seem to get my JavaScript to add the elements from my HTML page. Do I have a syntax error?
var mondayHours = document.getElementById("mondayHours").value;
var tuesdayHours = document.getElementById("tuesdayHours").value;
var wednesdayHours = document.getElementById("wednesdayHours").value;
var thursdayHours = document.getElementById("thursdayHours").value;
var fridayHours = document.getElementById("fridayHours").value;
var saturdayHours = document.getElementById("saturdayHours").value;
var sundayHours = document.getElementById("sundayHours").value;
var totalHours = mondayHours + tuesdayHours + wednesdayHours + thursdayHours + fridayHours + saturdayHours + sundayHours;
function alertHours() {
alert(totalHours);
}
<fieldset>
<p>Hours of Operation</p>
<p>
<label for="mondayHours">Monday
<input name="mondayHours" type="number" id="mondayHours" />
</label>
</p>
<p>
<label for="tuesdayHours">Tuesday
<input name="tuesdayHours" type="number" id="tuesdayHours" />
</label>
</p>
<p>
<label for="wednesdayHours">Wednesday
<input name="wednesdayHours" type="number" id="wednesdayHours" />
</label>
</p>
<p>
<label for="thursdayHours">Thursday
<input name="thursdayHours" type="number" id="thursdayHours" />
</label>
</p>
<p>
<label for="fridayHours">Friday
<input name="fridayHours" type="number" id="fridayHours" />
</label>
</p>
<p>
<label for="saturdayHours">Saturday
<input name="saturdayHours" type="number" id="saturdayHours" />
</label>
</p>
<p>
<label for="sundayHours">Sunday
<input name="sundayHours" type="number" id="sundayHours" />
</label>
</p>
</fieldset>
<input name="Calculate" type="submit" value="submit" onclick="alertHours()" />
<script src="Calculator_script.js"></script>
You have to retrieve form data when you called your alertHours function.
The problem was that you retrieved form data at the beginning, and these data were undefined.
JS
function alertHours(){
var mondayHours = parseFloat(document.getElementById("mondayHours").value) || 0;
var tuesdayHours = parseFloat(document.getElementById("tuesdayHours").value) || 0;
var wednesdayHours = parseFloat(document.getElementById("wednesdayHours").value) || 0;
var thursdayHours = parseFloat(document.getElementById("thursdayHours").value ) || 0;
var fridayHours = parseFloat(document.getElementById("fridayHours").value) || 0;
var saturdayHours = parseFloat(document.getElementById("saturdayHours").value ) || 0;
var sundayHours = parseFloat(document.getElementById("sundayHours").value) || 0;
var totalHours = mondayHours + tuesdayHours + wednesdayHours + thursdayHours + fridayHours + saturdayHours + sundayHours;
alert(totalHours)
}
When you see parseFloat(...) || 0, this tell : ok if an input is empty, i will set the 0 value for this input.
You are grabbing the values on page load and storing those in variables. Since at that time, they are valueless, you aren't getting your expected result. I would recommend the following option...
var mondayHours = document.getElementById("mondayHours");
var tuesdayHours = document.getElementById("tuesdayHours");
var wednesdayHours = document.getElementById("wednesdayHours");
var thursdayHours = document.getElementById("thursdayHours");
var fridayHours = document.getElementById("fridayHours");
var saturdayHours = document.getElementById("saturdayHours");
var sundayHours = document.getElementById("sundayHours");
function alertHours() {
var totalHours = mondayHours.value + tuesdayHours.value + wednesdayHours.value + thursdayHours.value + fridayHours.value + saturdayHours.value + sundayHours.value;
alert(totalHours);
}
This way you are getting the values of the inputs at the time the function is invoked, and not the time that the page was loaded. And scoping the getElementById outside of the alertHours function still gives you access to those elements should you need to use them somewhere else in code. There are more clever/eloquent ways to do this still, but this should work.

changing HTML form with javascript

I can't figure out how the size of the form can be determined with javascript, and how to change it. I've tried element.style.width but that isn't doing it either for reading or writing. I don't know what I'm looking for in the debugger either.
I need to change the width of the form depending on the length of the text in the newNameNode text node.
Thanks very much for any help.
Gerard
Here's my code -
<form name="Q1" autocomplete="off">
<fieldset>
<legend>1</legend>
Ludwig Van Beethoven<br />
<input type="radio" name="Q1" value="1756-1819"><span>1756-1819</span><br>
<input type="radio" name="Q1" value="1770-1827,Beethoven,correct"><span> 1770-1827</span><br />
<input type="radio" name="Q1" value="1815-1858"><span> 1815-1858</span><br />
<input type="radio" name="Q1" value="1832-1870"><span> 1832-1870</span>
</fieldset>
</form>
<script >
function buildForm() {
var newForm = document.createElement('form');
newForm.name = "Q1";
newForm.autocomplete = "off";
var newFieldset = document.createElement('fieldset');
var newNameNode = document.createTextNode('new text');
var br = document.createElement('br');
var newRadio = document.createElement('input');
newRadio.type = 'radio';
newRadio.name = 'Q1';
newRadio.value = "new value";
var dates ="1770-1827";
var newDateSpan = document.createElement('span');
newDateSpan.innerHTML = " " + dates + "<br />";
console.log("newSpan.innerHTML: " + newDateSpan.innerHTML); //!!
var newLegend = document.createElement('legend');
newLegend.innerHTML = newRadio.name;
newFieldset.appendChild(newLegend);
newFieldset.appendChild(newNameNode);
newFieldset.appendChild(br);
newFieldset.appendChild(newRadio);
newFieldset.appendChild(newDateSpan);
newForm.appendChild(newFieldset);
document.body.appendChild(newForm);
}
buildForm();
</script></body>
</html>
To determine the height/width, what you're looking for is Element.scrollHeight or Element.scrollWidth
You can set the width from the CSS (this is the better option), or by DOM manipulation in Javascript, as follows:
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].style.width = 250 + 'px';//sets the width of all forms to 250px
}

Match values of radio button selections to array

I have a few radio button groups, depending on which radio button is selected in each group, that particular answer needs to return 1 or more values which are preset in an array.
So, if 1 is selected in group 1, A & B values both increment by 1, If 2 is selected B, C & D increment and so on. At the end the letter with most points/increments should be returned (when the form is submitted)
How can I get going with this? I think the starting point is to return the selected radio buttons, match them to the correct array index, then check for the values in that array (letters) with the most increments and return it's value(s)?
$(function(){
var group1 = new Array();
group1[0] = "A, B";
group1[1] = "B, C, D";
group1[2] = "E, B";
group1[3] = "B";
group1[4] = "F";
var group2 = new Array();
group2[0] = "D, A";
group2[1] = "D, C";
group2[2] = "B, F, E";
group2[3] = "A";
group2[4] = "B, D";
$('form').submit(function(){
var checked = $('input:radio:checked').length;
//This is as far as I am
});
});
<form>
<input type="radio" name="group1" value="1" id="q1-1" /> 1
<input type="radio" name="group1" value="2" id="q1-2" /> 2
<input type="radio" name="group1" value="3" id="q1-3" /> 3
<input type="radio" name="group1" value="4" id="q1-4" /> 4
<input type="radio" name="group1" value="5" id="q1-5" /> 5
<br /><br />
<input type="radio" name="group2" value="1" id="q2-1" /> 1
<input type="radio" name="group2" value="2" id="q2-2" /> 2
<input type="radio" name="group2" value="3" id="q2-3" /> 3
<input type="radio" name="group2" value="4" id="q2-4" /> 4
<input type="radio" name="group2" value="5" id="q2-5" /> 5
<input type="submit" value="submit" />
</form>
Check with it will give you result as you created array so i used switch to select the values from array.
var temp=0;
var result = [];
var maxvalue = 0;
var topQualityjob = "";
$('input:radio:checked').each(function () {
switch ($(this).attr("name")) {
case "group1":
$(group1[parseInt($(this).val()) - 1].split(",")).each(function () {
result.push(this);
temp = getaccurance(result, this);
if (maxvalue < temp) {
maxvalue = temp;
topQualityjob = this;
}
});
break;
case "group2":
$(group2[parseInt($(this).val()) - 1].split(",")).each(function () {
result.push(this);
temp = getaccurance(result, this);
if (maxvalue < temp) {
maxvalue = temp;
topQualityjob = this;
}
});
break;
}
});
alert(topQualityjob);
}
function getaccurance(result, val) {
num = 0;
for (i = 0; i < result.length; i++) {
if (result[i] == val)
num++;
}
return num;
}
Hope this will give correct answer

How can I shift-select multiple checkboxes like GMail?

In GMail, the user can click on one checkbox in the email list, hold down the Shift key, and select a second checkbox. The JavaScript will then select/unselect the checkboxes that are between the two checboxes.
I am curious as to how this is done? Is this JQuery or some basic (or complex) JavaScript?
I wrote a self-contained demo that uses jquery:
$(document).ready(function() {
var $chkboxes = $('.chkbox');
var lastChecked = null;
$chkboxes.click(function(e) {
if (!lastChecked) {
lastChecked = this;
return;
}
if (e.shiftKey) {
var start = $chkboxes.index(this);
var end = $chkboxes.index(lastChecked);
$chkboxes.slice(Math.min(start,end), Math.max(start,end)+ 1).prop('checked', lastChecked.checked);
}
lastChecked = this;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
</head>
<body>
<input type="checkbox" id="id_chk1" class="chkbox" value="1" />Check 1<br/>
<input type="checkbox" id="id_chk2" class="chkbox" value="2" />Check 2<br/>
<input type="checkbox" id="id_chk3" class="chkbox" value="3" />Check 3<br/>
<input type="checkbox" id="id_chk4" class="chkbox" value="4" />Check 4<br/>
<input type="checkbox" id="id_chk5" class="chkbox" value="5" />Check 5<br/>
<input type="checkbox" id="id_chk6" class="chkbox" value="6" />Check 6<br/>
<input type="checkbox" id="id_chk7" class="chkbox" value="7" />Check 7<br/>
</body>
</html>
This is done through fairly simple javascript.
They keep track of the id of the last checked box and when when another checkbox is checked they use the shiftKey event attribute to see if shift was held while clicking the checkbox. If so they set the checked property of each checkbox in between the two to true.
To determine when a box is checked they probably use an onclick event on the checkboxes
It seems like every answer I can find online is completely dependent on jQuery for this. JQuery adds very little functionality. Here's a quick version that doesn't require any frameworks:
function allow_group_select_checkboxes(checkbox_wrapper_id){
var lastChecked = null;
var checkboxes = document.querySelectorAll('#'+checkbox_wrapper_id+' input[type="checkbox"]');
//I'm attaching an index attribute because it's easy, but you could do this other ways...
for (var i=0;i<checkboxes.length;i++){
checkboxes[i].setAttribute('data-index',i);
}
for (var i=0;i<checkboxes.length;i++){
checkboxes[i].addEventListener("click",function(e){
if(lastChecked && e.shiftKey) {
var i = parseInt(lastChecked.getAttribute('data-index'));
var j = parseInt(this.getAttribute('data-index'));
var check_or_uncheck = this.checked;
var low = i; var high=j;
if (i>j){
var low = j; var high=i;
}
for(var c=0;c<checkboxes.length;c++){
if (low <= c && c <=high){
checkboxes[c].checked = check_or_uncheck;
}
}
}
lastChecked = this;
});
}
}
And then initialize it whenever you need it:
allow_group_select_checkboxes('[id of a wrapper that contains the checkboxes]')
Recently, I wrote a jQuery plugin that provide that feature and more.
After including the plugin you just need to initialize the context of checkboxes with the following code snippet:
$('#table4').checkboxes({ range: true });
Here is the link to the documentation, demo & download: http://rmariuzzo.github.io/checkboxes.js/
Well, the post is quite old but here is a solution I've just come across:
jQuery Field Plug-In
I took the jQuery version from #BC. and transformed it into an ES6 version, since the code is actually pretty elegantly solving the problem, in case anyone still stumbles across this...
function enableGroupSelection( selector ) {
let lastChecked = null;
const checkboxes = Array.from( document.querySelectorAll( selector ) );
checkboxes.forEach( checkbox => checkbox.addEventListener( 'click', event => {
if ( !lastChecked ) {
lastChecked = checkbox;
return;
}
if ( event.shiftKey ) {
const start = checkboxes.indexOf( checkbox );
const end = checkboxes.indexOf( lastChecked );
checkboxes
.slice( Math.min( start, end ), Math.max( start, end ) + 1 )
.forEach( checkbox => checkbox.checked = lastChecked.checked );
}
lastChecked = checkbox;
} ) );
}
Got this solution from http://abcoder.com/javascript/jquery/simple-check-uncheck-all-jquery-function/ (now dead):
JavaScript and HTML code
var NUM_BOXES = 10;
// last checkbox the user clicked
var last = -1;
function check(event) {
// in IE, the event object is a property of the window object
// in Mozilla, event object is passed to event handlers as a parameter
if (!event) { event = window.event }
var num = parseInt(/box\[(\d+)\]/.exec(this.name)[1]);
if (event.shiftKey && last != -1) {
var di = num > last ? 1 : -1;
for (var i = last; i != num; i += di) {
document.forms.boxes['box[' + i + ']'].checked = true;
}
}
last = num;
}
function init() {
for (var i = 0; i < NUM_BOXES; i++) {
document.forms.boxes['box[' + i + ']'].onclick = check;
}
}
<body onload="init()">
<form name="boxes">
<input name="box[0]" type="checkbox">
<input name="box[1]" type="checkbox">
<input name="box[2]" type="checkbox">
<input name="box[3]" type="checkbox">
<input name="box[4]" type="checkbox">
<input name="box[5]" type="checkbox">
<input name="box[6]" type="checkbox">
<input name="box[7]" type="checkbox">
<input name="box[8]" type="checkbox">
<input name="box[9]" type="checkbox">
</form>
</body>
Inspired by the fine answers provided, here's a plain JavaScript version using Array.prototype to coerce nodelists to use array functions, rather than for loops.
(function () { // encapsulating variables with IIFE
var lastcheck = null // no checkboxes clicked yet
// get desired checkboxes
var checkboxes = document.querySelectorAll('div.itemslist input[type=checkbox]')
// loop over checkboxes to add event listener
Array.prototype.forEach.call(checkboxes, function (cbx, idx) {
cbx.addEventListener('click', function (evt) {
// test for shift key, not first checkbox, and not same checkbox
if ( evt.shiftKey && null !== lastcheck && idx !== lastcheck ) {
// get range of checks between last-checkbox and shift-checkbox
// Math.min/max does our sorting for us
Array.prototype.slice.call(checkboxes, Math.min(lastcheck, idx), Math.max(lastcheck, idx))
// and loop over each
.forEach(function (ccbx) {
ccbx.checked = true
})
}
lastcheck = idx // set this checkbox as last-checked for later
})
})
}())
<div class="itemslist">
<input type="checkbox" name="one" value="1">
<input type="checkbox" name="two" value="2">
<input type="checkbox" name="three" value="3">
<input type="checkbox" name="four" value="4">
<input type="checkbox" name="five" value="5">
</div>
I realy liked gyo's example and added some code so it works on all checkboxes with the same name.
I also added a MutationObserver so events are also handled on newly added checkboxes.
$(document).ready(function() {
var previouslyClicked = {};
var rangeEventHandler = function(event) {
if (event.shiftKey && previouslyClicked[this.name] && this != previouslyClicked[this.name]) {
var $checkboxes = $('input[type=checkbox][name='+this.name+']').filter(':visible');
var start = $checkboxes.index( this );
var end = $checkboxes.index( previouslyClicked[this.name] );
// console.log('range', start, end, this, previouslyClicked[this.name]);
$checkboxes.slice(Math.min(start,end), Math.max(start,end)+ 1).prop('checked', previouslyClicked[this.name].checked);
} else {
previouslyClicked[this.name] = this;
}
};
if ("MutationObserver" in window) { // https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/MutationObserver to refresh on new checkboxes
var mutationCallback = function(mutationList, observer) {
mutationList.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.nodeName == 'INPUT' && node.type == 'checkbox') {
$(node).on('click.selectRange', rangeEventHandler);
}
});
});
};
var observer = new MutationObserver(mutationCallback);
observer.observe(document, {
childList: true,
attributes: false, // since name is dynamically read
subtree: true
});
}
$('input[type=checkbox][name]').on('click.selectRange', rangeEventHandler);
});
<html>
<head>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
First:
<input type="checkbox" name="first">
<input type="checkbox" name="first">
<input type="checkbox" name="first">
<input type="checkbox" name="first">
<input type="checkbox" name="first">
</div>
<div>
Second:
<input type="checkbox" name="second">
<input type="checkbox" name="second">
<input type="checkbox" name="second">
<input type="checkbox" name="second">
<input type="checkbox" name="second">
</div>
</body>
</html>
Found the better solution it works for both select and deselects checkboxes.
Uses a core javascript & Jquery.
$(document).ready(function() {
var $chkboxes = $('.chkbox');
var lastChecked = null;
$chkboxes.click(function(e) {
if(!lastChecked) {
lastChecked = this;
return;
}
if(e.shiftKey) {
var start = $chkboxes.index(this);
var end = $chkboxes.index(lastChecked);
$chkboxes.slice(Math.min(start,end), Math.max(start,end)+ 1).prop('checked', e.target.checked);
}
lastChecked = this;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
</head>
<body>
<input type="checkbox" id="id_chk1" class="chkbox" value="1" />Check 1<br/>
<input type="checkbox" id="id_chk2" class="chkbox" value="2" />Check 2<br/>
<input type="checkbox" id="id_chk3" class="chkbox" value="3" />Check 3<br/>
<input type="checkbox" id="id_chk4" class="chkbox" value="4" />Check 4<br/>
<input type="checkbox" id="id_chk5" class="chkbox" value="5" />Check 5<br/>
<input type="checkbox" id="id_chk6" class="chkbox" value="6" />Check 6<br/>
<input type="checkbox" id="id_chk7" class="chkbox" value="7" />Check 7<br/>
</body>
</html>
Here is also another implementation similar to Outlooks multiple selection..
<script type="text/javascript">
function inRange(x, range)
{
return (x >= range[0] && x <= range[1]);
}
$(document).ready(function() {
var $chkboxes = $('.chkbox');
var firstClick = 1;
var lastClick = null;
var range = [];
$chkboxes.click(function(e) {
if(!e.shiftKey && !e.ctrlKey) {
$('#index-' + firstClick).prop('checked', false);
firstClick = $chkboxes.index(this) + 1;
if (firstClick !== null && firstClick !== ($chkboxes.index(this)+1)) {
$('#index-' + firstClick).prop('checked', true);
}
} else if (e.shiftKey) {
lastClick = $chkboxes.index(this) + 1;
if ((firstClick < lastClick) && !inRange(lastClick, range)) {
for (i = firstClick; i < lastClick; i++) {
$('#index-' + i).prop('checked', true);
}
range = [firstClick, lastClick];
} else if ((firstClick > lastClick) && !inRange(lastClick, range)) {
for (i = lastClick; i < firstClick; i++) {
$('#index-' + i).prop('checked', true);
}
range = [lastClick, firstClick];
} else if ((firstClick < lastClick) && inRange(lastClick, range)) {
for (i = 1; i < 100; i++) {
$('#index-' + i).prop('checked', false);
}
for (i = firstClick; i < lastClick; i++) {
$('#index-' + i).prop('checked', true);
}
range = [firstClick, lastClick];
}else if ((firstClick > lastClick) && inRange(lastClick, range)) {
for (i = 1; i < 100; i++) {
$('#index-' + i).prop('checked', false);
}
for (i = lastClick; i < firstClick; i++) {
$('#index-' + i).prop('checked', true);
}
range = [lastClick, firstClick];
}
}
});
});
This is jquery solution that I wrote and use:
All checkboxes have same class named chksel
For faster individual selection a class will carry the order
named chksel_index
Also each checkbox has an attribute named rg that contain same
index
var chksel_last=-1;
$('.chksel').click(function(ev){
if(ev.shiftKey){var i=0;
if(chksel_last >=0){
if($(this).attr('rg') >= chksel_last){
for(i=chksel_last;i<=$(this).attr('rg');i++){$('.chksel_'+i).attr('checked','true')}}
if($(this).attr('rg') <= chksel_last){for(i=$(this).attr('rg');i<=chksel_last;i++){$('.chksel_'+i).attr('checked','true')}}
}
chksel_last=$(this).attr('rg');
}else{chksel_last=$(this).attr('rg');}
})
this solution works for me, also ajax based for DataTables
https://jsfiddle.net/6ouhv7bw/4/
<table id="dataTable">
<tbody>
<tr>
<td><input type="checkbox"></td>
</tr>
<tr>
<td><input type="checkbox"></td>
</tr>
<tr>
<td><input type="checkbox"></td>
</tr>
<tr>
<td><input type="checkbox"></td>
</tr>
</tbody>
</table>
<script>
$(document).ready(function() {
var $chkboxes = $('#dataTable');
var $range = '#dataTable tbody';
var $first = false;
var $indexWrapp = 'tr';
var lastChecked = null;
var $checkboxes = 'input[type="checkbox"]';
$chkboxes.on('click',$checkboxes,function(e) {
if ($first===false) {
lastChecked = $(this).closest($indexWrapp).index();
lastCheckedInput = $(this).prop('checked');
$first=true;
return;
}
if (e.shiftKey) {
var start = lastChecked;
var end = $(this).closest($indexWrapp).index();
$( $range+' '+$indexWrapp).each(function() {
$currIndex=$(this).index();
if( $currIndex>=start && $currIndex<=end ){
$(this).find($checkboxes).prop('checked', lastCheckedInput);
}
})
}
lastCheckedInput = $(this).prop('checked');
lastChecked = $(this).closest($indexWrapp).index();
});
</script>
Here is the Elegant implementation. The idea is to store the first selected input to the lastChecked variable and when the user selects the input field with shiftKey we will run a loop and toggle the inBetween(boolean) and mark all the checkboxes with true value.
Inspired by Wesbos.
let checkboxes = document.querySelectorAll('.wrapper input[type="checkbox"]');
let lastChecked;
function logic(e) {
let inBetween = false;
if (e.shiftKey) {
checkboxes.forEach(checkbox => {
if (checkbox === this || checkbox === lastChecked) {
inBetween = !inBetween;
}
if (inBetween) checkbox.checked = true;
})
}
lastChecked = this;
}
checkboxes.forEach((checkbox, i) => checkbox.addEventListener('click', logic));
.wrapper {
display: flex;
flex-direction: column;
}
<div class="wrapper">
<input type="checkbox" name="one">
<input type="checkbox" name="two">
<input type="checkbox" name="three">
<input type="checkbox" name="four">
<input type="checkbox" name="five">
</div>

Categories