Django: Writing JavaScript inside template vs loading it - javascript

I am using JavaScript to add comment without refreshing the page. When I am using JavaScript inside the template it is working perfectly fine but if I am writing the JavaScript to a file and loading the file inside the template then it is not displaying the name of the person who wrote the comment (It is displaying the comment fine). Below is the JavaScript I used inside the template:
function create_comment(event,div_id,form_id,commentinsert_id) {
event.preventDefault();
var text_id = '#'.concat(div_id,' ','#comment-text')
var slug_id = '#'.concat(div_id,' ','#post_slug')
var appenddiv_id = '#'.concat(div_id)
comment_count ++;
var divcommentinsert_id = 'inserted_comment-'.concat(comment_count.toString())
$.ajax({
url : "create_comment/", // the endpoint
type : "POST", // http method
data : { text : $(text_id).val(), post_slug: $(slug_id).val(),},
// handle a successful response
success : function(json) {
div.innerHTML = `
<div id = `+divcommentinsert_id+` class="card-footer">
<div class="row">
<div>
<img src="{{user.profile.profile_picture.url}}" alt="" width="40" height="40">
</div>
<div class="col-md-8">
<b style="color:rgb(240, 0, 0);"> {{user.first_name}} {{user.last_name}}</b>
<br>
`+json.text+`
<a onClick="edit_comment('`+json.slug+`','`+divcommentinsert_id+`','`+json.text+`')"><i class="fa fa-edit"></i></a>
<a onClick="delete_comment('`+json.slug+`','`+divcommentinsert_id+`')"><i class="fa fa-trash-o"></i></a>
</div>
</div>
</div>`;
document.getElementById(commentinsert_id).appendChild(div);
document.getElementById(form_id).reset();
},
// handle a non-successful response
error : function(xhr,errmsg,err) {
$('#results').html("<div class='alert-box alert radius' data-alert>Oops! We have encountered an error: "+errmsg+
" <a href='#' class='close'>×</a></div>"); // add the error to the dom
console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
}
});
};
In the above code <b style="color:rgb(240, 0, 0);"> {{user.first_name}} {{user.last_name}}</b> is used to display the name. It is displaying name of the person who added the comment but when I copy the same function to comments.js file and load the file like <script src="{% static 'scripts/comments.js' %}"></script> then its not displaying the name instead it is displaying {{user.first_name}} {{user.last_name}}. I am using this javascript in several pages, I thought it is best to write to file and load the file instead of writing the same script in every page. Can someone help me with this?

{{ dictionary.key }}, etc in a template is how you use variables with the django template engine.
A static javascript file is not a template. It isn't processed by the django template engine.
Put the values you need in your html (through the template engine), access them from JS.
Basic ideas:
Create a JS variable (eg: <script>var user_full_name = "{{ user.user_name }} {{ user.last_name }}"</script>), use user_full_name inside the ajax sucess callback.
Put the values inside some html element (eg: <input type="hidden" id="user_name" value="{{ user.user_name }}">) and get it with JS/jQuery $("#user_name").val().
edit: added missing closing double quote to the user_full_name declaration.

Related

Python Flask + AJAX how to update div variable without reloading page

