Can't Get Angular To Load Routes - html

I am making a local page following this tutorial, and it implements a login using django and angular. But I can't get the button register to show anything. It just changes the directory to /register. I think it has to do with routing. I get no errors. And I don't know how to debug this thing anymore, so I've run out of options. This is my first 'website'.
Reason this isn't going smooth is because I did not get the starter project the tutorial came with. I wanted to learn how to implement this from scratch. This means my packages are newer (bootstrap, django, etc). Let me know if you need any more info, please. Thanks.
/templates/index.html
<!DOCTYPE html>
<html ng-app="hawk">
<head>
<title>Hawk</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
</head>
<body>
{% include 'navbar.html' %}
<div class="container-fluid">
<div class="row">
<div class="col-xs-12 ng-view"></div>
</div>
</div>
{% include 'javascripts.html' %}
</body>
</html>
/static/javascripts/hawk.routes.js
(function () {
'use strict';
angular
.module('hawk.routes')
.config(config);
config.$inject = ['$routeProvider'];
function config($routeProvider) {
$routeProvider.when('/register', {
controller: 'RegisterController',
controllerAs: 'vm',
templateUrl: '/static/templates/authentication/register.html'
}).otherwise('/');
}
})();
/static/javascripts/authentication/controllers/register.controller.js
(function () {
'use strict';
angular
.module('hawk.authentication.controllers')
.controller('RegisterController', RegisterController);
RegisterController.$inject = ['$location', '$scope', 'Authentication'];
function RegisterController($location, $scope, Authentication) {
var vm = this;
console.log("\n\nregister\n\n");
vm.register = register;
function register() {
Authentication.register(vm.email, vm.password, vm.username);
}
}
})();
/static/javascripts/hawk.js
(function () {
'use strict';
angular
.module('hawk', [
'hawk.routes',
'hawk.authentication',
'hawk.config',
]);
angular
.module('hawk.routes', [require('angular-route')]);
angular
.module('hawk.config', []);
angular
.module('hawk')
.run(run);
run.$inject = ['$http'];
function run($http) {
$http.defaults.xsrfHeaderName = 'X-CSRFToken';
$http.defaults.xsrfCookieName = 'csrftoken';
}
})();
/templates/javascripts.html
{% load compress %} {% load staticfiles %} {% compress js %}
<script type="text/javascript" src="{% static '../node_modules/jquery/dist/jquery.js' %}"></script>
<script type="text/javascript" src="{% static '../node_modules/bootstrap/dist/js/bootstrap.js' %}"></script>
<script type="text/javascript" src="{% static '../node_modules/bootstrap-material-design/dist/js/material.js' %}"></script>
<script type="text/javascript" src="{% static '../node_modules/bootstrap-material-design/js/ripples.js' %}"></script>
<script type="text/javascript" src="{% static '../node_modules/underscore/underscore.js' %}"></script>
<script type="text/javascript" src="{% static '../node_modules/angular/angular.js' %}"></script>
<script type="text/javascript" src="{% static '../node_modules/angular-route/angular-route.js' %}"></script>
<script type="text/javascript" src="{% static '../node_modules/angular-cookies/angular-cookies.js' %}"></script>
<script type="text/javascript" src="{% static '../node_modules/ng-dialog/js/ngDialog.js' %}"></script>
<script type="text/javascript" src="{% static 'lib/snackbarjs/snackbar.min.js' %}"></script>
<script type="text/javascript" src="{% static 'javascripts/hawk.js' %}"></script>
<script type="text/javascript" src="{% static 'javascripts/hawk.config.js' %}"></script>
<script type="text/javascript" src="{% static 'javascripts/hawk.routes.js' %}"></script>
<script type="text/javascript" src="{% static 'javascripts/authentication/authentication.module.js' %}"></script>
<script type="text/javascript" src="{% static 'javascripts/authentication/services/authentication.service.js' %}"></script>
<script type="text/javascript" src="{% static 'javascripts/authentication/controllers/register.controller.js' %}"></script>
{% endcompress %}
/static/javascripts/authentication/services/authentication.service.js
(function () {
'use strict';
angular
.module('hawk.authentication.services')
.factory('Authentication', Authentication);
Authentication.$inject = ['$cookies', '$http'];
function Authentication($cookies, $http) {
var Authentication = {
register: register
};
return Authentication;
function register(email, password, username) {
return $http.post('/api/v1/accounts/', {
username: username,
password: password,
email: email
});
}
}
})();
/HawkProject/urls.py
from django.contrib import admin
from django.urls import path, re_path, include
from rest_framework_nested import routers
from authentication.views import AccountViewSet
from HawkProject.views import IndexView
router = routers.SimpleRouter()
router.register(r'accounts', AccountViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^api/v1/', include(router.urls)),
re_path(r'^.*$', IndexView.as_view(), name='index')
]

