performing sortable using JavaScript - javascript

i have a situation where i need to achieve this, in a table having n rows. if i click on a row in a table and then click on another row. the content in row of first click should go to content in row of second click and then each row should be shifted by on step backward or forward. this can be taken equivalent to JQUERY sortable.
Example:
|1|2|3|4| if i click on 1 and 4 then it should be |2|3|4|1|
how to record two clicks, and the contents of my rows are div elements containing many input elements. I thought of this idea and is this a good way to achieve sortable or is there a still better way, i want to do it using java script.
thanks in advance.

my script fucntion goes like this. I really should have thought for a little longer. i used flags here, i got two questions more, can i do that with out flags?, is there a better way?
<script>
var flag=0;
var id1;
var id2;
function Myfunction(id)
{
if(flag==0)
{
id1=id;
flag=1;
}
else
{
id2=id;
var x=document.getElementById(id1).innerHTML;
var num1=parseInt(id1);
var num2=parseInt(id2);
for(var i=num1;i<num2;i++)
{
var j=i.toString();
var k=(i+1).toString();
document.getElementById(j).innerHTML=document.getElementById(k).innerHTML;
}
document.getElementById(id2).innerHTML=x;
flag=0;
}
}
</script>

I made up a little http://jsfiddle.net/zxKeg/. Works with jQuery only, no additional plugins needed. Hope this will help you!
JS Code:
$(document).ready(function() {
var $table = $('table');
var $toCopy = null;
$table.on('click', 'tr', function() {
if($toCopy === null || $toCopy[0] == this) {
$toCopy = $(this);
}
else {
$toCopy.remove();
$(this).after($toCopy);
$toCopy = null;
}
});
});

Related

How to iterate over htmlCollection

I'm having some difficulty with this. In Backbone, I have a function like this:
functionOne: function(){
$('#myTExtbox-' + budgetLine.attr('id')).on('change keyup paste', function(){
that.mySecondFunction(this);
});
}
In this case, the this is a textbox, which is in a table, inside a div. Then:
mySecondFunction: function(tb){
var tbody = tb.parentElement.parentElement.parentElement.parentElement.parentElement;
//gets main parent, which is a tbody, inside a table, inside a div
}
I then want to iterate over tbody, to go through each row and find a textbox in a specific cell. The problem is that this code:
$.each(tbody, function(index, item){
cost = item;
var t= index;
});
Doesn't seem to allow me to get to any of the items. In this example, if I try to do something like:
item.getElementById('test');
I get an error:
TypeError: Object #<HTMLCollection> has no method 'getElementById'
Why can't I iterate over this object and access objects within?
Thanks
UPDATE
Here's a fiddle: http://jsfiddle.net/HX8RL/14/
Essentially, what should happen is this: When a text box changes, I want to iterate over all the rows in the tb's parent table and sum all the Tb values. Keeping in mind, all the tb's in the same cell position, as there could be other tb's in other places that I dont want to include.
There wont be any collection of TBody
try using children() instead
$.each(tbody.children('tr'), function(index, item){
cost = item;
var t= index;
});
Demo Fiddle
Iterate over all input elements directly to get values.
var tbody = tb.parentElement.parentElement.parentElement;
alert(tbody.id);
var input = $('#tbody').find('input');
alert(input);
console.log(input);
for (var i = 0; i < input.length; i++) {
alert(input[i].value);
alert(i);
}
See fiddle-http://jsfiddle.net/HX8RL/18/
I think there are a few things going wrong here. You know you can only have one ID per page? So you have to do document.getElementByid('test') instead.
Since you are also using jQuery you can use the find function, item.find('#test'). But I think this wouldn't solve you problem. Not sure what you want to achieve, maybe I can help you if you explain a bit more in detail what your problem is.
Also
tb.parentElement.parentElement.parentElement.parentElement.parentElement;
can be written as (in jQuery)
$(tb).parents('tbody');
I've setup a fiddle, maybe it can help you.
Code used in fiddle:
var myFuncs = (function() {
function funcA() {
$('input').on('keyup', function() {
funcB(this);
});
}
function funcB(myInput) {
var $table = $(myInput).parents('table');
$table.find('tr > td > input').each(function() {
var $input = $(this);
if($(myInput).attr('id') != $input.attr('id'))
$input.val("I'm called from another input");
});
}
return {
funcA : funcA
}
})();
myFuncs.funcA();

Multi-select checkboxes with tablesorter

