Sorting and unsorting function - javascript

I made script for sorting (A to Z)
My question is what I need to add to this to have unsort function, I mean set to default (how it was before you sort them).
Code:
function sortList() {
document.getElementById('sortedtxt').innerHTML = 'Sorted A-Z';
document.getElementById('sortedtitle').innerHTML = 'BFMAS - Sorted A-Z';
var list, i, switching, b, shouldSwitch;
list = document.getElementById("sortingUL");
switching = true;
while (switching) {
switching = false;
b = list.getElementsByTagName("LI");
for (i = 0; i < (b.length - 1); i++) {
shouldSwitch = false;
if (b[i].innerHTML.toLowerCase() > b[i + 1].innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
}
if (shouldSwitch) {
b[i].parentNode.insertBefore(b[i + 1], b[i]);
switching = true;
}
}
}

Please use this code JS & HTML
let globalList, temp = [], sorted = true;
document.getElementById("sort").addEventListener('click', sortList);
document.getElementById("unsorted").addEventListener('click', UnsortedList);
function UnsortedList() {
let currentList = document.getElementById("countries");
currentList.innerHTML = '';
temp.forEach(function (item) {
let li = document.createElement('li');
currentList.appendChild(li);
li.innerHTML += item;
});
sorted = true;
}
function getTempArray(pList) {
globalList = pList.getElementsByTagName("li");
temp = [];
for (let j = 0; j < globalList.length; j++) {
temp.push(globalList[j].innerText);
}
}
function sortList() {
let list, i, switching, b, shouldSwitch;
list = document.getElementById("countries");
if (sorted === true) {
getTempArray(list);
sorted = false;
}
switching = true;
while (switching) {
switching = false;
b = list.getElementsByTagName("li");
for (i = 0; i < (b.length - 1); i++) {
shouldSwitch = false;
if (b[i].innerHTML.toLowerCase() > b[i + 1].innerHTML.toLowerCase()) {
shouldSwitch = true;
break;
}
}
if (shouldSwitch) {
b[i].parentNode.insertBefore(b[i + 1], b[i]);
switching = true;
}
}
}
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Pues </title>
</head>
<body>
<p>Click the button to sort the list alphabetically 🙂</p>
<button id="sort"><b>Sort</b></button>
<button id="unsorted"><i>Unsorted</i></button>
<ul id="countries">
<li>Peru</li>
<li>Argentina</li>
<li>Brazil</li>
<li>Colombia</li>
<li>Paraguay</li>
<li>Bolivia</li>
</ul>
</body>
</html>

First, it seems kind crazy that you are sorting DOM elements in situ (in place), rather than having a separate list data structure (e.g. an array) and treating the DOM as a view... i.e. rendering the list data into the DOM as needed (i.e. after it updates or after you sort it).
Recommendation:
Move the sortedtxt data into an array.
Keep a copy of the array for the original sort order.
create and call a function that renders the array elements into the DOM, e.g. into the appropriate <ul>, <ol> or <table>.
On a user action that changes the sort order or restores the original, apply that to the array and then call the above function again.
Benefits:
Better webpage performance.
Cleaner, simpler that separates data from presentation code.
You can implement fancier sort features such as Sort array of objects by string property value much easier.

Related

How do you build a row sorting (Horizontal sort) for html table?

I need to implement a functionality in jquery where a user clicks on very first row and sort remaining items in clicked row.
I've prepared a codepen here https://codepen.io/shaikh709/pen/orNLaY?editors=0010
Here is the js I've for sorting table
function sortRow(rowIndex) {
let table = $('.report')
let tr = table.find('tr');
let selectedRow = $(tr[rowIndex]);
let selectedRowTd = selectedRow.find('td');
let selectedRowSorting = [];
// find and get clicked tr and it formats it in index and value of the cells
selectedRowTd.each(function(tdIndex){
let td = $(selectedRowTd[tdIndex]);
selectedRowSorting.push({
tdIndex: tdIndex,
value: parseInt(Math.ceil(td.text().trim()))
})
})
// it will compare values and sort
selectedRowSorting = selectedRowSorting.sort(function(a, b){
if (a.value == 0) {
return -1;
}
if (b.value == 0) {
return -1;
}
return b.value - a.value
});
console.log(selectedRowSorting)
// it will only return indexs of sorted list of cells
var sortedIndexs = selectedRowSorting.map(function(rowSorting){
return rowSorting.tdIndex
})
console.log(sortedIndexs)
table.find('tr').each(function(){
let tr = $(this);
let modifiedTr = [];
tr.children().each(function(tdIndex, td){
if (tdIndex == 0) {
console.log(td)
modifiedTr[0] = td;
} else {
for (let i =0; i < sortedIndexs.length;i++) {
console.log(sortedIndexs[i])
// it gives me index of sorted column.
if (tdIndex == i) {
let sortedIndex = sortedIndexs[i];
if ( sortedIndex == undefined) {
console.log('i', i, sortedIndex)
sortedIndex = sortedIndexs.length+1
}
modifiedTr[sortedIndex] = td;
}
}
}
})
tr.append(modifiedTr)
})
}
I've created a demo here https://codepen.io/shaikh709/pen/orNLaY?editors=0010
When user click on first (very left) cell in a row. I want rest of the row to switch to largest to smallest value.
Been stuck here for about couple of days. Any help is appreciated. Thanks.
:)
I would keep it simple and just build a small Array of the values, and then use .sort() upon the Array.
Working Example: https://jsfiddle.net/Twisty/ondf3ram/
JavaScript
$(function() {
function sortDesc(a, b) {
return a - b;
}
function sortAsc(a, b) {
return b - a;
}
function sortRow(rObj, desc) {
var curArr = [];
$("td", rObj).each(function(i, el) {
curArr.push(parseInt($(el).text().trim()));
});
if (desc == undefined || desc == true) {
curArr.sort(sortDesc);
} else {
curArr.sort(sortAsc);
}
$("td", rObj).each(function(i, el) {
$(el).html(curArr[i]);
});
}
$(".sortable tbody th").on("click", function(e) {
var r = $(this).parent();
if ($(this).data("sort") == undefined) {
$(this).data("sort", true);
}
sortRow(r, $(this).data("sort"));
$(this).data("sort", $(this).data("sort") ? false : true);
});
});
Making use of the proper Selectors will help you a lot! I wasn't sure if you wanted to reverse the sort Descending to Ascending. So here are the goals I went for:
Click on <th> (first) cell in the <tbody> to execute a sort of the parent <tr>
Initially sort with Descending Sort
Additional clicks will toggle the sort from Desc. to Asc.
To this effect we have the sortRow() function that expects a jQuery <tr> Object. Optionally it can accept a sort Direction as a Boolean (Default: true, true = Desc. / false = Asc). It performs the sort and does not return anything.
I created an Array and populated it using the .each() function to iterate over each <td> in the <tr> that is targeted. Since I am getting the .text() or Text node of the cell, I use .trim() to drop any white space and then use parseInt() to populate the Array with Integers.
We then Sort the Array based on compare function:
A function that defines an alternative sort order. The function should return a negative, zero, or positive value, depending on the arguments.
We then re-iterate the same cells and replace the content from the array. All done!
I added the toggle feature by looking for .data() on each row. If this is the first click, there will be no data, so we assume a Desc. sort. The next time we click on that row header, it will have a value and toggle to an Asc. sort.
Update
Base don your comments, it sounds like you want to sort a Martix. This is discussed here: How to sort 2 dimensional array by column value?
Working Example: https://jsfiddle.net/Twisty/ondf3ram/70/
JavaScript
$(function() {
var selInd;
function sortMatrixDesc(a, b) {
if (a[selInd] === b[selInd]) {
return 0;
} else {
return (a[selInd] < b[selInd]) ? -1 : 1;
}
}
function sortMatrixAsc(a, b) {
if (a[selInd] === b[selInd]) {
return 0;
} else {
return (a[selInd] > b[selInd]) ? -1 : 1;
}
}
function getTblCont(tb) {
var cols = [];
$("tr:first td", tb).each(function(i, el) {
cols[i] = [];
});
for (var c = 0; c < cols.length; c++) {
$("tr", tb).each(function(i, el) {
cols[c].push(parseInt($("td", el).eq(c).text().trim()));
});
}
return cols;
}
function sortRow(rObj, desc) {
var tblObj = getTblCont(rObj.parent());
var rowInd = rObj.index();
if (desc == undefined || desc == true) {
tblObj.sort(sortMatrixDesc);
} else {
tblObj.sort(sortMatrixAsc);
}
rObj.parent().find("tr").each(function(r, tr) {
$("td", tr).each(function(i, el) {
$(el).html(tblObj[i][r]);
});
});
}
$(".sortable tbody th").on("click", function(e) {
var r = $(this).parent();
selInd = r.index();
if ($(this).data("sort") == undefined) {
$(this).data("sort", true);
}
sortRow(r, $(this).data("sort"));
$(this).data("sort", $(this).data("sort") ? false : true);
});
});
Hope that helps.

