changing text inside element script - events

I have a script which contains 2 functions.
First function is responsible for creating a paragraph element inside existing div.
Second part of the script is a function which changes the predefined text (the text is predefined in the first function) triggered by onclick event.
HTML:
Change Text
<div id='box'></div>
Javascript:
var x, el;
window.onload = function createEl() {
x = document.getElementById('box');
el = document.createElement('p');
el.appendChild(document.createTextNode("Hello"));
x.appendChild(el);
}
function changeText() {
el.innerHTML = 'other text';
}
My question is: Is there any way to achieve the same result but do this without using global variables? I know there should be an option just to pass the variable from one function to another and then update it there, but I am not sure how to do this though

Just give the p tag an id and use document.getElementById to get it.

Related

mousePressed method is launching prematurely in p5js

I created the following function using p5.js and the mousePressed method is firing immediately when the page loads. It doesn't wait for me to click the button object to display a paragraph containing the ans variable.
What am I doing wrong?
function setup() {
var ans = generate();
var checkMe = createButton('Check Answer');
checkMe.mousePressed(createP(ans));
}
Let's take a closer look at this line:
checkMe.mousePressed(createP(ans));
This could be split into two lines:
var createPValue = createP(ans);
checkMe.mousePressed(createPValue);
In other words, you're calling the createP() function, and then passing the value returned (which is probably undefined) into the mousePressed() function. I'm surprised this doesn't cause an error in the JavaScript console.
Instead, what you want to do is pass a function as a value into the mousePressed() function. Since you need to use a parameter, you might do that this way:
function callCreateP(){
createP(ans);
}
checkMe.mousePressed(callCreateP);
Notice that callCreateP doesn't have parentheses () after its name when we pass it into the mousePressed() function. That's because we're using it as a value instead of directly calling it.
You could shorten that to this line:
checkMe.mousePressed(function(){ createP(ans); });

How to indent the first line of a paragraph in CKEditor

I'm using CKEditor and I want to indent just the first line of the paragraph. What I've done before is click "Source" and edit the <p> style to include text-indent:12.7mm;, but when I click "Source" again to go back to the normal editor, my changes are gone and I have no idea why.
My preference would be to create a custom toolbar button, but I'm not sure how to do so or where to edit so that clicking a custom button would edit the <p> with the style attribute I want it to have.
Depending on which version of CKE you use, your changes most likely disappear because ether the style attribute or the text-indent style is not allowed in the content. This is due to the Allowed Content Filter feature of CKEditor, read more here: http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter
Like Ervald said in the comments, you can also use CSS to do this without adding the code manually - however, your targeting options are limited. Either you have to target all paragraphs or add an id or class property to your paragraph(s) and target that. Or if you use a selector like :first-child you are restricted to always having the first element indented only (which might be what you want, I don't know :D).
To use CSS like that, you have to add the relevant code to contents.css, which is the CSS file used in the Editor contents and also you have to include it wherever you output the Editor contents.
In my opinion the best solution would indeed be making a plugin that places an icon on the toolbar and that button, when clicked, would add or remove a class like "indentMePlease" to the currently active paragraph. Developing said plugin is quite simple and well documented, see the excellent example at http://docs.ckeditor.com/#!/guide/plugin_sdk_sample_1 - if you need more info or have questions about that, ask in the comments :)
If you do do that, you again need to add the "indentMePlease" style implementation in contents.css and the output page.
I've got a way to indent the first line without using style, because I'm using iReport to generate automatic reports. Jasper does not understand styles. So I assign by jQuery an onkeydown method to the main iframe of CKEditor 4.6 and I check the TAB and Shift key to do and undo the first line indentation.
// TAB
$(document).ready(function(){
startTab();
});
function startTab() {
setTimeout(function(){
var $iframe_document;
var $iframe;
$iframe_document = $('.cke_wysiwyg_frame').contents();
$iframe = $iframe_document.find('body');
$iframe.keydown(function(e){
event_onkeydown(e);
});
},300);
}
function event_onkeydown(event){
if(event.keyCode===9) { // key tab
event.preventDefault();
setTimeout(function(){
var editor = CKEDITOR.instances['editor1'], //get your CKEDITOR instance here
range = editor.getSelection().getRanges()[0],
startNode = range.startContainer,
element = startNode.$,
parent;
if(element.parentNode.tagName != 'BODY') // If you take an inner element of the paragraph, get the parentNode (P)
parent = element.parentNode;
else // If it takes BODY as parentNode, it updates the inner element
parent = element;
if(event.shiftKey) { // reverse tab
var res = parent.innerHTML.toString().split(' ');
var aux = [];
var count_space = 0;
for(var i=0;i<res.length;i++) {
// console.log(res[i]);
if(res[i] == "")
count_space++;
if(count_space > 8 || res[i] != "") {
if(!count_space > 8)
count_space = 9;
aux.push(res[i]);
}
}
parent.innerHTML = aux.join(' ');
}
else { // tab
var spaces = " ";
parent.innerHTML = spaces + parent.innerHTML;
}
},200);
}
}

For loop with events

I'm working with along with an online tutorial and trying to understand the code below. What I don't get is why this works more than two times. When the loop has been executed two times i == len and the condition i < len isn't true anymore. So how come it's possible to toggle the different clases more than two times?
My guess is that when the condition is false i gets set to 0 again, did I understand that correctly? Hope someone can help me, I didn't find an explanation of this particular problem anywhere online.
HTML
<button>Normal</button>
<button>Changed</button>
CSS
.normal {background-color: white;color:black;}
.changed {background-color: black;color:white;}
JavaScript
(function() {
var buttons = document.getElementsByTagName("button");
for (var i = 0, len = buttons.length; i < len; i +=1)
buttons[i].onclick = function() {
var className = this.innerHTML.toLowerCase();
document.body.className = className;
}}
}());
The for loop gets excecuted only once and iterates through all buttons.
In the for loops body, you define an onclick function for each button.
So, before you can click anywhere the loop already has finished, and added an onclick function to each single button, which will be called everytime, you click on that button.
With button[i].onclick = function() {...} you add an event handler function to the buttons click event.
You should read more about event handlers in general.

