Assign Django variable value to AngularJS - html

I have this template tags in my html code
{{ djangoVar}} //Django template tag
{$ angularVar $} //AngularJS template tag
How can I assign {{ djangoVar}} to {$ angularVar $} in my html?
Something like:
{% {$ angularVar $} = djangoVar %}

The angularVar must be assigned with javascript code. So, in your django template you can do something like
<script>
var django_variables = {};
django_variables.djangoVar = {{ djangoVar }};
</script>
So you declare a django_variables global variable. Then, in your angular controllers you can do:
function MyController($scope) {
$scope.angularVar = django_variables.djangoVar;
}
The important thing is to run the 1st snippet inside a normal django html template that the context will be passed and {{ djangoVar }} will get its value.

Related

What's the more efficient way to create dynamic tags on MeteorJS / Blaze?

I'm looking for a solution to manage a HTML tag type with a Reactive Var. I looked all the Blaze documentation but found nothing..
Simple example
I want to change a tag from div to form when a boolean ReactiveVar is updated.
Template.MyExample.onCreated(function() {
this.is_form = new ReactiveVar(false)
})
Template.MyExample.helpers({
getTag() {
return Template.instance().is_form.get() ? 'form' : 'div'
}
})
This obviously didn't work:
<Template name="MyExample">
<{{getTag}}>
</{{getTag}}>
</Template>
Nicer solution ?
The "best" way I found to get it was to create a tag template and list everycase a single time, but I didn't like that solution.
Template.MyExample.onCreated(function() {
this.is_form = new ReactiveVar(false)
})
Template.MyExample.helpers({
getTag() {
return Template.instance().is_form.get() ? 'form' : 'div'
}
})
Template.MyExample.events({
'click .switch'(e, instance) {
e.preventDefault()
instance.is_form.set(!instance.is_form.get())
}
})
Blaze Templates:
<Template name="MyExample">
<div>
Switch type
{{#MyTag tag=getTag}}
Parent tag is {{getTag}}
{{/MyTag}}
{{#MyTag tag="a" attributes=(object href="#" target="_blank")}}
Link
{{/MyTag}}
</div>
</Template>
<Template name="MyTag">
{{#if equals tag 'form'}}
<form {{attributes}}>
{{> Template.contentBlock }}
</form>
{{else if equals tag 'a'}}
<a {{attributes}}>
{{> Template.contentBlock }}
</a>
<!-- and more and more.... -->
{{else}}
<div {{attributes}}>
{{> Template.contentBlock }}
</div>
{{/if}}
</Template>
Helpers required:
Template.registerHelper('object', function({hash}) {
return hash;
})
Template.registerHelper('equals', function (a, b) {
return a === b
})
This is working but i'm wondering if it's to much for Meteor (and DOM updates). Does this solution works like an simple {{#if}}...{{/if}} or it's way heavier ?
The feature you request is basically not supported by Blaze. While static code generators can easily include dynamic tags, this is a very hard one at runtime where you have to deal with the DOM tree, whose element's tag-types are immutable by design.
I first thought of a workaround, that uses child swapping using jQuery in the onRendered of MyTag:
Template.MyTag.onRendered(function () {
const instance = this
instance.autorun(() => {
const data = Template.currentData()
const attributes = data.attributes || {}
const elementName = data.tag
const refTag = instance.$('.my-tag-ref')
const newTag = $(`<${elementName}>${refTag.html()}</${elementName}>`)
Object.keys(attributes).forEach(attKey => newTag.attr(attKey, attributes[ attKey ]))
newTag.addClass('my-tag-ref')
refTag.replaceWith(newTag)
})
})
But this is unfortunately not working, because the content bock looses it's reactivity and the jQuery instance of the current Template looses it's scope to the root element. I just add it here in case someone catches up on this and finds a solution that works.
Now there is still a solution that works using dynamic Templates:
<Template name="MyTag">
{{#Template.dynamic template=getTemplate data=getData}}
{{> Template.contentBlock }}
{{/Template.dynamic}}
</Template>
<template name="mytaga">
<a {{attributes}}>
{{> Template.contentBlock }}
</a>
</template>
<template name="mytagform">
<form {{attributes}}>
{{> Template.contentBlock }}
</form>
</template>
<template name="mytagdiv">
<div {{attributes}}>
{{> Template.contentBlock }}
</div>
</template>
As you can see the disadvantage is clearly that you have to define lots of new Templates. The advantage is, that you don't have to use so many if/else anymore and it pays out the more often you will have to include MyTag in your code.
The respective helpers look like the following:
Template.MyTag.helpers({
getTemplate() {
const instance = Template.instance()
console.log(instance.data)
return `mytag${instance.data.tag}`
},
getData () {
return Template.instance().data
}
})
This is working but i'm wondering if it's to much for Meteor (and DOM updates). Does this solution works like an simple {{#if}}...{{/if}} or it's way heavier ?
Blaze is overall slower than for example React or Vue. However, the rendering only updates if the reactive data updates, thus it is just as heavy as the amount of updates to be triggered.

CKEditor - HTML code keep adding new line very time I switch between source code view and wysiwyg view?

I tried to keep my jinja code in CKEditor as it was after I toggle the view between code view and WYSIWYG view.
And I could get this result by adding below line in my config.js file
CKEDITOR.config.protectedSource.push(/\r|\n/g);
CKEDITOR.config.autoParagraph = false;
However, it does not work well for HTML code. For instance, if jinja code and html mixed together like this:
{% if name=='bob' %}
{{'hello bob'}}
{%else%}
{{ 'hello ' + name }}
{% endif %}
<p>Hello visitor</p>
Here is Demo on Fiddle JS
After this, when I change from code view to wyiwyg view in CKEditor, the HTML code just increase by one new line, and another new line for another toggle view as shown below:
I can't find what is wrong with HTML code, I just what to format jinja code only, how can I fix it? Thanks
Write these additional lines under your code
$("body").on("click", ".cke_button__source", ()=>{
// if(CKEDITOR.instances.editor1.mode==="source"){
let vtk = CKEDITOR.instances.editor1.getData();
// vtk = vtk.replace(/\n<p>/gm, "<p>");
vtk = vtk.replace(/^\s*[\r\n]/gm, "");
$(".cke_source").val(vtk)
// }
})
Here is jsFiddle

Angular 6 String interpolation not updating DOM whereas innerHTML does

I have events page and event detail page.
When I place <h1>{{ Eventinfo.EventTitle }}</h1> to display title, the DOM does not get updated with new title. However, when I use <h1 [innerHTML]="Eventinfo.EventTitle"></h1>, I do get the update title in H1 tag.
Why do string interpolation <h1>{{ Eventinfo.EventTitle }}</h1> does not work?
try console in this function and reply with whatever data you are getting in console
public getEventInfo(id)
{
this.apiService.getEventInfo(id).subscribe((data : any) => {
this.Eventinfo = data.events.results[0];
});
console.log(this.Eventinfo); //view data in console
}

Using Ajax in django template to update an element

So I have a button that is suppose to "Add" an "Item" to a list and update the list on the same page without refreshing it.
Adding the Item without redirecting worked. but the element is not refreshed properly
Here is my script:
<div id="list">
{% for item in items %}
{{ item.name }}
{% endfor %}
</div>
<button id="add" type="submit">+</button>
<script>
$('#add').click(function () {
$.get('/url/page/', function (data) {
$('#list').html(data);
});
});
</script>
views.py
def add_to_list(request, item_id, list_id):
item, created = List.objects.get_or_create(list_id=list_id,
item_id=item_id)
return HttpResponse(request)
I feel like I have to add something in the views? and maybe use json code?
You should append the result of your request to the div element. Try this:
$('#add').click(function () {
$.get('/url/page/', function (data) {
$('#list').append(data);
});
});
Assuming that data that you receive from GET request is not an object but just a string. If it is an object add data.name:
$('#list').append(data.name)
Hope it helps.

Passing value from Django view to AngularJS inserted template

Is there a way to pass a value from a Django view to an AngularJS inserted template?
In my view.py I have the code:
count_users = Profile.objects.filter(user_id__gte = 0).count()
context_dict = {'users': count_users}
return render_to_response('dashboard.html', context_dict)
In dashboard.html I am able to insert the user count into the html as follows:
{{ users }}
This works fine but dashboard.html uses AngularJS to insert some more html as follows:
<div ui-view class="fade-in-up">
</div>
Mt problem that the html file inserted by AngularJS does not respond to the:
{{ users }}
Is there a way to pass the value of users through to the AngularJS inserted HTML?
using ng-init you can attach your value into the $scope
<div ui-view class="fade-in-up" ng-init="User='{{user}}' " >
</div>
In your javascript do:
mainModule
.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{$');
$interpolateProvider.endSymbol('$}');
});
This way, if you want to bind an angular variable in the html, you use:
{$ variable $}
If you want to add a Django variable, you use:
{{ variable }}
And your code may work if you leave it as it is, and just add this configuration to the angular module.