Toggle between seats using javascript - javascript

I am designing seating arrangement fo buses. I have written javascript function to create seats dynamically, so that when page loads, it will create the seats. Now I want a condition where User can select only one seat. After selecting one seat if he clicks on the other then previous seat must be deselected. Below is my code.... what must be added to toggle between them?
function createSeats(oSeatsContainer,seatsPerRow,rowNumber){
for(i=0; i < rowNumber; i++){
var oRow = document.createElement('tr');
for(j=1; j <= seatsPerRow; j++){
oCell = document.createElement('td');
var oImg = document.createElement('img');
oImg.src = statusPics['avail'].src;
oImg.status = 'avail';
oImg.id = (i*10)+j;
oImg.onclick=function(){
this.status = (this.status == 'avail')? 'mine' : 'avail';
this.src = (this.status == 'avail')? statusPics['avail'].src : statusPics['mine'].src;
oTotalprice.innerHTML = '';
oBookedSeatNos.innerHTML = '';
oBtnCheckout.disabled = true;
}
oCell.appendChild(oImg);
oRow.appendChild(oCell);
}
oSeatsContainer.appendChild(oRow);
}
}

I suggest you bind a single event to the parent container and get the target element using e.target.
You can add a data-seat_id attribute to your individual seats to uniquely identify them.
var selected_seat_id;
oSeatsContainer.onClick = function(e) {
selected_seat_id = e.target.getAttribute("data-seat_id");
drawSeats();
}
drawSeats();
drawSeats() will be similar to the code you wrote above but without the onClick handler and taking into account the selected_seat_id to draw an available/taken seat. Also set the data-seat_id attribute in the loop.

Related

Deselect a radio button in qualtrics

Is there a way to use the qualtrics javascript api (or, if not, a workaround) to programatically clear all entries made to radio buttons on a page?
My usage case is in a matrix table question that "pipes" (actually uses embedded data) values from the previous question to puts calculated numbers into the statements. However, if the respondent navigates back then when the return to the following question the numbers have changed but the responses have remained. As such, if it is the second time a respondent is viewing a page constructed like this, I want to clear all their previous answers.
I want to make sure that qualtrics' data is updated properly.
My survey is currently using the JFE engine if that makes a difference.
Qualtrics.SurveyEngine.addOnload(function() {
var QID = this.questionId;
var that = this;
var counts = [];
var radioButtonsClean = [];
var radioButtons = $(QID).getElementsByTagName('input');
var radioIndex = [];
for(var i=0; i<radioButtons.length; i++) {
if(radioButtons[i].type == 'radio') {
radioButtonsClean.push(radioButtons[i]);
radioIndex.push(radioButtons[i].id);
}
}
// Set counts for each displayed radio button to 0
for(var i=0; i<radioButtonsClean.length; i++) {
counts[i] = 0;
}
this.questionclick = function(event,element){
if (element.type == 'radio') {
var thisId = element.id;
var spotCheck = radioIndex.indexOf(thisId);
var count = counts[spotCheck];
if (count == 0) {
for(var i=0; i<counts.length; i++) {
counts[i] = 0;
}
counts[spotCheck] = 1;
}
else {
this.setChoiceValue(element.id.split('~')[2], element.id.split('~')[3], false);
counts[spotCheck] = 0;
}
}
}
});

How do I change an html cell's color on click, if the table is generated dynamically?

