Open uikit modal on page load - javascript

I'm currently working on a project in Flask and I'd like for (under specific circumstances) open up a modal when the page loads. Currently what I have is as follows:
My view function passes a variable 'open_modal' into the template
return render_template('index.html', open_modal = "window.onload() = function(){UIkit.modal(#modal1).show();};")
and inside the template itself, there's a part in the template which looks like:
<script type="text/javascript">
{{ open_modal }}
</script>
And the modal itself looks something like:
<div id="modal1" uk-modal>
<div class="uk-modal-dialog uk-modal-body">
Test test!
</div>
</div>
And so what I was hoping is that whenever I use the render_template with the kwarg 'open_modal' as that value above, it'd insert the javascript fragment into the template and then ta-dah! The modal would open when the page loads. However, this doesn't seem to work, and I can't figure out why.
Admittedly, I have no experience with javascript so I would have no clue if the script fragment that is inserted by 'open_modal' even works, but I'd rather stick to vanilla javascript because this is the only bit of javascript in my program, and I'd rather not add more bulk to it unnecessarily with jquery etc.
Thanks a bunch if you can help!

The onload is not a function, it's a property of window. You have to assign a function to it:
return render_template('index.html', open_modal = "window.onload = function(){UIkit.modal('#modal1').show();};")

Related

Can you change the order in which RenderSection executes?

Is there a way to tell the RenderSection to run after everything else on the _layout page is completed?
I have a RenderSection which contains Javascript. I want to modify elements on the _Layout.cshtml page.
If the RenderSection is called after the element on the _Layout page then it works fine but if RenderSection is called before the end it doesn't work since the element in the _Layout does not yet exist.
<h1 id="AA"> NewContent </h1> <!-- works because AA exists -->
#RenderSection("MySection") <!-- Contains javascript to add New Content to AA and BB -->
<h1 id="BB"> </h1> <!-- Does not receive content because it does not exist yet -->
I was unable to find a way of changing the order that Razor renders sections but I found a work around.
There's a tutorial on W3Schools which allows you to insert HTML from a URL into a DIV of your choice.
How to insert HTML tutorial
This allows you to specify a URL in your DIV from where to load the HTML. In my case, I just loaded it from one of my MVC controllers.
<div w3-include-html="content.html"></div>
You can then just call a method when you are ready to load your HTML in.
includeHTML();

Problems with vue.js content rendering

I've just learning Vue.js and I'm getting stuck with some problems with its rendering.
Let's say I have the following lines of code:
index.html
<div id="header">
<h5>{{pageName}}</h5>
<p>{{pageSubtitle}}</p>
</div>
app.js
var header = new Vue({
el: '#header',
data: {
pageName: 'CuteCat',
pageSubtitle: 'World of cats'
}
});
When I load the page, the CuteCat and World of cats is shown perfectly but when I view source, this is what I get:
<div id="header">
<h5>{{pageName}}</h5>
<p>{{pageSubtitle}}</p>
</div>
What can I do to replace the mustaches brackets in the view source with its declared value like this?
<div id="header">
<h5>CuteCat</h5>
<p>World of cats</p>
</div>
Just as #yuriy636 is telling you, this is not an error by any means.
Vue is a JavaScript UI framework, making its magic in the client (i.e. in the browser). In the source view you see what's been loaded from the server and what you see is exactly that.
If you disable JavaScript for a session and reload your app, the double mustaches will be visible. Because they are replaced by Vue when JS is on.
Edit: In the DOM, however everything is normal after Vue rendering, just as you would expect it.

load react script inside text/template script

I'm trying to contribute to a project that uses <script type="text/template"></script> for rendering the elements of a page.
My contribution is to change the elements of the page into react components. However when I order the react to render in a specific div with ReactDOM.render() I get an error saying
Uncaught Error: _registerComponent(...): Target container is not a DOM element.
I know that means that react doesn't find the div where to render so propably I will need to load the react script after the div, I've tried that but the error is there again.
I've tried loading the react script otherwise like this
<script type="text/template">
<ul class="new-component-template" id="xblocklist" >
</ul>
<script type="text/babel" src="path to react file"/>
</script>
but when I load the page the error is gone an the script is not loaded at all.
What I need is to load the script when the outer script is called, I.E can I write a function inside <script type="text/template"></script> that actually loads the react script inside.
UPDATE
var ListXblocks = React.createClass({
componentWillMount: function(){
this.setState({Problemstyle: this.props.Problemstyle})
fetch('http://192.168.33.10:8002/XBlocks/')
.then(result=>result.json())
.then(result=> {
this.setState({items:result})
})
},
render:function(){
return(
<div>
{
this.state.items.map((item)=>{return(
<li className="editor-manual" key={item.title}>
<button type="button" className="button-component" data-category="problem" data-boilerplate="">
<span className="name">{item.description}</span>
</button>
</li>)})
}
</div>
);
}
});
ReactDOM.render(<ListXblocks/>, document.getElementById('xblocklist'));
Script tag with type="text/template" doesn't do anything particularly and it just let browser to ignore what inside it. This approach usually uses by templating systems like handlebarjs and React doesn't support it. You can read more about this here. So if you put your React scripts also inside that, the browser is just going to ignore that as well.
Beacuse your ul tag is not a html element, document.getElementById('xblocklist') is going to return null. That's why you get "Target container is not a DOM element." error. So you have to get the html out of the script tag either manually or using JavaScript.

