jquery ui tabs: how to call a function in the parent page from an external URL in a tab - jquery-ui-tabs

Just like the question title says:
I've got a standard jquery ui tab set. One tab is to another php file, from which i would like to be able to call a function with an argument on the parent page. Can't figure out how to do it.
Code in external page loaded into the tab:
<script language="javascript">
function doSomething(){
parent.dummyfunction("Hello world!");
}
</script>
<input type='button' value='use recipe' onClick='javascript:doSomething()'>
and on the parent, where the tabs are defined, I have:
<script language="javascript">
function dummyfunction(whatever){
alert(whatever);
}
</script>
Thank so much for looking

OK I've figured it out. The jquery ui tabs code loads the external file into the target div as flat html. So instead of needing to call a middle-man function (like the doSomething function in the above example), we just call dummyfunction directly, even though the function is not defined on the external page.

Related

How to add a click function to an imported component in Vue

So I have a Vue2 app. I have create a component "u-button"
when i import this and use it in another component, I want to be able to add a click function to it. However at the moment it looks for a function on the u-button component rather than the component it is being used in.
so for example, in the below if i click the first button nothing happens, if i click the second button i get the console log.
<template>
<div>
<u_button #click="clicked">Click me</u_button>
<button #click="clicked">Click me</button>
</div>
</template>
<script>
import u_button from '../components/unify/u_button'
export default {
components: {
u_button
},
methods: {
clicked() {
console.log("Working!");
}
}
}
</script>
However if i add a method on the u-button component, then it calls that. So how can i get my below example to work ? The only thing I can think of is to wrap it in another div and add the click function to that. but I'm wondering if there is a better way?? I dont want to use events to do this either as that gets messy very quickly.
As you can imagine having a reusable button that when clicked always performs the same function is a bit pointless.
It's because of the nature of components for example if we had a (virtual) iframe component which had a button in it and we'd like to detect click event on it we might name the event click and listen for it in the parent component; therefore, Vue introduced a feature called event modifiers for example in Vue, We have .native modifier (you can read more about the Vue modifiers here)
Now, to make your code work, You should add a .native after #click like this:
<u_button #click.native="clicked">Click me</u_button>
By the way, it's better to develop a naming convention for yourself It'd become handy when your projects get larger.

Best way to load page data into div with VueJS

