I'm making my first flask app which is a text adventure and a separate section to leave a review. I'm trying to follow along with a text adventure tutorial. I've got my site running however when I refresh the page to see my progress the changes in game.js are not reflected and I'm met with the error in the title.
This is my first post on Stack Overflow so I've put all of my code below. Thanks in advance for any help! I'm still relatively new so sorry for any stupid mistakes, Paddy.
game.js
const textElement = document.getElementById('text')
const optionsButtonsElement = document.getElementById('options-buttons')
let state = {}
function startGame() {
state = {}
showTextNode(1)
}
function showTextNode(textNodeIndex) {
const textNode = textNodes.find(textNode => textNode.id === textNodeIndex)
textElement.innerText = textNode.text
while (optionsButtonsElement.firstChild)
optionsButtonsElement.removeChild(optionsButtonsElement.firstChild)
}
function selectOption(option) {
}
const textNodes = [
{
id:1
text: 'You wake up staring at the ceiling of your bunker.',
options [
{
text: 'Turn on the radio',
nextText: 2
},
{
text: 'Grab your pistol and pack up the remainder of your supplies.',
}
]
}
]
startGame()
game.html
{% block title %}Get ready to play!{% endblock %}
{% block content %}
<body>
<div class="container">
<div id="text">Text</div> <br/>
<div id="option-buttons" class="btn-grid">
<button type="button" class="btn btn-outline-dark btn-lg btn-block">Option 1</button>
<button type="button" class="btn btn-outline-dark btn-lg btn-block">Option 2</button>
<button type="button" class="btn btn-outline-dark btn-lg btn-block">Option 3</button>
<button type="button" class="btn btn-outline-dark btn-lg btn-block">Option 4</button>
<script src="{{ url_for('static', filename='js/game.js')}}"></script>
</div>
</body>
{% endblock %}
app.py
from flask import Flask, render_template, request, redirect
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///posts.db'
#Initialising the database
db = SQLAlchemy(app)
#Creating a database model
class Posts(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.String(200), nullable=False)
date_created = db.Column(db.DateTime, default=datetime.utcnow)
#Creating a function to return a string when a post is added to db
def __repr__(self):
return '<Content %r>' % self.id
#app.route('/')
def index():
return render_template("index.html")
#app.route('/game')
def game():
return render_template("game.html")
#app.route('/blog', methods=['POST', 'GET'])
def blog():
if request.method == "POST":
post_content = request.form['content']
new_post = Posts(content=post_content)
try: #Push the blog post to the db
db.session.add(new_post)
db.session.commit()
return redirect('/blog')
except:
return "There was an error adding your post"
else:
posts = Posts.query.order_by(Posts.date_created)
return render_template("blog.html", posts=posts)
#app.route('/update/<int:id>' , methods=['POST', 'GET'])
def update(id):
post_to_update = Posts.query.get_or_404(id)
if request.method == "POST":
post_to_update.content = request.form['content']
try:
db.session.commit()
return redirect('/blog')
except:
return "There was a problem updating your blog post"
else:
return render_template('update.html', post_to_update=post_to_update)
#app.route('/delete/<int:id>')
def delete(id):
post_to_delete = Posts.query.get_or_404(id)
try:
db.session.delete(post_to_delete)
db.session.commit()
return redirect('/blog')
except:
return "There was a problem deleting this post :("
my base.html template
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<title>
{% block title %}GEN TITLE{% endblock %}
</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="{{ url_for('index')}}">Patricks Site</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="{{ url_for('index')}}">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('game')}}">Game</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('blog')}}">Blog</a>
</li>
</ul>
</div>
</nav>
</br>
<!-- Optional JavaScript; choose one of the two! -->
<!-- Option 1: jQuery and Bootstrap Bundle (includes Popper) -->
<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/bootstrap#4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
<!-- Option 2: jQuery, Popper.js, and Bootstrap JS
<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://cdn.jsdelivr.net/npm/bootstrap#4.5.3/dist/js/bootstrap.min.js" integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s" crossorigin="anonymous"></script>
-->
{% block content %}
{% endblock %}
</body>
</html>
Sorry for the wall of text, I wasn't quite sure how much I should show. Thanks
Your error is telling you to look at line 25 of game.js.
It appears you're missing a colon on that line, after options, and a comma after id: 1. You have:
const textNodes = [
{
id:1
text: 'You wake up staring at the ceiling of your bunker.',
options [...],
You need:
const textNodes = [
{
id:1,
text: 'You wake up staring at the ceiling of your bunker.',
options: [...],
Related
Hello last few days I am trying to learn call API from different site. Now I try to build a website like this. My task is call API from The MealDB and implement a site and also show API data in card view and when I click any card it's show another view where contain all ingredients
but I can't call the API from The mealDB I wanted to implement this website by calling the mealBD API. But whenever I tried it's not work as I want. I don't know how to call that API.
My project is given below :I can't call the API
this is my js code
fetch('https://www.themealdb.com/api/json/v1/1/search.php?f=a')
.then(res=>res.json())
.then(data=> displayFoods(data))
const displayFoods = foods =>{
const foodsDiv = document.createElement('food-items');
foods.forEach(meals=>{
const foodDiv = document.createElement('div');
foodDiv.className = 'meals';
const foodInfo = `
<h3>${meals.strMeal}</h3>
`;
foodDiv.innerHTML = foodInfo;
foodsDiv.appendChild(foodDiv);
});
}
I used bootstrap in html file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cooking master</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/all.min.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<section class="container">
<header>
<nav class="navbar navbar-expand-lg navbar-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">Cooking master</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-
target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-
label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse d-flex justify-content-end"
id="navbarNavAltMarkup">
<div class="navbar-nav">
<a class="nav-link active" aria-current="page" href="#">Home</a>
<a class="nav-link" href="#about">About</a>
<a class="nav-link" href="#recipes">Recipes</a>
<a class="nav-link" href="#blog" tabindex="-1">Blog</a>
</div>
</div>
</div>
</nav>
</header>
</section>
<section class="container input-style">
<main class="d-flex justify-content-center">
<div class="input-group mb-3 input-filed ">
<input type="text" class="form-control" placeholder="Search for Meal...." aria-label="Recipient's username" aria-describedby="basic-addon2">
<span class="input-group-text bg-color text-light" id="basic-addon2">Search</span>
</div>
</main>
</section>
<div id="food-items">
</div>
<script src="js/bootstrap.min.js"></script>
<script src="js/app.js"></script>
The result json is an object with property meals. So you cannot execute forEach on that. You need to run on foods.meals
Below is your working code.
(function(){
fetch('https://www.themealdb.com/api/json/v1/1/search.php?f=a')
.then(res=>res.json())
.then(data=> displayFoods(data))
const displayFoods = foods =>{
const foodItemsDiv = document.getElementById('food-items');
foods.meals.forEach(meal=>{
const foodDiv = document.createElement('div');
foodDiv.className = 'meal';
const foodInfo = `
<h3>${meal.strMeal}</h3>
`;
foodDiv.innerHTML = foodInfo;
foodItemsDiv.appendChild(foodDiv);
});
}
})();
<div id="food-items">
</div>
Try this in your browser console:
fetch('https://www.themealdb.com/api/json/v1/1/search.php?f=a')
.then(res=>res.json())
.then(data=> console.log(data))
You'll see an end result like this:
{
meals: [
{ // meal 1 },
{ // meal 2 },
{ // meal 3 },
{ // meal 4 }
]
}
Inside your displayFoods function, you're trying to call forEach on this data, but forEach can only operate on arrays, not objects.
Instead, you need to pass the meals array inside the returned data to your function:
fetch('https://www.themealdb.com/api/json/v1/1/search.php?f=a')
.then(res=>res.json())
.then(data=> displayFoods(data.meals)) // data.meals instead of data
I have a drop down bar with a multi selection tool. A user picks from titles of graphs stored in a model for the graphs they want to display. How can I use those selections to display these graphs? I am using Ajax to send the data to the backend. From that data I created a new context_dict full of the model objects we want displayed. I want to either display in the same template or link to another template that can use this context dict. I do not know the best way to do this. Here is some of my code below.
Models:
from django.db import models
class ChartPrac(models.Model):
title = models.CharField(max_length=256)
chart = models.ImageField()
def __str__(self):
return self.title
Views:
def querier(request):
if request.method == 'POST':
options_arr = request.POST.get('optionsArr')
options = options_arr.split(':')
options = options[1:]
print(options)
context_arr = []
context_graphs = {}
i = 0
for elements in options:
charts_to_display = ChartPrac.objects.get(title=elements)
context_arr.append(charts_to_display)
i += 1
context_graphs['titles'] = context_arr
return HttpResponse(options_arr)
else:
graph_titles = ChartPrac.objects.all()
context_dict = {'titles': graph_titles}
print(context_dict)
print(type(context_dict['titles']))
return render(request, 'graph_querier/base.html', context=context_dict)
Urls:
from django.urls import path
from graph_querier import views
app_name = 'graph_querier'
urlpatterns = [
path('', views.index, name='index'),
path('querier/', views.querier, name='querier'),
# path('graph/', views.graph, name='graph'),
]
Template:
<!DOCTYPE html>
{% load static %}
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<title>Marketing Querier</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<link rel="stylesheet" href="https://res.cloudinary.com/dxfq3iotg/raw/upload/v1569006288/BBBootstrap/choices.min.css?version=7.0.0">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://res.cloudinary.com/dxfq3iotg/raw/upload/v1569006273/BBBootstrap/choices.min.js?version=7.0.0"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="{% static 'graph_querier\querier.css' %}">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark" style="background-color: rgba(0,96,155,255)";>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="{% url 'main_dash:main_dash' %}">Main Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="">Marketing Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="">Sales Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="">Input</a>
</li>
<li class="nav-item">
<a class="nav-link" href="">Input</a>
</li>
<li class="nav-item">
<a class="nav-link" href="">Input</a>
</li>
</ul>
</div>
</nav>
<div id="title">
<h1 id="graph-querier-text">Graph Querier</h1>
</div>
<div class="row d-flex justify-content-center mt-100" id='search'>
<div class="col-md-6"> <select class="select-option" id="choices-multiple-remove-button" placeholder="Select up to 10 Graphs" multiple>
{% for graphs in titles %}
<option class="option-rend" value={{ graphs.title }}>{{ graphs.title }}</option>
{% endfor %}
</select> </div>
</div>
<script>
$(document).ready(function(){
var multipleCancelButton = new Choices('#choices-multiple-remove-button', {
removeItemButton: true,
maxItemCount:10,
searchResultLimit:1000,
renderChoiceLimit:1000
});
});
</script>
<script src="{% static '\graph_querier\javascript\base.js' %}"></script>
<div id='render-graphs'>
<button type="button" class="btn btn-primary btn-lg" onclick='rendGraphs();'>Render Graphs</button>
{% csrf_token %}
</div>
</body>
</html>
JS:
function rendGraphs(){
var select = document.getElementById('choices-multiple-remove-button');
var csrf = $("input[name=csrfmiddlewaretoken]").val();
var optionsArr = [];
for (var x = 0; x < select.length; x++){
var temp = select.options[x].text;
optionsArr.push(temp);
}
var stringOptions = ''
for (var i= 0; i < optionsArr.length; i++){
var stringOptions = stringOptions.concat(":" + String(optionsArr[i]));
}
$.ajax({
url: '/query/querier/',
type: 'POST',
data: {'optionsArr': stringOptions,
'csrfmiddlewaretoken': csrf
}
}).done(function(response){
console.log(response)
});
}
$(function(){ $.get("header.html", function(data){
$("#header").html(data); }); });
So I am eventually going to have to do this in java but for now I just want to do this in the javascript extension known as jquery but any format that makes this work will please me.
I have 2 files:
header.html
<!-- Header -->
<div class="row navigationBar">
<!-- Company Logo -->
<div class="col-2">
<img src="images/GCB.png" alt="GCB-logo" class="gcb-logo">
</div>
<!-- Top Bar -->
<div class="col-md-10">
<div class="top-navigationBar">
<nav class="navbar navbar-expand-md quick-help">
<!-- Collapse Button -->
<button class="navbar-toggler navbar-light" type="button" data-toggle="collapse" data-target="#navbarTogglerDemo01" aria-controls="navbarTogglerDemo01" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<!-- Quick Help -->
<div class="collapse navbar-collapse" id="navbarTogglerDemo01">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link black-font blue-line" href="">CONSULTATION</a>
</li>
<li class="nav-item">
<a class="nav-link black-font blue-line" href="">CUSTOMER SUPPORT</a>
</li>
<li class="nav-item">
<a class="nav-link black-font blue-line" href="">TIẾNG VIỆT</a>
</li>
</ul>
</div>
</nav>
</div>
<!-- Bottom Bar -->
<div>
<nav class="navbar navbar-expand-md bottom-navigationBar">
<div class="row bottom-navigationBar">
<!-- Quick Navigation -->
<div class="col-4">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<button type="button" class="btn btn-primary btn-sm thick-font button-flat-bottom">Checking</button>
</li>
<li class="nav-item">
<button type="button" class="btn btn-outline-secondary btn-sm thick-font button-flat-bottom">Savings</button>
</li>
<li class="nav-item">
<button type="button" class="btn btn-outline-secondary btn-sm thick-font button-flat-bottom">Loans</button>
</li>
</ul>
</div>
<!-- Bank Name -->
<div class="col-md-4">
<h1 class="bank-name">Go<span class="orange-text">Com</span>Bank</h1>
</div>
<!-- Login Form -->
<div class="login-container">
<form action="/action_page.php">
<input type="text" placeholder="Username" name="username">
<input type="text" placeholder="Password" name="psw">
<button type="button" class="btn btn-primary btn-sm">Login</button>
</form>
</div>
</div>
</nav>
</div>
</div>
</div>
<!-- Header End -->
and the webpage
webpage.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="header"></div>
</body>
</html>
I am trying to load header.html and set it into the id=("header") of webpage.html
Currently the only code that works is $("#header").html("")
Using this format I can set things like
<p>Hello World</p>
but it doesn't work when I want to add the loaded header.html items.
--NEW CONTENT WITH ANSWER IN PROGRESS--
So none of the answers have even come close to being correct but I have came up with my own solution that should in theory work but I have been unable to implement it myself.
Before the res.send(/*HTML Code Here*/);
I propose this solution::
A: load the HTML file into a var
B: load the insertion code into another var
C: A.replace("ReplaceKeyword", B);
D: res.send(A);
This method has worked for me when I use java and it sometimes works with jQuery but I can't seem to find the appropriate syntax to do this inside of javascript.
If you can provide the code to implement this then I can mark your response as the answer.
Note
A is something like
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<!--InsertionPoint-->
</body>
</html>
B is something like
<p>Hello World</p>
Replace keyword in this instance would be ""
The End result that is sent in the res.send() is
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<p>Hello World</p>
</body>
</html>
=====================================
try this
<script>
document.getElementById("header").innerHTML='<object type="text/html" data="header.html"></object>';
</script>
Edited for new method
i found this on w3school. I already try it and i think this can solve your problem
https://www.w3schools.com/howto/howto_html_include.asp
<script>
includeHTML();
function includeHTML() {
var z, i, elmnt, file, xhttp;
/*loop through a collection of all HTML elements:*/
z = document.getElementsByTagName("*");
for (i = 0; i < z.length; i++) {
elmnt = z[i];
/*search for elements with a certain atrribute:*/
file = elmnt.getAttribute("w3-include-html");
if (file) {
/*make an HTTP request using the attribute value as the file name:*/
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4) {
if (this.status == 200) {
elmnt.innerHTML = this.responseText;
}
if (this.status == 404) {
elmnt.innerHTML = "Page not found.";
}
/*remove the attribute, and call this function once more:*/
elmnt.removeAttribute("w3-include-html");
includeHTML();
}
}
xhttp.open("GET", file, true);
xhttp.send();
/*exit the function:*/
return;
}
}
};
</script>
on your body tag add something like this
<div w3-include-html="header.html"></div>
as long as you add w3-include-html attribute it will work, and you can add your stylesheet at the top of webpage.html
I've tried looking up online, rewriting the code but the submit() won't fire but when I use a click event, it fire an calls the callback and the ajax() runs. I cannot figure out what's really wrong with the code even after going through so many tutorials and documentation online.
Here's the code:
HTML template with the form
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Login</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<!-- site icon -->
<link rel="icon" href="{% static 'img/question.png' %}">
<!-- Bootstrap core CSS -->
<link href="{% static 'bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">
<!-- Font Awesome -->
<link href="{% static 'css/font-awesome.min.css' %}" rel="stylesheet">
<!-- Endless -->
<link href="{% static 'css/endless.min.css' %}" rel="stylesheet">
</head>
<body>
<div class="login-wrapper">
<div class="text-center">
<span>
<img src="{% static 'img/question.png' %}" style="height: 100px; width: 100px; border-radius: 50%;">
</span>
</div>
<div class="text-center">
<h2 class="fadeInUp animation-delay8" style="font-weight:bold">
<span class="text-success">CitiSpy User Login</span>
</h2>
</div>
<div class="login-widget animation-delay1">
<div class="panel panel-default">
<div class="panel-heading clearfix">
<div class="pull-left">
<i class="fa fa-lock fa-lg"></i> Login
</div>
</div>
<div class="panel-body">
<div id="login-form-main-message"></div>
<form class="form-login" id="login_form" method="POST">
{% csrf_token %}
<div id="form_content">
{{ form.non_field_errors }}
<div class="form-group">
{{ form.email.errors }}
<label for="{{ form.email.id_for_label }}">{{ form.email.label }}</label>
{{ form.email }}
</div>
<div class="form-group">
{{ form.password.errors }}
<label for="{{ form.password.id_for_label }}">{{ form.password.label }}</label>
{{ form.password }}
</div>
<div class="seperator"></div>
<hr/>
<div class="form-group">
<!-- <button class="btn btn-success btn-sm bounceIn animation-delay5 login-link pull-right" type="submit" id="id_submit">
<i class="fa fa-sign-in"></i>
Login
</button> -->
<a type="submit" class="btn btn-success btn-sm bounceIn animation-delay5 login-link pull-right" id="login_submit" href="#"> -->
<i class="fa fa-sign-in"></i>
Login
</a>
</div>
</div>
</form>
</div>
</div><!-- /panel -->
</div><!-- /login-widget -->
</div><!-- /login-wrapper -->
<!-- Jquery -->
<script src="{% static 'js/jquery-1.10.2.min.js' %}"></script>
<!-- Bootstrap -->
<script src="{% static 'bootstrap/js/bootstrap.js' %}"></script>
<!-- Pace -->
<script src="{% static 'js/uncompressed/pace.js' %}"></script>
<!-- Popup Overlay -->
<script src="{% static 'js/jquery.popupoverlay.min.js' %}"></script>
<!-- Slimscroll -->
<script src="{% static 'js/jquery.slimscroll.min.js' %}"></script>
<!-- Modernizr -->
<script src="{% static 'js/modernizr.min.js' %}"></script>
<!-- Cookie -->
<script src="{% static 'js/jquery.cookie.min.js' %}"></script>
<!-- Endless -->
<script src="{% static 'js/endless/endless.js' %}"></script>
<!--login js-->
<script src="{% static 'js/accounts/login_1.js' %}"></script>
</body>
</html>
JavaScript
$(document).ready(function(){
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var $csrf_token = {
name: "csrfmiddlewaretoken",
value: getCookie('csrftoken')
};
var $myId = $("#login_form >#form_content > .form-group > button").attr('class');
console.log($myId);
$("#login_form").submit(function(event){
console.log("I am in submit");
event.preventDefault();
var $form_data = $(this).serializeArray();
$form_data.push($csrf_token);
$.ajax({
type: 'POST',
data: $form_data,
cache: false,
dataType: 'json',
url: '/accounts/userLogin/',
beforeSend: function(){
$("#login-form-main-message").css("display", "block").html("<div class='alert alert-info'><img height=\"24px;\" src=\"{% static '/images/double-ring.gif' %}\" alt=\"loading\" /> Please wait...</div>");
$("#form_content").css("display", "none");
},
success: function(data){
if (data.status === "ok"){
if (data.to === "verify") {
//redirect to account verification
} else {
if (data.to === "user") {
//redirect to user account
$("#login-form-main-message").css("display", "block").html("<div class='alert alert-info'><img height=\"24px;\" src=\"{% static '/images/double-ring.gif' %}\" alt=\"loading\" /> Success! login you in, please wait...</div>");
$("#form_content").css("display", "none");
}else{
$("#login-form-main-message").css("display", "block").html("<div class='alert alert-info'><img height=\"24px;\" src=\"{% static '/images/double-ring.gif' %}\" alt=\"loading\" /> Success! login you in, please wait...</div>");
$("#form_content").css("display", "none");
location.href = '/em_dept/dashboard/';
}
}
}
},
error:function(xhr,errmsg,err){
console.log("error error error!!!");
console.log(xhr.status + ": " + xhr.responseText);
}
});
// return false;
});
});
The View rendering the form
#method_decorator(csrf_protect, name='post')
class UserLogin(LoginView):
"""docstring for UserLogin"""
template_name = 'accounts/login.html'
# authentication_form = LoginForm()
def get(self, request):
'''a func to work on the request.POST'''
print("getting the form for you ")
form = LoginForm()
return render(request,self.template_name,{'form':form})
def post(self, request):
form = LoginForm(request.POST)
print("go the data for you")
if request.is_ajax():
print("entered form")
if form.is_valid():
print("form valid")
email = form.cleaned_data['email']
try:
user = User.objects.get(email=email)
print("user obj", user)
if user.check_password(form.cleaned_data['password']):
# 0-super admin, 1-dept admin,2-dept staff, 3-end user
print("correct password")
if user.account_type == 4:
if user.last_login == None or user.last_login == '':
to = "verify"
else:
to = "user"
else:
if user.account_type == 2:
to = 'dept_admin'
elif user.account_type == 3:
to = 'dept_staff'
elif user.account_type == 1:
to = 'super_user'
else:
to = None
res = {'status':'ok', 'error':False, 'acc_type':to, 'data':user.email}
else:
print("incorrect password")
res = {'status':'fail', 'error':'incorrect password'}
except Exception as e:
print("User not found!", e)
res = {'status':'fail', 'error':'account not found'}
else:
print("form valid")
res = {'status':'fail', 'error':form.errors}
return JsonResponse(res)
<a type="---" is just a type hinting having submit there does not trigger form submit.
Why is the actual submit button commented out?
<!-- <button class="btn btn-success btn-sm bounceIn animation-delay5 login-link pull-right" type="submit" id="id_submit">
<i class="fa fa-sign-in"></i>
Login
</button> -->```
I would uncomment this and go from there.
try to use on('submit') instead of submit().
What version of jquery do you use ?
it should be <Input type='submit'not<a>thats why your click worked before...
I'm following a tut from Mike hibbert and have tried to modify it a bit to suit my needs but it's not working. I wanted to use his way because my way was breaking the DRY rule, I had to write search logic for each of my views I thought it might be the order my js But I dont think it is. I could be wrong, as I am fairly new to prgramming. I'm not sure but i think the issue may be with my search being on the nav which I nav in an include. Heres my code
views.py
def search_title(request):
if request.method == "POST":
search_text = request.POST['search_text']
else:
search_text = ''
posts = Post.objects.filter(
Q(title__contains=search_text)|
Q(content__contains=search_text)
)
context = {
"posts": posts
}
return render(request, "posts/ajax_search.html", context)
my nav.html
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{% url 'posts:list' %}">HiSPANIC HEiGHTS</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<form method="POST" action=" " class="navbar-form navbar-right">
<div class="input-group">{% csrf_token %}
<input type="text" name="search" id="search" placeholder="search" value="{{ request.GET.q }}" class="form-control"
style="width: 350px">
<ul id="search-results">
</ul>
<span class="input-group-btn">
<button type="submit" class="btn btn-primary"><span style="font-size:1.4em" class="glyphicon glyphicon-search"></span> </button>
</span>
</div>
</form>
<ul class="nav navbar-nav">
<li>Home</li>
<li>Sewp</li>
{% if user.is_authenticated %}
<li>Admin</li>
<li>Create</li>
{% endif %}
</ul>
</div><!--/.nav-collapse -->
</div>
base.html
{% load staticfiles %}
<html>
<head>
<title> {% block head_title %} try django 1.9 {% endblock head_title %}</title>
<link rel="stylesheet" href='{% static "css/base.css" %}'/>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css"
integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">
{% include "includes/nav.html" %}
{% include "includes/messages_display.html" %}
<div class="container">
{% if title == "posts" %}
<div class="jumbotron" style="margin-top: 80px">
{% block jumbotron %}{% endblock jumbotron %}
</div>
{% endif %}
{% block content %}{% endblock content %}
</div>
<!-- Latest compiled and minified JavaScript -->
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"
integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS"
crossorigin="anonymous">
</script>
<script src="{% static 'js/ajax.js' %}"></script>
<script src="{% static 'js/jquery.bootstrap-autohidingnavbar.js' %}"></script>
<script>
$("nav.navbar-fixed-top").autoHidingNavbar();
</script>
ajax.js
$(function(){
$('#search').keyup(function() {
$.ajax({
type: "POST",
url: "/posts/search/",
data: {
'search_text': $('#search').val(),
'csrfmiddlewaretoken': $("input[name=csrfmiddlewaretoken]").val()
},
success: searchSuccess,
dataType: 'html'
});
});
});
function searchSuccess(data, textStatus, jqXHR)
{
$('#search-results').html(data);
}
my posts/urls.py
urlpatterns = [
url(r'^$', post_list, name='list'),
url(r'^tag/(?P<slug>[\w-]+)/$', tag_list, name="tag_list"),
url(r'^create/$', post_create, name='create'),
url(r'^sewp$', sewp, name='sewp'),
url(r'^(?P<slug>[\w-]+)/$', post_detail, name='detail'),
url(r'^(?P<slug>[\w-]+)/edit/$', post_update, name='update'),
url(r'^(?P<id>\d+)/delete/$', post_delete, name='delete'),
url(r'^search/', search_title),
]
I see no errors in the network, I've switched back and forth from GET to POST, just trying to tweak things to make it work but nothing has changed. My jquery is from a CDN but I don't think that's an issue, but I am a newb and could be wrong. any help with this will be appreciated
Move your search url definition to the top of the urlpatterns list, so it doesn't get masked by the post_detail wildcards:
urlpatterns = [
url(r'^$', post_list, name='list'),
url(r'^search/', search_title),
url(r'^tag/(?P<slug>[\w-]+)/$', tag_list, name="tag_list"),
url(r'^create/$', post_create, name='create'),
url(r'^sewp$', sewp, name='sewp'),
url(r'^(?P<slug>[\w-]+)/$', post_detail, name='detail'),
url(r'^(?P<slug>[\w-]+)/edit/$', post_update, name='update'),
url(r'^(?P<id>\d+)/delete/$', post_delete, name='delete'),
]
From the docs:
Django runs through each URL pattern, in order, and stops at the first one that matches the requested URL.
And your post_detail regexp certainly matches search/.
I think you may be required to have $ at the end of your search url string.
url(r'^search/$', search_title),
This lets django know it's the end of the string. Unless you've confirmed that you've actually been able to dispatch to the search_title view.