function drawTable() {
var table = document.getElementById("myTable");
var input = prompt("Insert height (in number of cells)");
var a = +input;
var input2 = prompt("Insert width (in number of cells)");
var b = +input2;
for (var i = 0; i < a; i++) {
var row = table.insertRow(i);
for (var j = 0; j < b; j++) {
var cell = row.insertCell(j);
};
};
};
I can't for the life of me figure out how to add a onClick event that would change the color of a cell. Do I create a new function in JavaScript and add an onClick event to the table element? That's what I did, but it doesn't seem to work.
function changeColor() {
var td = document.getElementsById("myTable").getElementsByTagName("td");
td.style.backgroundColor = "red";
}
for (var j = 0; j < b; j++) {
var cell = row.insertCell(j);
cell.addEventListener("click", changeColor.bind(cell), false);
};
function changeColor(e) {
this.style.backgroundColor = "red";
}
Should do the trick. Every cell gets an onclick handler set in the for loop. Bind passes the reference of the cell to the changeColor function. The function can address the cell by using this.
For some situations, the answer suggested by Mouser work well. But if consider a situation taking your example of table creation based on number of rows and columns, then adding eventlistener to each cell doesn't sound a good approach. Suppose at initial user requested for 10X10 table. At that moment,
eventlistener is added to each cell.
But what if at some later point of time, more rows/columns are added dynamically. In that situation, only thing you will left with is to add event listeners.
Better approach is to understand the term
Event Delegation
In this approach, you add event listener to parent and just listen to event bubbled up(default behavior) by the child elements.In that case you dont have to be worry about dynamically created cells and adding event listeners to those.
You can take a look on working sample with Event Delegation approach on your code at below link:
http://jsfiddle.net/zL690Ljb/1/
function drawTable() {
var table = document.getElementById("myTable");
table.addEventListener("click", changeColor);
var input = prompt("Insert height (in number of cells)");
var a = +input;
var input2 = prompt("Insert width (in number of cells)");
var b = +input2;
for (var i = 0; i < a; i++) {
var row = table.insertRow(i);
for (var j = 0; j < b; j++) {
var cell = row.insertCell(j);
//cell.addEventListener("click", changeColor.bind(cell), false);
};
};
};
function changeColor(event) {
if (event.target && event.target.tagName && (!event.target.tagName.match(/table|th|tr|tbody|thead/i)) )
{
var element = event.target;
while (element && element.parentElement)
{
if(element.tagName=='TD'){
element.style.backgroundColor = "red";
break;
}
else
{
element = element.parentElement;
}
}
}
}
drawTable();
I hope Mouser will agree on this. Thanks!
Inside the for you can add the onclick event for each cell:
for (var i = 0; i < a; i++) {
var row = table.insertRow(i);
for (var j = 0; j < b; j++) {
var cell = row.insertCell(j);
cell.onclick = function(){
changeColor(this);
}
};
};
Then the changeColor will be as following:
function changeColor(cell) {
cell.style.backgroundColor = "red";
}

Swap canvas element with another table cells value

