var ButtonFarmAtivada = new Array();
function X() {
var tableCol = dom.cn("td"); //cell 0
//create start checkbox button
ButtonFarmAtivada[index] = createInputButton("checkbox", index);
ButtonFarmAtivada[index].name = "buttonFarmAtivada_"+index;
ButtonFarmAtivada[index].checked = GM_getValue("farmAtivada_"+index, true);
FM_log(3,"checkboxFarm "+(index)+" = "+GM_getValue("farmAtivada_"+index));
ButtonFarmAtivada[index].addEventListener("click", function() {
rp_farmAtivada(index);
}, false);
tableCol.appendChild(ButtonFarmAtivada[i]);
tableRow.appendChild(tableCol); // add the cell
}
1) is it possible to create the button inside an array as I'm trying to do in that example? like an array of buttons?
2) I ask that because I will have to change this button later from another function, and I'm trying to do that like this (not working):
function rp_marcadesmarcaFarm(valor) {
var vListID = getAllVillageId().toString();
FM_log(4,"MarcaDesmarcaFarm + vListID="+vListID);
var attackList = vListID.split(",");
for (i = 0; i <= attackList.length; i++) {
FM_log(3, "Marca/desmarca = "+i+" "+buttonFarmAtivada[i].Checked);
ButtonFarmAtivada[i].Checked = valor;
};
};
For number 1) yes, you can.
function createInputButton(type, index) { // um, why the 'index' param?
// also, why is this function called 'createInputButton'
// if sometimes it returns a checkbox as opposed to a button?
var inputButton = document.createElement("input");
inputButton.type = type; // alternately you could use setAttribute like so:
// inputButton.setAttribute("type", type);
// it would be more XHTML-ish, ♪ if that's what you're into ♫
return inputButton;
}
I don't really understand part 2, sorry.
Related
I am using the jQuery.steps plugin (http://www.jquery-steps.com/) to guide the users in an internal webpage.
So far so good, now I am facing a little issue, I do have 5 Steps at the moment, what I need to achieve now is: If in the first step a special value from a dropdown is selected, I have to skip the steps 2 and 4 since these are not required at this moment.
Do you guys may have any solution for this?
I hope you get my question and please let me know if you do need additional information.
Thanks!
In the jquery.steps.js
add class to <ul role=\"tablist\" class=\"tablist\"></ul> (line 1037)
change functions goToNextStep & goToPreviousStep to
var length_custom;
function goToNextStep(wizard, options, state)
{
length_custom = $('ul.tablist li.skip').length;
var newIndex = increaseCurrentIndexBy(state, 1);
var anchor = getStepAnchor(wizard, newIndex),
parent = anchor.parent(),
isSkip = parent.hasClass("skip");
if(isSkip){
goToStep(wizard, options, state, newIndex + length_custom)
}else{
return paginationClick(wizard, options, state, newIndex);
}
}
function goToPreviousStep(wizard, options, state)
{
var newIndex = decreaseCurrentIndexBy(state, 1);
var anchor = getStepAnchor(wizard, newIndex),
parent = anchor.parent(),
isSkip = parent.hasClass("skip");
if(isSkip){
goToStep(wizard, options, state, newIndex - length_custom)
}else{
return paginationClick(wizard, options, state, newIndex);
}
}
Then add these functions at the bottom of your file
$.fn.steps.skip = function (i) {
var wizard = this,
options = getOptions(this),
state = getState(this);
if (i < state.stepCount) {
var stepAnchor = getStepAnchor(wizard, i);
stepAnchor.parent().addClass("skip");
refreshSteps(wizard, options, state, i);
}
};
$.fn.steps.unskip = function (i) {
var wizard = this,
options = getOptions(this),
state = getState(this);
if (i < state.stepCount) {
var stepAnchor = getStepAnchor(wizard, i);
stepAnchor.parent().removeClass("skip");
refreshSteps(wizard, options, state, i);
}
};
Now, initialize which step you want to skip
$("#wizard").steps('skip', index);
$("#wizard").steps('skip', index);// if you want to skip more than one step
$("#wizard").steps('skip', index);// if you want to skip more than one step
Disable skip
$("#wizard").steps('unskip', index);
$("#wizard").steps('unskip', index);// if you want to unskip more than one step
$("#wizard").steps('unskip', index);// if you want to unskip more than one step
There are events called onStepChanging , onStepChanged which could be passed to the form.steps . You can write a function to validate your form and steps in that and based on the currentIndex,newIndex you can trigger the next tab.
I am attaching here the link for the same which would help you.
I came up with a solution based on ajl80 answer.
But I had to change the goToNextStep & goToPreviousStep to:
var length_custom;
function goToNextStep(wizard, options, state)
{
var valid = false;
var i = 0;
while (!valid) {
i++;
var newIndex = increaseCurrentIndexBy(state, i);
var anchor = getStepAnchor(wizard, newIndex),
parent = anchor.parent(),
isSkip = parent.hasClass("skip");
if (!isSkip) valid = true;
}
return paginationClick(wizard, options, state, newIndex);
}
function goToPreviousStep(wizard, options, state)
{
var valid = false;
var i = 0;
while (!valid) {
i++;
var newIndex = decreaseCurrentIndexBy(state, i);
var anchor = getStepAnchor(wizard, newIndex),
parent = anchor.parent(),
isSkip = parent.hasClass("skip");
if (!isSkip) valid = true;
}
return paginationClick(wizard, options, state, newIndex);
}
In Google App Scripts (GAS), I want to be able to add and remove TextBox and TextArea elements to a FlexTable (that's being used as a form) and not worry about how many there are. I've named the text elements based on a counter to make this process easier.
So, is there a way to get the number of inputs (TextBox + TextArea) passed to e.parameter after the form is submitted?
Here's the relevant code from the FlexTable:
function doGet() {
var app = UiApp.createApplication();
var flex = app.createFlexTable().setId('myFlex');
var counter = 0;
var row_counter = 0;
...
var firstnameLabel = app.createLabel('Your FIRST Name');
var firstnameTextBox = app.createTextBox().setWidth(sm_width).setName('input' + counter).setText(data[counter]);
flex.setWidget(row_counter, 1, firstnameLabel);
flex.setWidget(row_counter, 2, firstnameTextBox);
row_counter++;
counter++;
var lastnameLabel = app.createLabel('Your LAST Name');
var lastnameTextBox = app.createTextBox().setWidth(sm_width).setName('input' + counter).setText(data[counter]);
flex.setWidget(row_counter, 1, lastnameLabel);
flex.setWidget(row_counter, 2, lastnameTextBox);
row_counter++;
counter++;
...
var submitButton = app.createButton('Submit Proposal');
flex.setWidget(row_counter, 2, submitButton);
var handler = app.createServerClickHandler('saveProposal');
handler.addCallbackElement(flex);
submitButton.addClickHandler(handler);
var scroll = app.createScrollPanel().setSize('100%', '100%');
scroll.add(flex);
app.add(scroll);
return app;
}
And here's the code for the ClickHandler (notice that I currently have 39 elements in my FlexTable):
function saveProposal(e){
var app = UiApp.getActiveApplication();
var userData = [];
var counter = 39;
for(var i = 0; i < counter; i++) {
var input_name = 'input' + i;
userData[i] = e.parameter[input_name];
}
So, is there a way to get the number of elements (in this case 39) without manually counting them and assigning this value to a variable?
I'm new at this stuff and I'd appreciate your help.
Cheers!
The simplest way is to add a hidden widget in your doGet() function that will hold the counter value like this :
var hidden = app.createHidden('counterValue',counter);// don't forget to add this widget as a callBackElement to your handler variable (handler.addCallBackElement(hidden))
then in the handler function simply use
var counter = Number(e.parameter.counterValue);// because the returned value is actually a string, as almost any other widget...
If you want to see this value while debugging you can replace it momentarily with a textBox...
You can search for arguments array based object.
function foo(x) {
console.log(arguments.length); // This will print 7.
}
foo(1,2,3,4,5,6,7) // Sending 7 parameters to function.
You could use a while loop.
var i = 0;
var userData = [];
while (e.parameter['input' + i] != undefined) {
userData[i] = e.parameter['input' + i];
i++;
};
OR:
var i = 0;
var userData = [];
var input_name = 'input0';
while (e.parameter[input_name] != undefined) {
userData[i] = e.parameter[input_name];
i++;
input_name = 'input' + i;
};
I am trying to call two functions when only the "add" button is clicked. the problem I am having is that the final four textboxes in the calculate_balances function are not outputting their variables.
var $ = function (id) {
return document.getElementById(id);
}
// Declare Arrays to store information from Inputs //
var transactions = [];
transactions[0] = []; // holds date
transactions[1] = []; // holds transaction type
transactions[2] = []; // holds amount
// Function to print results to text area //
var update_results = function () {
var list = ""; // string variable to build output //
// check to see if arrays are empty //
if (transactions[0].length == 0) {
$("results").value = "";
} else {
list = "";
// for loop to cycle through arrays and build string for textarea output //
for (var i = 0; i < transactions[0].length; i++) {
list += transactions[0][i] + " " + transactions[1][i] + " " + transactions[2][i] + "\n";
}
// display results //
$("results").value = list;
}
}
// function to gather inputs //
var add_transaction = function () {
$("add").blur();
transactions[0][transactions[0].length] = $("date").value;
transactions[1][transactions[1].length] = $("transType").value;
transactions[2][transactions[2].length] = parseFloat( $("amount").value);
update_results();
calculate_balances();
}
// function for Calculations //
var calculate_balances = function () {
var startBal = 2000.00;
var ttlDeposits = 0;
var ttlWithdrawals = 0;
var endBal = startBal;
if (transactions[1][transactions[1].length] == "deposit")
{
ttlDeposits += transactions[2][transactions[2].length];
endBal += ttlDeposits;
}
if (transactions[1][i] == "withdrawal")
{
ttlWithdrawals += transactions[2][transactions[i]];
endBal -= ttlWithdrawals;
}
$("balStart").value = parseFloat(startBal);
$("ttlDeposits").value = parseFloat(ttlDeposits);
$("ttlWithdrawals").value = parseFloat(ttlWithdrawals);
$("balEnd").value = parseFloat(endBal);
}
window.onload = function () {
$("add").onclick = add_transaction, calculate_balances;
update_results();
}
tHank you
Edit: Did not realize the OP was NOT using jQuery. Your onclick should look like this:
$("add").onclick = function(){
add_transaction();
calculate_balances();
};
The rest here is for jQuery which is not what the OP wanted.
For setting the value of a text box with jQuery use the val() method:
$("balStart").val(parseFloat(startBal));
To call the two methods when the button is clicked:
$("add").click(function(){
add_transaction();
calculate_balances();
});
$('input.ISSelectSearch').each(function(i) {
var box = new Object;
box.size = 80;
box.width = 110;
//CODE CODE CODE
});
How can I access the value of box which was set in the previous iteration? Alternatively, is it possible to access it via a key of some kind?
$('input.ISSelectSearch').each(function(i) {
var box = new Object;
box.size = 80;
box.width = 110;
prevsize = $(this).box[/* previous iteration element id or name */].size
//CODE CODE CODE
});
The problem is that I need to know the data associated with each 'input.ISSelectSearch' element box so that I can change them depending on the values of the current or preceding box objects. In other words I need a connection between the element box objects so that I can specify certain changes in one based on the values of another.
you can do something like this
var pre = null;
$('input.ISSelectSearch').each(function(i) {
var box = new Object;
box.size = 80;
box.width = 110;
//condition so that first time it dosent shows an error
if(pre!=null){
//CODE
}
pre = this;
//CODE CODE CODE
});
EDIT AFTER THE COMMENT:-
probably you wanna use $.data() method
this was you can associate the data with the element
so inside the loop you can do
$('input.ISSelectSearch').each(function(i) {
var box = new Object;
box.size = 80;
box.width = 110;
$('input.ISSelectSearch').data(i,box);
//and now you can retrive the data whenevr you want
var olderObject = $('input.ISSelectSearch').data(SOME_OLDER_INDEX)
});
You can do it with index if you like
var $This = $('input.ISSelectSearch');
$This.each(function (index, value) {
var Pre;
var box = { size: 80, width: 110 };
if (index > 0) {
Pre = $This[index - 1];
//Your code hear
} else {
//otherwise
}
});
I have a large array, with non-sequential IDs, that looks something like this:
PhotoList[89725] = new Array();
PhotoList[89725]['ImageID'] = '89725';
PhotoList[89725]['ImageSize'] = '123';
PhotoList[89726] = new Array();
PhotoList[89726]['ImageID'] = '89726';
PhotoList[89726]['ImageSize'] = '234';
PhotoList[89727] = new Array();
PhotoList[89727]['ImageID'] = '89727';
PhotoList[89727]['ImageSize'] = '345';
Etc....
I'm trying to figure out, given an ID, how can I can get the next and previous ID... So that I could do something like this:
<div id="current">Showing You ID: 89726 Size: 234</div>
Get Prev Get Next
Obviously, if we're at the end or beginning of the array we just a message...
Why don't you add properties 'Prev' & 'Next' to that array?
PhotoList[89725] = new Array();
PhotoList[89725]['Prev'] = 89724;
PhotoList[89725]['Next'] = 89726;
PhotoList[89725]['ImageID'] = '89725';
PhotoList[89725]['ImageSize'] = '123';
This is just 'doubly-linked list' data structure.
Based on your example the IDs are sequential...
This is another way of writing your example. new Array() really isn't what you should be using because those are objects you are creating. Also, I left the numbers as strings, but I'm not sure why you would want to do that. You could add next and prev like kuy suggested
PhotoList[89725] = {ImageID: '89725',
ImageSize: '123'};
PhotoList[89725] = {ImageID: '89726',
ImageSize: '234',
Next: '89727',
Prev: '89725'};
PhotoList[89725] = {ImageID: '89727',
ImageSize: '345'};
All of these are accessible just like your other structure.
There's really no way other than to iterate through the possible ids sequentially until you find one which has an entry in your array. For example:
function findClosest(arr, id, increasing) {
var step = increasing ? 1 : -1;
for(var i=id+step; i>=0 && i<=max_id; i+=step)
if( arr[id] )
return id;
}
Obviously, this approach requires that you keep track of the max_id so that you don't iterate forever; here I assume that it's a global variable, but you might want to make it a parameter to the findClosest function. You'd call this function like so:
var prev = findClosest(arr, id, false);
var next = findClosest(arr, id, true);
I agree with the rest quotes you should be using objects not an array. Also make sure you create new arrays using the literal notation and not the new keyword with built in types. The new keyword is bad news and you could clobber the global object. Check out JSLint.
var a = new Array(); //bad dont use
var a = []; //this is the best way to create a new array
var o = {}; //create new objects like this
As for the problem at hand. Why not write a simple container that has its own internal counter?
function PhotoListContainer(PhotoList)
{
if(PhotoList === undefined)
throw("no photo list");
this.counter = 0;
var self = this;
this.current = function(){
return PhotoList[self.counter];
};
this.next = function(){
return PhotoList[self.counter + 1];
};
this.prev = function(){
return PhotoList[self.counter - 1];
};
// You could even write a function that loops each value from the current counter :)
this.each_from_counter = function(callback){
for(var i = self.counter; i < PhotoList.length; i++)
{
callback(PhotoList[i], i);
self.counter++;
}
};
}
//use
var pc = new PhotoListContainer(PhotoList);
pc.counter = 500;
pc.next(); //returns the 501st object
pc.prev(); //returns the 499th object
pc.each_from_counter(function(photo, index){
photo.somehting;
});
No arrays at all are better..
images = {
0: {
size: 12345, /* dont realy need as you can use JS to mesure the size. */
title: "day 1 on holiday"
},
1: {
size: 13549, /* dont realy need as you can use JS to mesure the size. */
title: "day 2 on holiday"
},
2: {
size: 16548, /* dont realy need as you can use JS to mesure the size. */
title: "day 3 on holiday"
},
}
for(x in images){
/* x = "the id of the image." */
url[] = "/images/" + x + ".png";
title[] = images[x].title;
size[] = images[x].size;
console.log("File: " + url[x] + " , Title: " + title[x] + " , Size: " + size + "bytes")
}
var sibNum = 0;
var sibList = [];
var prevSiblingID = false;
for (n in w) {
sibNum++;
sibList[n] = {
title : n,
prevSiblingID : prevSiblingID
};
if (prevSiblingID) {
sibList[prevSiblingID].nextSiblingID = n;
}
prevSiblingID = n;
};
sibList[prevSiblingID].nextSiblingID = false;
you can use grep function and calculate prev or next item of specified array:
object = $.grep(data, function(e) {
if(e.id == yourId) {
return data[data.indexOf(e) + 1]; // or -1 for prev item
}
});
i think your image list will come from DB so you may can try this code, this code is working for me.
<?
$prev="";
$next="";
$cur=0;
$i=0;
$pid=$_GET['pid'];
while($rowcon=mysql_fetch_assoc($result))
{
$arr[$i]=$rowcon['pid'];
if($rowcon['pid']==$pid)
{
$cur=$i;
}
$i++;
}
if($cur<$num_rows)
$next=$arr[$cur+1];
else
$next="";
if($cur>0)
$prev=$arr[$cur-1];
else
$prev="";
echo $prev." ".$cur." ".$next;
?>