I am loading in a js file to build a form (I know this isn't standard; this is just for my learning). The contents of that file look like this:
window.captor = (function () {
function Captor () {
}
var captor = {
create: function () {
return new Captor();
}
};
Captor.prototype.build = function (json) {
//CREATE BACKDROP WITH CLOSE FUNCTION
var interstitial = this.backdrop();
//CREATE DIV CONTAINER
var container = this.container();
//CREATE TITLE
var title = this.setTitle();
//CREATE CALL TO ACTION
var cta = this.callToAction();
//CREATE FORM WITH INPUTS
var form = this.capture(json);
interstitial.appendChild(container);
container.appendChild(title);
container.appendChild(cta);
container.appendChild(form);
document.body.parentNode.appendChild(interstitial);
};
Captor.prototype.backdrop = function(){
var b = document.createElement("div");
b.setAttribute('style',"position:fixed;width:100%;height:100%;background: rgba(0,0,0,.6);z-index: 100;");
return b;
};
Captor.prototype.container = function(){
var c = document.createElement("div");
c.setAttribute('style',"position:relative;background:#dedede;min-height:100px;width: 480px;margin: auto;top: 45%;-webkit-border-radius: 10px; -moz-border-radius: 10px; border-radius: 10px;");
return c;
};
Captor.prototype.setTitle = function(){
var t = document.createElement("h1");
var inside = document.createTextNode("Join Our Newsletter");
t.appendChild(inside);
return t;
};
Captor.prototype.callToAction = function(){
var cta = document.createElement("p");
var inside = document.createTextNode("Would you like to find out more about stuff? Join our newsletter!");
cta.appendChild(inside);
return cta;
};
Captor.prototype.capture = function(json){
var f = document.createElement("form");
var hidden = document.createElement("input");
hidden.setAttribute('type',"hidden");
f.appendChild(hidden);
return f;
};
return captor;
}());
Then after including that file, I call:
var n = captor.create();
n.build(window.builder.getj);
Where window.builder.getj returns a json object (I haven't done anything with that obj, just yet).
So far, the form doesn't build. I'm not sure if anything is getting called. When I look at the console, nothing is output. If I call var c = captor.create(); it returns undefined. If I run c = captor.create(); it returns Captor {build: function, backdrop: function, container: function, setTitle: function, callToAction: function…}.
I feel like I must be missing something, but for the life of me I can't see what it is. How do I get this form to render in the correct way?
Related
I have a javascript code which contains more number of functions. inside each functions code looks similar. Is there any way to reduce and optimize the code using javascript oop. So my script goes like this.
function cal_a() {
var a_list = [];
function fetch_dom() {
var a = document.getElementById("pOne");
a.innerHTML = "Hello";
a_list.push("Hello");
}
fetch_dom();
}
function cal_b() {
var b_list = [];
function fetch_dom() {
var b = document.getElementById("pTwo");
b.innerHTML = "World";
b_list.push("World");
}
fetch_dom();
}
cal_a();
cal_b();
//..
//..
//..
//cal_z();
HTML code looks
<p id="pOne"></p>
<p id="pTwo"></p>
Please pardon me if the question is wrong. Thanks in advance.
I have to say the list doesn't do anything here
function cal(id, text) {
var list = [];
function fetch_dom() {
var el = document.getElementById(id);
el.innerHTML = text;
list.push(text);
}
fetch_dom();
}
cal('id', 'text');
Sure, pull out the common parts and make a function which returns a function.
function make_cal(elem_id, text) {
return function() {
var list = [];
function fetch_dom() {
var b = document.getElementById(elem_id);
b.innerHTML = text;
list.push(text);
}
fetch_dom();
}
}
let cal_a = make_cal("pOne", "Hello");
let cal_b = make_cal("pTwo", "World");
The fetchDom is better to be placed on object constructor:
function Cal(elClass, text) {
this.list = [];
this.elClass = elClass;
this.text = text;
}
Cal.prototype.fetchDom = function() {
var el = document.getElementById(this.elClass);
el.innerHTML = this.text;
this.list.push(el);
};
var calA = new Cal("pOne", "Hello");
var calB = new Cal("pTwo", "World");
calA.fetchDom();
calB.fetchDom();
Then you can access your lists by:
calA.list;
calB.list;
I am trying to call the method getTitulo, getDuracion and getLink inside the cancion.js file but when i call the function it returns the following error: "listaCanciones_Lcl[i].getTitulo is not a function". I have searched in different websites but i didnt got lucky with finding an answer. Hopefully someone here can give me some help, i will gladly appreciate it!
//Logic.js file
var listaCanciones = [],
ejecuTitulo = '',
ejecuDuracion = '',
ejecuLink = '';
var btnGenerarLista = document.getElementById("addList").addEventListener("click", agregarCanc);
var btnAgregarLista = document.getElementById("gnrList").addEventListener("click", llenarTabla);
function agregarCanc (){
var nameSong = document.querySelector('#nameSong').value;
var duraSong = document.querySelector('#duraSong').value;
var linkSong = document.querySelector('#linkSong').value;
var objCancion = new Cancion(nameSong, duraSong, linkSong);
listaCanciones.push(objCancion);
var listaCancionesJson = JSON.stringify(listaCanciones);
localStorage.setItem('json_canciones', listaCancionesJson);
}
function llenarTabla (titulo){
var celdaTitulo = document.querySelector('#tituloList'),
celdaDuracion = document.querySelector('#duracionList'),
celdaLink = document.querySelector('#linkList'),
listaCanciones_Lcl = JSON.parse(localStorage.getItem('json_canciones'));
for(var i=0; i<listaCanciones_Lcl.length;i++){
// Acceder a lista canciones
I am getting an error in this line, where is says "getTitulo" is not a function but i dont really know why?
var nodoTextoTitulo = document.createTextNode(listaCanciones_Lcl[i].getTitulo()),
nodoTextoDuracion = document.createTextNode(listaCanciones_Lcl[i].getDuracion()),
nodoTextoLink = document.createTextNode(listaCanciones_Lcl[i].getLink());
// Create td
var elementoTdTitulo = document.createElement('td'),
elementoTdDuracion = document.createElement('td'),
elementoTdLink = document.createElement('td');
// Celda Id Append Child
elementoTdTitulo.appendChild(nodoTextoTitulo);
elementoTdDuracion.appendChild(nodoTextoDuracion);
elementoTdLink.appendChild(nodoTextoLink);
// Fila Append Child
celdaTitulo.appendChild(elementoTdTitulo);
celdaDuracion.appendChild(elementoTdDuracion);
celdaLink.appendChild(elementoTdLink);
}
}
//Cancion.js File
var Cancion = function(pTitulo, pDuracion, pLink){
var id = 0;
var titulo = pTitulo;
var duracion = pDuracion;
var link = pLink;
this.getId = function (){
return id;
};
this.setTitulo = function (pTitulo){
titulo = pTitulo;
};
this.getTitulo = function(){
return titulo;
};
this.setDuracion = function(pDuracion){
duracion = pDuracion;
};
this.getDuracion = function(){
return duracion;
};
this.setLink = function (pLink){
link = pLink;
};
this.getLink = function(){
return link;
};
};
First, make sure you are loading the Cancion.js file before the others in your HTML. Your problem is that when you parse the JSON back out of local storage, Cancion is not a known object, so getTitulo is undefined. You'll have to do listaCanciones_Lcl[i].titulo; instead.
And another change you'll need is to loosen the scope of your variables. The reason you need this.x = pX is because before JSON.stringify(new Cancion(1, 2, 3)) just returned "{}". With this code it returns "{"id":0,"titulo":1,"duracion":2,"link":3}", which I think is what you were after.
function Cancion(pTitulo, pDuracion, pLink){
this.id = 0;
this.titulo = pTitulo;
this.duracion = pDuracion;
this.link = pLink;
this.getId = function (){
return this.id;
};
this.setTitulo = function (pTitulo){
this.titulo = pTitulo;
};
this.getTitulo = function(){
return this.titulo;
};
this.setDuracion = function(pDuracion){
this.duracion = pDuracion;
};
this.getDuracion = function(){
return this.duracion;
};
this.setLink = function (pLink){
this.link = pLink;
};
this.getLink = function(){
return this.link;
};
};
var objWithFunction = {
name: 'Object with Function',
getName: function() { return this.name }
};
undefined
objWithFunction.getName() // --> "Object with Function"
var string = JSON.stringify(objWithFunction)
string // -=> "{"name":"Object with Function"}"
JSON is for data only..
Better you create a model, and fill it with data.. but this model has to exist in your application.. or you load the model parallel to your data..
function SomeThing() {};
SomeThing.prototype.getName = function() { return this.name };
var Thing1 = new SomeThing(JSON.parse("{name:'ThingOne'}"));
Thing1.getName(); // ThingOne
I have a JavaScript Win Pivot Application
Into the Hub I am retrieving some information:
function initPages(options) {
for (var i = 0; i < options.length ; i++) {
var menuItem = options[i];
menuItem.showBanner = (i == 0);
definePages(options);
}
}
and in a .Js file I have the definePages function created:
functions.js:
function definePages(item) {
var action = item[0];
var animation = item[1];
var scyfy = item[2];
var localmovies = item[3];
var clasic = item[4];
var comedy = item[5];
var biography = item[6];
var drama = item[7];
var kids = item[8];
var musical = item[9];
var romantic = item[10];
var suspense = item[11];
var horror = item[12];
var art = item[13];
var personalities = item[14];
var history = item[15];
var society = item[16];
}
Now, in my section 1 I initialize the page by calling another function there:
ready: function (element, options) {
// TODO: Inicializar la página aquí.
options = options || {};
initMovies();
},
function initMovies() {
var element = document.getElementById("movieContainer");
//var movies = ??????????????????????????
//console.log(movies);
//it keeps going
}
I need to be able to retrive, in that var movies, the var action, from the functions.Js or, which is the same, the items[0]...
However, if I call a function in functions.Js, which is defined in section1Page, it won´t work...
I can call functions and pass data from anywhere to functions.Js, but not the other way around...
Any ideas on what should I do? Thanks!!!
I fixed it... I created a global var in function.Js and I get the info from the array in each section later on:
function definePages(item) {
tooSleepyToThink = item;
}
section1Page:
function initMovies() {
var elemento = document.getElementById("movieContainer");
console.log(tooSleepyToThink[0].text);
}
I'm having trouble putting an array's value into the function call of an added event on a dynamically created element.
So here's the hard-coded version that works just fine:
var parent_item = document.getElementById("developers_container");
var part = document.createElement('div');
part.id = "developer_A";
part.name = "developer_A";
part.className = "developer_block_un";
part.onmouseover = function() { hilight_dev('A',true)};
part.onmouseout = function() { hilight_dev('A',false)};
parent_item.appendChild(part);
var parent_item = document.getElementById("developer_A");
var part = document.createElement('span');
part.id = "developer_title_A";
part.name = "developer_title_A";
part.className = "developer_un";
part.innerHTML = "John Doe";
part.onclick = function() { select_dev('A')};
parent_item.appendChild(part);
Basically what this does is create a listing of users for selecting. Each user's listing has mouseover, mouseoff and onclick events. The meat of the above code is currently being duplicated for every user.
I want to replace the duplication with an array-based function:
var dev_id = new Array();
var dev_fn = new Array();
var dev_ln = new Array();
document.getElementById("developers_container").innerHTML = "";
dev_id[0] = "A";
dev_fn[0] = "John";
dev_ln[0] = "Doe";
dev_id[1] = "B";
dev_fn[1] = "John";
dev_ln[1] = "Smith";
dev_id[2] = "C";
dev_fn[2] = "John";
dev_ln[2] = "Jones";
dev_id[3] = "D";
dev_fn[3] = "John";
dev_ln[3] = "Yougetthepoint";
document.getElementById("developers_container").innerHTML = "";
for(var i = 0; i < dev_id.length; i++)
{
var parent_item = document.getElementById("developers_container");
var part = document.createElement('div');
part.id = "developer_"+dev_id[i];
part.name = "developer_"+dev_id[i];
part.className = "developer_block_un";
part.onmouseover = function() { hilight_dev(dev_id[i],true)};
part.onmouseout = function() { hilight_dev(dev_id[i],false)};
parent_item.appendChild(part);
var parent_item = document.getElementById("developer_"+dev_id[i]);
var part = document.createElement('span');
part.id = "developer_title_"+dev_id[i];
part.name = "developer_title_"+dev_id[i];
part.className = "developer_un";
part.innerHTML = dev_fn[i]+"<BR>"+dev_ln[i];
part.onclick = function() { select_dev(dev_id[i])};
parent_item.appendChild(part);
}
Every bit of that is working just fine, save for the added events. Where "dev_id[i]" is being used within the function code (as in "part.onmouseover = function() { hilight_dev(dev_id[i],true)};"), it doesn't seem to be doing anything. The event fires off and the function is called, but the variable that's being passed is coming through as "undefined" instead of that user's id like it should be.
I'm hoping someone here knows how to get this to work. Googling was not very helpful, and this is one of those silly little issues that's cost me half a day trying to figure out. Any and all help is greatly appreciated.
Thanks
part.onmouseover = function(i) {
return function() { hilight_dev(dev_id[i],true) }
}(i)
The variable i that you have in the loop is undefined at the time the function is invoked, you need to form a closure over it in order to keep it's value. Please refer to "JavaScript, the Good Parts" by Douglas Crockford for a detailed explanation on this
Err.. after Neil's comment.. yes.. i is not undefined.. it will always be the length of dev_id.. in any case, it's not what the op wants :)
I am trying to do the following:
var element = {};
element.attrA = 'A';
element.attrB = 1;
element.autoAdvance = function(){
var that = this;
setInterval(function(){
that.attrB++;
},100);
}
element.instance = function(){
var clone = $.extend(true, {}, this);
return clone;
}
Now I can do the following just fine:
var e1 = element.instance();
var e2 = element.instance();
e1.attrA = 'not e2s business';
e2.attrA = 'not e1s attrA';
The trouble starts when I try to use autoAdvance:
e1.autoAdvance();
will start the autoAdvance for all cloned 'instances' of element. I am sure this is probably rather trivial but I just don't know how to refer to the parent object inside my autoAdvance-function in a way that it gets properly cloned and only affects the instance. Thanks!
EDIT:
This is the actual code I am using:
var player = {};
player.sprites = {};
player.sprites.back = ['img/playerback_01.png','img/playerback_02.png','img/playerback_03.png'];
player.sprites.head = ['img/playerhead_01.png','img/playerhead_02.png','img/playerhead_03.png'];
player.back = new Image();
player.back.src = player.sprites.back[0];
player.head = new Image();
player.head.src = player.sprites.head[0];
player.loop = function(){
var that = this;
var loop = setInterval(function(){
//remove the [0] state from the sprite array and add it at [2]
var state = that.sprites.head.shift();
that.sprites.head.push(state);
state = that.sprites.back.shift();
that.sprites.back.push(state);
that.back.src = that.sprites.back[0];
that.head.src = that.sprites.head[0];
}, 100);
}
player.x = 0;
player.y = 0;
player.instance = function(){
var clone = $.extend(true, {}, this);
return clone;
}
I generate two players:
var player1 = player.instance();
var player2 = player.instance();
But what is happening is that when I use:
player1.loop();
The animation for player2 will start to play as well.
I suggest you start using "class" in JavaScript. They are more or less a function.
function Player(){
this.sprites={};
......
}
Player.prototype.loop=function(){
....
}
var player1=new Player();
var player2=new Player();
player1.loop();
player2.loop();// this should work better
It doesn't really answer your question but it's an alternative way to write code in a cleaner and better way.