Django How to route to a js file from urlpattern - django

I want to route to a js file (may be static or dynamic).
The js file has format same thing:
(function() {
var img = new Image,
url = encodeURIComponent(document.location.href),
title = encodeURIComponent(document.title),
ref = encodeURIComponent(document.referrer);
img.src = '%s/a.gif?url=' + url + '&t=' + title + '&ref=' + ref;
})();
And from client I will run this script from header by:
<script async="" src="https://example.com/a.js"> </script>
without use staticfile, I think we can use it by urlpattern. But I don't know use for javascript file.

I found a solution.
in views.py:
def generatejs(request):
js_str="""
(function() {
var img = new Image,
url = encodeURIComponent(document.location.href),
title = encodeURIComponent(document.title),
ref = encodeURIComponent(document.referrer);
img.src = 'http://127.0.0.1:8000/a.gif?url=' + url + '&t=' + title + '&ref=' + ref;
})();
"""
return HttpResponse(js_str)
And In urlpatterns, insert:
url(r'^gtag/js', collector.generatejs),

Related

Django template tag URL is not working in JavaScript

I want to add an edit button and delete image dynamically to table, but it is showing error
Page Not Found at
Request URL: http://127.0.0.1:8000/%7B%25%20url%20'expense-edit'%20expense.id%20%25%7D
here is js file
const searchField = document.querySelector("#searchField");
const tableOutput = document.querySelector(".table-output");
const appTable = document.querySelector(".app-table");
const paginationContainer = document.querySelector(".pagination-container");
tableOutput.style.display = 'none';
const noResults = document.querySelector(".no-results");
const tbody = document.querySelector(".table-body");
searchField.addEventListener('keyup', (e) => {
const searchValue = e.target.value;
if (searchValue.trim().length > 0) {
paginationContainer.style.display = "none";
tbody.innerHTML = "";
fetch("http://127.0.0.1:8000/search-expenses", {
body: JSON.stringify({ searchText: searchValue }),
method: "POST",
})
.then((res) => res.json())
.then((data) => {
console.log("data", data);
appTable.style.display = "none";
tableOutput.style.display = "block";
console.log("data.length", data.length);
if (data.length === 0) {
noResults.style.display = "block";
tableOutput.style.display = "none";
}
else {
noResults.style.display = "none";
data.forEach((item) => {
tbody.innerHTML += `
<tr>
<td>${item.amount}</td>
<td>${item.category}</td>
<td>${item.description}</td>
<td>${item.date}</td>
<td>Edit<img src="{% static 'img/delete.png' %}" width="35" height="35"/></td>
</tr>`;
});
}
});
}
else {
noResults.style.display = "none";
tableOutput.style.display = "none";
appTable.style.display = "block";
paginationContainer.style.display = "block";
}
});
urls.py
from django.urls import path
from . import views
from django.views.decorators.csrf import csrf_exempt
urlpatterns = [
path('', views.home, name="home"),
path('expenses', views.index, name='expenses'),
path('add-expenses', views.add_expenses, name='add-expenses'),
path('edit-expense/<int:id>', views.expense_edit, name='expense-edit'),
path('expense-delete/<int:id>', views.delete_expense, name='expense-delete'),
path('search-expenses', csrf_exempt(views.search_expenses), name='search_expenses'),
path('expense_category_summary', views.expense_category_summary, name="expense_category_summary"),
path('stats', views.stats_view, name="stats"),
path('export_csv', views.export_csv, name="export-csv"),
path('export_excel', views.export_excel, name="export-excel"),
path('export_pdf', views.export_pdf, name="export-pdf"),
]
I want to add a button that has a link to the next page through JavaScript using the Django URL template tag. thanks in advance
When you write {% url 'expense-edit' expense.id %}, you're using a Django-specific "language" called Django template language which means that the mentioned syntax can only be "understood" by Django templates.
What you're doing here is loading a separate JavaScript file in which the Django template syntax simply won't work because when browser comes to the point to evaluate that file, {% url 'expense-edit' expense.id %} will look just another string literal, and not what you would expect to.
It should work if you inline your JavaScript example directly into the Django template.
So there is two possible Hacks to do this:
One is putting the written script in your tenplate file as:
<script type="text/javascript">
const searchField = document.querySelector("#searchField");
const tableOutput = document.querySelector(".table-output");
...
</script>
The issue with this approach is the scope of variables as you may not want to declare things globally so it could be considered an easy approach, but not necessarily the best solution.
So the other solution is to change the name of file from script.js to script.js.html and include in your desired template as :
...
{% include "my_app/script.js.html" %}
Instead of this:
Edit<img src="{% static 'img/delete.png' %}" width="35" height="35"/></td>
Try this way:
Edit
<img src="{% static 'img/delete.png' %}" width="35" height="35"/></td>

