Basic Snackbar Example doesn't show on Material Design Components for Web - snackbar

The basic example of snackbar for Material Design Components for Web doesn't work. It produces the error:
```
TypeError: snackbar.show is not a function
```
I have tried using jQuery to make sure the DOM loaded properly. I have tried changing back and forth the javascript initialisation methods, but none seems to work.
You can find the code here: https://jsbin.com/mejefeq/edit?html,console,output
I have read the docs over and overs again, but none of it mentioned anything about this. Since this MDC for Web is not at all popular, I have nowhere left to go for help.

Yeah that was a breaking change in the 0.43.0 update. The new way of showing the snackbar is by using
snackbar.open();
This however will just open the snackbar. If you want to change the text in the snackbar you can use:
snackbar.labelText = 'Your new text';
So together you can use them:
snackbar.labelText = 'Your new text';
snackbar.open();
You can check out more of the documentation here, with the current javascript properties and events here

Related

How to update vue2-frappe chart?

I've been breaking my head over this for the last few hours and no matter where I look I can't seem to find the answer.
I'm using vue2-frappe as my chart library. I'm using a simple bar chart to display certain values by day. Everything was fine until my higher-ups decided they wanted to show a whole year's worth of values on this chart, meaning I have to add some pagination to it.
The problem is, now I can't figure out how to make the chart rerender. I've tried replacing the entire object I've bound the chart to, as well as manipulating specific values, but nothing seems to make the component rerender.
In the documentation for frappe.js, you can modify data via specific methods, but this being Vue I can't just call chart.update() like in normal .js. And if I inspect the component via vue dev tools, I can see it contains the modified data, it just doesn't redraw itself.
Anyone have an idea what to do?
I would try to force update the view component.
VueJs reactivity can sometimes be confusing where you think it should react to changes but it doesn't.
You can force a view update like so:
// Globally
import Vue from 'vue';
Vue.forceUpdate();
// Using the component instance
export default {
methods: {
methodThatForcesUpdate() {
// ...
this.$forceUpdate(); // Notice we have to use a $ here
// ...
}
}
}
You can read about correct ways of re-rendering here: https://michaelnthiessen.com/force-re-render
There are caveats to this approach as outlined in vueJs's docs: https://v2.vuejs.org/v2/guide/list.html#Caveats
Note #
A force re-render wont update computed values, but your computed property shouldn't contain any external non-reactive variable anyway.
Note 2
The above article written by Michael Thiessen also states the best way in his opinion is key-changing which I think we all should be aware of.
I hope this puts you on the right track. It sounds like (with limited information) you could be replacing the data but using the same key.

Initialize dynamic Component in Code using Vue.js

I am currently developing a web application that is used to display elements for events on a map provided by HERE Maps. I am using Vue.
I have some components, but the relevant component is the component HereMaps.vue which initializes the map using the HERE Maps Api.
The HERE Maps Api provides the possibility to place so called InfoBubbles on the map showing additional information. These InfoBubbles can be provided some HTML-code in order to customize their appearance.
Please refer to the documentation for additional information
Following the documentation the code looks something like this:
let bubble = new H.ui.InfoBubble(marker.getPosition(), {
content: "<div class='someClass'>Some Content</div>"
});
this.ui.addBubble(bubble)
This is happening after mount in the "mounted" method from Vue in the "HereMaps" component.
The Bubbles are added in a "closed" (hidden) form and dynamically "opened" to reveal their content when the corresponding marker icon on the map is clicked. Therefore the HTML-code is present on the DOM after the component is mounted and is not removed at a later stage.
Now instead of supplying custom code within each bubble added to the UI i want to just add a component like this:
let bubble = new H.ui.InfoBubble(marker.getPosition(), {
content: "<myDynamicComponent></myDynamicComponent>"
});
this.ui.addBubble(bubble)
It does not matter to me wether the component is initialized using props or if it is conditionally rendered depending on the state of a global variable. I just want to be able to use the "myDynamicComponent" in order to customize the appearance in a different file. Otherwise the design process gets very messy.
As far as i know this is not possible or at least i was not able to get it work. This is probably due to the fact that the "myDynamicComponent" is not used within the "template" of the "HereMaps" component und thus Vue does not know that it needs to render something here after the directive is added to the DOM in the "mounted" method.
This is what the InfoBubble looks using normal HTML as an argument:
This is what the InfoBubble looks using the component as an argument:
It appears to just be empty. No content of the "myDynamicComponent" is shown.
Does anyone have any idea how i could solve this problem.
Thank You.
Answer is a bit complicated and I bet you wouldn't like it:)
content param can accept String or Node value. So you can make new Vue with rendered your component and pass root element as content param.
BTW, Vue does not work as you think, <myDynamicComponent></myDynamicComponent> bindings, etc exists in HTML only in compile time. After that all custom elements(components) are compiled to render functions. So you can't use your components in that way.
Give us fiddle with your problem, so we can provide working example:)

xpages view picklist custom control

