how to trigger a function in vuejs after the page is loaded? - function

I am trying to trigger a function which hides or show the images on the basis of data i have written two function one which calls the api which is in created hook and second function which renders the image . The problem is how do i call that second function after the dom is loaded , right now when i am trying to call in the first function or created it is returning me error that css cannot be changed of null.I have tried using mounted function with newtick but its still firing the render_badges function first and hence values are null inside
created:function(){
this.loadlike()
},
methods:{
loadlike:function(){
var self = this
this.$http.get('/api/user_profile').then(function (res) {
self.tasksdata = res.body
self.badges = self.tasksdata.data2
console.log(self.badges)
console.log(this.tasksdata)
console.log(this.max)
})
},
getHumanDate : function (date) {
return moment(date, 'YYYY-MM-DD hh-mm-ss').locale("en-gb").format('LL');
},
render_badges:function(){
var self = this
var counter = 0;
self.badges.map(function(e){
counter ++;
console.log(counter)
if(counter <=self.max){
document.getElementById("i").style.display = "initial";
}
else{
document.getElementById("i").style.display = "none";
}
})
},
mounted: function () {
this.$nextTick(function () {
this.render_badges();
})
}

Rather than manipulating the DOM, you should use v-if on the element itself that turns it on or off based on data. It is a different way of thinking than direct DOM manipulation learned in the jQuery days. Read more in the Vue docs about conditional rendering.
If you are wanting to trigger once the DOM is available, use mounted()

Related

TVML listItemLockup click event

I'm using the 'Compilation.xml' template from the TVMLCatalog
I'd like to add a button click event to a 'listItemLockup'
<listItemLockup>
<ordinal minLength="2" class="ordinalLayout">0</ordinal>
<title>Intro</title>
<subtitle>00</subtitle>
<decorationLabel>(3:42)</decorationLabel>
</listItemLockup>
I've tried adding:
App.onLaunch = function(options) {
var templateURL = 'http://localhost:8000/hello.tvml';
var doc = getDocument(templateURL);
//doc.addEventListener("select", function() { alert("CLICK!") }, false);
var listItemLockupElement = doc.getElementsByTagName("listItemLockup");
listItemLockupElement.addEventListener("select", function() { alert("CLICK!") }, false);
}
addEventListener
void addEventListener (in String type, in Object listener, in optional Object extraInfo)
Is "select" the correct type?
I've been using the following tutorials
http://jamesonquave.com/blog/developing-tvos-apps-for-apple-tv-with-swift/
http://jamesonquave.com/blog/developing-tvos-apps-for-apple-tv-part-2/
Update
I'm getting an error
ITML <Error>: doc.getElementsByTagName is not a function. (In 'doc.getElementsByTagName("listItemLockup")', 'doc.getElementsByTagName' is undefined) - http://localhost:8000/main.js - line:27:58
I tried adding this to the 'onLaunch'
var listItemLockupElements = doc.getElementsByTagName("listItemLockup");
for (var i = 0; i < listItemLockupElements.length; i++) {
//var ele = listItemLockupElements[i].firstChild.nodeValue;
listItemLockupElements[i].addEventListener("select", function() { alert("CLICK!") }, false);
}
I'll see about the error first
Cross Post: https://forums.developer.apple.com/thread/17859
More common example I have seen by Apple is to define a single overall listener like:
doc.addEventListener("select", Presenter.load.bind(Presenter));
In your xml, assign unique ids to elements, or give them ways to identify them.
For example, the beginning would be something like:
load: function(event) {
var self = this,
ele = event.target,
attr_id = ele.getAttribute("id"),
audioURL = ele.getAttribute("audioURL"),
videoURL = ele.getAttribute("videoURL")
And then you can do whatever you want with your item.
if(audioURL && (event.type === "select" || event.type === "play")) {
//
}
My advice would be to study the Presenter.js file more carefully for this pattern.
Edit:
Answering your "Update" related to doc.getElementsByTagName is not a function. "doc" does not actually exist, but the general pattern is to get it with
var doc = getActiveDocument();
I assumed you would know the above.
Does that fix it?
var listItemLockupElement = doc.getElementsByTagName("listItemLockup”);
In this case, the listItemLockupElement is a NodeList, not an element. You can either iterate through the list and add an event listener to each listItemLockup, or you could add the event listener to the containing element.
When addressing items in a NodeList, you use the item(i) method rather than the standard array access notation:
listItemLockupElements.item(i).addEventListener("select", function() { })
See: https://developer.mozilla.org/en-US/docs/Web/API/NodeList/item
Adding event listeners is straightforward if you're using atvjs framework.
ATV.Page.create({
name: 'mypage',
template: your_template_function,
data: your_data,
events: {
select: 'onSelect',
},
// method invoked in the scope of the current object and
// 'this' will be bound to the object at runtime
// so you can easily access methods and properties and even modify them at runtime
onSelect: function(e) {
let element = e.target;
let elementType = element.nodeName.toLowerCase();
if (elementType === 'listitemlockup') {
this.doSomething();
}
},
doSomething: function() {
// some awesome action
}
});
ATV.Navigation.navigate('mypage');
Disclaimer: I am the creator and maintainer of atvjs and as of writing this answer, it is the only JavaScript framework available for Apple TV development using TVML and TVJS. Hence I could provide references only from this framework. The answer should not be mistaken as a biased opinion.

TinyMCE and AngularJS - not loading after NgSwitch

I hope I am clear enough with this request for assistance, as it is hard to explain and I can't post all the code here. I have downloaded code to enable TinyMCE to be used in a NgRepeat with AngularJS:
angular.module('ui.tinymce', [])
.value('uiTinymceConfig', {})
.directive('uiTinymce', ['uiTinymceConfig', function (uiTinymceConfig) {
uiTinymceConfig = uiTinymceConfig || {};
var generatedIds = 0;
return {
require: 'ngModel',
link: function (scope, elm, attrs, ngModel) {
var expression, options, tinyInstance;
// generate an ID if not present
if (!attrs.id) {
attrs.$set('id', 'uiTinymce' + generatedIds++);
}
options = {
// Update model when calling setContent (such as from the source editor popup)
setup: function (ed) {
ed.on('init', function (args) {
ngModel.$render();
});
// Update model on button click
ed.on('ExecCommand', function (e) {
ed.save();
ngModel.$setViewValue(elm.val());
if (!scope.$$phase) {
scope.$apply();
}
});
// Update model on keypress
ed.on('KeyUp', function (e) {
ed.save();
ngModel.$setViewValue(elm.val());
if (!scope.$$phase) {
scope.$apply();
}
});
},
mode: 'exact',
elements: attrs.id
};
if (attrs.uiTinymce) {
expression = scope.$eval(attrs.uiTinymce);
} else {
expression = {};
}
angular.extend(options, uiTinymceConfig, expression);
setTimeout(function () {
tinymce.init(options);
});
ngModel.$render = function () {
if (!tinyInstance) {
tinyInstance = tinymce.get(attrs.id);
}
if (tinyInstance) {
tinyInstance.setContent(ngModel.$viewValue || '');
}
};
}
};
}]);
var gwApp = angular.module('gwApp', ['ui.tinymce']);
I don't really understand this code, but it works fine initially. My page starts with a list of Posts. I click on 'Show Reply' for the first post, and using NgSwitch the multiple replies become visible (nested NgRepeat). I submit a new reply message (the reply text is entered using tinymce) using a RESTful API service and a http call (too much code to post here). Then after clicking the submit button for the new reply message, the NgSwitch kicks in again unexpectedly to make the replies no longer visible. When I expand the replies again, the tinymce is just a regular textarea again, and the proper editor is gone.
I know this is not very clear, but I'm hoping someone can make sense of what I've written and can help me solve this problem..
I was having the same problem using ng-switch and ng-show so i added:
scope.$watch('onHidden()',function(){ tinymce.editors = [] });
after the setTimeout function.
Also replace the
ed.on('init',function(args){ ngModel.$render(); });
with
ed.on('init',function(args){ ed.setContent(ngModel.$viewValue); });
and remove the $render function.
This is the link to the working code in JsFiddle

Clicking, pasting text and uploading files from extension

So I'm basically developing an automated click-paste-and-upload system for mutiple texts and files inside a google page.
This method helped me get the instances of objects that I'm looking for: buttons, textboxes, richtextboxes, etc.
Now I want to work with them.
So for example I know the id of a button , and the function subscribed to its click event. How do I trigger the click event from the extension ? I've tried injecting a script with the click event handler (discovered with DOM inspector) at "document_startup" but I don't get an error or anything else.
Here's the content script! The loggerhead function should have inserted the script but I don't think it did. What might be the reason for the blow code not giving anything?
// Runs a function for every added DOM element that matches a filter
// filter -- either function(DOM_node){/*...*/}, returns true or false
// OR a jQuery selector
// callback -- function(DOM_node){/*...*/}
function watchNodes(filter, callback){
observer = new MutationObserver( function (mutations) {
mutations.forEach( function (mutation){
if(typeof filter === "function"){
$(mutation.addedNodes).filter(
function(i){ return filter(this); }
).each(
function(i){ callback(this); }
);
} else {
$(mutation.addedNodes).filter(filter).each(
function(i){ callback(this); }
);
}
});
});
// For every added element, a mutation will be processed
// with mutation.taget == parent
// and mutation.addedNodes containing the added element
observer.observe(document, { subtree: true, childList: true });
}
function loggerhead(node) {
console.log("passhead");
//also inject jquery
var jqueryEl = document.createElement('script');
jqueryEl.setAttribute('src', chrome.extension.getURL('jquery-1.11.1.min.js'));
jqueryEl.setAttribute('type', 'text/javascript');
var scriptEl = document.createElement('script');
scriptEl.setAttribute('src', chrome.extension.getURL('script.js'));
scriptEl.setAttribute('type', 'text/javascript');
node.appendChild(jqueryEl);
node.appendChild(scriptEl);
}
watchNodes("head", loggerhead);
// method not working
//var gmailHead = jQuery("head", document).get(0);
script.js contains the function of subscribed to the click event of the button that I've managed to find through the DOM inspector:
function Cdb(b){return function(){if(Vbb()){return Ddb(b,this,arguments)}else{var a=Ddb(b,this,arguments);a!=null&&(a=a.val);return a}}}
You should try to call the existing click handler like
buttonElement.click()

HTML service error creating elements dynamically

I'm working with html service of google-apps-script and I'm writing some modules to make life easier. The module below its designed to create elements fast and easy with an easy to read notation.
All works fine except the text function. It uses the input function to create a specific input type. In this case, a text one. When I try to use it I get the following error:
Untaming of guest constructed objects unsupported
I can't understand this error. Could anyone explain it to me?
var util = {
create: (function(){
var element = function (elementName,atributes ){
var element = $( document.createElement(elementName) );
return atributes ? element.attr(atributes) : element;
},
div = function(atributes){ return element('div',atributes); },
textArea = function(atributes){ return element('textarea',atributes); },
input = function(atributes){ return element('input',atributes); },
text = function(atributes){
atributes.type = "text";
return input(atributes);
};
return { div:div, input : input, text:text, textArea:textArea}
})()
};

Repeatedly Grab DOM in Chrome Extension

I'm trying to teach myself how to write Chrome extensions and ran into a snag when I realized that my jQuery was breaking because it was getting information from the extension page itself and not the tab's current page like I had expected.
Quick summary, my sample extension will refresh the page every x seconds, look at the contents/DOM, and then do some stuff with it. The first and last parts are fine, but getting the DOM from the page that I'm on has proven very difficult, and the documentation hasn't been terribly helpful for me.
You can see the code that I have so far at these links:
Current manifest
Current js script
Current popup.html
If I want to have the ability to grab the DOM on each cycle of my setInterval call, what more needs to be done? I know that, for example, I'll need to have a content script. But do I also need to specify a background page in my manifest? Where do I need to call the content script within my extension? What's the easiest/best way to have it communicate with my current js file on each reload? Will my content script also be expecting me to use jQuery?
I know that these questions are basic and will seem trivial to me in retrospect, but they've really been a headache trying to explore completely on my own. Thanks in advance.
In order to access the web-pages DOM you'll need to programmatically inject some code into it (using chrome.tabs.executeScript()).
That said, although it is possible to grab the DOM as a string, pass it back to your popup, load it into a new element and look for what ever you want, this is a really bad approach (for various reasons).
The best option (in terms of efficiency and accuracy) is to do the processing in web-page itself and then pass just the results back to the popup. Note that in order to be able to inject code into a web-page, you have to include the corresponding host match pattern in your permissions property in manifest.
What I describe above can be achieved like this:
editorMarket.js
var refresherID = 0;
var currentID = 0;
$(document).ready(function(){
$('.start-button').click(function(){
oldGroupedHTML = null;
oldIndividualHTML = null;
chrome.tabs.query({ active: true }, function(tabs) {
if (tabs.length === 0) {
return;
}
currentID = tabs[0].id;
refresherID = setInterval(function() {
chrome.tabs.reload(currentID, { bypassCache: true }, function() {
chrome.tabs.executeScript(currentID, {
file: 'content.js',
runAt: 'document_idle',
allFrames: false
}, function(results) {
if (chrome.runtime.lastError) {
alert('ERROR:\n' + chrome.runtime.lastError.message);
return;
} else if (results.length === 0) {
alert('ERROR: No results !');
return;
}
var nIndyJobs = results[0].nIndyJobs;
var nGroupJobs = results[0].nGroupJobs;
$('.lt').text('Indy: ' + nIndyJobs + '; '
+ 'Grouped: ' + nGroupJobs);
});
});
}, 5000);
});
});
$('.stop-button').click(function(){
clearInterval(refresherID);
});
});
content.js:
(function() {
function getNumberOfIndividualJobs() {...}
function getNumberOfGroupedJobs() {...}
function comparator(grouped, individual) {
var IndyJobs = getNumberOfIndividualJobs();
var GroupJobs = getNumberOfGroupedJobs();
nIndyJobs = IndyJobs[1];
nGroupJobs = GroupJobs[1];
console.log(GroupJobs);
return {
nIndyJobs: nIndyJobs,
nGroupJobs: nGroupJobs
};
}
var currentGroupedHTML = $(".grouped_jobs").html();
var currentIndividualHTML = $(".individual_jobs").html();
var result = comparator(currentGroupedHTML, currentIndividualHTML);
return result;
})();