I have a Python script which generates an HTML table. The final column of the table contains checkboxes. I want to use the Shift key to select multiple checkboxes. So, I've incorporated this Javascript.
However, I'm sorting the table columns after loading using tablesorter (and after calling the above Javascript). Furthermore, the user can also sort columns by clicking on column headers. This results in the wrong checkboxes being selected after the user uses Shift-click.
So far I have tried:
moving the select multiple checkboxes javascript to after the sorting (which seems logical to me), but then the sorting functionality does not work
the other javascript answers to that question (How can I shift-select multiple checkboxes like GMail?) but then multi-select does not work
other Googled code (like this) - but again multi-select does not work
The code:
<script src='shift-click-select.js'></script>
<script src='jquery-latest.js'></script>
<script src='jquery.tablesorter.min.js'></script>
<script>
//Javascript function to sort table "my_table" by default on first column (0,0) and then on second column (1) in ascending order (0).
$(function() {
$("#my_table").tablesorter({sortList:[[0,0],[1,0]]});
});
</script>
<table id="my_table" class="tablesorter" border="0" cellpadding="0" cellspacing="1">
<td><input type="checkbox" name="%s" class="chkbox" /></td>
...
</table>
note: shift-click-select.js is from answer mention above.
My guess is that I might need to re-number the checkboxes every time the table is resorted, but I'm hoping there is an easier way?
I suspect that you copied the code from this post almost exactly:
<script type="text/javascript">
var lastChecked = null;
$(document).ready(function() {
var $chkboxes = $('.chkbox');
$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).attr('checked', lastChecked.checked);
}
lastChecked = this;
});
});
</script>
The problem you're probably experiencing is caused by the var $chkboxes = $('.chkbox'); invoked on the document being ready. That's declaring a list of .chkbox objects in their initial order when the page loads. tablesorter then changes the order.
If what I'm assuming is correct, then getting it to work properly would be as simple as changing:
var $chkboxes = $('.chkbox');
$chkboxes.click(function(e) ...
to:
$('.chkbox').click(function(e) {
var $chkboxes = $('.chkbox');
This way the checkbox order is determined on each click rather than once on page load.
It would help if we got to see the contents of your shift-click-select.js.
using this i was able to achieve desired function
$(function() {
var $table = $('#myTable');
var $chkboxes,lastChecked = null;
$table
.tablesorter({sortList:[[0,0],[1,0]]})
.on('sortEnd',function() {
$chkboxes = $table.find(':checkbox');
})
.on('click',":checkbox",function(e){
if(!lastChecked) {
lastChecked = this;
return;
}
if(e.shiftKey) {
var start = $chkboxes.index(this);
var end = $chkboxes.index(lastChecked);
var last = lastChecked.checked; //cache as we might change its value
$chkboxes.slice(Math.min(start,end), Math.max(start,end)+ 1).prop('checked', last);
}
lastChecked = this;
});
});
notice i changed attr('checked' to prop('checked' as checked="false" is an invalid state
I used senordev's solution on my app, but found a large pitfall in my testing, which I've resolved below.
senordev's implied solution:
$('.chkbox').click(function(e) {
var $chkboxes = $('.chkbox')
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;
});
The issue I ran into was regarding filtration, if I filtered out some rows, and shift-selected, the script would select all the hidden rows in between as well (sometimes thousands). Therefore, I added a small fix:
var $chkboxes = $('.chkbox')
to
var $chkboxes = $('.chkbox').filter(':visible');
Additional corner cases I accounted for include resetting the lastChecked value whenever the sort changes (because lastChecked might now be on a completely different page) and when the filters change (because lastChecked might not be visible anymore).
$("table").tablesorter({
...
})
// Clear the lastChecked to avoid unexpected selections.
// e.g. lastChecked might not be on the visible page anymore.
.bind("sortStart",function() {
lastChecked = null
}).bind("sortEnd",function() {
lastChecked = null
}).bind('filterEnd', function() {
lastChecked = null
});

Add Class to all table rows with any 2 classes and another style to all table rows with any 3 classes

Another YUI3 question.
I want to add a class(.two) to all table rows with 2 classes and another class(.three) to all table rows with 3 classes.
I found this piece JQuery of code from another question on here, I suspect this will work, but need to convert it to YUI3 and also allow for the two classes to be added, as well as changing the div to somehow:
$(function(){
var div = $('div[class*=" "]').filter(function(){
var clsArray = $.trim(this.className.split(' ');
return clsArray.size > 1;
});
div.css('background','yellow');
});
jsfiddle for above exmaple here:http://jsfiddle.net/udBZy/3/
Thanks!
EDIT:
Here is what I have so far, but no luck :(
$(function() {
YUI().use('node', function(Y) {
var div = Y.all()('div[class*=" "]').filter(function(){
var clsArray = Y.all().Lang.trim(this.className).split(' ');
return clsArray.length > 1;
});
div.setStyle('background','yellow');
});
});
For any JQuery to YUI conversions, you have http://www.jsrosettastone.com/ and no, it is not difficult. Search the page for your JQuery methods and you'll find the equivalents. You will need Y.all() and node.addClass().
Here is the solution, via the YUI forums. This might help someone in the future:
YUI().use('node', function (Y) {
var re = / {1,}/g;
var div = Y.all('div[class *= " "]').each(function (n) {
var numClasses = Y.Lang.trim(n.get("className")).split(re).length;
n.addClass("numClasses" + numClasses);
n.setContent(n.getContent() + " found " + numClasses);
});
});

Adding text values to dynamically create text inputs

I am trying to build a dynamic form. I have the clone and masking down along with it submits and post to my database but now I am trying to take the value from the previous id #endtime_* and make it the value of the new dynamically created input field of #starttime_*. The ids start with 1. For Example: the first row is: then next is 2 and so on.
As a bonus maybe someone could also tell me how to make each created row alternate in color. odd rows blue and even rows white say.
Thanks so much in advance!
Here is the code thus far.
<script type="text/javascript">
function maskInput(){
$.mask.definitions['~'] = "[+-]";
$(".time").mask("99:99 aa");
$("input").blur(function() {
$("#info").html("Unmasked value: " + $(this).mask());
}).dblclick(function() {
$(this).unmask();
});
}
var clone;
function cloneRow(){
var rows=document.getElementById('TimeCard').getElementsByTagName('tr');
var index=rows.length-1;
clone=rows[index-0].cloneNode(true);
var inputs=clone.getElementsByTagName('input'), inp, i=0,n ;
while(inp=inputs[i++]){
inp.name=inp.name.replace(/\d/g,'')+(index+1);
}
var select=clone.getElementsByTagName('select'), sel, i=0,n ;
while(sel=select[i++]){
sel.name=sel.name.replace(/\d/g,'')+(index+1);
}
maskInput();
}
function addRow(){
var tbo=document.getElementById('TimeCard').getElementsByTagName('tbody')[0];
tbo.appendChild(clone);
cloneRow();
}
function checkDOM(){
var rows=document.getElementById('TimeCard').getElementsByTagName('tr');
for(var i=0;i<rows.length;i++){
alert(rows[i].getElementsByTagName('input')[0].name);
}
}
onload=cloneRow;
</script>
when youre creating your new inputs in cloneRow, after they're in the dom you can just take your names/index and work them then.
$('#starttime_'+index).attr('value',$('#endtime_'+index-1).attr('value'));
for your rows, you need to just give everyother one a different/extra class and then style it accordingly
.odd { background-color:#cfcfcf; }
then, in your cloneRow()
clone=rows[index-0].cloneNode(true);
if (index%2) $(clone).addClass("odd"); //added this line
var inputs=clone.getElementsByTagName('input'), inp, i=0,n ;
It's difficult to guess what you really want when you provided no HTML code, but I built something that should at least point you to the correct direction. I made it into a jsfiddle but I'll post it here as well. So assuming your HTML is something like this:
<div id="inputs">
<input class="endtime" id="endtime_123" type="text" value="endtime_123"/>
</div>
Then this JavaScript will create you new inputs whose starttime equals the endtime of the other input:
$(function() {
$('#inputs .endtime').each(function(index) {
var endtime = $(this).attr('id').substring(8);
$('#inputs').append("<input class='starttime' id='starttime_'"+endtime+"' value='starttime_"+endtime+"'/>");
});
});

Expanding table row using javascript or CSS

I'm creating a webapp asp.net and C# that will display list of users in a table but one of this fields contains lots of information and it will make a row larger. So I'm thinking that I want to create a link, then when I click this link the information will expand, then when I click again the link the information will retract. Like a +/- expand sign.
I know it's possible using javascript and CSS. Please advise.
Many thanks.
Krakat,
Try using this:
<script type="text/javascript">
var rowVisible = true;
function toggleDisplay(tbl) {
var tblRows = tbl.rows;
for (i = 0; i < tblRows.length; i++) {
if (tblRows[i].className != "headerRow") {
tblRows[i].style.display = (rowVisible) ? "none" : "";
}
}
rowVisible = !rowVisible;
}
</script>
place the table tr class as "headerRow" to expand on click of the link.

Categories

Resources