trigger.io file.saveURL and looping

I am using the file.saveURL in a loop and its working good but I am seeing some strage things. Basically I loop over about 70 images and then grab the uri to them after they are saved and store that locally so I can then use it to display in the app
What happens is that once the loop is done I display the images out but randomly some of the images are the same. I have validated the correct URL is being passed but its as if and I don't know for sure but maybe the function is not done with the previous and is somehow overwriting it?
This makes the most sence because the issue usually happens with images right next to each other.
So I guess my question is, does the file.saveURL only work on a one to one aspect, like it has to by synchronous?
If that is the case what would be the recommended approach for looping over and saving these images.
Thanks!
EDIT
This is a basic sample (I have some conditional stuff in there but this is the main part)
I have the JSON object stored and I loop over it
$(data).each(function(i){
var slcval = 'speaker' + this.SID;
var imageID = 'simageid' + this.IMAGE;
var speakerImage = "http://mydomain.com/users/images/speakers/" + this.IMAGE;
//then I call the save url function
saveURLImage(speakerImage,slcval,'speaker',this.SID,imageID);
}
this loops over my images and calls the save image function that then does the save URL function
function saveURLImage(url,ID,type,extraVal,imageID){
forge.file.saveURL(url, function (file) {
forge.file.URL(file, function (url) {
var fileObject = JSON.stringify(url);
localStorage.setItem(ID, fileObject);
})
});
}
This is a simple version of it, I have some other parts that set some localstorage vars but this is the main call.
So my problem was a scoping issue
so if anyone else comes arrocss this I found this thred that helped out
Javascript: function in setTimeout and references
Basically what I did was creat a function that has an announmous function in it so the scope would be correct
function saveURLImage(url,ID,type,extraVal,imageID) {
(function() {
saveURLImageScoped(url,ID,type,extraVal,imageID)
})();
}
so the function name is still the same as before but I renamed the main function saveURLImageScoped and now it has its own variable scope

How to change the value of a text box in Firefox Add-on SDK (Jetpack)?

I'm trying to change the contents of a text box (using the latest version of Add-on SDK, 1.05b). I'm able to get its contents but I could not find out how I can change it. Here's the relevant part of my code:
var deasciifyItem = contextMenu.Item({
label: "Label",
context: contextMenu.SelectorContext("input[type=text], textarea"),
contentScript: 'self.on("click", function (node) {' +
'var text = node.value;' +
'self.postMessage(text);' +
'});',
onMessage: function(text) {
if (text.length == 0) {
throw ("Text to convert must not be empty!");
}
console.log(text);
console.log(someMyFunction(text));
text = "A computed new value to replace the old value in text box!";
}
});
I can read the contents of any text box and log it to the console but how can I change its contents, e.g. the node.value by passing node.value to a function that I defined? I tried to pass node.value as a parameter to self.postMessage function but it does not work. What I'm trying to achieve is something like:
node.value = someMyFunction(node.value);
I also tried to do that inside
' node.value = someMyFunction(node.value); ' + ...
part but then it says that someMyFunction is not defined in this context (I know that it is defined because I tested that
console.log(someMyFunction(text));
works).
I'm stuck at this point. Any tips? I can neither force someMyFunction into the scope of contentScript nor can I get the 'node' within 'onMessage'. What used to be very easy in previous versions of Add-on SDK turned out to be very difficult (or very unintuitive, at least) this time.
If you can't include the entire function inside your content script (you can put your function in a separate file if it makes this easier) then you can post a message back to your content script, although this needs a function inside your content script to receive the message. See Working with Content Scripts.

Resources