I'm creating a function that is looking for users in database.
I've done the server-side code, but I don't know how to display the results in the html code. I know that I have to write some JavaScript code but I don't know how
I found something on Google, but it doesn't work.
This is my route.
router.get('/search', isAuth, feedController.getSearch);
This is my controller.
exports.getSearch = (req,res,next) => {
const search = req.query.searchField;
User.find({
firstname:{
$regex: new RegExp(search)
},
}, {
_id:0,
__v:0
}, function (err,data) {
res.json(data);
}
).limit(10);
}
This is my HTML
<li>
<div class="search-box">
<form action="/search" method="GET" class="form-inline my-0 my-lg-0">
<input type="text" aria-label="Search" class="form-control mr-sm-0" onkeyup="showResults(this.value)" placeholder="Mirror-Mirror Search">
<span class="hightlight"></span>
<span class="bar"></span>
</input>
<button type="submit" class="search-btn"><i class="fas fa-search"></i></button>
</form>
</div>
<div style="position: relative; width:100%; top:-1px;">
<div class="border" id="search-results"></div>
</div>
</li>
And this is what I found on Google
var showResults = debounce(function(arg) {
var value = arg.trim();
if(value == "" || value.length <=0)
{
$("#search-results").fadeOut();
return;
}
else {
$("#search-results").fadeIn();
}
var jgxh = $.get('/controllers/feed/getSearch?searchField=' + value, function(data) {
$("#search-results").html("");
})
.done(function(data){
if(data.length === 0) {
$("#search-results").append('<p class="lead text-center mt-2">No results</p>');
} else {
data.forEach(x => {
$("#search-results").append('<a href="#> <p class="m-2 lead>' +x.firstname+' '+x.lastname + '</p></a>')
});
}
})
.fail(function(err){
console.log(err);
})
},200)
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this;
args = arguments;
var later = function () {
timeout = null;
if(!immediate) func.apply(context,args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if(callNow) func.apply(context,args);
};
};
I expected to autodisplay the results, but It doesn't work. I want to search in my database either for 'firstname' or 'lastname', I hope you can help me, thank you!
Related
so I was working on making this Todo list website but I am facing a problem.
NODE.JS CODE:
//jshint esversion:6
// _______________________________Database Code_________________________________
const mongoose = require("mongoose")
none = []
main().catch(err => console.log(err));
async function main() {
mongoose.set('strictQuery', false);
await mongoose.connect('mongodb://0.0.0.0:27017/todolistDB');
}
// For the main list
const itemSchema = {
itemName: {
type: String,
required: true
}
}
const Item = mongoose.model("Item", itemSchema)
const buyFood = new Item({
itemName: "Buy Food"
})
const cookFood = new Item({
itemName: "Cook Food"
})
const eatFood = new Item({
itemName: "Eat Food"
})
const defaultItems = [buyFood, cookFood, eatFood]
// New list schema
const listSchema = {
listName: String,
items: [itemSchema]
}
const List = mongoose.model("list", listSchema)
// Function that creates new lists
function makeNewList(name) {
const list = new List({
listName: name,
items: defaultItems
})
list.save()
}
// Function that creates new list items
function createNewItem(newItem) {
const item = new Item ({
itemName: newItem
})
}
// Function to find a list
function findList(listName) {
List.findOne({listName: listName}, function(err, list) {
if (!err) {
return list
}
})
}
// _______________________________Server Code___________________________________
const express = require("express");
const bodyParser = require("body-parser");
const date = require(__dirname + "/date.js");
const _ = require("lodash")
const popup = require("node-popup")
const app = express();
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static("public"));
const workItems = [];
// Default Home List
app.get("/", function(req, res) {
const day = date.getDate();
Item.find(function(err, item) {
if (item.length === 0) {
Item.insertMany(defaultItems, function(err) {
if (err) {
console.log(err);
} else {
console.log("Items added successfully.");
}
})
}
else if (err) {
console.log(err);
}
else {
List.find({}, function(err, list) {
if (err) {
console.log(err);
}
else if (list.length === 0) {
res.render("list", {listTitle: day, newListItems: item, array: none});
}
else {
list.forEach(function(listName) {
console.log(listName);
})
res.render("list", {array: list, newListItems: defaultItems, listTitle: day})
}
})
}
})
});
// Creating new list items
app.post("/", function(req, res){
const item = req.body.newItem;
const listName = req.body.list;
if (listName === "day") {
createNewItem(item)
res.redirect("/")
}
// else {
// List.findOne({listName: listName}, function(err, foundList) {
// foundList.items.push(item)
// foundList.save()
// res.redirect("/" + listName)
// })
// }
});
// Deleting list items
app.post("/delete", function(req, res) {
deletedItem = String(req.body.box)
Item.deleteOne({_id: deletedItem}, function(err) {
if (err) {
console.log(err);
} else {
console.log("Item deleted successfully");
}
})
res.redirect("/")
})
// Making new lists
app.post("/list", function(req, res) {
newList = req.body.newListName.toLowerCase()
List.findOne({listName: newList}, function(err, listInSearch) {
if (!listInSearch) {
console.log("Does not exist");
makeNewList(newList)
res.redirect("/" + newList)
}
else {
console.log("Exist");
}
})
})
// Loading existing list
app.get("/:extension", function(req, res) {
extension = req.params.extension.toLowerCase()
console.log("Site ends with " + extension);
if (extension !== "list") {
List.find({}, function(err, list) {
if (err) {
console.log(err);
}
else {
List.findOne({listName: extension}, function(err, foundList) {
if (!err) {
items = foundList.items
console.log(items);
res.render("list", {array: list, newListItems: foundList.items, listTitle: _.startCase(extension)})
}
})
}
})
}
})
// app.post("/:extension", function(req, res) {
// extension = req.params.extension.toLowerCase()
// item = req.body.newItem.toString()
//
// console.log(item);
// console.log(extension);
//
// List.findOne({listName: extension}, function(err, foundList) {
// if (!err) {
// createNewItem(item)
// foundList.items.push(item)
// foundList.save()
// res.redirect("/" + extension)
// }
// })
// })
// About page
app.get("/about", function(req, res){
res.render("about");
});
// Server port
app.listen(2000, function() {
console.log("Server started on port 2000");
});
HTML CODE:
<%- include("header") -%>
<!-- Showing list title -->
<div class="content">
<div class="box" id="heading">
<h1> <%= listTitle %> </h1>
</div>
<!-- Showing all lists -->
<div class="form">
<div class="btn-group">
<button type="button" class="btn btn-danger dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
Lists
</button>
<ul class="dropdown-menu">
<% array.forEach(function(item) {%>
<li><a class="dropdown-item" href="/<%= item.listName %>"> <%= item.listName %> </a></li>
<% }) %>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="/">Default List</a></li>
</ul>
</div>
<!-- Making new lists -->
<div class="list drop">
<form action="/list" method="post">
<input type="text" name="newListName" placeholder="New List Name" autocomplete="off">
<button class="btn btn-primary btn-md" type="submit" name="newList">Create</button>
</form>
</div>
</div>
<!-- Showing each list item -->
<div class="box">
<% newListItems.forEach(function(item) {%>
<form class="form-group" action="/delete" method="post">
<div class="item">
<input type="checkbox" onChange="this.form.submit()" name="box" value="<%= item._id %>">
<p><%= item.itemName %></p>
</div>
</form>
<% }) %>
<!-- Adding new list items -->
<form class="item" action="/" method="post">
<input type="text" name="newItem" placeholder="New Item" autocomplete="off">
<button class="button" type="submit" name="list" value="<%= listTitle %>">+</button>
</form>
</div>
</div>
<%- include("footer") -%>
Now, the website works well for the home page but I have added the functionality to make custom lists with custom names and that's where the issue arises. Whenever I make a new list, I want to add some items to it that are then stored in mongodb database. But if you look at the "Loading existing list" section of the .js code, there's the "newListItems" parameter which is supposed to take a list of items which are later displayed on the screen using a forEach() loop in the html document using EJS. Now, I have checked it multiple times, the items always get added to the database and exist there but when it's time to render them, the "foundList.items" gives that "TypeError: Cannot read properties of null (reading 'items')" error. I don't know what to do... And one more thing, when I try to create a new list after already creating one before, the second one doesn't gets any issues whatsoever. No idea what that is but it only happens the first time.
I hope someone can help...
After a search, I am sending the result to frontend in the form of array. But I am not being able to get that array in frontend using fetch. Through postman I am able to get the result from the backend but I am not able to get it in the frontend. In another file, I have set axios.post as well and exported from there and imported in frotend.
I am beginner so I might have written a bad code, any help will mean a lot.
In frontend :
class Hostel extends Component{
constructor (){
super();
this.state = {
country : '',
city : '',
category : '',
errors : {}
};
}
componentWillReceiveProps(nextProps) {
if (nextProps.errors) {
this.setState({
errors: nextProps.errors
});
}
}
onChangeAddOptions = e => {
this.setState({ [e.target.id]: e.target.value });
};
addOption = e => {
e.preventDefault();
const newOption = {
country : this.state.country,
city : this.state.city,
category:this.state.category,
}
this.props.saveOptions(newOption,this.props.history);
};
getHostels = async ()=> {
console.log("getHostel function is called");
const response = await fetch('http://localhost:5000/api/users/hostel',{
method : "POST",
// headers:{
// "Content-Type" : "application/json"
// },
})
.then((response)=> {response.json()})
.then((data)=>{
console.log("inside data");
console.log(data);
})
.catch(e=>{
console.error(e.error);
})
console.log("From outside of data");
console.log(response);
}
componentDidMount(){
this.getHostels();
}
render (){
const {errors,country,city,category} = this.state;
return(
<section className="Hosteldashboard">
<div className="left_container">
<h2>Yo che left section</h2>
<div>
<form noValidate onSubmit={this.addOption}>
<div class="form-row">
<label htmlFor="country">Country</label> <br />
<input
type="text"
className="input-control"
placeholder="Country name"
id="country"
value={country}
onChange={this.onChangeAddOptions}
error={errors.country}
className={classnames('', {
invalid: errors.country
})}
/>{' '}
<br />
<span className="text-danger">{errors.country}</span>
</div>
<div class="form-row">
<label htmlFor="city">City</label> <br />
<input
type="text"
className="input-control"
placeholder="City name"
id="city"
value={city}
onChange={this.onChangeAddOptions}
error={errors.city}
className={classnames('', {
invalid: errors.city
})}
/>{' '}
<br />
<span className="text-danger">{errors.city}</span>
</div>
<div class="form-row">
<label htmlFor="category">Category</label> <br />
<input
type="text"
className="input-control"
placeholder="Boys or Girls"
id="category"
value={category}
onChange={this.onChangeAddOptions}
error={errors.category}
className={classnames('', {
invalid: errors.category
})}
/>{' '}
<br />
<span className="text-danger">{errors.category}</span>
</div>
<div>
<button type="submit" className = "searchHostel" onClick={this.getHostels}>
Search
</button>
</div>
</form>
</div>
</div>
In backend :
router.post('/hostel',async (req,res)=>{
try{
console.log(req.body);
const {
errors,
isValid
} = validateSearchHostelInput(req.body);
//Check Validation
// if (!isValid){
// return res.status(400).json(errors);
// }
const page = parseInt(req.query.page) - 1 || 0;
const limit = parseInt(req.query.limit) || 5;
const search = req.query.search || "";
let sort = req.query.sort || "price";
let category = req.query.category || "All";
const categoryOptions = [
req.body.country,
req.body.city,
req.body.category
]
category === "All"
? (category = [...categoryOptions])
: (category = req.query.category.split(","));
req.query.sort ? (sort = req.query.sort.split(",")) : (sort = [sort]);
let sortBy = {};
if(sort[1]) {
sortBy[sort[0]] = sort[1];
} else {
sortBy[sort[0]] = "asc";
}
const hostel = await Hostel.find({title: {$regex: search, $options: "i"}})
.where("category")
.in([...category])
.sort(sortBy)
.skip(page * limit)
.limit(limit);
// const total = await Hostel.countDocuments({
// category: {$in: [...category]},
// title: { $regex: search, $options: "i"},
// });
// const response = {
// error: false,
// total,
// page: page + 1,
// limit,
// categories: categoryOptions,
// hostel
//}
console.log("From Hostel : " + hostel);
res.status(200).json({hostel:hostel});
}catch(err){
console.log(err);
res.status(500).json({error:true,message:"Internal Server Error"});
}
});
module.exports = router;
Im using Nodejs, EJS, Mongoose and MongoDB and i have a table that is created from the documents in my DB and cant get paging buttons to work without clearing my search query.
The way my app works is
Click on the search link which opens a search filter page.
My Search page
Then you select you filer and search. Results are then shown. With Search Query in URL
Searched Results with Search Query
3.When you click on the next page it clears your query.
Page buttons
Here is my paging buttons and below is my route
My search filters are on another page.
<div class="container">
<nav aria-label="...">
<ul class="pagination float-right">
<li class="page-item disabled">
<span class="page-link">Previous</span>
</li>
<li class="page-item active">
<a class="page-link" name="1" href="/searched/1">1</a>
</li>
<li class="page-item">
<a class="page-link" name="2" href="/searched/2">2</a>
</li>
<li class="page-item">
<a class="page-link" name="3" href="/searched/3">3</a>
</li>
<li class="page-item">
<a class="page-link">Next</a>
</li>
</ul>
</nav>
</div>
app.get("/searched/:page/:limit", function (req, res) {
if (req.isAuthenticated()) {
// const { page, limit } = req.params;
// const options = {
// sort: { dateAdded: -1 },
// page: page,
// limit: limit,
// };
const query = req.query;
if (query.btu === "") {
delete query.btu;
}
if (query.sn1 === "") {
delete query.sn1;
}
if (query.sn2 === "") {
delete query.sn2;
}
if (query.userCreated === "") {
delete query.userCreated;
}
if (query.split === "") {
delete query.split;
}
if (query.supplier === "") {
delete query.supplier;
}
if (query.issued === "") {
delete query.issued;
}
// Aircon.paginate(query, options, function (err, foundAircons) {
// if (err) {
// console.log(err);
// } else {
// console.log(foundAircons);
// res.render("instock", {
// foundAircons: foundAircons.docs,
// });
// }
// });
Aircon.find(query)
.sort({
dateAdded: "desc",
})
.exec((err, foundAircons) => {
if (err) {
console.log(err);
} else {
res.render("instock", {
foundAircons: foundAircons,
});
}
});
} else {
res.redirect("/login");
}
});
Actually, your structure looks unfamiliar to me. I'm not sure have you ever heard "pagination token" term. If you didn't you can check this magnificent guide.
I wrote searching endpoint with parameters like searchTerm, limit and pageToken to paginate. pageToken is important. If you want to go page: 2 for example. page token should be first record after the last record of the first page results. I used _id parameter in this example
Note: Creating index is mandatory for filter the records with searchTerm. Index creation is like this:
await db.collection(feedSettings._collection).createIndex({ "$**": "text" }, { name: "TextIndex" });
Code:
exports.pagination = async (req, res, next) => {
const db = await database.mongo;
const feedSettings = req.feedSettings;
// Query parameters
const limit = parseInt(req.query.limit) || 100;
let searchTerm = req.query.searchTerm;
let pageToken = req.query.pageToken;
const query = { _feedName: feedSettings.name };
// Start from last item
let paginatedQuery = {
_feedName: feedSettings.name,
_id: { $gt: ObjectID(pageToken) },
_trashed: { $ne: true }
}
// If we don't have a pageToken start from first item
if (!pageToken) {
let firstFeed = await db.collection(feedSettings._collection).findOne(query, { projection: { _id: 1 } });
if (!firstFeed) {
return res.status(200).json({
success: 1,
data: []
});
}
paginatedQuery._id = { $gte: ObjectID(firstFeed._id) };
}
// If user doesn't want to search a term in items
if (typeof searchTerm === 'string') {
await db.collection(feedSettings._collection).createIndex({ "$**": "text" }, { name: "TextIndex" });
paginatedQuery.$text = { $search: searchTerm };
}
feedsData = await db.collection(feedSettings._collection)
.find(paginatedQuery)
.limit(limit)
.toArray();
return res.status(200).json({
success: 1,
data: feedsData
});
}
managed to get it working as well with mongoose paginate v2 and found a function to rebuild the query string and pass back to the buttons
function objectToQueryString(obj) {
var str = [];
for (var p in obj)
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
return str.join("&");
}
app.get("/searched", function (req, res) {
if (req.isAuthenticated()) {
const { page } = req.query;
const options = {
sort: { dateAdded: -1 },
page: !page ? 1 : page,
limit: 20,
};
const query = req.query;
delete query.page;
if (query.btu === "") {
delete query.btu;
}
if (query.sn1 === "") {
delete query.sn1;
}
if (query.sn2 === "") {
delete query.sn2;
}
if (query.userCreated === "") {
delete query.userCreated;
}
if (query.split === "") {
delete query.split;
}
if (query.supplier === "") {
delete query.supplier;
}
if (query.issued === "") {
delete query.issued;
}
var queryString = objectToQueryString(query);
console.log(queryString);
Aircon.paginate(query, options, function (err, results) {
if (err) {
console.log(err);
} else {
res.render("instock", {
foundAircons: results.docs,
total: results.totalDocs,
hasPrev: results.hasPrevPage,
hasNext: results.hasNextPage,
pageCount: results.totalPages,
page: results.page,
url: queryString,
});
}
});
} else {
res.redirect("/login");
}
});
<div class="container">
<nav aria-label="...">
<ul class="pagination float-right">
<% let prev = "disabled"; if(hasPrev){ prev = "" }; %>
<li class="page-item <%= prev %>">
<a class="page-link" href="/searched/?<%= url %>&page=<%= page - 1 %>"
>Previous</a
>
</li>
<% for(let i = 1; i <= pageCount; i++){ %> <% let active = ""; %>
<%if(page === i) { active = "active"} %>
<li class="page-item <%= active %>">
<a class="page-link" name="1" href="/searched/?<%= url %>&page=<%= i %>"
><%= i %></a
>
</li>
<% }; %> <% let next = "disabled"; if(hasNext){ next = "" }; %>
<li class="page-item <%= next %>">
<a class="page-link" href="/searched/?<%= url %>&page=<%= page + 1 %>"
>Next</a
>
</li>
</ul>
</nav>
</div>
Please help me when i want to show message sender name near message, my data came undefined, message is sending successfuly but socket.nickname get undefined. How can i fix this problem. Can u help me ? I've been working on this for a very long time. I just couldn't realize where I was wrong. Finally I decided to seek help.
Server.js
const app = require('express')();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const users = {};
http.listen(8005, () =>{
console.log('8005 portu dinleniyor...');
});
io.sockets.on('connection', function (socket) {
socket.on('yeni-kullanici', function (data, callback) {
if (data in users){
callback(false);
} else {
callback(true);
socket.nickname = data;
users[socket.nickname] = socket;
updateUsers();
}
});
function updateUsers(){
io.sockets.emit('users', Object.keys(users));
}
updateUsers();
socket.on('mesaj-gonder', function (data) {
io.sockets.emit('mesaj', {msg: data, nick: socket.nickname});
});
socket.on('disconnect', (data) => {
if (!socket.nickname) return;
delete users[socket.nickname];
updateUsers();
});
});
client
import React, {Component} from 'react';
import io from "socket.io-client";
class Home extends Component {
constructor() {
super();
this.state = {
url:'http://127.0.0.1:8005'
}
}
kullaniciAl(e){
e.preventDefault();
const userName = $('#userName').val();
const socket = io(this.state.url);
socket.emit('yeni-kullanici', userName, function (data) {
if (data){
$('.giris').hide();
$('.chat').show();
}else{
$('.uyari').show();
$('#userName').val('');
}
});
}
yeniMesaj(e){
e.preventDefault();
const mesaj = $('#mesaj').val();
const socket = io(this.state.url);
socket.emit('mesaj-gonder', mesaj);
$('#mesaj').val('');
}
render() {
const socket = io(this.state.url);
socket.on('users', function (data) {
let html = '';
for(let i=0; i<data.length; i++){
html += data[i] + '<br/>';
}
$('#users').html(html);
});
socket.on('mesaj', function (data){
$('#contentMesaj').append('<b>' + data.nick + ': </b>' + data.msg + '<br/>');
});
return (
<div>
<div className="giris">
<div className="alert alert-danger uyari" role="alert" style={{display: "none"}}>
Bu kullanıcı adı zaten mevcut. Tekrar Deneyiniz...
</div>
<form>
<div className="form-group">
<label htmlFor="exampleInputEmail1">Kullanıcı Adı</label>
<input className="form-control" id="userName" placeholder="Kullanıcı adınızı girin..."/>
</div>
<button onClick={this.kullaniciAl.bind(this)} className="btn btn-primary">Gönder</button>
</form>
</div>
<div className="row chat" style={{display: "none"}}>
<div className="col-md-8" >
<div id="contentMesaj" style={{height: "500px",border:"1px solid"}}>
</div>
<div className="message">
<form>
<div className="input-group mb-3">
<input id="mesaj" className="form-control" placeholder="Mesajınızı Yazın..." aria-describedby="basic-addon2"/>
<div className="input-group-append">
<button onClick={this.yeniMesaj.bind(this)} className="btn btn-outline-secondary" type="button">Gönder</button>
</div>
</div>
</form>
</div>
</div>
<div className="col-md-4">
<div className="head col-md-12">
<h3>Kullanıcılar</h3>
</div>
<div className="kul col-md-12">
<span id="users"/>
</div>
</div>
</div>
</div>
);
}
}
export default Home;
Result SS :
Result SS :
I have 2 drop down menus that are being populated using a query in SQL Server. Based on the selected items, I am loading a different ejs template. I have done this using the help of AJAX. However, I want to be able to load the data according to the selected criteria. For instance, if DD1 is selected as Andrew and DD2 as Date the table should load 7 columns based on those conditions.
AKA
SELECT * FROM exTable x WHERE x.Name = Andrew and x.Date = '4/22/2019
router.js
router.get('/', async (req, res) => {
try {
var name = await conn.query("SELECT DISTINCT pr.Name FROM WFS.PRTABLE pr WHERE pr.Functional_Group = 'Test'");
var dates = await conn.query('SELECT r.Date FROM WFS.Dates r');
res.render('index', {name : name , dates: dates});
} catch (err) {
res.status(500)
res.send(err.message)
}
});
router.post('/selection', async (req, res) =>{
try {
var name = await conn.query("SELECT DISTINCT pr.Name FROM WFS.PRTABLE pr WHERE pr.Group = 'Test'");
var dates = await conn.query('SELECT r.Date FROM WFS.Dates r');
var dateID = req.body.Dates;
var nameID = req.body.Names;
var tables = await conn.query("SELECT * FROM WFS.Views v WHERE v.Name = ? AND v.Date = ?", [ nameID , dateID ], function(err){
if(err) throw err;
res.render('selection', {tables: tables, name : name , dates: dates});
});
}
catch (err) {
res.status(500)
res.send(err.message)
}
});
index.ejs
<script>
$(document).ready(function(){
$('#date').on('change', function(event) {
var dates = $('#selections option:selected').val();
});
$('#name').on('change', function(event) {
var manVal = $('#selection option:selected').val();
alert(manVal);
});
$('#submitData').on('submit', function(e){
e.preventDefault();
$.ajax({
type: "POST",
url: "/selection",
data: {dates : dates , manVal: manVal},
success: function() {
alert('success');
}
});
});
});
</script>
<form action="/selection" method="POST">
<select class="DateDD" id="date" name="Dates">
<% for(var n=0; n < dates.recordset.length; n++) { %>
<option><%= dates.recordset[n].Date%></option>
<% } %>
</select>
<select class="NameDD" id="name" name="Names">
<% for(var n=0; n < name.recordset.length; n++) { %>
<option><%= name.recordset[n].Name%></option>
<% } %>
</select>
<input type="submit" name="Submit" id="submitData" class="btn btn-primary" value="View Report" />
</form>
selection.ejs
CONTAINS THE SAME THING AS INDEX.EJS (besides the <script> tag) AND ...
<table class="table table-bordered table-condensed table-striped">
<% for(var n=0; n < tables.recordset.length; n++) { %>
<tr>
<td><%=tables.recordset[n].Name%></td>
<td><%=tables.recordset[n].Date%></td>
....
....
....
....
</tr>
<% } %>
</table>
This is the error I receive: Incorrect syntax near '?' after I hit the submit button.