Backtracking algorithm to create a "jumbled" but not random array [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have written this backtracking algorithm to make a jumbled-looking array of 70 items from an input array of 10 items. The rules it needs to follow are:
No repeat item in each group of 5
No item appears in the same position in any of 3 consecutive groups of 5
Each item appears exactly 7 times in total
This almost works, but only if I make my input array bigger than my output array, which then breaks rule 3. If I make my input array length 70, the algorithm sometimes works but sometimes overflows.
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html" />
<title>Backtracking Pseudo Randomiser</title>
</head>
<body>
<button onclick=go();>Go</button>
<script>
function go() {
function pseudoRan(input,output) {
if (output.length==70) {
output=listToMatrix(output,5);
printIt(output);
return;
}
else {
var tmp=input.shift();
var mod=output.length % 5;
if (output.slice(-mod-1).indexOf(tmp)==-1 && output[output.length-5]!=tmp && output[output.length-10]!=tmp) {
output.push(tmp);
pseudoRan(input,output);
}
else {
input.push(tmp);
pseudoRan(input,output);
}
}
}
var input=["A","B","C","D","E","F","G","H","I","K"];
var output=[];
input=pool(input,70);
input=yatesShuffle(input);
pseudoRan(input, output);
//analyse it
var freqs=output.byCount();
var strFreqs="";
for(a=0;a<freqs.length;a++){
strFreqs+="Item: " + freqs[a].item + " ..." + freqs[a].frequency + "<br />";
document.getElementById("2").innerHTML=strFreqs;
}
}
function pool(array,total) {
var factor=total/array.length;
var newArray=[];
for (a=0;a<factor;a++) {
for (b=0;b<array.length;b++) {
newArray.push(array[b]);
}
}
//console.log(newArray);
return newArray;
}
function yatesShuffle (array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * i); // no +1 here!
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
function listToMatrix(list, elementsPerSubArray) {
var matrix = [], i, k;
for (i = 0, k = -1; i < list.length; i++) {
if (i % elementsPerSubArray === 0) {
k++;
matrix[k] = [];
}
matrix[k].push(list[i]);
}
return matrix;
}
function printIt(array) {
for (i=0;i<array.length;i++) {
var str=" ";
for (j=0;j<array[i].length;j++) {
str+=array[i][j]+" ";
}
document.getElementById("1").insertAdjacentHTML('beforeend',str + "</br>");
//console.log(array[i]);
}
}
Array.prototype.byCount= function(){
var itm, a= [], L= this.length, o= {};
for(var i= 0; i<L; i++){
itm= this[i];
if(!itm) continue;
if(o[itm]== undefined) o[itm]= 1;
else ++o[itm];
}
for(var p in o) a[a.length]= {item: p, frequency: o[p]};
return a.sort(function(a, b){
return o[b.item]-o[a.item];
});
}
</script>
<div id="1" style="font-family:'Courier New';"></div>
<br />
<div id="2"></div>
</body>
</html>
It's not having too many inputs that's a problem. If you run the code enough times I think that you will find that sometimes it will work, but other times, depending on the result of the shuffle, it's just impossible to fit any of the remaining inputs onto the output array.
It's like playing Solitaire: There might be a solution at the start, but depending on the decisions you make as you go (picking items out of the input array) you might still lose.
You should at a minimum track if you have looped completely through the input array without any success.
If you have looped completely through the input list with no success, you never will. Then you have a couple of options:
Return the output you have and the remaining input (might be helpful just to see that it failed.
Whether or not you log the failed attempt, you can then restart and then try again. Just brute force attempts at random to find a solution.
One way to do it:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html" />
<title>Backtracking Pseudo Randomiser</title>
</head>
<body>
<button onclick=go();>Go</button>
<script>
function go() {
var tracker = 0
function pseudoRan(input,output) {
if (output.length==70) {
output=listToMatrix(output,5);
printIt(output);
return true;
}
else {
var tmp=input.shift();
var mod=output.length % 5;
console.log('input.length::tracker ==>', input.length + '::' + tracker)
if (output.slice(-mod-1).indexOf(tmp)==-1 && output[output.length-5]!=tmp && output[output.length-10]!=tmp) {
tracker = 0
output.push(tmp);
return pseudoRan(input,output);
}
else {
tracker++
if (tracker > input.length) {
console.log('Failed this time.')
output=listToMatrix(output,5);
console.log('output-----------------------');
printIt(output);
console.log('input------------------------');
printIt(input);
return false // FAILED to finish
}
input.push(tmp);
return pseudoRan(input,output);
}
}
}
var input=["A","B","C","D","E","F","G","H","I","K"];
input=pool(input,300);
// run until we get an answer
do {
var output=[];
tracker = 0;
// operate on copy of the data
runInput=yatesShuffle(JSON.parse(JSON.stringify(input)));
} while (!pseudoRan(runInput, output))
// analyse it
var freqs=output.byCount();
var strFreqs="";
for(a=0;a<freqs.length;a++){
strFreqs+="Item: " + freqs[a].item + " ..." + freqs[a].frequency + "<br />";
document.getElementById("2").innerHTML=strFreqs;
}
}
function pool(array,total) {
var factor=total/array.length;
var newArray=[];
for (a=0;a<factor;a++) {
for (b=0;b<array.length;b++) {
newArray.push(array[b]);
}
}
//console.log(newArray);
return newArray;
}
function yatesShuffle (array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * i); // no +1 here!
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
function listToMatrix(list, elementsPerSubArray) {
var matrix = [], i, k;
for (i = 0, k = -1; i < list.length; i++) {
if (i % elementsPerSubArray === 0) {
k++;
matrix[k] = [];
}
matrix[k].push(list[i]);
}
return matrix;
}
function printIt(array) {
for (i=0;i<array.length;i++) {
var str=" ";
for (j=0;j<array[i].length;j++) {
str+=array[i][j]+" ";
}
document.getElementById("1").insertAdjacentHTML('beforeend',str + "</br>");
console.log(array[i]);
}
}
Array.prototype.byCount= function(){
var itm, a= [], L= this.length, o= {};
for(var i= 0; i<L; i++){
itm= this[i];
if(!itm) continue;
if(o[itm]== undefined) o[itm]= 1;
else ++o[itm];
}
for(var p in o) a[a.length]= {item: p, frequency: o[p]};
return a.sort(function(a, b){
return o[b.item]-o[a.item];
});
}
</script>
<div id="1" style="font-family:'Courier New';"></div>
<br />
<div id="2"></div>
</body>
</html>

function organize list not working in firefox

This function organize list, not organized in alphabetical order: ascending/descending in Firefox and Internet Explorer.
In google chrome and Edge is working.
Here is code:
<script type="text/javascript">
window.onload = function () {
var desc = false;
document.getElementById("Order").onclick = function () {
sortUnorderedList("PostList", desc);
desc = !desc;
return false;
}
}
function compareText(a1, a2) {
var t1 = a1.innerText,
t2 = a2.innerText;
return t1 > t2 ? 1 : (t1 < t2 ? -1 : 0);
}
function sortUnorderedList(ul, sortDescending) {
if (typeof ul == "string") {
ul = document.getElementById(ul);
}
var lis = ul.getElementsByTagName("li");
var vals = [];
for (var i = 0, l = lis.length; i < l; i++) {
vals.push(lis[i]);
}
vals.sort(compareText);
if (sortDescending) {
vals.reverse();
}
ul.innerHTML = '';
for (var i = 0, l = vals.length; i < l; i++) {
ul.appendChild(vals[i]);
}
}
</script>
Try this:
document.getElementById("hello").onclick = talk;
function talk()
{
alert('It works!');
}
<a id="hello">Click me!</a>
It seems to be right. Is your element ID right? Check if you have more then one element using the same ID also. If you can, post you HTML code.
It's bad if you use code of unknown source, you might even get in trouble with copyrights! Here is a simplified version (No, I won't apologize for the use of Bubble-sort!) that should be easy to follow.
Edited on request of OP to add an example of deep copying
<!DOCTYPE html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script type="text/javascript">
// as shown in http://stackoverflow.com/questions/3066427/copy-all-childnodes-to-an-other-element-in-javascript-native-way
function copyElements (dst,src){
while (src.hasChildNodes()) {
dst.appendChild(src.removeChild(src.firstChild))
}
}
function sortUnorderedList(element_id, direction){
var table = document.getElementById(element_id);
var rows,i,tmp;
// get the rows in the order as they are
rows = table.rows;
i = rows.length - 1;
// tmp must be a node for this highly simplified stuff to work
tmp = document.createElement("getoffmylawn");
// do a simple Bubble sort (sorts lexically, maybe not what you want!)
// Assumes things to sort are in the first cell, adjust if necessary
for(; i > 0; i--){
for(j = 0;j < i; j++){
if(direction === false){
if(rows[j].firstChild.firstChild.textContent < rows[j+1].firstChild.firstChild.textContent){
copyElements (tmp , rows[j]);
copyElements (rows[j] , rows[j+1]);
copyElements (rows[j+1] , tmp);
}
}
else{
if(rows[j].firstChild.firstChild.textContent > rows[j+1].firstChild.firstChild.textContent){
copyElements ( tmp , rows[j]);
copyElements (rows[j] , rows[j+1]);
copyElements (rows[j+1] , tmp);
}
}
}
}
}
window.onload = function () {
var desc = false;
document.getElementById("Order").onclick = function () {
sortUnorderedList("FileList", desc);
desc = !desc;
return false;
};
};
</script>
</head>
<body>
<table id="FileList">
<tr><td>Foo</td></tr>
<tr><td>Bar</td></tr>
<tr><td>Foobar</td></tr>
<tr><td>Something</td></tr>
<tr><td>Anything</td></tr>
<tr><td>Somehwere</td></tr>
<tr><td>elsewhere</td></tr>
<tr><td>completely lost</td></tr>
</table>
<button id="Order">Sort</button>
</body>
</html>
If you think the order is wrong you have found out what "lexical order" actually means.
To work in Internet Explorer and Firefox, I replaced:
innerText to textContent

two delimiters output formatting javascript

I thought this would be easier, but running into a weird issue.
I want to split the following:
theList = 'firstword:subwordone;subwordtwo;subwordthree;secondword:subwordone;thirdword:subwordone;subwordtwo;';
and have the output be
firstword
subwordone
subwordtwo
subwordthree
secondword
subwordone
thirdword
subwordone
subwordtwo
The caveat is sometimes the list can be
theList = 'subwordone;subwordtwo;subwordthree;subwordfour;'
ie no ':' substrings to print out, and that would look like just
subwordone
subwordtwo
subwordthree
subwordfour
I have tried variations of the following base function, trying recursion, but either get into infinite loops, or undefined output.
function getUl(theList, splitOn){
var r = '<ul>';
var items = theList.split(splitOn);
for(var li in items){
r += ('<li>'+items[li]+'</li>');
}
r += '</ul>';
return r;
}
The above function is just my starting point and obviously doesnt work, just wanted to show what path I am going down, and to be shown the correct path, if this is totally off base.
It seems you need two cases, and the difference between the two is whether there is a : in your string.
if(theList.indexOf(':') == -1){
//Handle the no sublist case
} else {
//Handle the sublist case
}
Starting with the no sublist case, we develop the simple pattern:
var elements = theList.split(';');
for(var i = 0; i < elements.length; i++){
var element = elements[i];
//Add your element to your list
}
Finally, we apply that same pattern to come up with the implementation for the sublist case:
var elements = theList.split(';');
for(var i = 0; i < elements.length; i++){
var element = elements[i];
if(element.indexOf(':') == -1){
//Add your simple element to your list
} else {
var innerElements = element.split(':');
//Add innerElements[0] as your parent element
//Add innerElements[1] as your child element
//Increment i until you hit another element with ':', adding the single elements each increment as child elements.
//Decrement i so it considers the element with the ':' as a parent element.
}
}
Keep track of the current list to add items to, and create a new list when you find a colon in an item:
var baseParent = $('ul'), parent = baseParent;
$.each(theList.split(';'), function(i, e) {
if (e.length) {
var p = e.split(':');
if (p.length > 1) {
baseParent.append($('<li>').append($('<span>').text(p[0])).append(parent = $('<ul>')));
}
parent.append($('<li>').text(p[p.length - 1]));
}
});
Demo: http://jsfiddle.net/Guffa/eWQpR/
Demo for "1;2;3;4;": http://jsfiddle.net/Guffa/eWQpR/2/
There's probably a more elegant solution but this does the trick. (See edit below)
function showLists(text) {
// Build the lists
var lists = {'': []};
for(var i = 0, listKey = ''; i < text.length; i += 2) {
if(text[i + 1] == ':') {
listKey = text[i];
lists[listKey] = [];
} else {
lists[listKey].push(text[i]);
}
}
// Show the lists
for(var listName in lists) {
if(listName) console.log(listName);
for(var j in lists[listName]) {
console.log((listName ? ' ' : '') + lists[listName][j]);
}
}
}
EDIT
Another interesting approach you could take would be to start by breaking it up into sections (assuming text equals one of the examples you gave):
var lists = text.match(/([\w]:)?([\w];)+/g);
Then you have broken down the problem into simpler segments
for(var i = 0; i < lists.length; i++) {
var listParts = lists[i].split(':');
if(listParts.length == 1) {
console.log(listParts[0].split(';').join("\n"));
} else {
console.log(listParts[0]);
console.log(' ' + listParts[1].split(';').join("\n "));
}
}
The following snippet displays the list depending on your requirements
var str = 'subwordone;subwordtwo;subwordthree;';
var a = []; var arr = [];
a = str;
var final = [];
function split_string(a){
var no_colon = true;
for(var i = 0; i < a.length; i++){
if(a[i] == ':'){
no_colon = false;
var temp;
var index = a[i-1];
var rest = a.substring(i+1);
final[index] = split_string(rest);
return a.substring(0, i-2);
}
}
if(no_colon) return a;
}
function display_list(element, index, array) {
$('#results ul').append('<li>'+element+'</li>');
}
var no_colon_string = split_string(a).split(';');
if(no_colon_string){
$('#results').append('<ul><ul>');
}
no_colon_string.forEach(display_list);
console.log(final);
working fiddle here

question number reordering

I have a list of question in my javascript file. Each question has a question number and question description and options. A question can be added anywhere in the list of questions. So if a question is added into the top of all questions, then i need to change the question numbers of all the below ones. How can achieve this. Can i use javascript for this?
I would suggest using an <ol> for each question, and let the page handle reflowing the numbers.
Otherwise you'll need to set a target number before inserting, and for each element in the list you'll check to see if it's number is greater than the target, and then if so increment the number by one.
var Target = //new number that I want the inserted question to be
foreach (element in list) {
if (element.Number > Target) element.Number += 1;
}
list.add( //new question with # set to Target );
This works.
<ol id="questions_list"></ol>
var questions = ["A foo walks into a bar. What happens?", "Why did foo cross the road?"];
addQuestion("foo", 1);
function addQuestion(question, position)
{
if(position > 0 && position < questions.length)
{
var firstHalf = questions.slice(0, position);
var secondHalf = questions.slice(position, questions.length);
firstHalf.push(question);
questions = firstHalf.concat(secondHalf);
console.log("slice");
}else if(position <= 0)
{
questions.unshift(question);
console.log("beginning");
}else if(position >= questions.length)
{
questions.push(question);
console.log("end");
}
updateQuestionList();
}
function updateQuestionList()
{
var questions_list = document.getElementById("questions_list");
questions_list.innerHTML = "";
for(var i=0;i<questions.length;i++)
{
var question = document.createElement("LI");
question.innerHTML = questions[i];
questions_list.appendChild(question);
}
}
http://jsfiddle.net/jPxwW/1/
Array prototype ( fun! =) ):
// zero-based insert
Array.prototype.insert = function(index, item) {
var i = 0, list = [];
if (this.length == index) {
list = this;
list.push(item);
return list;
}
for(; i < this.length; i++) {
if (index == list.length) {
list.push(item);
i--;
} else {
list.push(this[i]);
}
}
return list;
};
Array.prototype.print = function (base) {
base = base || 1;
for (var i = 0, out = []; i < this.length; i++) {
out.push((base + i) + '. ' + this[i]);
}
return out.join("\n");
};
list = ['when?', 'where?', 'why?'];
list = list.insert(0, 'who?'); // first: ["who?", "when?", "where?", "why?"]
list = list.insert(3, 'how?'); // 4th: ["who?", "when?", "where?", "how?", "why?"]
list = list.insert(list.length, 'last?'); // last: ["who?", "when?", "where?", "how?", "why?", "last?"];
list.print();
/**
"1. who?
2. when?
3. where?
4. how?
5. why?
6. last?"
**/
You could do something like this using ordered lists (ol) and jQuery:
<html>
<head>
<script src="http://code.jquery.com/jquery-1.4.4.min.js" type="text/javascript"></script>
<script type ="text/javascript">
$(function(){
var n = 2;
$('button').delegate('click', function(){
$(this).parents('li').after('<li><p><span>Question'+n+'</span><button>Create new question</button></p></li>');
n += 1;
})
})
</script>
</head>
<body>
<ol>
<li>
<p><span>Question 1</span><button>Create new question</button></p>
</li>
</ol>
</body>
</html>

Categories