i've tried to create some notification message that should showing up anytime i have a new message. is done but the problem is if i refresh the browser then the message showing again. this is wrong. it should be hidden if already shows. does not matter if i refresh the browser again. it should be not show.
this is my code:
$(function(){
/* global MessageBus */
var name,
msgCube = $('.message_bus').data('queue') ;
MessageBus.ajax = function(args){
args["headers"]["X-NAME"] = name;
return $.ajax(args);
};
MessageBus.subscribe("/tasks" + msgCube, function(msg){
var obj = $.parseJSON(msg);
showMsg = function(){
var deffered = $.Deferred();
if(obj.state.viewed == 0){
dataModel = '<div class="msg">'
+ '<p>' + obj.task.name + '</p>'
+'<p>' + obj.task.description + '</p>';
$('.noticed').html(dataModel);
setTimeout(function () {
$(".noticed").fadeOut(300);
deffered.resolve();
}, 5000);
}
return deffered.promise();
};
//test don't show up after load
stopToLoad = function(){
console.log('load after');
$('.noticed').hide();
};
showMsg().then(function(){
stopToLoad();
});
//console.log(msg);
}, 0);
});
if you guys have an any sugestion, any solution, idea, i'll be glad and thanks for the Adviced.
best regard,
Related
I am working on a web application, I am just using javascript at the moment. The problem that I am trying to solve is that I have three different objects and only one HTML page. Based on the user click event, I want the objects for the chosen category to be loaded and displayed on the same page. For example, let's say the user is at the home page, if they click on category A from the navigation bar, the page will be loaded first and then the script will load the objects to the data structure. Finally, display them to the javascript generated HTML containers. The same thing should happen with a different category after the User click Event is fired. To be more precise I want to be able to reuse the HTML page for different objects without having to create a page for each category.
I already have created the code that does all of the data loading and HTML generation for the n objects I want to load. The code works fine when I am at the object's page but if the event is fired from another page nothing seems to happen. I am guessing this has to do with page loading timing.
I have posted the complete code of the part that I am working on.
var dataController = (function() {
var JSONurls = {
bags: "../JSON/bags.json",
bc: "../JSON/briefcases.json",
belts: "../JSON/belts.json",
accs: "../JSON/accs.json",
};
ProductObj = function(name, des, colors, price, pics, type, ID) {
this.name = name;
this.description = des;
this.colors = colors;
this.price = price;
this.pics = pics;
this.type = type;
this.ID = ID;
};
var dataStruc = {
allProducts: {
bags: [],
briefcases: [],
belts: [],
accessories: [],
},
};
return {
addProd: function(obj) {
var newProd, ID;
if (dataStruc.allProducts[obj.type].length > 0) {
ID =
dataStruc.allProducts[obj.type][
dataStruc.allProducts[obj.type].length - 1
].ID + 1;
} else {
ID = 0;
}
newProd = new ProductObj(
obj.name,
obj.description,
obj.colors,
obj.price,
obj.pics,
obj.type,
obj.ID
);
dataStruc.allProducts[obj.type].push(newProd);
return newProd;
},
getDataStruct: function() {
return dataStruc;
},
getJsonUrls: function() {
return JSONurls;
},
loadJSON: function(url, cat, callback) {
var requestURL, request, JsonObj;
requestURL = url;
request = new XMLHttpRequest();
request.open("GET", requestURL);
request.responseType = "text";
request.send();
request.onload = function() {
JsonObj = JSON.parse(request.response);
dataStruc.allProducts[cat] = JsonObj[cat];
callback(cat);
};
},
};
})();
var UIcontroller = (function() {
var DomStrings = {
shopCatg: ".shop-catg",
productCont: ".product-container",
};
//public methods
return {
// function display the object based on the category based on the event target
displayObjectToPage: function(cat) {
var deafultHtml;
// 1. loop over the product category
dataController.getDataStruct().allProducts[cat].forEach(function(cur) {
deafultHtml =
'<div class="col-lg-4 col-md-6 col-sm-10">' +
'<img class="img-fluid" src="../img/' +
cur.type +
"/" +
cur.pics[0] +
'.jpg">' +
'<h6 class="text-center">' +
cur.name +
"</h6>" +
'<div class="text-center text-muted">' +
cur.price +
"</div>" +
"</div>";
document
.querySelector(DomStrings.productCont)
.insertAdjacentHTML("beforeend", deafultHtml);
});
},
getDomStrings: function() {
return DomStrings;
},
};
})();
var mainController = (function(UIctrl, dataCrtl) {
var setUpEvents = function() {
var doneLoading = false;
var DOM = UIctrl.getDomStrings();
document.querySelector(DOM.shopCatg).addEventListener("click", function() {
InitializeData(event, function(cat) {
UIcontroller.displayObjectToPage(cat);
});
});
};
InitializeData = function(event, callback) {
var category = event.target.textContent;
if (event.target.textContent === "bags") {
dataController.loadJSON(
dataController.getJsonUrls().bags,
category,
callback
);
} else if (event.target.textContent === "briefcases") {
dataController.loadJSON(dataController.getJsonUrls().bags, "briefcases");
} else if (event.target.textContent === "belts") {
dataController.loadJSON(dataController.getJsonUrls().bags, "belts");
} else {
dataController.loadJSON(dataController.getJsonUrls().bags, "accs");
}
};
displayObject = function() {};
return {
init: function() {
setUpEvents();
},
};
})(UIcontroller, dataController);
mainController.init();
I'm not sure, but I noticed this potential issue:
request.send();
request.onload = function() {
// ...
}
I believe when you call send, the request should start asynchronously. If the request comes back before onload is assigned, you might be seeing it get skipped. I haven't used XHR directly in years, though.
Normally you'd want to add the onload callback before calling send() to avoid this issue.
I also just noticed that you're missing the event in the arguments of the callback function here:
▽
document.querySelector(DOM.shopCatg).addEventListener("click", function() {
▽ event is undefined
InitializeData(event, function(cat) {
UIcontroller.displayObjectToPage(cat);
});
});
I have a published captivate html file that is loaded into an iframe of another html. I cannot communicate between the two, not even with localStorage. Can anyone tell me what I'm missing?
Parent html
var everythingLoaded = setInterval(function () {
if (/loaded|complete/.test(document.readyState)) {
clearInterval(everythingLoaded);
init();
}
}, 10);
function init() {
ScormProcessInitialize();
var studentID = ScormProcessGetValue("cmi.core.student_id");
var student_name = ScormProcessGetValue ("cmi.core.student_name");
var nameArraya = student_name.split(" ");
var nameArrayb = nameArraya[1].split(",");
var studentNumber = nameArrayb[0];
ScormProcessSetValue("cmi.core.lesson_status", "incomplete");
localStorage.setItem("_studentNumber", studentNumber);
alert("Student Number: " + studentNumber + " Student Mame: " + student_name);
setTimeout(function () {
document.getElementById("iFrame_a").innerHTML = "<iframe name='iframe_1' id='frame_1' src='//somepath.com/sandbox/somecourse/index.html' frameborder='0' width='1000px' height='605px'></iframe>";
}, 250);
}
function sendComplete() {
alert("Send from index start!");
ScormProcessSetValue("cmi.core.lesson_status", "completed");
alert("send status: Completed");
}
window.onbeforeunload = function (){
cpInfoCurrentSlide = localStorage.getItem("_cpInfoCurrentSlide")
alert(cpInfoCurrentSlide);
if(cpInfoCurrentSlide >= 40)
{
alert("onbeforeunload called: " + cpInfoCurrentSlide )
ScormProcessSetValue("cmi.core.lesson_status", "completed");
}
}
iframe code snippet
localStorage.setItem("_cpInfoCurrentSlide", cpInfoCurrentSlide);
I believe your problem is with onbeforeunload. As I remember captivate packages clobber any functions associated with onbeforeunload in the parent frame when they load.
Try this instead, override your SCORM api setvalue method:
var oldLMSSetValue = window.API.LMSSetValue;
window.API.LMSSetValue = function(key, value){
if(key === 'cmi.core.lesson_status' && value === 'completed'){
//do your stuff here
cpInfoCurrentSlide = localStorage.getItem("_cpInfoCurrentSlide")
alert(cpInfoCurrentSlide);
}
//call the original scorm api function so that it runs as expected.
oldLMSSetValue(key,value);
};
edit: this code would go in the parent window, not the iframe.
I'm working on a twitter clone in JS + jQuery for a pre-course to a development program, so if this is an obvious fix - let me know!
I have a problem I'm unable to solve: "click on username, page returns with that user's last tweets".
The only thing I could come up with is, an event handler on the <a> tag filter the page. However I'm vastly inexperienced and unclear in how to proceed.
Any ideas?
note- I removed some code for brevity.
$(document).ready(function() {
var $body = $('body');
$body.html();
var stream = function() {
var index = streams.home.length - 1;
while (index >= 0) {
var tweet = streams.home[index];
var $tweet = $('<div class="tweetbody"></div>');
$tweet.text(': ' + tweet.message);
$tweet.appendTo($body);
index -= 1;
var link = $('<a>', {
text: tweet.user,
href: '#',
}).prop('outerHTML');
$tweet.html('#' + link + ': ' + tweet.message);
}
};
Here's the <a> tag event:
//click on a username to see that user's timeline.
$('a').on('click', function() {
console.log("a tag is clicked ");
console.log(this);
});
}();
}); //end document ready body
In the on click function you could perhaps do either of the two things, so go to another page, like redirecting to a new page
//click on a username to see that user's timeline.
$('a').on('click', function() {
//console.log("a tag is clicked ");
//console.log(this);
window.location = '/some_file.php?get_tweets='+tweet.user;
});
or, use an ajax call to do the same:
//click on a username to see that user's timeline.
$('a').on('click', function() {
//console.log("a tag is clicked ");
//console.log(this);
$.ajax({
type: "GET",
url: "/some_file.php",
data: {
'user' : tweet.user
},
success: function(msg) {
$body.html(msg);
});
});
In both cases some_file.php should format the content.
I am trying to use jquery with phantomjs. I tried a standalone example and it worked fine. Here is what I did:
var page = require('webpage').create();
page.open("http://www.phantomjs.org", function(status) {
page.onConsoleMessage = function(msg) {
console.log("message recvd: " + msg);
};
var result;
page.includeJs("https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js", function() {
console.log("loading jquery");
});
setTimeout(function() {
page.evaluate(function() {
console.log("$(\"title\").text() -> " + $("title").text());
});
}, 1000);
}
Here is the output I got:
loading jquery
message recvd: $("title").text() -> PhantomJS | PhantomJS
In the above code snippet, I have used setTimeout() on evaluate function because includeJs() would execute asynchronously and need some time to load jquery. If I do not use setTimeout() or use a small value for timeout, it doesn't work.
However, when I try the same code in my application it doesn't work. Here is what I have:
var baseSetup = function(guid, page, config, request, response) {
/* enable the console output inside the callback functions */
page.onConsoleMessage = function (msg) {
console.log(guid + ": console msg: " + msg);
};
/* used for ignoring potential alert messages when evaluating js code */
page.onAlert = function (msg) {
console.log(guid + " (alert): alert msg: " + msg);
};
/* suppress the error messages */
page.onError = function(msg, trace) {
var msgStack = ['ERROR: ' + msg];
if (trace && trace.length) {
msgStack.push('TRACE:');
trace.forEach(function(t) {
msgStack.push(' -> ' +
t.file +
': ' +
t.line +
(t.function ? ' (in function "' + t.function + '")' : ''));
});
}
console.error(guid + ": " + msgStack.join('\n'));
};
}
module.exports = function extractionDriver(responseFromUrl, responseToUser, page, request) {
console.log(page.customHeaders['guid'] + ": extractionDriver, status = " + responseFromUrl.status);
if(page.isLocalFile || responseFromUrl.status !== 0)
{
var viewportStr = page.customHeaders['viewportStr'];
console.log(page.customHeaders['guid'] + ": Setting viewport size: " + viewportStr);
var viewportObj = parseViewport(viewportStr);
page.viewport = viewportObj;
page.evaluate(function(w,h) {
document.body.style.width = w + "px";
document.body.style.height = h + "px";
}, viewportObj.width, viewportObj.height);
page.includeJs("https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js", function() {
console.log("loading jquery");
});
setTimeout(function() {
page.evaluate(function() {
console.log("$(\"title\").text() -> " + $("title").text());
});
}, 1000);
}
And this is what I see when I run my application:
d8db6045-a0e8-11e4-a619-6949593d958d: ERROR: ReferenceError: Can't find variable: $
TRACE:
-> phantomjs://webpage.evaluate(): 3
-> phantomjs://webpage.evaluate(): 4
-> phantomjs://webpage.evaluate(): 4
The log line "loading jquery" is never printed and jquery is never loaded.
I have tried wrapping up the evaluate() function inside the callback of includeJs() but that didn't work either (no console log printed).
What could be going wrong here? Please let me know if I should provide more information.
That is why page.includeJs has a callback, so you can put the code that depends on jQuery in there. The callback is called when the referenced JavaScript is already loaded. Welcome to another level on the road to the callback hell.
I experienced one time though that this didn't work for some reason. The workaround was to set a global variable in the includeJs callback and use waitFor to wait for the global variable to be set outside of the includeJs callback.
var _loadIndicator = false;
page.includeJs("https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js", function() {
_loadIndicator = true;
});
waitFor(function check() {
return _loadIndicator;
}, function onReady() {
page.evaluate(function() {
console.log("$(\"title\").text() -> " + $("title").text());
});
}, 10000);
I just have troubles with this, but my mistake was that, i tried phantom.injectJs, not page.injectJs (jerk). And then, if status is success, put
page.injectJs('lib/jquery.min.js');
and try
page.evaluate(function(){
console.log($("body").length);
});
I'm using this jQuery script to show search results. Everything works fine, but when search results have more than one page and I'm browsing pages via paging then every page loading is gradually getting slower. Usually first cca 10 pages loads I get quickly, but next are getting avoiding loading delay. Whole website get frozen for a little while (also loader image), but browser is not yet. What should be the problem?
function editResults(def) {
$('.searchResults').html('<p class=\'loader\'><img src=\'images/loader.gif\' /></p>');
var url = def;
var url = url + "&categories=";
// Parse Categories
$('input[name=chCat[]]').each(function() {
if (this.checked == true) {
url = url + this.value + ",";
}
});
url = url + "&sizes=";
// Parse Sizes
$('input[name=chSize[]]').each(function() {
if (this.checked == true) {
url = url + this.value + ",";
}
});
url = url + "&prices=";
// Parse Prices
$('input[name=chPrice[]]').each(function() {
if (this.checked == true) {
url = url + this.value + ",";
}
});
$('.searchResults').load('results.php'+url);
$('.pageLinks').live("click", function() {
var page = this.title;
editResults("?page="+page);
});
}
$(document).ready(function(){
editResults("?page=1");
// Check All Categories
$('input[name=chCat[0]]').click(function() {
check_status = $('input[name=chCat[0]]').attr("checked");
$('input[name=chCat[]]').each(function() {
this.checked = check_status;
});
});
// Check All Sizes
$('input[name=chSize[0]]').click(function() {
check_status = $('input[name=chSize[0]]').attr("checked");
$('input[name=chSize[]]').each(function() {
this.checked = check_status;
});
});
// Edit Results
$('.checkbox').change(function() {
editResults("?page=1");
});
// Change Type
$(".sort").change(function() {
editResults("?page=1&sort="+$(this).val());
});
});
$('.pageLinks').live("click", function() {
var page = this.title;
editResults("?page="+page);
});
just a wild guess but... wouldn't this piece of code add a new event handler to the click event instead reaplacing the old one with a new one? causing the click to call all the once registered handlers.
you should make the event binding just once
var global_var = '1';
function editResults(def) {
// all your code
global_var = 2; // what ever page goes next
};
$(document).ready(function() {
// all your code ...
$('.pageLinks').live("click", function() {
var page = global_var;
editResults("?page="+page);
});
});