I have been doing a lot of VueJS tutorials including the router, event bus, and trying to use fetchival and axios to no avail.
The setup, I want there to be two sections. One where I have buttons and the second section would be updated with html data from html files that varies depending on the button pressed.
I have used event bus to be able to just update the second div with basic, static html
(i.e. <p>got it</p>) but I cannot, for the life of me, use any request to get html from another website or file and load it into the div.
I don't necessarily need anyone to build it for me, but even some guidance and direction would be infinitely appreciated.
Based on your comments above, I think you want to change your thinking from "loading html files" to "showing different parts of the Vue component."
Here's a basic example. I'm going to use Vue single-file component syntax, but it's not hard to refactor for class-based components:
<template>
<div>
<button #click="clickedShowFirst">Show First</button>
<button #click="clickedShowSecond">Show Second</button>
<div v-if="showingFirst">
This is the first section!
</div>
<div v-else>
This is the second section!
</div>
</div>
</template>
<script>
export default {
data: function () {
return {
// We default to showing the first block
showingFirst: true
}
}
methods: {
clickedShowFirst: function () {
this.showingFirst = true
},
clickedShowSecond: function () {
this.showingFirst = false
}
}
}
</script>
You could of course make each of the v-if blocks components of their own that you import (which makes sense if they are complex themselves).
Or as suggested by Phillipe, you can use vue-router and make each of those views a different page with a different URL.
One last recommendation to leave you with, I found Jeffrey Way's Laracasts series on Vue.js amazingly helpful when I was learning. His episode titled "Exercise #3: Tabs" is very similar to what you're asking here.
You could use vue-router (https://router.vuejs.org/en/). In first section put the router-link (https://router.vuejs.org/en/api/router-link.html), your buttons, in second section put the router-view (https://router.vuejs.org/en/api/router-view.html).

accessing dojo attach point outside templated widget

I have a dojo attach point for list item which is inside a templated widget.I need to access the dojo attach point outside the widget in order to assign onclick to the list item created by the template.How do I do it?
Well, if you want to attach an event handler to it, you have to provide a function. You can override functions/properties from outside using getters and setters.
I also suggest using data-dojo-attach-event if you only need the node for attaching event handlers. For example by using: data-dojo-attach-event="onclick: myFunction". By doing this, it needs a function called myFunction in your templated widget, provide a default function (in your widget) for example:
myFunction: function() {
/** Stub */
},
And then you can do something like this from outside:
myWidget.set("myFunction", function(evt) {
console.log("Someone clicked on the list item");
});
Because the myFunction event handler is overriden, it will execute the function provided in the setter.
You could also directly access the attach points from outside using:
myWidget.listItemNode
When you have a data-dojo-attach-point="listItemNode". However, I don't think it's recommended to use it this way because now your widget is tightly coupled (you use the internal functionality of the widget).
HTML template:-
<div data-dojo-attach-point="infoDialog" >
</div>
Save this as "Template.html"
---------------------------------------------
load this html file using "dojo\text" plugin in your widget i.e.
"dojo/text!./templates/Template.html",
and store as template in widget main function
-----------------------------------------------
assign it as template string to the widget.
templateString: template,
now this template attachpoint(infoDialog) will be the part of your current widget scope.
-----------------------------------------------
attach event:-
this.infoDialog.onclick=function(){
alert("hello world")
};

Loading jquery plugin result into Durandal view

I am using the Durandal Starter Template for mvc4. I have set the following simple View:
<section>
<h2 data-bind="html: displayName"></h2>
<h3 data-bind="html: posts"></h3>
<button data-bind="click: getrss">Get Posts</button>
<div id="rsstestid" ></div>
</section>
and ViewModel:
define(function (require) {
var http = require('durandal/http'),
app = require('durandal/app');
return {
displayName: 'This is my RssTest',
posts: ko.observable(),
activate: function () {
return;
},
getrss: function () {
$('#rsstestid').rssfeed('http://feeds.reuters.com/reuters/oddlyEnoughNews');
return;
}
};
});
As you can see, it is simply using the zRssReader plugin to load posts into a div when the 'Get Posts' button is clicked. Everything works fine, the display name is populated and the posts show up as expected.
Where I am having trouble is when I try to eliminate the button and try to load the posts at creation time. If I place the plugin call in the activate function, I get no results. I assume this is because the view is not fully loaded, so the element doesn't exist. I have two questions:
How do I delay the execution of the plugin call until the view is fully composed?
Even better, how do I load the plugin result into an the posts observable rather than using the query selector? I have tried many combinations but no luck
Thanks for your help.
EDIT** the below answer is for durandal 1.2. In durandal 2.0 viewAttached has changed to attached
Copy pasted directly from durandaljs.com
"Whenever Durandal composes, it also checks your model for a function called viewAttached. If it is present, it will call the function and pass the bound view as a parameter. This allows a controller or presenter to have direct access to the dom sub-tree to which it is bound at a point in time after it is injected into its parent.
Note: If you have set cacheViews:true then viewAttached will only be called the first time the view is shown, on the initial bind, since technically the view is only attached once. If you wish to override this behavior, then set alwaysAttachView:true on your composition binding."
--quoted from the site
There are many ways you can do it but here is just 1 quick and dirty way:
<section>
<h2 data-bind="html: displayName"></h2>
<h3 data-bind="html: posts"></h3>
<button data-bind="click: getRss">Get Posts</button>
<div id="rsstestid"></div>
</section>
and the code:
define(function (require) {
var http = require('durandal/http'),
app = require('durandal/app');
var $rsstest;
return {
displayName: 'This is my RssTest',
posts: ko.observable(),
viewAttached: function(view) {
$rssTest = $(view).find('#rsstestid');
},
getRss: function() {
$rssTest.rssfeed('http://feeds.reuters.com/reuters/oddlyEnoughNews');
}
};
});
In general, I think it's wise to refrain from directly touching UI elements from within your view model.
A good approach is to create a custom KO binding that can render the rss feed. That way, you're guaranteed that the view is in place when the binding executes. You probably want to have the feed url exposed as a property on your view model, then the custom binding can read that when it is being updated.
Custom bindings are pretty simple - if I can do it, then it must be :)
Here's a link to the KnockOut custom bindings quickstart: http://knockoutjs.com/documentation/custom-bindings.html
I too am having the same problem, I'm trying to set a css property directly on an element after the durandal view model and view are bound together. I too assume that it's not working because the view is not fully composed at the point I am setting the value.
Best I have come up with is using the viewAttached lifecycle event in durandal, which I think is the last event in the loading cycle of a durandal viewmodel, and then using setTimeout to delay the setting of the property still further.
It's a pretty rubbish workaround but it's working for now.
var viewAttached = function (view) {
var _this = this;
var picker = new jscolor.color($(view).children('.cp')[0], {
onImmediateChange: function() {
_updateCss.call(_this, this.toString());
}
});
picker.fromString(this.color());
setTimeout(function() {
_updateCss.call(_this, _this.color());
}, 1000);
};
var activate = function (data) {
system.log('activated: ' + this.selectors + ' ' + this.color());
};
var deactivate = function (isClose) {
system.log('deactivated, close:' + isClose);
};
return {
viewAttached: viewAttached,
deactivate: deactivate,
activate: activate,
color: this.color
};
I was having a similar issue with timing. On an initial page load, where a partial view was being loaded on the page I could call the viewAttached function and use jQuery to bind some elements within the partial view. The timing worked as expected
However, if I navigated to a new page, and then back to the initial page, the same viewAttached + jQuery method failed to find the elements on the page... they had not yet been attached to the dom.
As best as I have been able to determine (so far) this is related to the transition effects in the entrance.js file. I was using the default transition which causes an object to fade out and a new object to fade in. By eliminating the fadeOutTransition (setting it to zero in entrance.js) I was able to get the viewAttached function to actually be in sync with the partial views attachment.
Best guess is that while the first object is fading out, the incoming object has not yet been attached to the dom but the viewAttached method is triggered anyway.