Although its not an answer to this question precisely but its an answer with a diff approach
The tutorial you have provided is too long and not included with video. I have worked on Django and AngularJS to create an ecommerce website. I'l suggest you not to mix Django and AngularJS as much as you can to avoid conflicts. That being said, I'll provide you what I implemented for User Registration in brief:
I kept User form separate from AngularJS forms because Django has its own way to handle User Management (Sign in,sign Up, session (using #login_required) etc).
I provided Register on the nav-bar. (Note: /signup is a url mapped in urls.py file)
<form name="regForm" class="form-signup" action="/sign_up/" method="post" role="form" onsubmit="return validateForm()">
{% csrf_token %}
{{form.errors.values.0}}
<div class="form-group reg-username" id="fname">
<div>
<input name="first_name" class="form-control input" size="20" placeholder="Enter First Name" type="text" required>
</div>
<p id="fname-error" class="help-block"></p>
</div>
<div class="form-group reg-username">
<div>
<input name="last_name" class="form-control input" size="20" placeholder="Enter Last Name" type="text" required>
</div>
</div>
<div class="form-group reg-email">
<div>
<input name="email" class="form-control input" placeholder="Enter Email" type="email" required>
</div>
</div>
<div class="form-group reg-password" id="pwd1">
<div>
<input name="password1" class="form-control input" placeholder="Password" type="password" required>
</div>
<p id="pwd-error1" class="help-block"></p>
</div>
<div class="form-group reg-password" id="pwd2">
<div>
<input name="password2" class="form-control input" placeholder="Confirm Password" type="password" required>
</div>
<p id="pwd-error2" class="help-block"></p>
</div>
<input name="submit" class="btn btn-block btn-lg btn-primary" value="REGISTER" type="submit">
</form>
Where url(r'^sign_up/', ('ecommerce.views.register_user')),
In the views.py
#sensitive_post_parameters()
#csrf_protect
#requires_csrf_token
def register_user(request):
args = {}
args.update(csrf(request))
if request.method == 'POST':
if not verify_google_recaptcha(request.POST):
return HttpResponse(get_status_response('Failure', 'Are you sure you are not a robot?'))
else:
logger.info('Recaptcha passed !!!')
form = RegistrationForm(request.POST)
msg = 'register'
args['form'] = form
if form.is_valid():
try:
# username = form.cleaned_data['username']
email_obj ={}
email_obj['email'] = form.cleaned_data['email']
email_obj['first_name'] = form.cleaned_data['first_name']
email_obj['last_name'] = form.cleaned_data['last_name']
salt = hashlib.sha1(str(random.random())).hexdigest()[:5]
activation_key = hashlib.sha1(salt + email_obj['email']).hexdigest()
email_obj['activation_link'] = ACTIVATION_LINK.format(activation_key)
template = get_template('RegistrationLink.html')
context = Context({'email': email_obj})
content = template.render(context)
emsg = EmailMultiAlternatives('Activation link for {0}'.format(DEFAULT_DOMAIN) , content, DEFAULT_FROM_EMAIL, to=[email_obj['email']])
emsg.attach_alternative(content, "text/html")
emsg.send()
form.save() # save user to database if form is valid
# Get user by username
user = SiteUser.objects.get(email=email_obj['email'])
# Create and save user profile
new_profile = UserProfile(user=user, activation_key=activation_key,
key_expires=settings.EXPIRATION_DAYS)
new_profile.save()
except Exception as e:
logger.exception(e)
return render_to_response('500.html')
# return HttpResponseRedirect('/register_success')
return render_to_response('confirm.html', {'msg': msg})
else:
args['form'] = RegistrationForm()
return render_to_response('userRegistration.html', args, context_instance=RequestContext(request))
Note: The code written in def register_user is core Djnago feature to handle user registration which I am exploiting. You can get these over internet
If you need to render any form such as Order address, then create a form of angular and simple pass the value to Django using $http (the /url_called from $http will be mapped in urls.py).
Make sure you are using {% verbatim %} and {% endverbatim %} whenever you are using {{ some_angular_variable }} because it contradicts withDjango Templatesyntax. Better to go forng-bind` as much as you can.
Ignore $locationProvider for now if you are in initial stage. You'll get some issues when using that with Django. I have a solution for that as well but for beginner, dont get into that. Try to integrate the plunkr code in your Django app and see if it's working. Start small, dont jump to complicated examples.
Check one basic example of ngRoute.
In case you get stuck, post another question and put the link in the comment so that I can help you in that as well

Related

Live Search with Bootstrap forms in Flask/Jinga2

I'm trying to replicate the live search option as described here https://developer.snapappointments.com/bootstrap-select/examples/ in my Flask application. The minimal example below has the third box hardcoded as in the example and it works as expected.
My actual app uses WTF forms/Jinga2 and I cannot figure out how to modify the Jinga2 code such that the live search would be available in my first SelectField or in the second SelectMultipleField.
Can someone suggest how I can implement a live search using the WTF form/Jinga2 to resemble the working example?
from flask import Flask, render_template, request, session, current_app, flash,redirect, url_for, jsonify
from flask_wtf import FlaskForm
from wtforms import StringField, TextField, SubmitField, SelectField, IntegerField, BooleanField, RadioField, FileField, HiddenField,SelectMultipleField
from wtforms.validators import DataRequired, Length
server = Flask(__name__)
server.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
class simpleForm(FlaskForm):
varlist1 = SelectField('Choose', [DataRequired()], coerce=str)
varlist2 = SelectField('Choose', [DataRequired()], coerce=str)
submitA = SubmitField('Get Stuff')
varlist3 = SelectMultipleField('Choose Test(s):', [DataRequired()], choices=[('', '')])
#server.route('/menu', methods=["post", "get"])
def menu():
form = simpleForm()
vars = ['Option 1','Option 2']
var2list = [['A', 'B', 'C'],['D','E', 'F', 'G'],['1', '2']]
vars3 = ['a','b','c','d']
form.varlist1.choices = vars
form.varlist2.choices = var2list[0]
form.varlist3.choices = [(i, i) for i in vars3]
#form.varlist2.choices = var2list[1]
#form.varlist2.choices = var2list[2]
return render_template('menu.html', form = form)
if __name__ == '__main__':
server.run(debug=True)
Here is a minimal html menu.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.1/css/bootstrap.min.css" integrity="sha384-VCmXjywReHh4PwowAiWNagnWcLhlEJLA5buUprzK8rxFgeH0kww/aWY76TfkUoSX" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.1/js/bootstrap.min.js" integrity="sha384-XEerZL0cuoUbHE4nZReLT7nx9gQrQreJekYhJD9WNWhH8nEW+0c5qq7aIo2Wl30J" crossorigin="anonymous"></script>
</head>
<title>My Application</title>
<body>
<br><br><br>
<form action="{{url_for('menu')}}" method="POST" enctype="multipart/form-data">
<br>
<div>
{{ form.varlist2.label}}
{{ form.varlist2 (class="form-control") }}
<br>
{{ form.varlist3.label}}
{{ form.varlist3 }}
</div>
</form>
<br><br>
<select class="selectpicker" data-live-search="true">
<option data-tokens="ketchup mustard">Hot Dog, Fries and a Soda</option>
<option data-tokens="mustard">Burger, Shake and a Smile</option>
<option data-tokens="frosting">Sugar, Spice and all things nice</option>
</select>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-select#1.13.14/dist/css/bootstrap-select.min.css">
<!-- Latest compiled and minified JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap-select#1.13.14/dist/js/bootstrap-select.min.js"></script>
<!-- (Optional) Latest compiled and minified JavaScript translation files -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap-select#1.13.14/dist/js/i18n/defaults-*.min.js"></script>
</body>
</html>
A little late but here is an answer if someone else is having the same issue.
In your Jinja template, you need to replace:
{{ form.varlist2 (class="form-control") }}
with:
<select class="selectpicker form-control" name="varlist2" data-live-search="true">
{% for option in form.varlist2 %}
{{ option }}
{% endfor %}
</select>

why the update function return int where it must return string?

i have a django website where it include an update function where the user is allow to edit data.
the update is done and the data in the database is changed but the problem is that the system crash.
and when i tried to print the result of the query the system return int where it should return string
and it display the error below :
dbEntry.save() #to save into DB AttributeError: 'int' object has no
attribute 'save'
views.py
def update(request,pk):
#deny anonymouse user to enter the create page
if not request.user.is_authenticated:
return redirect("login")
else:
dbEntry = suspect.objects.get(pk =pk)
print( "db entry : ",dbEntry)
if request.method == 'POST':
first_name = request.POST['fname']
print("first_name : ", first_name)
dbEntry = suspect.objects.filter(pk = pk).update(suspect_name = first_name)
print( "db entry after update: ",dbEntry)
dbEntry.save() #to save into DB
return render(request,'blog/update.html', {"dbEntry":dbEntry})
update.html
{% extends "base.html" %}
{% load static %}
{% block body %}
<head>
<link rel="stylesheet" type="text/css" href="{% static '/css/linesAnimation.css' %}">
<link rel="stylesheet" type="text/css" href="{% static '/css/input-lineBorderBlue.css' %}">
<link rel="stylesheet" type="text/css" href="{% static '/css/dropDown.css' %}">
<link rel="stylesheet" type="text/css" href="{% static '/css/home.css' %}">
<link rel="stylesheet" type="text/css" href="{% static '/css/meta-Input.css' %}">
<meta name= "viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="{% static '/js/jquery-3.1.1.min.js'%}"></script>
<title>Welcome</title>
</head>
<body>
<div class="lines">
<div class="line"></div><div class="line"></div>
<div class="line"></div><div class="line"></div>
<div class="line"></div><div class="line"></div><div class="line"></div>
</div>
<form method = "POST" enctype="multipart/form-data">
{% csrf_token %}
<div id='left-column-Input' class="formInput" include="select()">
<div class="forminputs">
<input type="text" id="fname" name="fname" autocomplete="off" required />
<label for="fname" class="label-name">
<span class="content-name" name="fname">{{dbEntry.suspect_name}}</span>
</label></div>
<div class="home-Button">
<button id="save" name="save" type="submit">Edit</button>
</div>
From the docs,
The update() method is applied instantly and returns the number of rows matched by the query (which may not be equal to the number of rows updated if some rows already have the new value.
Here you are applying the update command on the queryset, which would update the matched rows and return num of affected rows. Since you're trying to update only one row then you could do like,
dbEntry = suspect.objects.filter(pk = pk).first()
if dbEntry:
dbEntry.suspect_name = first_name
dbEntry.save()
print( "db entry after update: ",dbEntry)
else:
raise Http404('Id not found')
simply remove this line: dbEntry.save()
because dbEntry = suspect.objects.filter(pk = pk).update(suspect_name = first_name) update database and .save() dose not need any more

Unable to use double braces to resolve variables [duplicate]

This question already has answers here:
How to escape {{ or }} in django template?
(10 answers)
Closed 3 years ago.
I am unable to use double braces to resolve variables. Here's my js code.
var app = angular.module('toDo',[]);
app.controller('toDoController', function($scope, $http) {
$http.get('/todo/api/').then(function(response) {
$scope.todoList = response.data;
});
});
HTML code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>To Do List</title>
{% load static %}
<link rel="stylesheet" href="{% static 'css/todo.css' %}">
</head>
<body ng-app="toDo" ng-controller="toDoController">
<h1>Todo List</h1>
<form ng-submit="add()">
<input type="text" ng-model="todoInput" placeholder="Add a new todo task...">
<button type="submit">Add Task</button>
</form>
<br>
<div ng-repeat="todo in todoList">
<input type="checkbox" ng-model="todo.done"><a ng-href="/todo/api/{{todo.id}}" ng-bind="todo.task"></a>
</div>
<p>
<button class="delete" ng-click="delete()">Delete</button>
<button class="update" ng-click="update()">Update</button>
</p>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.8/angular.js"></script>
<script src="{% static 'js/todo.js' %}"></script>
</body>
</html>
tasks which displayed in screen should redirect me to the url "/todo/api/". But values given in the braces not resolving it's ID. Currently the hyperlink redirecting always to the url "/todo/api/".
Kindly let me know if I am doing anything wrong or help me to fix this issue.
The brackets are interpreted by the Django template renderer. You can use {% verbatim %}…{% endverbatim %} [Django-doc] to avoid interpreting the double curly brackets, like:
<a {% verbatim %}ng-href="/todo/api/{{todo.id}}"{% endverbatim %} ng-bind="todo.task"></a>

I don't see the expected view in angular JS, maybe binding issue?

So I am trying to build the simplest Angular JS application and no idea what I am doing wrong.
It is made of 4 files:
index.html - which I use like a layout to display main.html
app1.js - used for defining simple routing rules like /main should redirect to main.html in combination with MainController; when it doesn't find a valid path, revert to a default which equals the previous path
MainController.js - I just have some timer functions here
main.html - displays a search button and search textbox
For some reason, I can't see mainvtemplate from my index.html which should redirect me to /main.
Here is the code:
index.html file
<!DOCTYPE html>
<html ng-app="githubViewer">
<head>
<script data-require="angular.js#*" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<script data-require="angular-route#*" data-semver="1.2.14" src="http://code.angularjs.org/1.2.14/angular-route.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="app.js"></script>
<script src="MainController.js"></script>
</head>
<body>
<h1>Github Viewer</h1>
<div ng-view></div>
</body>
</html>
the app1.js
(function(){
var app = angular.module("githubViewer", ["ngRoute"]);
app.config(function($routeProvider){
$routeProvider
.when("/main", {
templateUrl: "main.html",
controller: "MainController"
})
.otherwise({redirectTo:"/main"});
});
}());
the main.html file:
<div>
{{ countdown }}
<form name="searchUser" ng-submit="search(username)">
<input type="search" required="" ng-model="username" />
<input type="submit" value="Search" />
</form>
</div>
You may ignore the countdown, this is a timer created in MainController.js. I render its simplified logic:
(function() {
var app = angular.module("githubViewer");
var MainController = function($scope, $interval, $location) {
$scope.search = function(username) {
if(countdownInterval) {
$interval.cancel(countdownInterval);
$scope.countdown = null;
}
$location.path("/user/" + username);
};
$scope.countdown = 5;
};
app.controller("MainController", MainController);
}());
Isn't weird I'm not able to see the search button and search textbox? Maybe I am missing sth really obvious here.
in your index.html
<script src="app.js"></script>
replace with
<script src="app1.js"></script>
main.html
<div ng-app="githubViewer" ng-controller="MainController ">// add ng app ang nd cntroller
{{ countdown }}
<form name="searchUser" ng-submit="search(username)">
<input type="search" required="" ng-model="username" />
<input type="submit" value="Search" />
</form>
</div>

Uncaught ReferenceError: Markdown is not defined

I am trying to add markdown to my input text box for a flask project. I am following the Grinburg text book. In my forms.py I have :
from flask_pagedown.fields import PageDownField
from wtforms.fields.simple import HiddenField
class NewEntry(Form):
'''
A form for new entries
'''
title = TextAreaField("Title", validators=[Required()])
text = PageDownField("Text", validators=[Required()])
tags = TextAreaField("Tags", validators=[Required()])
srcLibEntries = HiddenField(label=None, id="srcLibArticles")
submit = SubmitField('Submit', id="new_entry_submit_button")
Over in my HTML, I have :
{% extends "layout.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block scripts %}
{{super()}}
{{pagedown.include_pagedown()}}
{% endblock %}
{% block body %}
<form method="post" role="form">
{{ wtf.form_field(form.title) }}
{{ wtf.form_field(form.text) }}
{{ wtf.form_field(form.tags) }}
{{ form.srcLibEntries }}
{{ wtf.form_field(form.submit) }}
</form>
All this unfurls at the browser to have the following code for the text input box :
<div class="form-group required"><label class="control-label" for="text">Text</label>
<div class="flask-pagedown"><textarea class="form-control flask-pagedown-input" id="flask-pagedown-text" name="text" required>fsdafds</textarea></div>
<div class="flask-pagedown-preview" id="flask-pagedown-text-preview"></div>
<script type="text/javascript">
f = function() {
if (typeof flask_pagedown_converter === "undefined")
flask_pagedown_converter = Markdown.getSanitizingConverter().makeHtml;
var textarea = document.getElementById("flask-pagedown-text");
var preview = document.getElementById("flask-pagedown-text-preview");
textarea.onkeyup = function() { preview.innerHTML = flask_pagedown_converter(textarea.value); }
textarea.onkeyup.call(textarea);
}
if (document.readyState === 'complete')
f();
else if (window.addEventListener)
window.addEventListener("load", f, false);
else if (window.attachEvent)
window.attachEvent("onload", f);
else
f();
</script>
</div>
I am getting an exception at the browser, namely, "Uncaught ReferenceError: Markdown is not defined" and it is referring to this line :
flask_pagedown_converter = Markdown.getSanitizingConverter().makeHtml;
I don't think I have to import any more markdown anywhere. What is going on here?
Edit 1:
I needed to add the following to my layout.css:
<script src="//cdnjs.cloudflare.com/ajax/libs/pagedown/1.0/Markdown.Converter.js"> </script>
<script src="//cdnjs.cloudflare.com/ajax/libs/pagedown/1.0/Markdown.Editor.js"> </script>
<script src="//cdnjs.cloudflare.com/ajax/libs/pagedown/1.0/Markdown.Sanitizer.js"> </script>
I needed to add the following to my layout.css:
<script src="//cdnjs.cloudflare.com/ajax/libs/pagedown/1.0/Markdown.Converter.js"> </script>
<script src="//cdnjs.cloudflare.com/ajax/libs/pagedown/1.0/Markdown.Editor.js"> </script>
<script src="//cdnjs.cloudflare.com/ajax/libs/pagedown/1.0/Markdown.Sanitizer.js"> </script>