I have this example where I am trying to see if I have a record in my database to see whether or not this Triggered variable in my <div class="container-fluid"> is true or false. I have it that I can POST the page just fine but I am wondering if you could show me how I can get AJAX to constantly check if it has been triggered and change the variable Triggered inside that div without refreshing anything else.
HTML
**<div class="container-fluid" id="trigger-container">**
<h1>Incubator Controller</h1>
<div class="col-sm-4" style="background-color:lavender;">
{% if Triggered == "True" %}
<span class="badge badge-pill badge-success">ALL CLEAR</span>
{% else %}
<span class="badge badge-pill badge-danger">PROXIMITY ALERT</span>
{% endif %}
</div>
and the python flask side looks like this:
#app.route('/update', methods=['POST','GET'])
def Updater():
Node = DAO.Pull_Node_Status(NodeID)
Triggered= Node.Triggered[0]
return render_template('Controller.html',Triggered=Triggered)
I know that I will need to use setInterval to call a javascript function.. but I am having a hard time piecing it together. This is the most simplest example that I can think of. I would like to be able to update multiple things constantly without refreshing the page and losing everything.
HTML script portion
<script>
function UPDATETriggerDiv() {
$.get('/updateTrigger',
function(data){
const parsed = JSON.parse(data)
something to do here with (parsed.Triggered);
g2.refresh(parsed.currentHumidity);
};
)
};
setInterval(function () {
UPDATETriggerDiv();
return false;
}, 2500);
</script>
Any help would greatly be appreciated!
If parsed.Triggered is boolean then you can set the Incubator Controller with an if/else statement.
var html = '<span class="badge badge-pill ';
if (parsed.Triggered){
html += 'badge-success">ALL CLEAR</span>';
}
else{
html += 'badge-danger">PROXIMITY ALERT</span>';
}
$("#trigger-container h1 + div").html(html);

Included template getting loaded before model is available from controller - Angular

I have created a basic tool using vanilla javascript/html/css to perform certain functions across all emails associated with the business. To maintain the code base simplicity, i have started to porting the application using angularJS, creating modules/controllers etc. However, i got stuck with below situation. It looks like from the logs that my included html template gets called before data is ready from the controller.
I am placing an ajax call from the server which roughly takes ~1 sec. But by the time, I guess Angular executes the included template and because of no model availability, it renders nothing on the application side.
A look into my code:
index.html
<div class="tab-pane active fade in" id="results">
<section ng-controller = "messageSelectionController" ng-include src="'templates/messageSelectionTemplate.html'"></section>
</div>
messageSelectionController.js
app.controller('messageSelectionController',function($scope,$log){
//Generic ajax call
var makeRequest = function(paramObj,successCallback,errorCallBack,url,type){
$.ajax({
method : type ? type : "GET",
url : url ? url : "https://xx.xx.xx/xx/xx",
data : paramObj,
xhrFields : { withCredentials : true }
}).then(successCallback,errorCallBack);
};
var messageSelectionSuccessHandler = function(data){
$scope.messageselectionlist = JSON.parse(data).response.docs;
$log.info($scope.messageselectionlist);
};
var messageSelectionErrorHandler = function(data){
$log.info(data.responseText);
};
var data = {
q : "",
fq:[
'View:xx',
'Platform:xx'
],
start : 0,
rows : 9999
};
makeRequest(data, messageSelectionSuccessHandler,messageSelectionErrorHandler);
});
messageSelectionTemplate.html
<ul>
<li ng-repeat="item in messageselectionlist">
<article class="">
<span class="label label-success">MessageSelection</span>
<a> "Platform : {{item.Platform}} | View : {{item.View}} | Locale : {{item.Locales[0]}}"
<i class = "ocon-flag-{{item.Locales[0] | lowercase }}"></i>
</a>
<span class = "label label-inverse">{{item.Description}}</span>
</article>
</li>
</ul>
I tried to put logs to see when the messageSelectionTemplate is loaded, using below code:
$scope.$on('$includeContentLoaded', function(event, target){
console.log(event); //this $includeContentLoaded event object
console.log(target); //path to the included resource, 'snippet.html' in this case
});
and here's the logs:
-----templates/messageSelectionTemplate.html angular.js:13424
-----Array[654]
Can someone let me know how to defer the included template loading until the modal for template is not available. Thanks!

Getting Value from Dynamic Url and Post it into HTML/PHP by Using AngularJS