how to call js function in another js file in Metro apps?

I have a metro application in which I want to call a javascript function from another .js file? can anyone help me.
Thank you.
All scripts in javascript are merged into a "script context". This means that if you have:
File1.js:
function a() { b(); }
File2.js:
function b() { alert("hi"); }
then as long as file2.js is included before b is called, everything will be fine.
This means in your HTML should have the <script> tags included, and you'll be good.
If you are using WinJS, a better example might be:
File1.js:
WinJS.Namespace.define("MyNamespace", {
firstFunction: function() { MyNamespace.secondFunction(); }
});
File2.js
WinJS.Namespace.define("MyNamespace", {
secondFunction: function() { alert("hi"); }
});
default.html:
<script src="/file1.js"></script>
<script src="/file2.js"></script>
However JavaScript doesn't have a built in dynamic loading of "References". You have to build or use your own.
There are many ways to skin this cat, so I would recommend you look a them and decide which meets your needs.
Require JS
Built in Page controls/fragment loading in WinJS. If you define a page in WinJS, when the html file for that page is loaded, any scripts declared in the html will be brought in automatically. Same is true of raw fragment loading.
You can just the file that contains the definition of the function needs to be referenced before the file which calls the function just like you would do if it was a browser not a Windows 8 app.
In fact not even that much is necessary. If you are calling the function after window.load or document.load then that means that all of your referenced javascript files have loaded already so the reference sequence doesn't even matter.