Knockout + Ajax Content results in multiple binding error

I have built a web application with multiple pages. Some of them are Knockout-driven.
I am trying to apply some Ajax-optimized page loading and stumble over the following issue.
Say I have the following general page structure
<body>
<div id="content">
</div>
</body>
And the following view, which is using Knockout. I include the call to applyBindings inline for being able to load the right ViewModel for every view.
<section id="editor">
<ul data-bind="foreach: items">
....
</form>
</section>
<script>
ko.applyBindings({items: {}}, $("#editor").el)
</script>
I load the view asynchronously into div#content for example using JQuery.load("editor.html #content")
The first page load works fine, but when navigating away (again using JQuery.load) from this view and coming back again I receive the error:
You cannot apply bindings multiple times to the same element.
I have already tried to apply ko.cleanNode but with no success. What am I missing? The #editor node should be removed from the DOM when other content is shown. So I really do not understand how to clean bindings or reinitialize knockout.
Note: I do not want the old data, I want to initialize the Bindings like on a freshly loaded page
Could you test your $("#editor").el in console? It doesn't work in standard jQuery.
If your $("#editor").el returns undefined, your ko.applyBindings({items: {}}, $("#editor").el) is essentially binding to window.document.body.
You may try
ko.applyBindings({items: {}}, $("#editor").get(0));
...
// call cleanNode before loading new page.
ko.cleanNode($("#editor").get(0));
$("#content").load( "newpage.html" );
if your bindings in "editor" section doesn't change,i suggest you to load(AJAX) only json data from server,and replace(modify) your viewModel in the browser,in that way knockout will refresh the dom automaticly.

Mustache JS Templating - How do I embed a variable in a script tag string?

I just started using Mustache and I like it so far, but this has me perplexed.
I am using the GitHub gist API to pull down my gists, and part of what I want to do is include the embedding functionality into my page. The problem is Mustache seems to not want to have anything to do with my dynamic script tag.
For example, this works fine:
<div class="gist-detail">
{{id}} <!-- This produces a valid Gist ID -->
</div>
Additionally, this works perfect:
<div class="gist-detail">
<script src='http://gist.github.com/1.js'></script> <!-- Produces the correct embed markup with Gist ID #1 -->
</div>
If I try to pull these together, something goes terribly wrong:
<div class="gist-detail">
<script src='http://gist.github.com/{{id}}.js'></script> <!-- Blows up! -->
</div>
Chrome Inspector shows this:
GET https://gist.github.com/%7B%7Bid%7D%7D.js 404 (Not Found)
... which looks like to me something is weird with escapes or whatnot, so I switch over to the raw syntax:
<div class="gist-detail">
<script src='http://gist.github.com/{{{id}}}.js'></script> <!-- Blows again! -->
</div>
And I get the same result in Inspector:
GET https://gist.github.com/%7B%7B%7Bid%7D%7D%7D.js 404 (Not Found)
How do I get the correct values to embed in the script tag?
EDIT
I am injecting the template as follows (in document.ready:
function LoadGists() {
var gistApi = "https://api.github.com/users/<myuser>/gists";
$.getJSON(gistApi, function (data) {
var html, template;
template = $('#mustache_gist').html();
html = Mustache.to_html(template, {gists: data}).replace(/^\s*/mg, '');
$('.gist').html(html);
});
}
The actually template is inside of a ruby partial, but it is wrapped in a div (not a script tag, is that a problem?) (that's hidden):
<div id="mustache_gist" style="display: none;">
{{#gists}}
<!-- see above -->
{{/gists}}
</div>
I assume a div is ok rather than a script because in either case, I'm pulling the .html(). Is this a bad assumption?
To avoid automatic escaping in Mustache use {{{token}}} instead of {{token}}.
It seems like your template is in HTML and trying to retrieve the template using html() results in a pre-URL-escaped template to be returned. Try placing your template inside a <script type="text/html"> tag instead.
When you embed your template inside an HTML element that excepts more HTML elements as children, it may get processed by the browser as HTML. Escaping may occur. By using a <script> tag with a non-script content type, you're basically telling the browser not to touch your template.
It looks like your script is getting requested before Mustache has a chance to update the src property. What you want to do is define the template in a way that it's not parsed as part of the DOM. A common approach is to define your template inside of a <textarea> tag. This will preserve formatting and prevent character escaping.
<textarea id="gist-detail-template" style="display:none">
<script src='http://gist.github.com/{{id}}.js'></script>
</textarea>
Now, to instantiate the template:
var template = $('#gist-detail-template').val();
var html = Mustache.to_html(template, yourTemplateData);
Here's an official example: http://mustache.github.com/#demo

Categories