I am using mark t hughes view picklist custom control from open NTF.
Link to control on openNTF
I have set all the paramenters etc, however when I load the page with the control on, I get my custom error page, and the error below in my error logging database
Error on dialog1button5999 null property/event:
1:
Script interpreter error, line=1, col=35: [ReferenceError]
'compositeData' not found
compositeData.picklistButtonClass + " domfindmebutton5999"
This is trying to set the styleClass of a button in the custom control here:
<xp:this.styleClass><![CDATA[#{javascript:compositeData.picklistButtonClass + " domfindmebutton5999"}]]></xp:this.styleClass>
I am also definately passing this parameter is with the default code:
picklistButtonClass="button2"
I also followed the video Here to the letter, and still get exactly the same issue.
Has anyone come across this before or have any pointers as to where I should be looking to resolve it? Im not sure where to start, as all the instructions and video's explain how to complete the custom properties of the control, but there is never any mention of a need to actually modify any code WITHIN the custom control....
Thanks
(as a side note, I am using bootstrap, should this make any difference)
This is because of the theme definition. Look at the Mark Leusink's blog entry here. http://linqed.eu/2014/08/28/xpages-gotcha-modeconcat-in-your-themes/
If a theme has a "concat" definition, that will be computed at a very early phase. To concat values, it needs to compute the initial value. However, in some cases (e.g. Repeat, Custom control, etc.), the initial value cannot be computed at the page-load section.
For such cases, you can override the theme with a special themeId, as Mark suggested.

Win8 JS App: How can one prevent backward navigation? Can't set WinJS.Navigation.canGoBack

Fairly new to developing for Windows 8, I'm working on an app that has a rather flat model. I have looked and looked, but can't seem to find a clear answer on how to set a WinJS page to prevent backward navigation. I have tried digging into the API, but it doesn't say anything on the matter.
The code I'm attempting to use is
WinJS.Navigation.canGoBack = false;
No luck, it keeps complaining about the property being read only, however, there are no setter methods to change it.
Thanks ahead of time,
~Sean
canGoBack does only have a getter (defined in base.js), and it reflects the absence or presence of the backstack; namely nav.history.backstack.
The appearance of the button itself is controlled by the disabled attribute on the associated button DOM object, which in turn is part of a CSS selector controlling visibility. So if you do tinker with the display of the Back button yourself be aware that the navigation plumbing is doing the same.
Setting the backstack explicitly is possible; there's a sample the Navigation and Navigation History Sample that includes restoring a history as well as preventing navigation using beforenavigate, with the following code:
// in ready
WinJS.Navigation.addEventListener("beforenavigate", this.beforenavigate);
//
beforenavigate: function (eventObject) {
// This function gives you a chance to veto navigation. This demonstrates that capability
if (this.shouldPreventNavigation) {
WinJS.log && WinJS.log("Navigation to " + eventObject.detail.location + " was prevented", "sample", "status");
eventObject.preventDefault();
}
},
You can't change canGoBack, but you can disable the button to hide it and free the history stack.
// disabling and hiding backbutton
document.querySelector(".win-backbutton").disabled = true;
// freeing navigation stack
WinJS.Navigation.history.backStack = [];
This will prevent going backward and still allow going forward.
So lots of searching and attempting different methods of disabling the Back Button, finally found a decent solution. It has been adapted from another stackoverflow question.
Original algorithm: How to Get Element By Class in JavaScript?
MY SOLUTION
At the beginning of a fragment page, right as the page definition starts declaring the ready: function, I used an adapted version of the above algorithm and used the resulting element selection to set the disabled attribute.
// Retrieve Generated Back Button
var elems = document.getElementsByTagName('*'), i;
for (i in elems)
{
if((" "+elems[i].className+" ").indexOf("win-backbutton") > -1)
{
var d = elems[i];
}
}
// Disable the back button
d.setAttribute("disabled", "disabled");
The code gets all elements from the page's DOM and filters it for the generated back button. When the proper element is found, it is assigned to a variable and from there we can set the disabled property.
I couldn't find a lot of documentation on working around the default navigation in a WinJS Navigation app, so here are some methods that failed (for reference purposes):
Getting the element by class and setting | May have failed from doing it wrong, as I have little experience with HTML and javascript.
Using the above method, but setting the attribute within the for loop breaks the app and causes it to freeze for unknown reasons.
Setting the attribute in the default.js before the navigation is finished. | The javascript calls would fail to recognize either methods called or DOM elements, presumably due to initialization state of the page.
There were a few others, but I think there must be a better way to go about retrieving the element after a page loads. If anyone can enlighten me, I would be most grateful.
~Sean R.

Existing widgets not available in a widget template in some (strange) cases

This took me a while. A long while. I battled two problems at once (circular dependencies, fixed with refactoring, and this problem). To get this problem into a JSFiddle required a LOT of work... but I think it was worth it.
So:
http://jsfiddle.net/EVbTL/3/
I define three widgets:
r.AppMainScreen -- This is the main app's widget. Easy: just a bunch of tabs, and a button which contains a simple button, which goes:
// SUbmit form
this.form.onSubmit = function(e){
e.preventDefault();
console.log("HERE");
dialog = new r.RetypePasswordDialog();
dialog.show();
return false;
}
Pretty uninteresting.
r.RetypePasswordDialog() -- A templated widget which represents a dialog box. The only interesting thing about it is:
< input name="password" id="${id}_password" data-dojo-attach-point="password" data-dojo-type="app.ValidationPassword" />
It's a simple custom widget, defined in this very file, which does validation. NOTE: I know there is no point in having a subclass here for this little work. Please keep in mind that this is an example.
r.ValidationPassword()
An augmented ValidationTextBox with some extra validation.
If you click on the button, you get:
Uncaught Error: Could not load class 'app.ValidationPassword
...?!? app.ValidationPassword has definitely been defined. It ought to be available there. At the beginning, I thought it was because of aa circular dependency (it was very fun, yesterday: I had to learn about AMD circular dependencies WHILE trying to figure out this problem...)
If you uncomment this line, executed within the script:
TEST = new r.RetypePasswordDialog();
The whole thing works. It's a meaningless instance, and I cannot figure out why on earth this would or should make a difference.
Explanations most welcome... I couldn't find any!
Thank you,
Merc.
app = new r.AppMainScreen( {});
You redefine the global app variable here, but are trying to use it elsewhere as the base object for your type system. Use var to scope variables to the function.