I'm working on my first school project so I don't have much experience in doing such web applications, that's why I decided to ask here.
How can I update the value in the for loop syntax or reset it entirely, so it iterates again, like I just reloaded it? I have another function that I decided not to show, simply because it would be useless to. What it does in the end is increments the taskCount.length by one. This part technically works but problem is, the function I'm going to show you now, once iterated, will always keep the default taskCount.length value, once the page is loaded, it never changes there. Is there any way I can update it?
Here's an example: The function above makes taskCount.length = '5' but when the page started it was taskCount.length = 4, and when I do alert(taskCount.length) from the console, I get 5. But the for loop doesn't want to change.
for (var i = 0; i < taskCount.length; i++) {
document.getElementsByClassName('task')[i].addEventListener('click', ((j) => {
return function() {
var shadow = document.createElement('div');
// Styling
var changingWindow = document.createElement('div');
// Styling
var changingTitle = document.createElement('p');
// Styling
var changingText = document.createElement('p');
// Styling
var changingTitleNode = document.createTextNode('Промяна');
var changingTextNode = document.createTextNode('Моля, изберете действие.');
var deleteTask = document.createElement('button');
var goUp = document.createElement('button');
var goDown = document.createElement('button');
var unchange = document.createElement('button');
// Styling
var deleteElementNode = document.createTextNode('Премахни задачата');
var goUpNode = document.createTextNode('Премести нагоре');
var goDownNode = document.createTextNode('Премести надолу');
var unchangeNode = document.createTextNode('Отказ');
var justBreak = document.createElement('br');
var justBreakAgain = document.createElement('br');
var justBreakOneMoreTime = document.createElement('br');
body.appendChild(shadow);
shadow.appendChild(changingWindow);
changingWindow.appendChild(changingTitle);
changingTitle.appendChild(changingTitleNode);
changingWindow.appendChild(changingText);
changingText.appendChild(changingTextNode);
changingWindow.appendChild(deleteTask);
deleteTask.appendChild(deleteElementNode);
deleteTask.onclick = function() {
document.getElementsByClassName('task')[j].parentNode.removeChild(document.getElementsByClassName('task')[j]);
shadow.parentNode.removeChild(shadow);
localStorage.setItem("listContent", document.getElementById('list').innerHTML);
}
changingWindow.appendChild(justBreak);
changingWindow.appendChild(goUp);
goUp.appendChild(goUpNode);
goUp.onclick = function() {
if (j !== 0) {
var saveThisTaskValue = document.getElementsByClassName('task')[j].innerHTML;
var savePreviousTaskValue = document.getElementsByClassName('task')[j - 1].innerHTML;
document.getElementsByClassName('task')[j].innerHTML = savePreviousTaskValue;
document.getElementsByClassName('task')[j - 1].innerHTML = saveThisTaskValue;
}
shadow.parentNode.removeChild(shadow);
localStorage.setItem("listContent", document.getElementById('list').innerHTML);
}
changingWindow.appendChild(justBreakAgain);
changingWindow.appendChild(goDown);
goDown.appendChild(goDownNode);
goDown.onclick = function() {
if (j !== document.getElementsByClassName('task').length - 1) {
var saveThisTaskValue = document.getElementsByClassName('task')[j].innerHTML;
var saveNextTaskValue = document.getElementsByClassName('task')[j + 1].innerHTML;
document.getElementsByClassName('task')[j].innerHTML = saveNextTaskValue;
document.getElementsByClassName('task')[j + 1].innerHTML = saveThisTaskValue;
}
shadow.parentNode.removeChild(shadow);
localStorage.setItem("listContent", document.getElementById('list').innerHTML);
}
changingWindow.appendChild(justBreakOneMoreTime);
changingWindow.appendChild(unchange);
unchange.appendChild(unchangeNode);
unchange.onclick = function() {
shadow.parentNode.removeChild(shadow);
}
}
})(i))
}
As a matter of the page reloading, you can always save the value as a cookie and reuse it again and again. You can update it whenever you want.
I don't fully understand you question, but maybe some recursion is what you need. Something along the lines of:
loop(5);
function loop(xTimes) {
for (var i = 0; i < xTimes; i++) {
if (newXTimes !== xTimes) {
loop(newXtimes);
break;
}
}
}
Maybe set newxTimes as a global variable that can be accessed inside loop.
In case someone "from the future" reads this question and it doesn't have any answers, I came up with the solution to reload the page everytime you change the value. Still, I'd like to do it without reloading.
Related
I'm writing a simple JavaScript program to examine every element in an HTML website and add a child node to every non-text node that labels the type of tag:
Here is my code:
window.onload = function() {
var body_elems = document.body.getElementsByTagName("*");
for (var i = 0; i < body_elems.length; i++) {
if (body_elems[i].nodeType != 3) {
var tag_name = body_elems[i].tagName;
var child = document.createElement("P");
var child_text = document.createTextNode(tag_name);
child.appendChild(child_text);
body_elems[i].appendChild(child);
body_elems[i].firstChild.className = "hoverNode";
}
}
}
For some reason the line var child = document.createElement("P") causes the page to never load; if I comment out that line then the page will load.
On the other hand, here is a slightly different version that actually works:
window.onload = function() {
var body_elems = document.body.getElementsByTagName("*");
for (var i = 0; i < body_elems.length; i++) {
if (body_elems[i].nodeType != 3) {
var tag_name = body_elems[i].tagName;
var child = document.createTextNode(tag_name);
body_elems[i].appendChild(child);
child.className="hoverNode";
}
}
}
But I can't figure out how to assign a class name to the new node in order to apply CSS, so if someone could tell me how to do that my problem would be solved.
I'm new to JS so any help would be much appreciated.
This may seem a very newbie question, but I'm stuck with it. I've got this code to show a check list in a UI and insert the paragraphs of one or more documents into another target document:
var fact_list = [ ["Kennedy Inauguration", "politics", "tZwnNdFNkNklYc3pVUzZINUV4eUtWVWFSVEf"], ["Pericles’ Funeral Oration", "politics", "sdgrewaNkNklYc3pVUzZINUV4eUtW345ufaZ"], ["The Pleasure of Books", "culture", "1234rFszdgrfYc3pVUzZINUV4eU43usacd"], ["I Am The First Accused (Nelson Mandela)", "law", "34rsgadOsidjSZIswjadi95uydnfklsdks"] ];
function showList() {
var mydoc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication();
var panel = app.createVerticalPanel().setId('panel');
// Store the number of items in the array (fact_list)
panel.add(app.createHidden('checkbox_total', fact_list.length));
// add 1 checkbox + 1 hidden field per item
for(var i = 0; i < fact_list.length; i++){
var checkbox = app.createCheckBox().setName('checkbox_isChecked_'+i).setText(fact_list[i][0]);
var hidden = app.createHidden('checkbox_value_'+i, fact_list[i]);
panel.add(checkbox).add(hidden);
}
var handler = app.createServerHandler('submit').addCallbackElement(panel);
panel.add(app.createButton('Submit', handler));
app.add(panel);
mydoc.show(app);
}
function submit(e){
var numberOfItems = e.parameter.checkbox_total;
var itemsSelected = [];
// for each item, if it is checked / selected, add it to itemsSelected
for(var i = 0; i < numberOfItems; i++){
if(e.parameter['checkbox_isChecked_'+i] == 'true'){
itemsSelected.push(e.parameter['checkbox_value_'+i]);
}
}
var app = UiApp.getActiveApplication();
ScriptProperties.setProperties({'theses': itemsSelected}, true);
app.close();
return app;
}
function importTheses(targetDocId, thesesId, thesesType) { // adapted from Serge insas
var targetDoc = DocumentApp.openById(targetDocId);
var targetDocParagraphs = targetDoc.getParagraphs();
var targetDocElements = targetDocParagraphs.getNumChildren();
var thesesDoc = DocumentApp.openById(thesesId);
var thesesParagraphs = thesesDoc.getParagraphs();
var thesesElements = thesesDoc.getNumChildren();
var eltargetDoc=[];
var elTheses=[];
for( var j = 0; j < targetDocElements; ++j ) {
var targetDocElement = targetDoc.getChild(j);
// Logger.log(j + " : " + type);// to see targetDoc's content
eltargetDoc[j]=targetDocElement.getText();
if(el[j]== thesesType){
for( var k = 0; k < thesesParagraphs-1; ++k ) {
var thesesElement = thesesDoc.getChild(k);
elTheses[k] = thesesDoc.getText();
targetDoc.insertParagraph(j, elTheses[k]);
}
}
}
}
But when I call these functions inside my main function, I got a red message (in my language): service not available: Docs and, after the UI from showList() is closed, nothing more happens with my code (but I wanted the main functions continues to run). I call these functions this way:
if (theses == 1){
showList();
var thesesArrays = ScriptProperties.getProperty('theses');
for (var i = 0; i < thesesArrays.lenght(); i++){
var thesesId = ScriptProperties.getProperty('theses')[i][2];
var thesesType = ScriptProperties.getProperty('theses')[i][1];
importTheses(target, thesesId, thesesType);
}
}
showURL(docName, link); // Shows document name and link in UI
So, how can I fix that? How can I get the code run until the line showURL(docName, link);?
showList();
This function creates only Ui.
You are setting the script properties only in the Server Handler which executes on the click of submit button. Since then:
ScriptProperties.getProperty('theses');
will hold nothing. So you need to call these lines:
var thesesArrays = ScriptProperties.getProperty('theses');
for (var i = 0; i < thesesArrays.lenght(); i++){
var thesesId = ScriptProperties.getProperty('theses')[i][2];
var thesesType = ScriptProperties.getProperty('theses')[i][1];
importTheses(target, thesesId, thesesType);
}
Inside server handler or put them inside a method and call the method from the server Handler.
I've created a program where you can choose a set of images by checking checkboxes. The image URL's and the alt-texts are stored in two arrays. When clicking av button on the HTML-page you open a new window that calls on the arrays with window.opener.
When closing the new window I would like to empty the arrays. Otherwise the pictures chosen in the first round are displayed in the slideshow when opening it the second time. I understand you can empty arrays by this method: array.length= 0;
But where do I add the code? I'm quite lost. I'm pasting the code, perhaps someone can give me a hand.
var imgUrlList = [], imgTextList = [], //These arrays need to be emptied
windVar = null;
function init() {
var tags, i, openWindow;
tags = document.getElementsByClassName("unmarkedImg");
openWindow = document.getElementById("slideShowBtn");
openWindow.onclick = savePicsForSlideshow;
for (i = 0; i < tags.length; i++) {
tags[i].parentNode.onmouseover = showLargePict;
tags[i].parentNode.onmouseout = hideLargePict;
}
}
window.onload = init;
function showLargePict() {
var largePictTagDiv = this.getElementsByClassName("innerBox")[0];
var largePictTagParentDiv = largePictTagDiv.parentNode;
var imgTag = largePictTagParentDiv.getElementsByTagName('img')[0];
var checkBoxlargePict = largePictTagDiv.getElementsByTagName('input')[0];
if (checkBoxlargePict.checked)
imgTag.className = "markedImg";
else imgTag.className = "unmarkedImg";
largePictTagDiv.style.visibility = "visible";
} // End showLargePict
function hideLargePict() {
var largePictTag;
largePictTag = this.getElementsByClassName("innerBox")[0];
largePictTag.style.visibility = "hidden";
}
function savePicsForSlideshow() {
var innerBoxes = document.getElementsByClassName("innerBox");
for (i = 0; i < innerBoxes.length; i++) {
checkBoxlargePict = innerBoxes[i].getElementsByTagName('input')[0];
if (checkBoxlargePict.checked) {
var imgTagSrc = innerBoxes[i].getElementsByTagName('img')[0].src;
imgUrlList.push(imgTagSrc);
var spanTagText = innerBoxes[i].getElementsByTagName('span')[0].innerHTML;
imgTextList.push(spanTagText);
}
}
if (imgTextList.length > 0) {
newWindow(500, 600, "slideshow.htm");
}
}
function newWindow(width, height, filename) {
var windowProperties;
windowProperties = "top=100,left=100,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no,width=" + width + ",height=" + height;
if (windVar != null) if (windVar.closed == false) windVar.close();
windVar = window.open(filename, "", windowProperties);
}
Please excuse my programming and English grammar shortcomings. I'm new to javascript.
//Henrik, Göteborg, Sweden.
At the beginning of the savePicsForSlideshow function, empty out each array.
imgUrlList.length = 0;
imgTextList.length = 0;
You can check if thw window is close with the property closed of the object window
if(window.closed)
{
array.length = 0;
}
I need to add an onclick event to shapes from Visio in SharePoint, with JavaScript, like the vwaControl handler shapeselectionchanged but on click, is there any way I could do that?
I'm sorry about my English is not my native language.
I hope you can understand me.
I just did something similar.
You can use the shapeSelectionChangedHandler to handle clicks to. As far as I know there is no onClick functionality, but shapeSelectionChangedHandler works fine for me.
See:
Programming with Visio in SharePoint, create new Outlook meeting in ?Javascript?
See: http://msdn.microsoft.com/en-us/library/gg243427.aspx for guide to set it up with Content WebPart and so on.
Code I use, just add what you want in shapeSelectionChangedHandler = function(source, args) {}
<script language="javascript">
var app = Sys.Application;
app.add_load(onApplicationLoad);
// hold an instance of the Visio VWA control
var vwaControl;
var shapeSelectionChangedHandler = null;
function onApplicationLoad()
{
vwaControl= new Vwa.VwaControl("WebPartWPQ4");
vwaControl.addHandler("diagramcomplete", onDiagramComplete);
vwaControl.addHandler("shapeselectionchanged", shapeSelectionChangedHandler);
}
function onDiagramComplete()
{
var vwaPage = vwaControl.getActivePage();
vwaPage.setZoom(35); // force the initial zoom level
}
shapeSelectionChangedHandler = function(source, args)
{
// get the selected shape from the shapes on the page
var vwaPage = vwaControl.getActivePage();
var vwaShapes = vwaPage.getShapes();
var shape = vwaShapes.getItemById(args);
// get the data to display for the selected shape
var data = shape.getShapeData();
var strRoomName = "";
var strFloorNumber = "";
var strCapacity = "";
var strStatus = "";
for (var j = 0; j < data.length; j++)
{
if (data[j].label == "RoomName")
{
strRoomName = data[j].value;
continue;
}
if (data[j].label == "FloorNumber")
{
strFloorNumber = data[j].value;
continue;
}
if (data[j].label == "Capacity")
{
strCapacity = data[j].value;
continue;
}
if (data[j].label == "RoomStatus")
{
strStatus = data[j].value;
continue;
}
}
// get the selected state input and set its value
var inputRoomName = document.getElementById('strRoomName');
inputRoomName.value = strRoomName;
var inputFloorNumber = document.getElementById('strFloorNumber');
inputFloorNumber.value = strFloorNumber;
var inputCapacity = document.getElementById('strCapacity');
inputCapacity.value = strCapacity;
var inputStatus = document.getElementById('strStatus');
inputStatus.value = strStatus;
}
I am writing a Javascript dialog script which is seen in a lot of typical Role Playing Games.alt text http://www.dailynintendo.com/wp-content/uploads/2008/12/luminous-arc-2-dialogue.jpg
At the moment I got an array with text strings which you can skip trough. I got at the point where you can make a decision and based on the input a different string will show.
However I don't think this is the right way to do it. These are the requirements for the script:
Support for multiple dialog scripts
multiple characters
user decision input ("Do you like me?" -yes -no)
This is my code at the moment:
// Intro script
var script_intro = [];
script_intro[0] = 'Hello how are you?';
script_intro[1] = 'So I heard..';
script_intro[2] = 'This is a cool game!';
script_intro[3] = [];
script_intro[3][0] = 'Do you like me?';
script_intro[3][1] = [];
script_intro[3][1][0] = 'Jah';
script_intro[3][1][1] = 4;
script_intro[3][2] = [];
script_intro[3][2][0] = 'Nah';
script_intro[3][2][1] = 5;
// Intro script: variation I
var script_intro_1 = [];
script_intro_1[0] = 'I love you too!';
// Intro script: variation II
var script_intro_2 = [];
script_intro_2[0] = 'Damn you...';
function initDialog()
{
// This is where the text will be shown
var dialog = document.getElementById('dialog');
var content = document.getElementById('content');
var nextButton = document.getElementById('nextButton');
var optionButton_1 = document.getElementById('optionButton_1');
var optionButton_2 = document.getElementById('optionButton_2');
// How fast the characters will appear after each other (milliseconds)
var scrollSpeed = 50;
}
// Scroll text per line, character
function scrollText(script, line)
{
var char = 0;
// If this line contains a question that requires user input
if(typeof(script[line]) == 'object')
{
var textScroller = setInterval(
function()
{
// Add the string char for char
content.innerHTML += script[line][0][char];
char ++;
if(char >= script[line][0].length)
{
clearInterval(textScroller);
// Show options
options(script, line);
}
}, scrollSpeed);
}
else
{
var textScroller = setInterval(
function()
{
content.innerHTML += script[line][char];
char++;
if(char >= script[line].length)
{
clearInterval(textScroller);
// Show next line
next(script, line);
};
}, scrollSpeed);
}
}
function next(script, line)
{
line = line + 1;
// Last line has been shown
if(script[line] == undefined)
{
//alert('End of dialog');
}
else
{
nextButton.style.visibility = 'visible';
nextButton.onclick = function()
{
nextButton.style.visibility = 'hidden';
content.innerHTML = '';
scrollText(script, line);
}
}
}
function options(script, line)
{
optionButton_1.innerHTML = script[line][1][0];
optionButton_2.innerHTML = script[line][2][0];
optionButton_1.style.visibility = 'visible';
optionButton_2.style.visibility = 'visible';
optionButton_1.onclick = function()
{
optionButton_1.style.visibility = 'hidden';
optionButton_2.style.visibility = 'hidden';
content.innerHTML = '';
scrollText('script_intro_1', 0);
}
optionButton_2.onclick = function()
{
optionButton_1.style.visibility = 'hidden';
optionButton_2.style.visibility = 'hidden';
content.innerHTML = '';
scrollText('script_intro_2', 0);
}
}
html
<body onload="scrollText(script_intro, 0)">
<h1>rpg</h1>
<a id="reset" href="#">Reset</a>
<div id="device">
<div id="dialog">
<strong>NPC:</strong>
<div id="content"></div>
<a id="nextButton" href="#">Next</a>
<a id="optionButton_1" href="#"></a>
<a id="optionButton_2" href="#"></a>
</div>
</div>
</body>
I could really use some feedback. What is the best way to write such script with the requirements above? Is using JSON or XML a better option than an Array for the dialog scripts?
I especially need some hints on how to implement multiple choices in the script.
Thank you!
If this is a script that has a scripted flow to it, I would use the state machine pattern.
http://www.eventhelix.com/RealtimeMantra/HierarchicalStateMachine.htm
There are tons of links, I just grabbed the first I searched from google. What I would do is have a state for each situation the user will presented with options. Each option would be a transition to another state. So for instance
function State(questionText){
this.transitionsOut = [];
this.questionText = questionText;
}
State.prototype = {
transitionsOut:null,
questionText:null,
}
function Transition(startState, endState, optionText){
startState.transitionsOut[startState.transitionsOut.length] = this;
this.start = startState;
this.end = endState;
}
Transition.prototype = {
start:null,
end:null,
optionText:null
}
Then what you can do, is make your state machine, and then for the current state, print out your State Message, then underneath list each option for that state.
var startState = new State('Where do you want to go');
var north = new State('North');
var south = new State('South');
var transition1 = new Transition(startState,north,'Lets go north');
var transition2 = new Transition(startState,south,'Lets go south');
The code to then display what is in the current state, and the options is trivial, as is the transition from one state to another based on what the user picks.