I would like to ask whether I can get the data from dynamic URL... Here is the case:
I have given an (a) html tag into my angularJS php file to give direction to certain page with the value inside it e.g. localhost:8080/someurl/blablabla/{{item.master}} so the output is based on what I have clicked... so it will be localhost:8080/someurl/blablabla/221
After that, I have a laravel 5.2 and given a route based on this dynamic url, e.g. Route::get('order/{id}','someController#index')
After this route, I have prepared the php files and it is ready to display the data
The problem is, I don't know which angularJS code that I should use to display the data based on the {{item.master}} in this new page, when I use $http.get, it doesn't get anything, is there any clue about this?
UPDATED
Here is the codes:
HTML (order.html)
<div class="itemcheck" ng-repeat="item in dataItem.stores | regex:'name':alfabet | orderBy: 'name' | filter: searchItem" ng-model="item">
<div class="left" ng-if="item.preparation == ''" ng-click="klikItem(item)"><i class="fa fa-circle silver"></i>{{item.name}}</div>
<div class="left" ng-if="item.preparation == '1'" ng-click="klikItem(item)"><i class="fa fa-circle green"></i>{{item.name}}</div>
<div class="left" ng-if="item.preparation == '2'" ng-click="klikItem(item)"><i class="fa fa-circle yellow"></i>{{item.name}}</div>
<div class="left" ng-if="item.preparation == '3'" ng-click="klikItem(item)"><i class="fa fa-circle pink"></i>{{item.name}}</div> <div class="right" ng-click="tambahItem(item)"><a>+ Tambahkan</a></div></div>
Let's not focus on "tambahkan" but the item.name when I put klikItem function
So, when I click, the klikItem() function is triggered (what I want) or let's say I put the tag a inside the {{item.name}} function and when I click that it goes to order/{{item.id}} (somehow like that)...
Nah, the problem is, how can I get the data from order/{{item.id}}? If I use $http.get, it must have the data, and when I put id for example
$scope.tampilkanDeskripsiItem = function(id){
var url = 'order/' + id;
$http.get(url).success(function(data){
$scope.deskripsiItem = data;
});
};
$scope.tampilkanDeskripsiItem();
this code will return error as "id" is not defined...
You can assign id inside klikItem (if item object has id property.)
function klikItem(item){
$scope.tampilkanDeskripsiItem(item.id);
}

Latency when loading html content with FOSJsRoutingBundle and Ajax (route parameter {id})

I am using FOSjSrouting in my symfony2.7 project.
I have this html.twig view code:
<table>
<!--table header code ...etc... -->
<tbody>
{% for currentData in arrayData %}
<tr>
<td>{{ currentData.first_name}}</td>
<td>{{ currentData.last_name}}</td>
<td>{{ currentData.order}}</td>
<td>{{ currentData.category}}</td>
<td>{{ currentData.location}}</td>
<td>{{ currentData.price}}</td>
<td>
<a><button class="btn btn-info btn-xs showDetail" href="{{ path('detailsData', {'idData': currentData.idData }) }}">Show Detail</button></a> <!-- to open dialog tag through Ajax for each lines -->
<button class="btn btn-warning btn-xs">Edit</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- the dialog window to load detail content -->
<dialog id="window"></dialog>
<!-- javascript to open and close dialog window -->
<script>
(function() {
var dialog = document.getElementById('window');
var showButtons = document.getElementsByClassName('showDetail');
var showDialog = function() {
console.log(this);
dialog.show();
dialog.load(Routing.generate('detailsData', {'idData': currentData.idData }) }})
};
var i, len = showButtons.length;
for(i = 0; i < len; ++i) {
showButtons[i].onclick = showDialog;
}
document.getElementById('exit').onclick = function() {
dialog.close();
};
})();
</script>
As you can see, foreach data I want to display, I have a detail button. This detail button refers to another page which displays linked data to the current data I clicked on.
This the route for the detail view (respecting the FOSjSrouting needs):
detailData:
pattern: /manage/order/detail/{idData}
defaults: { _controller: MySpaceMyBundle:MyController:detailData }
requirements:
methods: GET
options:
expose: true
The purpose is to load via Ajax, jQuery, FOSjSrouting the linked datas in the dialog tag with the id="window" to the currentData.idData.
But when I click on the detail button, I have this error (in my browser console):
Uncaught ReferenceError: currentData is not defined
I understand that I need to take care about the {id} parameter of my route.
How can I load the page that the detail button refers to and displays the right linked data through ajax with my current script (at the end of my html code)?
EDIT
I add this code in javascript at the end of my script tag in my html.twig view, it allows me to display the datas I want in my dialog tag:
$('.showDetail').click(function() {
$.ajax({
'url': Routing.generate('detailsData', {'idData': $(this).val()}),
'cache' : false,
'success': function(loadDetail) {
$('#window').html(loadDetail);
}
});
});
The problem occured is that I have a latency to display the dialog tag, and just before displaying the current data I want, the last one I clicked on are displaying before for a few second, and then my current data I want is display later.
Maybe It's a cache problem?
Moreover, the first time I click on the detailButton, the dialog is displaying empty, then after (latency), the data are displaying.
How can I fix these problems?
The problem is, that the variable is not defined in javascript. You have to insert curly brackets to let twig translate the twig variable into the corresponding value like this:
{'idData': {{currentData.idData}} }
Unfortunately therefor it has to be in the for loop as well - so it might be better to safe the value in an data attribute and read it by using javascript.
You could also use the already populated href attribute like this (using jQuery as you said you are doing):
dialog.load($(this).attr('href'))