Retrieve data from list in SharePoint 2013 provider hosted App

I have developed a provider hosted app in SharePoint 2013. As you already know, Visual Studio creates web application and SharePoint app. The web application gets hosted inside IIS and the SharePoint App in SharePoint site collection. I'm trying to get data from a list hosted in SharePoint using CSOM. But I get ran insecure content error.
"[blocked] The page at 'https://localhost:44302/Pages/Default.aspx?SPHostUrl=http%3A%2F%2Fecontent&0319c41%2Eecontent%2Eelibrary%2Eapps%2Elocal%2FSharePointApp2%5Fsingeltest'
was loaded over HTTPS, but ran insecure content from 'http://apps-892db5a0319c41.econtent.elibrary.apps.local/sharepointapp2_singeltest/_layouts/15/AppWebProxy.aspx': this content should also be loaded over HTTPS."
here is my code in Default.aspx
<script type="text/javascript" src="../Scripts/jquery-1.8.2.js"></script>
<script type="text/javascript" src="../Scripts/MicrosoftAjax.js"></script>
<script type="text/javascript" src="../Scripts/SP.Core.js"></script>
<script type="text/javascript" src="../Scripts/INIT.JS"></script>
<script type="text/javascript" src="../Scripts/SP.Runtime.js"></script>
<script type="text/javascript" src="../Scripts/SP.js"></script>
<script type="text/javascript" src="../Scripts/SP.RequestExecutor.js"></script>
<script type="text/javascript" src="../Scripts/App.js"></script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<input id="Button1" type="button" value="Get title via CSOM" onclick="execCSOMTitleRequest()" /> <br />
<input id="Button2" type="button" value="Get Lists via CSOM" onclick="execCSOMListRequest()" />
</div>
<p ID="lblResultTitle"></p><br />
<p ID="lblResultLists"></p>
</form>
</body>
</html>
and App.js is:
var hostwebUrl;
var appwebUrl;
// Load the required SharePoint libraries
$(document).ready(function () {
//Get the URI decoded URLs.
hostwebUrl =
decodeURIComponent(
getQueryStringParameter("SPHostUrl")
);
appwebUrl =
decodeURIComponent(
getQueryStringParameter("SPAppWebUrl")
);
// resources are in URLs in the form:
// web_url/_layouts/15/resource
var scriptbase = hostwebUrl + "/_layouts/15/";
// Load the js files and continue to the successHandler
//$.getScript(scriptbase + "/MicrosoftAjax.js",
// function () {
// $.getScript(scriptbase + "SP.Core.js",
// function () {
// $.getScript(scriptbase + "INIT.JS",
// function () {
// $.getScript(scriptbase + "SP.Runtime.js",
// function () {
// $.getScript(scriptbase + "SP.js",
// function () { $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest); }
// );
// }
// );
// });
// });
// });
});
function execCrossDomainRequest() {
alert("scripts loaded");
}
function getQueryStringParameter(paramToRetrieve) {
var params = document.URL.split("?")[1].split("&");
var strParams = "";
for (var i = 0; i < params.length; i = i + 1) {
var singleParam = params[i].split("=");
if (singleParam[0] == paramToRetrieve)
return singleParam[1];
}
}
function execCSOMTitleRequest() {
var context;
var factory;
var appContextSite;
var collList;
//Get the client context of the AppWebUrl
context = new SP.ClientContext(appwebUrl);
//Get the ProxyWebRequestExecutorFactory
factory = new SP.ProxyWebRequestExecutorFactory(appwebUrl);
//Assign the factory to the client context.
context.set_webRequestExecutorFactory(factory);
//Get the app context of the Host Web using the client context of the Application.
appContextSite = new SP.AppContextSite(context, hostwebUrl);
//Get the Web
this.web = context.get_web();
//Load Web.
context.load(this.web);
context.executeQueryAsync(
Function.createDelegate(this, successTitleHandlerCSOM),
Function.createDelegate(this, errorTitleHandlerCSOM)
);
//success Title
function successTitleHandlerCSOM(data) {
$('#lblResultTitle').html("<b>Via CSOM the title is:</b> " + this.web.get_title());
}
//Error Title
function errorTitleHandlerCSOM(data, errorCode, errorMessage) {
$('#lblResultLists').html("Could not complete CSOM call: " + errorMessage);
}
}
function execCSOMListRequest() {
var context;
var factory;
var appContextSite;
var collList;
//Get the client context of the AppWebUrl
context = new SP.ClientContext(appwebUrl);
//Get the ProxyWebRequestExecutorFactory
factory = new SP.ProxyWebRequestExecutorFactory(appwebUrl);
//Assign the factory to the client context.
context.set_webRequestExecutorFactory(factory);
//Get the app context of the Host Web using the client context of the Application.
appContextSite = new SP.AppContextSite(context, hostwebUrl);
//Get the Web
this.web = context.get_web();
// Get the Web lists.
collList = this.web.get_lists();
//Load Lists.
context.load(collList);
context.executeQueryAsync(
Function.createDelegate(this, successListHandlerCSOM),
Function.createDelegate(this, errorListHandlerCSOM)
);
//Success Lists
function successListHandlerCSOM() {
var listEnumerator = collList.getEnumerator();
$('#lblResultLists').html("<b>Via CSOM the lists are:</b><br/>");
while (listEnumerator.moveNext()) {
var oList = listEnumerator.get_current();
$('#lblResultLists').append(oList.get_title() + " (" + oList.get_itemCount() + ")<br/>");
}
}
//Error Lists
function errorListHandlerCSOM(data, errorCode, errorMessage) {
$('#lblResultLists').html("Could not complete CSOM Call: " + errorMessage);
}
};
Any solution is appreciated.
well first off, i can tell you your decodeURIComponent logic isnt working.
Yours:https://localhost:44302/Pages/Default.aspx?SPHostUrl=http%3A%2F%2Fecontent&0319c41%2Eecontent%2Eelibrary%2Eapps%2Elocal%2FSharePointApp2%5Fsingeltest
Mine: https://localhost:44302/Pages/Default.aspx?SPHostUrl=http://econtent&0319c41.econtent.elibrary.apps.local/SharePointApp2_singeltest
Secondly, is the HostURL content supposed to be unsecure? If so, then you may want to change your browser settings. If not, then you need to see why your HostURL is in the Anonymous Zone but your AppURL is in the Secure Zone.
In either case, verify that Everyone has at least Read Access to the location your trying to pull from.
Last thing to do, is to setup a Trusted Host Location if you have access to the Admin Center.
Here is a code snippet for what i used to test:
$(document).ready(function () {
$.getScript(qsHostUrl + "/_layouts/15/SP.RequestExecutor.js", getHostInfo);
function getHostInfo() {
var ctxApp = new SP.ClientContext(qsAppUrl);
var factory = new SP.ProxyWebRequestExecutorFactory(qsAppUrl);
ctxApp.set_webRequestExecutorFactory(factory);
var ctxHost = new SP.AppContextSite(ctxApp, qsHostUrl);
var web = ctxHost.get_web();
ctxApp.load(web);
ctxApp.executeQueryAsync(
Function.createDelegate(this, getHostInfoSuccess),
Function.createDelegate(this, getHostInfoError)
);
function getHostInfoSuccess(sender, args) {
lblData.html(
'Title: ' + web.get_title() + '<br/>' +
'Description: ' + web.get_description()
);
}
function getHostInfoError(sender, args) {
lblData.html(
'Request Failed: ' + args.get_message() + '\n' +
'Stacktrace: ' + args.get_stackTrace()
);
}
}
}

Django-disqus: disqus comment box on

I've created a blog with django and am trying to use disqus comments. I am having a similar problem that I have seen in other questions in that when I post comments to any entries(on single entry pages) they all show up on the main page under one entry.
The main problem is that on the main page of the blog, where I have multiple entries, I can only get one disqus comment box to show up on one entry. When I look at the source code the javascript variables for the other blog entries seem to be showing up correctly so I'm not sure why the comment boxes won't render under the other blog entries.
I'm in development mode so I'm not sure if that makes a difference...I'm also a noob at all of this.
This is the source code I get for the disqus javascript for each entry...can anyone help me figure out why I can't get the comment box to render?
<div id="disqus_thread"></div>
<script type="text/javascript">
/* <![CDATA[ */
var disqus_shortname = 'whometaxi';
var disqus_developer = "1";
var disqus_identifier = "3";
var disqus_title = "Third";
/* * * DON'T EDIT BELOW THIS LINE * * */
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<div id="disqus_thread"></div>
<script type="text/javascript">
/* <![CDATA[ */
var disqus_shortname = 'whometaxi';
var disqus_developer = "1";
var disqus_identifier = "1";
var disqus_title = "First post";
/* * * DON'T EDIT BELOW THIS LINE * * */
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<script type="text/javascript">
/* <![CDATA[ */
var disqus_shortname = 'whometaxi';
var disqus_developer = "1";
var disqus_identifier = "2";
var disqus_title = "Second!";
/* * * DON'T EDIT BELOW THIS LINE * * */
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
Disqus is designed to load one Disqus postbox per page. Disqus uses the page URL as a unique identifier and only one Disqus embed can be associated with a single URL. If more than one Disqus embed is present in the source code of a page, only one embed will load.
There is a way to reload the disqus embed with different identifiers:
DISQUS.reset({
reload: true,
config: function () {
this.page.identifier = "newidentifier";
this.page.url = "http://example.com/#!newthread";
}
});
However, this method is still only used with one embed per page.
This is solved but I'd like to show a different approach by using django-disqus. The last line is the one that gets you the right comments for the specific page/object.
Install django-disqus and use it in your templates.
pip install django-disqus
Add disqus to your INSTALLED_APPS and put your disqus api key in your settings:
settings.py
INSTALLED_APPS = (
...
'disqus',
...
)
DISQUS_API_KEY = 'YOUR_SECRET_API_KEY'
DISQUS_WEBSITE_SHORTNAME = 'YOUR_WEBSITE_SHORTNAME'
Use disqus template tags in your templates:
some_template.html
# load the tags
{% load disqus_tags %}
# get comments for your website
{% disqus_show_comments "YOUR_WEBSITE_SHORTNAME" %}
# get the url for the current object to get the right comments
{% set_disqus_url object.get_absolute_url %}

How to add forreign key fields like it happens in django admin site?

Actually am trying to add a foreign key field in my form like how it happens in django admin site . When you click on the green " + " button it opens up a new pop up window where you add the respective field .
My models are like :
class DealType(models.Model):
label = models.CharField(max_length = 100)
def __unicode__(self):
return self.label
class Deal(models.Model):
label = models.ForeignKey(DealType, blank = True, null = True)
.
.
.
And i want to add DealType while i fill up my DealForm .
I think you have to create a seperate view to create a DealType.
In your DealForm you add a link to open that view.
...
I took a look at an admin page from a project of mine.
html
<img src="/static/admin/img/admin/icon_addlink.gif" width="10" height="10" alt="Add Another"/>
Javascript
taken from
<script type="text/javascript" src="/static/admin/js/admin/RelatedObjectLookups.js"> </script>
function showAddAnotherPopup(triggeringLink) {
var name = triggeringLink.id.replace(/^add_/, '');
name = id_to_windowname(name);
href = triggeringLink.href
if (href.indexOf('?') == -1) {
href += '?_popup=1';
} else {
href += '&_popup=1';
}
var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
win.focus();
return false;
}
This opens a new window with the view with the add form.
This view should add the DealType and then close the window using the following function also found in the same javascript file
function dismissAddAnotherPopup(win, newId, newRepr) {
// newId and newRepr are expected to have previously been escaped by
// django.utils.html.escape.
newId = html_unescape(newId);
newRepr = html_unescape(newRepr);
var name = windowname_to_id(win.name);
var elem = document.getElementById(name);
if (elem) {
if (elem.nodeName == 'SELECT') {
var o = new Option(newRepr, newId);
elem.options[elem.options.length] = o;
o.selected = true;
} else if (elem.nodeName == 'INPUT') {
if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
elem.value += ',' + newId;
} else {
elem.value = newId;
}
}
} else {
var toId = name + "_to";
elem = document.getElementById(toId);
var o = new Option(newRepr, newId);
SelectBox.add_to_cache(toId, o);
SelectBox.redisplay(toId);
}
win.close();
}
This is just backtracked from the admin panel but it should get you started.
...
Found a guide that walks you through the process here which probably explains alot better. (havn't read it)

Dojo widget controller

I am working on a new project and have been trying to get a JS controller to decide which dojo widgets are needed for any particular page.
I have this working, but only when I inject / hardcode the dojo widget's JS into the page. As soon as I try to get it working with dojo's provide and require mechanisms, everything stops working and I get the following error:
Could not load 'pf.PasswordStrength'; last tried '../dojopf/widget/PasswordStrength.js'
http://pf-dev-ad/wcsstore/js/dojo131/dojo/dojo.js
Line 16
Firebug shows this error right after it includes the file!
I am having real problems with this as dojo 1.3.1 (which I'm not allowed to upgrade) is very poorly documented and there aren't many tutorials.
The requirement is as follows:
1 site-wide JS controller (lib.js)
1 widget specific JS file (PasswordStrength.js)
1 widget template file (PasswordStrength.html)
1 pointer node
The file structre is setup as follows:
js
dojo131
dijit
dojo
dojotest
widget
templates
PasswordStrength.html
PasswordStrength.css
PasswordStrength.js
dojox
//JS controller (lib.js):
if(!ad){ var ad = {} }
ad.base = new (function(){
// init function will run on page load. Called by dojo.addOnLoad
this.init = function (){
/* This function acts as a controller for Dojo widgets.
// it uses a variable ('pageName') set by the JSTL in the parent JSP of a particular page
switch(ad.pageName){
case 'Home':
_getTemplateAssets('PasswordStrength');
break;
}
}
var $ = dojo.query;
var templatePath = 'js/dojo131/dojotest/widget';
var debug = false; // This should be set to false when on production
/*** PRIVATE FUNCTIONS ***/
function _getTemplateAssets(templateName){
// Injects the JS and CSS template assets into the page head
dojo.registerModulePath("ad", '../dojotest/widget'); // relative to dojo.js
//dojo.provide('ad.' + templateName);
dojo.require('ad.' + templateName);
//var headTag = document.getElementsByTagName('head').item(0);
//dojo.create("script", { src: templatePath + '/' + templateName + '.js', type: 'text/javascript' }, headTag);
//dojo.create("link", { href: templatePath + '/templates/' + templateName + '.css', type: 'text/css', rel: 'stylesheet' }, headTag);
}
});
/*** ONLOAD ***/
dojo.addOnLoad(ad.base.init);
// Widget JS (PasswordStrength.js)
if(!ad){ var ad = {} }
ad.passwordCheck = new (function(){
// init function will run on page load. Called by dojo.addOnLoad
this.init = function (){
_temp_addPasswordCheck();
}
/*** PRIVATE VARIABLES ***/
var $ = dojo.query;
var templateName = 'PasswordStrength';
var insertPointID = 'ins_passStrength';
var minLength = 6;
var objAdvice = { enterPass: 'Please enter a password', addChars: 'Add more characters (min ' + minLength + ')', addSpecials: 'Use special characters (!##$%^&*)', addUppers: 'Use some upper case characters', addLowers: 'Use some lower case characters', addNums: 'Use some numbers', remRepeats: 'Too many repeated repeat characters', passPass: 'Your password has been verified as Excellent!' };
var complexity = ['Bad', 'Very weak', 'Weak', 'Good', 'Strong', 'Excellent'];
var content = {
titles: {
h1: 'Password Strength'
},
labels: {
password: 'Password:',
confirmPassword: 'Confirm Password',
obscure: 'Obscure:',
strength: 'Password strength:',
advice: 'Advice:'
},
content:{
advice: 'Please enter a password',
strength: 'None'
}
}
/*** PRIVATE FUNCTIONS ***/
function _temp_addPasswordCheck(){
// Include extras
dojo.provide("ad.PasswordStrength");
dojo.require("ad.PasswordStrength");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dojo.parser");
dojo.declare(templateName, [dijit._Widget, dijit._Templated], {
// calls the HTML template to be used
templatePath: dojo.moduleUrl ('dojotest.widget','templates/' + templateName + '.html'),
// Content (titles, labels and general content)
label_password: content.labels.password,
label_confirmPassword: content.labels.confirmPassword,
label_obscure: content.labels.obscure,
label_passwordStrength: content.labels.strength,
label_advice: content.labels.advice,
title_passwordStrength: content.titles.h1,
content_advice: content.content.advice,
content_strength: content.content.strength,
obscurePassword: function(){
if(this.obscurePass.checked){ dojo.attr(this.passwordValue, 'type', 'password'); }
else{ dojo.attr(this.passwordValue, 'type', 'text'); }
},
checkPassword: function(){
// This function checks the password strength on keyup and alters the passwordAdvice div to reflect the strength of the password entered
// Runs the password through a validation function which returns the results
var results = _checkPassWord(this.passwordValue.value), score = results['score'];
var ele = dojo.byId('passStrength');
// Update the markup to inform the user of their passwords score
if(results['count'] == 0){
this.complexity.innerHTML = 'None';
ele.className = '';
this.advice.innerHTML = _doInsert([objAdvice.enterPass]);
}
else if(score <= 50){
this.complexity.innerHTML = complexity[0];
ele.className = 'bad';
this.advice.innerHTML = _doInsert(results.advice);
}
if(score == 60){
this.complexity.innerHTML = complexity[1];
ele.className = 'veryWeak';
this.advice.innerHTML = _doInsert(results.advice);
}
if(score == 70){
this.complexity.innerHTML = complexity[2];
ele.className = 'weak';
this.advice.innerHTML = _doInsert(results.advice);
}
if(score == 80){
this.complexity.innerHTML = complexity[3];
ele.className = 'good';
this.advice.innerHTML = _doInsert(results.advice);
}
if(score == 90){
this.complexity.innerHTML = complexity[4];
ele.className = 'strong';
this.advice.innerHTML = _doInsert(results.advice);
}
if(score >= 100){
this.complexity.innerHTML = complexity[5];
ele.className = 'excellent';
this.advice.innerHTML = _doInsert([objAdvice.passPass]);
}
}
});
// Calls the template into the right ID defined as the insert point as the first child
if(dojo.byId(insertPointID)){
var passStrength = new PasswordStrength().placeAt(insertPointID);
}
};
function _doInsert(arrInsert){
var content = '';
dojo.forEach(arrInsert, function(item, i){
content = content + '<p>' + item + '</p>';
});
return content;
}
function _checkPassWord(strPassword){
// Grades the password string and returns the results
var objResults = {}, scoreFactor = 10, score = 0, advice = [], lengthPass, alphaLCpass, alphaUCpass, numPass, specialsPass, repeatPass, count = strPassword.length;
// Check password string for uppercase alphas, lowercase alphas, numerals, special characters and repeated characters
alphaUCpass = strPassword.match(/[A-Z]/g) ? true : false;
alphaLCpass = strPassword.match(/[a-z]/g) ? true : false;
numPass = strPassword.match(/[0-9]/g) ? true: false;
specialsPass = strPassword.match(/[^a-zA-Z0-9]/g) ? true : false;
repeatPass = strPassword.match(/(.)\1\1/g) ? false : true;
lengthPass = count >= minLength ? true : false;
// Score the password based on the results of the check
if(alphaUCpass){ score += scoreFactor; }
else{ advice.push(objAdvice.addUppers); }
if(alphaLCpass){ score += scoreFactor; }
else{ advice.push(objAdvice.addLowers); }
if(numPass){ score += scoreFactor; }
else{ advice.push(objAdvice.addNums); }
if(specialsPass){ score += scoreFactor; }
else{ advice.push(objAdvice.addSpecials); }
if(repeatPass){ score += scoreFactor; }
else{ advice.push(objAdvice.remRepeats); }
if(lengthPass){ score += scoreFactor * 5; }
else{ advice.push(objAdvice.addChars); }
// Inserts the results into object to be returned
objResults = {
'alphaUC': alphaUCpass,
'alphaLC': alphaLCpass,
'numerals': numPass,
'specials': specialsPass,
'length': lengthPass,
'repeat': repeatPass,
'count': count,
'score': score,
'advice': advice
}
// Return results to parent function
return objResults;
}
/*** PUBLIC FUNCTIONS ***/
});
/*** ONLOAD ***/
dojo.addOnLoad(ad.passwordCheck.init);
// Widget HTML template (PasswordStrength.html)
<div>
<h1>${title_passwordStrength}</h1>
<form method="post" action="">
<fieldset>
<div class="formFields">
<label for="password">${label_password}</label>
<input type="password" name="password" id="password" dojoAttachPoint="passwordValue" dojoAttachEvent="onkeyup: checkPassword" />
</div>
<div class="formFields">
<label for="confirmPassword">${label_confirmPassword}</label>
<input type="password" name="confirmPassword" id="confirmPassword" dojoAttachPoint="passwordConfirmValue" dojoAttachEvent="onkeyup: checkPassword" />
</div>
<div class="formFields">
<label for="obscurePassword" class="wAuto">${label_obscure}</label>
<input class="wAuto" type="checkbox" value="true" checked="checked" name="obscurePassword" id="obscurePassword" dojoAttachPoint="obscurePass" dojoAttachEvent="onchange: obscurePassword" />
</div>
<div class="formFields">
<label>${label_passwordStrength}</label>
<div dojoAttachPoint="strength" id="passStrength" class=""></div>
<div dojoAttachPoint="complexity" id="passStrengthCaption">${content_strength}</div>
</div>
<div class="formFields">
<label>${label_advice}</label>
<div dojoAttachPoint="advice" id="passAdvice"><p>${content_advice}</p></div>
</div>
</fieldset>
</form>
The parent file has a HTML pointer in it as follows:
<div id="ins_passStrength" dojoType="PasswordStrength"></div>
If I change the following function in parent controller (lib.js):
function _getTemplateAssets(templateName){
// Injects the JS and CSS template assets into the page head
dojo.registerModulePath("ad", '../dojotest/widget'); // relative to dojo.js
//dojo.provide('ad.' + templateName);
dojo.require('ad.' + templateName);
//var headTag = document.getElementsByTagName('head').item(0);
//dojo.create("script", { src: templatePath + '/' + templateName + '.js', type: 'text/javascript' }, headTag);
//dojo.create("link", { href: templatePath + '/templates/' + templateName + '.css', type: 'text/css', rel: 'stylesheet' }, headTag);
}
To:
function _getTemplateAssets(templateName){
// Injects the JS and CSS template assets into the page head
dojo.registerModulePath("ad", '../dojotest/widget'); // relative to dojo.js
dojo.provide('ad.' + templateName);
dojo.require('ad.' + templateName);
//var headTag = document.getElementsByTagName('head').item(0);
//dojo.create("script", { src: templatePath + '/' + templateName + '.js', type: 'text/javascript' }, headTag);
//dojo.create("link", { href: templatePath + '/templates/' + templateName + '.css', type: 'text/css', rel: 'stylesheet' }, headTag);
}
The error goes away but the widegt JS isn't included.
And if you change it to:
function _getTemplateAssets(templateName){
// Injects the JS and CSS template assets into the page head
dojo.registerModulePath("ad", '../dojotest/widget'); // relative to dojo.js
//dojo.provide('ad.' + templateName);
//dojo.require('ad.' + templateName);
var headTag = document.getElementsByTagName('head').item(0);
dojo.create("script", { src: templatePath + '/' + templateName + '.js', type: 'text/javascript' }, headTag);
dojo.create("link", { href: templatePath + '/templates/' + templateName + '.css', type: 'text/css', rel: 'stylesheet' }, headTag);
}
It works fine but this is a dirty sidestep... I need to use dojo's prescribed methods.
Any help greatly appreciated.
Thank you!
I believe your error is that you have put your dojo.provide("ad.PasswordStrength") inside a bunch of functions. It needs to be at the top of the file. Dojo evaluates the file it believes to be correct (based on module path), but how is it supposed to know if PasswordStrength is in there, unless you tell it "yes, this file provides ad.PasswordStrength".
Edit: considering what you said on IRC, here's how I think PasswordStrength.js should look:
dojo.provide("ad.PasswordStrength");
if(!ad){ var ad = {} }
ad.passwordCheck = new (function(){
// init function will run on page load. Called by dojo.addOnLoad
this.init = function (){
_temp_addPasswordCheck();
dojo.parser.parse();
}
/*** PRIVATE VARIABLES ***/
var $ = dojo.query;
var templateName = 'PasswordStrength';
....
/*** PRIVATE FUNCTIONS ***/
function _temp_addPasswordCheck(){
// Include extras
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dojo.parser");
dojo.declare("ad." + templateName, [dijit._Widget, dijit._Templated], {
// calls the HTML template to be used
templatePath: dojo.moduleUrl ('dojotest.widget','templates/' + templateName + '.html'),
// Content (titles, labels and general content)
label_password: content.labels.password,
label_confirmPassword: content.labels.confirmPassword,
label_obscure: content.labels.obscure,
label_passwordStrength: content.labels.strength,
label_advice: content.labels.advice,
title_passwordStrength: content.titles.h1,
content_advice: content.content.advice,
content_strength: content.content.strength,
obscurePassword: function(){
....
},
checkPassword: function(){
....
}
});
/*
if(dojo.byId(insertPointID)){
var passStrength = new PasswordStrength().placeAt(insertPointID);
}
*/
};
function _doInsert(arrInsert){
....
}
function _checkPassWord(strPassword){
....
}
/*** PUBLIC FUNCTIONS ***/
});
/*** ONLOAD ***/
dojo.addOnLoad(ad.passwordCheck.init);
Moved dojo.provide("ad.PasswordStrength"); to the top of the file.
Removed dojo.require("ad.PasswordStrength"); from _temp_addPasswordCheck() - if this code is executed, ad.PasswordStrength (PasswordStrength.js) has obviously already been required and loaded.
Added dojo.parser.parse(); to the end of init(), so that after the widget has been declared, any widget dojoTypes in the HTML will be parsed. However, I still don't understand why you have to declare the widget inside _temp_addPasswordCheck. Why not have the widget in it's on file, and ad.passwordCheck wherever your applications other "page" files are?
Added "ad." to the widget declaration (dojo.declare("ad." + templateName)), it needs to have the full namespaced name here.
Commented out new PasswordStrength().placeAt(.... Since you want to insert your widgets declaratively in your HTML, it doesn't make sense to manually instantiate one here, and place it manually.
Now you should be able to put PasswordStrength widgets in your HTML, like so:
<script type="text/javascript" src="js/dojo131/dojo/dojo.js"></script>
<script type="text/javascript" src="js/dojo131/dojotest/lib.js"></script>
....
<div id="ins_passStrength" dojoType="ad.PasswordStrength"></div>
<div id="anotherOne" dojoType="ad.PasswordStrength"></div>
Remember that you need the whole namespaced name here as well (i.e. the ad. prerfix).
This worked nicely for me, using Dojo 1.3.3. Uploaded the sandbox if it's any use.
Your error:
Could not load 'pf.PasswordStrength'; last tried '../dojopf/widget/PasswordStrength.js'
http://pf-dev-ad/wcsstore/js/dojo131/dojo/dojo.js
Line 16
Is this a typo? Because it should be trying ../dojotest/widget/PasswordStrength.js
Do you have another dojo.require that is referring to dojopf? Or any other line like dojo.require("pf.PasswordStrength")?
If not, perhaps the registering of the module path is not happening before dojo tries to load your .js. Perhaps try using dojo.require to load your lib.js.