I have a 3x3 HTML table with each element storing a separate <canvas> element
There is one cell in the table containing text instead of a <canvas>
When a cell containing an image is clicked and the cell to its right contains text, I'm trying to swap that cell's canvas with the text stored in the neighbouring cell.
With the following code every time I click a cell, the canvas element disappears and only swaps the text, leaving the cell on the right no longer containing text or a <canvas>
I tried accessing the canvas using ("#blankCell").html() but it does not work .. anybody know how to access this content for swapping of values?
I created a simplified jsFiddle for this: http://jsfiddle.net/bobbyrne01/dbMnM/1/
$(function () {
var $tbl = $('<table border="1">').attr('id', 'grid');
var $tbody = $('<tbody>').attr('id', 'tableBody');
var tileCount = 0;
var rowCount = $("#numOfPieces").val();
for (var i = 0; i < rowCount; i++) {
var trow = $("<tr>").attr('id', 'row' + i); // New row
for (var j = 0; j < rowCount; j++) {
$cell.append(canvasArray[tileCount]); // Each data cell contains separate canvas element
$cell.appendTo(trow);
tileCount++;
}
trow.appendTo($tbody);
}
$tbl.append($tbody);
$('table').remove(); // removes previous table if it existed
$('body').append($tbl);
});
$('#grid tr:nth-child(2) td:last').prev().text("empty");
$('#grid tr:nth-child(2) td:last').prev().attr('id', 'blankCell');
Listens for clicks ..
$('body').on('click', '#grid td', function(e) {
var $this = $(this);
if ($(this).closest('td').next("#blankCell").length){
blank = $(this).closest('td').next("#blankCell");
if (blank.length) {
//alert('blank to the right');
$this.before(blank);
}
$(this).attr('id', 'blankCell');
$(this).closest('td').next("#blankCell").attr('id', 'piece');
}
Appreciate any help!
Instead of using canvas elements for swapping, it now only has text.
The goal is if a user selects a cell beside the blankCell I would like to swap that cell with the blankCell, if the user selects a cell not beside blankCell I would like nothing to happen.
Only concerned with left and right detection for now.
Make it simple and just exchange the whole table cells, not their contents or content strings and attributes:
$('#grid').on('click', 'td', function(e) {
var $this = $(this),
blank = $this.next("#blankCell");
if (blank.length) {
//alert('blank to the right');
$this.before(blank);
}
});
OK, some more complicated code for checking the position included:
var empty = $("#empty").get(0);
$('#grid').on('click', 'td', function(e) {
if (!empty || this == empty) return; // abort, abort!
var currow = this.parentNode,
emptyrow = empty.parentNode;
var cx = this.cellIndex,
cy = currow.rowIndex,
ex = empty.cellIndex,
ey = emptyrow.rowIndex;
if (cx==ex && Math.abs(cy-ey)==1 || cy==ey && Math.abs(cx-ex)==1) {
// empty and this are next to each other in the grid
var afterempty = empty.nextSibling,
afterthis = this.nextSibling;
currow.insertBefore(empty, afterthis);
emptyrow.insertBefore(this, afterempty);
}
});
Demo at jsfiddle.net

OnMouseOver and OnMouseOut on the same element to create hover effect using javascript only?

I am new to javascript and for practice, I am using javascript to stripe even rows for tables with a particular class. Besides that, I am trying to create a 'hover' effect on table rows using javascript only.
I was able to create the onmouseover effect, however, I am having a very difficult time going back to the default style onmouseout of the table row.
Please keep in mind that I know this can easily be achieved with css or JQuery; however, for this, I would like to stick to javscript only.
What I tried:
function alternate(){
var tables = document.getElementsByTagName("table");
//apply the code to ALL tables on the page with a particular class
for (var ti = 0; ti < tables.length; ++ti) {
if (tables[ti].className == "striped"){ //stripe tables
var rows = tables[ti].getElementsByTagName("tr");
for(i = 0; i < rows.length; i++){
//change style of even rows to create striped effect
if(i % 2 == 0){
rows[i].className += "even"; //stripe even rows while maintaining default style to odd rows
}
rows[i].onmouseover = function() {
this.className="";
this.className="hovered";
}
rows[i].onmouseout = function() {
if(i % 2 == 0){
this.className="even";
}else{
this.className="odd";
}
}
}
}
}
}
I'm not sure if I quite understood your question, but I have created a jsfiddle which does what I think you meant.
The problem, from what I could tell, was that when row[i].mouseout is triggered, the value of i is the number of tables rows in your table. The fix is, to save the original classname on mouseover, and then re-assign that classname onmouseout. Here is the fiddle. http://jsfiddle.net/LBaZu/4/
function alternate() {
var tables = document.getElementsByTagName("table");
for (var ti = 0; ti < tables.length; ++ti) {
if (tables[ti].className == "striped") {
var rows = tables[ti].getElementsByTagName("tr");
var cls; // Variable to save the className
for (var i = 0; i < rows.length; i++) {
if (i % 2 == 0) rows[i].className = "even";
rows[i].onmouseover = function() {
cls = this.className; // Assign the className here
this.className = "hovered";
}
rows[i].onmouseout = function() {
this.className = (cls == 'even') ? cls : 'odd';
}
}
}
}
}
Edit: I re-read your question and it occurred to me that you only wanted to set the odd table rows classname to odd on mouseout, not before.

javascript to create multiple checkboxes in for statement

Hi I am trying to create a bunch of checkboxes without having to make each one currently I have:
function test(obj) {
if (document.getElementByID("info").checked == true) {
document.getElementById("gender")[0].disabled = true;
}
}
and it works for one checkbox but I have been trying to use the code below:
function test(obj) {
var x = obj.name;
var rowCount = $('#List tr').length;
for (var i = 0; i rowCount-1; i++) {
if (x == document.getElementByID("info"["+i+"]).checked == true) {
document.getElementById("gender"["+i+"]).disabled = true;
}
}
}
to create as many checkboxes as I want without me having to make each one but it doesn't seem to be working.
Ok, lets start from the beginning:
To create a check-box in javascript you must do something like this:
var checkbox = document.createElement("input");
checkbox.type = "checkbox";
Then to add your checkbox into a div on your webpage you would do something like:
document.getElementById("your_div_id").appendChild(checkbox);
Then to see if the checkbox is checked you look at the "checked" property like so:
var isChecked = !!document.getElementById("your_checkbox").checked;
if(isChecked == true){
// Do whatever you want
}
Here's a function that would loop through a bunch of checkboxes
function testCheckBoxes(container_id){
var checkboxes = document.querySelector("#" + container_id + " > input[type='checkbox']");
for(var i = 0; i < checkboxes.length; i++){
if(!!checkboxes[i].checked == true){
// Your code
}
}
[Side Note: I'm using document.querySelector for consistency but since I think you're using jquery then use $ instead]
If you want to do something when someone clicks on your checkbox the use an event listener:
var list = document.getElementsByClassName("checkbox");
for(var i = 0; i < list.length; i++){
list[i].addEventListener('click', function(event){
if(!!event.target.checked == true){
// Do something
}
}, true);
}
Hopefully this is enough to get you started. Good Luck =)

Categories