How to access functions of a controller from within another controller via scope?

I have the following problem, I want to call a function of another controller from within a controller I want to use for a guided tour (I'm using ngJoyRide for the tour). The function I want to call in the other controller is so to say a translator (LanguageController), which fetches a string from a database according to the key given as parameter. The LanguageController will, if the key is not found, return an error that the string could not be fetched from the database. In my index.html fetching the string works, but I want to use it in the overlay element of my guided tour, which does not work, but only shows the "not fetched yet"-error of the LanguageController.
My index.html looks like this:
<body>
<div class="container-fluid col-md-10 col-md-offset-1" ng-controller="LangCtrl as lc" >
<div ng-controller="UserCtrl as uc" mail='#email' firstname='#firstname'>
<div ng-controller="GuidedTourCtrl as gtc">
<div ng-joy-ride="startJoyRide" config="config" on-finish="onFinish()" on-skip="onFinish()">
...
{{lc.getTerm('system_lang_edit')}}
...
</div>
</div>
</div>
</div>
</body>
The controller I'm using for the guided Tour looks like this:
guidedTourModule.controller('GuidedTourCtrl',['$scope', function($scope) {
$scope.startJoyRide = false;
this.start = function () {
$scope.startJoyRide = true;
}
$scope.config = [
{
type: "title",
...
},
{
type: "element",
selector: "#groups",
heading: "heading",
text: " <div id='title-text' class='col-md-12'>\
<span class='main-text'>"\
+ $scope.lc.getTerm('system_navi_messages') + "\
text text text text\
</span>\
<br/>\
<br/>\
</div>",
placement: "right",
scroll: true,
attachToBody: true
}
];
...
}]);
And the output I ultimately get looks like this for the overlay element:
<div class="row">
<div id="pop-over-text" class="col-md-12">
<div id='title-text' class='col-md-12'>
<span class='main-text'>
not fetched yet: system_navi_messages
text text text text
</span>
<br/>
<br/>
</div>
</div>
</div>
...
I hope someone can see the error in my code. Thanks in advance!
Things needs clarity are,
How you defined the 'getTerm' function in your Language controller, either by using this.getTerm() or $scope.getTerm(). Since you are using alias name you will be having this.getTerm in Language controller.
Reason why you are able to access the getTerm function in your overlay element is, since this overlay element is inside the parent controller(Language Controller) and you are referencing it with alias name 'lc' while calling the getTerm function. Thats' why it is accessible.
But the string you pass as a parameter is not reachable to the parent controller. that's why the error message is rendered in the overlay HTML.
Please make a plunker of your app, so that will be helpful to answer your problem.

Categories

Resources