Python Flask + HTML how to show selected parameters in URL - javascript

I have a python flask app and I'm wondering how to have the html page to show the selected parameters from dropdown list, text box, multi-selection etc.
A toy example of my current-working setup looks like this:
app.py
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
#app.route("/")
def index():
return render_template("index.html",
selection1=["1","2"],
selection2=["1","2"],
)
#app.route("/get-values")
def get_values():
dummy = [
["123", "123", "123"],
["456", "456", "456"],
["789", "789", "789"],
]
result = {
'sessions': dummy,
'total_sessions': 3,
'total_pages': 1,
'current_page': 1
}
return jsonify(result)
if __name__ == '__main__':
app.run(debug=True)
The step is basically:
index.html contains the page where user can update parameters to have the table showing different information
when you open the page, it shows the result from default selections
whenever you update any of the field, the result will be updated automatically (done by using $('#selection1-field').on('change', getFirstPageValues);
the update is done by calling /get-values in app.py and sending the new paramters.
What I want to do now is to be able to save (bookmark in browser) the url with updated parameters. Currently it is only saving http://localhost:5000/ which is the home page as well as where the result is shown, but I want it to be able to save url with updated parameters so that next time when I open the bookmarked page, it has the parameters applied already, something like: http://localhost:5000/get-values?c1=v1&c2=v2&c3=v3.
I think I will need to have something like getUrlParam (How to get the value from the GET parameters?) but I'm very new to js and I don't know how to do it. Also probably I need to make changes on the python flask end as well?
Another problem is that since the main url is the index (/) but I'm calling a different endpoint (/get-values) to get data for table, if I were to use something like http://localhost:5000/get-values?c1=v1&c2=v2&c3=v3, then according to the current setup, I'm basically just saving the json output rather than the page with table display of the json output result. Ideally it should be http://localhost:5000/c1=v1&c2=v2&c3=v3 but I don't know how to make this work and I was not able to find any references.
The corresponding index.html is below. You should be able to put it under /templates and make the app work. It has function displayResults(result) which is used to display the table.
<!doctype html>
<html>
<head>
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'>
<link rel='stylesheet' href='//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.css' />
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.4/css/bootstrap-select.min.css'>
<style type='text/css'>
.CSSTableGenerator {
margin: 50px;
padding: 0px;
width: 95%;
border: 1px solid #000000;
-moz-border-radius-bottomleft: 0px;
-webkit-border-bottom-left-radius: 0px;
border-bottom-left-radius: 0px;
-moz-border-radius-bottomright: 0px;
-webkit-border-bottom-right-radius: 0px;
border-bottom-right-radius: 0px;
-moz-border-radius-topright: 0px;
-webkit-border-top-right-radius: 0px;
border-top-right-radius: 0px;
-moz-border-radius-topleft: 0px;
-webkit-border-top-left-radius: 0px;
border-top-left-radius: 0px;
}
.CSSTableGenerator table {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
.CSSTableGenerator tr:last-child td:last-child {
-moz-border-radius-bottomright: 0px;
-webkit-border-bottom-right-radius: 0px;
border-bottom-right-radius: 0px;
}
.CSSTableGenerator table tr td {
-moz-border-radius-topleft: 0px;
-webkit-border-top-left-radius: 0px;
border-top-left-radius: 0px;
}
.CSSTableGenerator table tr:first-child td:last-child {
-moz-border-radius-topright: 0px;
-webkit-border-top-right-radius: 0px;
border-top-right-radius: 0px;
}
.CSSTableGenerator tr:last-child td:first-child {
-moz-border-radius-bottomleft: 0px;
-webkit-border-bottom-left-radius: 0px;
border-bottom-left-radius: 0px;
}
.CSSTableGenerator tr:hover td {
}
/*.CSSTableGenerator tr:nth-child(odd) {
background-color: #aad4ff
}
.CSSTableGenerator tr:nth-child(even) {
background-color: #ffffff
}*/
.CSSTableGenerator td {
vertical-align: middle;
border: 1px solid #000000;
border-width: 0px 1px 0px 0px;
text-align: left;
padding: 7px;
font-size: 13px;
font-family: Arial;
font-weight: normal;
color: #000000;
}
.CSSTableGenerator tr:last-child td {
border-width: 0px 1px 0px 0px
}
.CSSTableGenerator tr:last-child td:last-child {
border-width: 0px 0px 0px 0px
}
.CSSTableGenerator tr:first-child th {
background: -o-linear-gradient(bottom, #005fbf 5%, #003f7f 100%);
background: -webkit-gradient( linear, left top, left bottom, color-stop(0.05, #005fbf), color-stop(1, #003f7f) );
background: -moz-linear-gradient( center top, #005fbf 5%, #003f7f 100% );
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#005fbf", endColorstr="#003f7f");
background: -o-linear-gradient(top,#005fbf,003f7f);
background-color: #005fbf;
border: 0px solid #000000;
text-align: center;
border-width: 0px 0px 1px 1px;
font-size: 14px;
font-family: Arial;
font-weight: bold;
color: #ffffff;
}
.CSSTableGenerator tr:first-child td:first-child {
border-width: 0px 1px 1px 0px
}
.CSSTableGenerator tr:first-child td:last-child {
border-width: 0px 0px 1px 1px
}
#radial-center {
/* fallback */
background-color: #2F2727;
background-position: center center;
background-repeat: no-repeat;
/* Safari 4-5, Chrome 1-9 */
/* Can't specify a percentage size? Laaaaaame. */
background: -webkit-gradient(radial, center center, 0, center center, 460, from(#1a82f7), to(#2F2727));
/* Safari 5.1+, Chrome 10+ */
background: -webkit-radial-gradient(circle, #1a82f7, #2F2727);
/* Firefox 3.6+ */
background: -moz-radial-gradient(circle, #1a82f7, #2F2727);
/* IE 10 */
background: -ms-radial-gradient(circle, #1a82f7, #2F2727);
/* Opera couldn't do radial gradients, then at some point they started supporting the -webkit- syntax, how it kinda does but it's kinda broken (doesn't do sizing) */
}
td {
vertical-align: top;
}
.content {
width: 650px;
}
.sidebar {
width: 300px;
}
.leftNavButton {
width: 190px;
line-height: 1;
}
/* Start by setting display:none to make this hidden.
Then we position it in relation to the viewport window
with position:fixed. Width, height, top and left speak
speak for themselves. Background we set to 80% white with
our animation centered, and no-repeating */
/* When the body has the loading class, we turn
the scrollbar off with overflow:hidden */
body.isloading {
overflow: hidden;
}
/* Anytime the body has the loading class, our
modal element will be visible */
body.isloading .mymodal {
display: block;
}
.pace .pace-progress {
background: red;
position: fixed;
z-index: 2000;
top: 0;
left: 0;
height: 5px;
-webkit-transition: width 1s;
-moz-transition: width 1s;
-o-transition: width 1s;
transition: width 1s;
}
.pace-inactive {
display: none;
}
.ignoreDetailsRow {
cursor: pointer
}
.mistagDetailsRow {
cursor: pointer
}
.fixDetailsRow {
cursor: pointer
}
.ignoreSummaryRow {
cursor: pointer
}
.fixSummaryRow {
cursor: pointer
}
.mistagSummaryRow {
cursor: pointer
}
pre {
outline: 1px solid #ccc;
padding: 5px;
margin: 5px;
background-color: #000;
}
.string {
color: white;
}
.number {
color: darkorange;
}
.boolean {
color: blue;
}
.null {
color: magenta;
}
.key {
color: gold;
}
/* shirokov additions */
* {
-webkit-border-radius: 3 !important;
-moz-border-radius: 3 !important;
border-radius: 3 !important;
}
.container {
width: 95%;
}
.bootstrap-select > .dropdown-toggle {
width: 100%;
padding-right: 25px;
}
</style>
<title>Test</title>
</head>
<body>
<div id='homepage-container' class='container body-container' style='width: 1500px;'>
<div id='title-div' class='row' style='margin-bottom: 30px;'>
<h1 class='title' style='text-align: center; margin-top: 30px;'>Test</h1>
</div><!-- title-div -->
<div id='form-div' class='row' style='margin-bottom: 30px;'>
<div class='form-holder'>
<form id='query-form'>
<div class='col-lg-1 col-md-1'></div>
<div class='col-lg-2 col-md-2'>
<label id='date-range'>Date</label>
<div id='reportrange' class='pull-right' style='background: #fff; cursor: pointer; padding: 5px 8px; border: 1px solid #ccc; width: 100%'>
<span id='date-field'></span> <b class='caret'></b>
</div>
</div>
<div class='col-lg-1 col-md-1'>
<label>Selection1</label>
<select class='form-control' id='selection1-field'>
{% for d in selection1 %}
<option value="{{ d[0] }}">{{ d[1] }}</option>
{% endfor %}
</select>
</div>
<div class='col-lg-2 col-md-2'>
<label>Selection2</label>
<select id='selection2-field' class='selectpicker form-control' name='selection2' title='All' multiple data-live-search='true' style='width: 100%;'>
{% for d in selection2 %}
<option value='{{ d }}'> {{ d }}</option>
{% endfor %}
</select>
</div>
<div class='col-lg-2 col-md-2'>
<label>Query Search</label>
<input type="text" class="form-control" id="query-search-field">
</div>
</form>
</div><!-- form-holder -->
</div><!-- form-div -->
<div id='result-div' class='row' style='margin-bottom: 30px;'>
<p class='result-num' id='fetching' style='margin-left: 50px;'></p>
<table border="0" cellpadding="0" width="100%" id='result-table'> </table>
<p class='result-num' style='margin-left: 50px;'></p>
</div><!-- result-div -->
</div><!-- homepage-container -->
<script src='https://code.jquery.com/jquery.js'></script>
<script src='//cdn.jsdelivr.net/momentjs/latest/moment.min.js'></script>
<script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'></script>
<script src='//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.4/js/bootstrap-select.min.js'></script>
<script type='text/javascript'>
$(function() {
var start = moment().year(2019).month(10).day(1);
var end = moment().year(2019).month(10).day(5);
function cb(start, end) {
$('#reportrange span').html(start.format('MMMM DD, YYYY') + ' - ' + end.format('MMMM DD, YYYY'));
getFirstPageValues();
}
$('#reportrange').daterangepicker({
startDate: start,
endDate: end,
alwaysShowCalendars: true,
opens: 'right',
ranges: {
'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
'Last 7 Days': [moment().subtract(6, 'days'), moment()],
'Last 30 Days': [moment().subtract(29, 'days'), moment()],
'This Month': [moment().startOf('month'), moment().endOf('month')],
'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
}
}, cb);
cb(start, end);
});
function displayResults(result) {
$('.result-num').empty();
$('#result-table').empty();
if ((result == 'ERROR: memory exceeded') || (result == 'ERROR: no results found for given parameters') || (result == 'ERROR: invalid date range')) {
$('#result-table').append(result);
} else {
var sessions = result['sessions'];
var totalSessions = result['total_sessions'];
var totalPages = result['total_pages'];
var currentPage = result['current_page'];
console.log(sessions[0]);
// setup table
var table = $("<table id=\'result-table\' />").addClass('CSSTableGenerator');
var row1 = $("<tr/>");
row1.append($("<td/>").text("C1"));
row1.append($("<td/>").text("C2"));
row1.append($("<td/>").text("C3"));
table.append(row1);
for (var i=0, len=sessions.length; i<len; i++) {
for (var j=0, len2=sessions[i].length; j<len2; j++) {
var c1 = sessions[i][j][0];
var c2 = sessions[i][j][1];
var c3 = sessions[i][j][2];
row = $("<tr/>").css("border-top", "1px solid #d6d6d6");
row.append($("<td/>").text(c1));
row.append($("<td/>").text(c2));
row.append($("<td/>").text(c3));
table.append(row);
}
}
$('.result-num').append('Total sessions: ' + totalSessions.toString() + '<br/>');
$('.result-num').append('Showing page ' + currentPage.toString() + ' out of ' + totalPages.toString() + '<br/>');
if (currentPage == 1) {
$('.result-num').append('>> Next Page');
} else if (currentPage == totalPages) {
$('.result-num').append('<< Prev Page');
} else {
$('.result-num').append('Prev Page << >> Next Page');
}
$('#result-table').append(table);
var nextPageBtn = document.querySelectorAll('#nextpage-btn');
for (var i = 0; i < nextPageBtn.length; i++) {
nextPageBtn[i].addEventListener('click', function(evt) {
goToNextPage(evt);
});
}
var prevPageBtn = document.querySelectorAll('#prevpage-btn');
for (var i = 0; i < prevPageBtn.length; i++) {
prevPageBtn[i].addEventListener('click', function(evt) {
goToPrevPage(evt);
});
}
}
}
function getFirstPageValues() {
$('.result-num').empty();
$('#result-table').empty();
$('#fetching').append('Fetching results...');
var formInputs = {
'date': $('#date-field').html(),
'selection1': $('#selection1-field').val(),
'selection2': JSON.stringify($('#selection2-field').val()),
'querypattern': $('#query-search-field').val(),
'page_num': 1
};
$.get('/get-values',
formInputs,
displayResults
);
}
$('#selection1-field').on('change', getFirstPageValues);
$('#selection2-field').on('change', getFirstPageValues);
$('#query-search-field').on('change', getFirstPageValues);
function goToNextPage(evt) {
evt.preventDefault();
var formInputs = {
'date': $('#date-field').html(),
'selection1': $('#selection1-field').val(),
'selection2': JSON.stringify($('#selection2-field').val()),
'querypattern': $('#query-search-field').val(),
'page_num': parseInt(document.getElementById('nextpage-btn').dataset.page) + 1
};
$.get('/get-values-ns',
formInputs,
displayResults
);
}
function goToPrevPage(evt) {
evt.preventDefault();
var formInputs = {
'date': $('#date-field').html(),
'selection1': $('#selection1-field').val(),
'selection2': JSON.stringify($('#selection2-field').val()),
'querypattern': $('#query-search-field').val(),
'page_num': parseInt(document.getElementById('prevpage-btn').dataset.page) - 1
};
$.get('/get-values',
formInputs,
displayResults
);
}
</script>
</body>
</html>

What I want to do now is to be able to save (bookmark in browser) the
url with updated parameters. Currently it is only saving
http://localhost:5000/ which is the home page as well as where the
result is shown, but I want it to be able to save url with updated
parameters so that next time when I open the bookmarked page, it has
the parameters applied already, something like:
http://localhost:5000/get-values?c1=v1&c2=v2&c3=v3.
You'll need JavaScript. When you modify the value in the select box, you'll need to update the query string so that when you bookmark it, you're bookmarking the correct url.
Modifying a query string without reloading the page
Then in the /get-values route, you need to use request.args.get('c1'), etc. to get the values.

Related

Comments disappear after refreshing site

I'm trying to make a simple comment system. It display comments, but when I refresh the page , all comments disappear, only to re-appear again when I add a new comment. I would like to see the comments even after refreshing the page. And preferably with time stamp and in reverse order: so latest on top.
const field = document.querySelector('textarea');
const comments = document.getElementById('comment-box');
// array to store the comments
var comments_arr = [];
if(!localStorage.commentData){localStorage.commentData = [];}
else{
comments_arr = JSON.parse(localStorage.commentData);
}
// to generate html list based on comments array
const display_comments = () => {
let list = '<ul>';
comments_arr.forEach(comment => {
list += `<li>${comment}</li>`;
})
list += '</ul>';
comments.innerHTML = list;
}
submit.onclick = function(event){
event.preventDefault();
const content = field.value;
if(content.length > 0){ // if there is content
// add the comment to the array
comments_arr.push(content);
localStorage.commentData = JSON.stringify(comments_arr);
// re-genrate the comment html list
display_comments();
// reset the textArea content
field.value = '';
}
}
html {
font-size: 14px;
font-family: "Open Sans", sans-serif;
background-color: rgb(239, 239, 238);
}
/*Comment section*/
textarea {
margin: 40px 0px 10px 0px;
background-color: rgb(255, 255, 255);
width: 800px;
padding: 10px;
line-height: 1.5;
border-radius: 5px;
border: 1px solid #7097d1;
box-shadow: 1px 1px 1px #999;
}
#submit {
border-radius: 5px;
border: 1px solid #7097d1;
background-color: #e2e9ea;
}
#submit:hover {
background-color: #7097d1;
}
li {
list-style-type: none;
width: 770px;
margin: 10px 0px 10px -20px;
padding: 5px;
border-radius: 5px;
border: 1px solid #7097d1;
box-shadow: 1px 1px 1px #999;
background-color: #e2e9ea;
}
<link href="comment.css" rel="stylesheet">
<form>
<textarea id="comment" placeholder="Your response pls." value=""></textarea>
</form>
<input id="submit" type="submit" value="add">
<h4>Responses</h4>
<div id="comment-box"></div>
<script src="comment.js"></script>
Adding window.addEventListener('load', display_comments) will fix
This will run the display_comments function on every refresh
You call display_comments after submitting a comment, but you don't call it anywhere else - it needs to be called when the page loads as well.

How can I passing data from jquery codes to my project backend

I did create a form and A submit button in my website
but I do not know How can I passing data from javascript codes to My asp.net core codes
My Html jquery css codes Here:
*{
box-sizing: border-box;
}
body{
padding:20px 25px 70px 25px;
}
#all-questions-preview>.content{
display: flex;
flex-direction: column;
}
#all-questions-preview>.content>.question-container{
width:100%;
background: #fefefe;
border-radius: 8px;
box-shadow: 0 1px 5px 1px rgba(0,0,0,0.2);
padding:12px 18px 70px 18px;
position: relative;
margin-bottom:15px;
}
#all-questions-preview>.content>.question-container>.question-title{
color: #444;
font-weight: bold;
}
#all-questions-preview>.content>.question-container>.question-title::before{
content: ":.";
}
#all-questions-preview>.content>.question-container>.close{
position:absolute;
padding:5px;
color: #f02f24;
font-size: 1.3em;
font-weight: bold;
transform: rotate(45deg);
top:10px;
right:10px;
background-color:#f6f6f6;
border:none !important;
outline: none !important;
cursor:pointer;
border-radius:100%;
display: flex;
align-items: center;
justify-content: center;
width: 30px;
height: 30px;
}
#all-questions-preview>.content>.question-container input{
background: none !important;
outline: none !important;
border:none;
font-weight: bold;
}
#all-questions-preview>.content>.question-container .question-sentence{
display:inline-block;
width:100%;
font-size:1.2em;
padding:5px 10px;
border-bottom:2px solid #71c9db;
color: #61adbb;
}
#all-questions-preview>.content>.question-container .answer-span{
display:inline-block;
margin-right:20px;
margin-top:20px;
width:20%;
min-width: 150px;
position: relative;
/*text-align: right;*/
/*border:1px solid red;*/
}
#all-questions-preview>.content>.question-container .answer-input{
display:inline-block;
padding:5px 10px;
border-bottom:2px solid #e171ae;
color: #be3e89;
width:calc(100% - 50px)
}
#all-questions-preview>.content>.question-container .answer-span .close{
position:absolute;
padding:5px;
color: #f02f24;
font-size: 1.2em;
transform: rotate(45deg);
top:15px;
right:22px;
background-color:transparent;
border:none !important;
outline: none !important;
cursor:pointer;
border-radius:100%;
display: flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
}
#all-questions-preview>.content>.question-container .add-answer{
display: inline-block;
margin-top:15px;
background-color: rgba(243, 200, 86, 0.48);
border:2px solid rgb(221, 177, 84);
color: rgb(153, 122, 58);
padding:10px 20px;
border-radius: 5px;
cursor: pointer;
position: absolute;
right:15px;
bottom:10px;
}
#all-questions-preview> .add-question{
display: inline-block;
background-color: rgba(60, 243, 71, 0.48);
border:2px solid rgb(69, 198, 59);
color: rgb(32, 114, 31);
padding:10px 20px;
border-radius: 5px;
cursor: pointer;
position: absolute;
margin-top: -62px;
margin-left:10px;
font-weight: bold;
}
#all-questions-preview> .submit{
display: block;
width:90%;
margin:15px auto 15px auto;
background-color: rgba(74, 148, 243, 0.48);
border:2px solid rgb(74, 148, 243);
color: rgb(39, 77, 127);
padding:15px 20px;
font-weight: bold;
box-shadow: 0 5px 5px 1px rgba(61, 122, 200, 0.5);
border-radius: 5px;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="jquery.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="content">
<form action="#" method="post" id="all-questions-preview">
<div class="content">
</div>
<button class="add-question" type="button">Add new question</button>
<br>
<button type="submit" class="submit">Submit</button>
</form>
<form action="test.php" id="all-questions-main" method="post" style="display: none">
<input type="hidden" name="data" id="questions-data">
</form>
</div>
<script>
$(document).ready(function() {
createQuestion($('#all-questions-preview')); //default one question added
$('#all-questions-preview').on('submit', previewFormSubmit);
$('#all-questions-preview .add-question').on('click', addQuestion);
});
function previewFormSubmit(ev) {
ev.preventDefault();
let data = [];
getQuestions($(this)).each(function() {
let question = $(this);
let question_data = {};
question_data['question_sentence'] = question.find('.question-sentence').eq(0).val();
let question_answers = [];
getAnswers(question).each(function() {
let answer = $(this);
let answer_input = answer.find('.answer-input').val();
if (answer_input.trim() !== "") {
question_answers.push(answer_input)
}
});
question_data['question_answers'] = question_answers;
data.push(question_data);
});
$('#all-questions-main>#questions-data').val(JSON.stringify(data));
$('#all-questions-main')[0].submit();
}
function addAnswer(event) {
let question_container = $(this).parents('.question-container').eq(0);
createAnswer(question_container);
}
function createAnswer(question_container) {
let answers = getAnswers(question_container);
let answer_span = $("<span>").addClass('answer-span');
let closeBtn = null;
if (answers.length > 0) {
closeBtn = $("<button>").attr({
type: 'button',
class: 'close'
}).text('+').on('click', deleteAnswer);
}
let answer_input = $("<input>").addClass('answer-input').attr({
type: 'text',
name: 'answer',
placeholder: 'answer' + (answers.length + 1)
});
if (answers.length === 0) {
answer_input.attr('required', 'required')
}
let container_answers = question_container.find('.answers-container').eq(0);
answer_span.append(closeBtn, answer_input);
container_answers.append(answer_span);
return answer_span;
}
function getAnswers(question_container) {
return (question_container.find(".answers-container .answer-span"));
}
function addQuestion(event) {
let all_questions_form = $(this).parents("#all-questions-preview").eq(0);
createQuestion(all_questions_form);
}
function getQuestions(all_question_form) {
return (all_question_form.find('.question-container'));
}
function createQuestion(all_questions_form) {
let all_questions_form_content = all_questions_form.find(">.content").eq(0);
let questions = getQuestions(all_questions_form);
let new_question = $("<div>").addClass('question-container');
let question_title = $("<h4>").addClass('question-title').text('Question number' + (questions.length + 1));
let closeBtn = null;
if (questions.length > 0) {
closeBtn = $("<button>").attr({
type: 'button',
class: 'close'
}).text('+').on('click', deleteQuestion);
}
let question_sentence = $("<input>").addClass('question-sentence').attr({
type: 'text',
name: 'question_sentence',
placeholder: 'question' + (questions.length + 1),
required: 'required'
});
let container_answers = $("<div>").addClass('answers-container');
let add_answer_btn = $("<button>").addClass('add-answer').attr('type', 'button').text('Add answer').on('click', addAnswer);
new_question.append(question_title, closeBtn, question_sentence, container_answers, add_answer_btn);
all_questions_form_content.append(new_question);
createAnswer(new_question);
return new_question;
}
function deleteQuestion() {
let question_container = $(this).parents('.question-container').eq(0);
let all_questions_form = $(this).parents("#all-questions-preview").eq(0);
let questions = getQuestions(all_questions_form);
if (questions.index(question_container) !== 0) {
question_container.fadeOut(200, function() {
$(this).remove();
})
}
}
function deleteAnswer() {
let question_container = $(this).parents('.question-container').eq(0);
let answer_span = $(this).parents('.answer-span').eq(0);
let all_questions_form = $(this).parents("#all-questions-preview").eq(0);
let answers = getAnswers(question_container);
if (answers.index(answer_span) !== 0) {
answer_span.fadeOut(200, function() {
$(this).remove();
})
}
}
</script>
</body>
</html>
In fact I want when The user clicks submit button The Data passes To Asp.net core codes
Please help me, I have been involved in this issue for several days
Thanks
Binding model does not happen in your HTML that is sent to the action method with a submit . You can transfer array question and answer with Ajax.
I find the reason why you can't get the model in backend code.
Because the data you passed is string format, so we can installNewtonsoft.Json library. And deserialize the string to object.
public class list_questions {
public string question_sentence { get; set; }
public List<string> question_answers { get; set; }
}
STEPS
In your .cshtml, you code should like below.
<form action="/ForTest/get_data" id="all-questions-main" method="post" style="display: none">
<input type="hidden" name="data" id="questions-data">
</form>
My /ForTest/get_data method
My test result

Question on element alignment and how cursor is able to stay flush with the text in this editable code textarea?

Looking at this codepen, most of it I grok. But a couple of things I don't understand:
How does the <code> element stay perfectly on top of the <textarea>? I would expect it to be below the textarea looking at the HTML code.
How is the cursor staying so well-aligned with the text such that it functions like the type of cursor in a word document? The cursor even aligns well with the text when I copy and paste the text. Is it the emmet dependency that's helping?
Here is the code:
HTML
<div class="editor-holder">
<ul class="toolbar">
<li><i class="fa fa-indent"></i></li>
<li><i class="fa fa-expand"></i></li>
</ul>
<div class="scroller">
<textarea class="editor allow-tabs"><div class="Editable Textarea">
<h1>This is a fully editable textarea which auto highlights syntax.</h1>
<p>Type or paste any code in here...</p>
<div>
<?php
var simple = "coding";
?>
<script>
with = "Tab or double space functionality";
</script></textarea>
<pre><code class="syntax-highight html"></code></pre>
</div>
</div>
(S)CSS
html, body{
margin: 0;
padding: 0;
height: 100%;
width: 100%;
position: relative;
background: rgb(114, 195, 195);
}
.editor-holder{
width: 800px;
height: 500px;
margin-top: 50px;
border-radius: 3px;
position: relative;
top: 0;
margin-left: -400px;
left: 50%;
background: #1f1f1f !important;
overflow: auto;
box-shadow: 5px 5px 10px 0px rgba(0, 0, 0, 0.4);
transition: all 0.5s ease-in-out;
&.fullscreen{
width: 100%;
height: 100%;
margin: 0;
left: 0;
}
.toolbar{
width: 100%;
list-style: none;
position: absolute;
top: -2px;
margin: 0;
left: 0;
z-index: 3;
padding: 8px;
background: #afafaf;
li{
display: inline-block;
}
a{
line-height: 20px;
background: rgba(144, 144, 144, 0.6);
color: grey;
box-shadow: inset -1px -1px 1px 0px rgba(0,0,0,0.28);
display: block;
border-radius: 3px;
cursor: pointer;
&:hover{
background: rgba(144, 144, 144, 0.8);
}
&.active{
background: rgba(144, 144, 144, 0.8);
box-shadow: none;
}
}
i{
color: #565656;
padding: 8px;
}
}
textarea, code{
width: 100%;
height: auto;
min-height: 450px;
font-size: 14px;
border: 0;
margin: 0;
top: 46px;
left: 0;
padding: 20px !important;
line-height: 21px;
position: absolute;
font-family: Consolas,Liberation Mono,Courier,monospace;
overflow: visible;
transition: all 0.5s ease-in-out;
}
textarea{
background: transparent !important;
z-index: 2;
height: auto;
resize: none;
color: #fff;
text-shadow: 0px 0px 0px rgba(0, 0, 0, 0);
text-fill-color: transparent;
-webkit-text-fill-color: transparent;
&::-webkit-input-placeholder{
color: rgba(255, 255, 255, 1);
}
&:focus{
outline: 0;
border: 0;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
}
code{
z-index: 1;
}
}
pre {
white-space: pre-wrap;
white-space: -moz-pre-wrap;
white-space: -pre-wrap;
white-space: -o-pre-wrap;
word-wrap: break-word;
code{
background: #1f1f1f !important;
color: #adadad;
.hljs {
color: #a9b7c6;
background: #282b2e;
display: block;
overflow-x: auto;
padding: 0.5em
}
.hljs-number,
.hljs-literal,
.hljs-symbol,
.hljs-bullet {
color: #6897BB
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-deletion {
color: #cc7832
}
.hljs-variable,
.hljs-template-variable,
.hljs-link {
color: #629755
}
.hljs-comment,
.hljs-quote {
color: #808080
}
.hljs-meta {
color: #bbb529
}
.hljs-string,
.hljs-attribute,
.hljs-addition {
color: #6A8759
}
.hljs-section,
.hljs-title,
.hljs-type {
color: #ffc66d
}
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #e8bf6a
}
.hljs-emphasis {
font-style: italic
}
.hljs-strong {
font-weight: bold
}
}
}
JavaScript
var tabCharacter = " ";
var tabOffset = 2;
$(document).on('click', '#indent', function(e){
e.preventDefault();
var self = $(this);
self.toggleClass('active');
if(self.hasClass('active'))
{
tabCharacter = "\t";
tabOffset = 1;
}
else
{
tabCharacter = " ";
tabOffset = 2;
}
})
$(document).on('click', '#fullscreen', function(e){
e.preventDefault();
var self = $(this);
self.toggleClass('active');
self.parents('.editor-holder').toggleClass('fullscreen');
});
/*------------------------------------------
Render existing code
------------------------------------------*/
$(document).on('ready', function(){
hightlightSyntax();
emmet.require('textarea').setup({
pretty_break: true,
use_tab: true
});
});
/*------------------------------------------
Capture text updates
------------------------------------------*/
$(document).on('ready load keyup keydown change', '.editor', function(){
correctTextareaHight(this);
hightlightSyntax();
});
/*------------------------------------------
Resize textarea based on content
------------------------------------------*/
function correctTextareaHight(element)
{
var self = $(element),
outerHeight = self.outerHeight(),
innerHeight = self.prop('scrollHeight'),
borderTop = parseFloat(self.css("borderTopWidth")),
borderBottom = parseFloat(self.css("borderBottomWidth")),
combinedScrollHeight = innerHeight + borderTop + borderBottom;
if(outerHeight < combinedScrollHeight )
{
self.height(combinedScrollHeight);
}
}
// function correctTextareaHight(element){
// while($(element).outerHeight() < element.scrollHeight + parseFloat($(element).css("borderTopWidth")) + parseFloat($(element).css("borderBottomWidth"))) {
// $(element).height($(element).height()+1);
// };
// }
/*------------------------------------------
Run syntax hightlighter
------------------------------------------*/
function hightlightSyntax(){
var me = $('.editor');
var content = me.val();
var codeHolder = $('code');
var escaped = escapeHtml(content);
codeHolder.html(escaped);
$('.syntax-highight').each(function(i, block) {
hljs.highlightBlock(block);
});
}
/*------------------------------------------
String html characters
------------------------------------------*/
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
/*------------------------------------------
Enable tabs in textarea
------------------------------------------*/
$(document).delegate('.allow-tabs', 'keydown', function(e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.preventDefault();
var start = $(this).get(0).selectionStart;
var end = $(this).get(0).selectionEnd;
// set textarea value to: text before caret + tab + text after caret
$(this).val($(this).val().substring(0, start)
+ tabCharacter
+ $(this).val().substring(end));
// put caret at right position again
$(this).get(0).selectionStart =
$(this).get(0).selectionEnd = start + tabOffset;
}
});
How does code and textarea elements stay aligned?
They are aligned because in the CSS they both use the same style which outlines the positioning of both elements. They both use position: absolute and the same top and left properties so stay in the same position.
See here https://www.w3schools.com/css/css_positioning.asp
In terms of the z-axis you can see that code has a z-index of 1 while textarea has 2 so text area stays on top.
How is the cursor staying aligned with the text?
There is no javascript acting on the cursor here. If you were to have any textarea in html the cursor would align with the text.

how to run javascript function 'live' without refresh?

im trying to make a average grade calculator, now thats is going fine but now i want to calculate the average immediately when a number gets inputted in one of the fields. I've been trying this with "on(), live(), onkeyup()" but can't get it to work.
The result of the average now displays beneath the inputfields 'onclick' on the button. I want the average displayed there but then as soon as you input numbers in one of the fields it should show there as it now does after the onclick.
What i've tryed with the 'on(), live(), onkeyup()' is to connect them to the input fields and connect them to the calculator() function.
Is there a easy way to do this or a other certain way?
greetings.
function calculator() {
var weight = 0;
var mark = 0;
var weights = document.querySelectorAll('[id^=weight-]');
var grades = document.querySelectorAll('[id^=mark-]');
var trs = document.getElementsByTagName('tr');
var tBody = document.getElementsByTagName('tbody')[0];
var totalWeight = 0;
var totalGrade = 0;
for (var i = 0; i < weights.length; i++) {
totalWeight += +weights[i].value;
}
for (var i = 0; i < grades.length; i++) {
totalGrade += +grades[i].value;
}
var finalGrade=totalGrade/totalWeight;
var display = document.getElementById('output-div');
var newTr = document.createElement('TR');
newTr.innerHTML = `<td><input id="weight-${trs.length + 1}" type="text" size=2 value=""></td><td><input id="mark-${trs.length + 1}" type="text" size=2 value=""></td>`;
tBody.appendChild(newTr);
display.innerHTML='Je gemiddelde is: ' +finalGrade.toFixed(2);
}
html {
background-color: ;
}
header {
background-color: ;
}
h2 {
text-align: center;
}
h3 {
text-align: center;
}
body {
font-family: 'Roboto', sans-serif;
}
table {
margin: auto;
}
tr {
background-color: ;
}
td {
background-color: ;
}
#table-title {
font-size: 20px;
font-style: italic;
text-align: center;
position: relative;
}
input {
text-align: center;
}
[id^="mark"] {
width: 100px;
}
[id^="weight"] {
width: 100px;
}
#calc-btn-div {
position: relative;
width: 150px;
margin: auto;
}
#calc-btn {
position: relative;
padding: 5px;
margin-top: 20px;
}
#calc-btn:hover {
border-color: black;
box-shadow: 8px 8px 8px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19);
}
/* #add-input-div {
height: 50px;
text-align: center;
width: 300px;
margin: auto;
margin-top: 20px;
}
#add-input-btn {
position: relative;
padding: 5px;
margin-top: 20px;
}
#add-input-btn:hover {
border-color: black;
box-shadow: 8px 8px 8px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19);
} */
#output-div {
background-color: ;
height: 50px;
text-align: center;
width: 300px;
margin: auto;
margin-top: 20px;
}
/* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Content/Box */
.modal-content {
background-color: #fefefe;
margin: 15% auto; /* 15% from the top and centered */
padding: 20px;
border: 1px solid #888;
width: 80%; /* Could be more or less, depending on screen size */
}
/* The Close Button */
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
</head>
<header>
<h2>Gemiddelde cijfer</h2>
<h3>Voer hieronder je cijfers in</h3>
</header>
<body>
<table id="table">
<tr id="table-title">
<td>Weging</td>
<td>Cijfer</td>
</tr>
<tr>
<td><input id="weight-1" type="text" size=2 value=""></td>
<td><input id="mark-1" type="text" size=2 value=""></td>
</tr>
</table>
<div id="calc-btn-div">
<input id="calc-btn" type="button" value="Berekenen je gemiddelde" onclick="calculator()">
</div>
<!-- <div id="add-input-div">
<input id="add-input-btn" type="button" value="Voeg cijfer toe" onclick="addInput()">
</div> -->
<div id="output-div"></div>
</body>
</html>
Using vanilla JavaScript I would attach an eventListener to the inputfields like this
document.getElementById('weight-1').addEventListener('change',function(){
calculator();
});
document.getElementById('mark-1').addEventListener('change',function(){
calculator();
});
These addEventListener functions adds listeners to the "input" field's predefined 'change'-events, and fires the calculator(); function from your code.
Seeing that you are using some sort of dynamic generation of the inputfields, you could add the listeners to your inputfields using the same querySelector that you use to target them during calculation. It would mean replacing getElementById('weight-1') in my example above with querySelectorAll('[id^=weight-]') for the weight-fields.
Also, doing work with values, IO, and calculation between html and JavaScript, I would suggest using a library like jQuery. jQuery simplifies these processes a lot.
This is the documentation for the jQuery alternative onClick function:
https://api.jquery.com/change/
I think you could do that with an angularJS module. Take a look at this tutorial : https://www.w3schools.com/angular/angular_modules.asp
maybe it will help.

Responsive HTML form

I am using the following css code:
html {
background: #2B2B2B url(images/bg.gif) repeat;
}
body {
max-width: 1000px;
margin: 0px auto;
font-family: sans-serif;
margin: 0 auto;
}
header,
footer,
aside {
display: block;
}
h1 {
text-align: center;
color: rgba(0, 0, 0, 0.6);
text-shadow: 2px 8px 6px rgba(0, 0, 0, 0.2), 0px -5px 35px rgba(255, 255, 255, 0.3);
text-decoration: underline;
}
label {
display: block;
}
fieldset {
border: 0px dotted red;
width: 400px;
margin: 0 auto;
}
input,
select {
width: 400px;
height: 30px;
border-radius: 5px;
padding-left: 10px;
font-size: 14px;
}
select {
line-height: 30px;
background: #f4f4f4;
}
button {
font-size: 14px;
padding: 5px;
background: #333333;
color: #FFFCEC;
float: right;
width: 100px;
}
button:hover {
font-size: 16px;
}
#edit {
background: #DC5B21;
}
#delete {} #course,
#name,
#profesor,
#subject {
background: #ABDCD6;
}
label {
font-size: 15px;
font-weight: bold;
color: #282827;
}
table {
border-spacing: 0.5rem;
border-collapse: collapse;
margin: 0 auto;
background: #ABDCD6;
}
th {
background: #E9633B;
}
th,
td {
border: 2px solid black;
padding: 10px;
}
td {
font-weight: bold;
font-style: oblique;
}
tr:nth-child(even) {
background: #ABDCD6
}
tr:nth-child(odd) {
background: #DCD8CF
}
.container {
width: 1000px;
margin: 0 auto;
}
.headerbar {
width: 988px;
float: left;
}
.headerbar.top {
background: linear-gradient(45deg, rgba(255, 102, 13, 1) 3%, rgba(255, 109, 22, 1) 32%, rgba(255, 121, 38, 1) 77%, rgba(255, 121, 38, 1) 100%);
min-height: 100px;
border-radius: 19px 30px 0px 0px;
box-shadow: #938D94 7px 7px 5px;
}
.headerbar.bottom {
background: linear-gradient(45deg, rgba(255, 102, 13, 1) 3%, rgba(255, 109, 22, 1) 32%, rgba(255, 121, 38, 1) 77%, rgba(255, 121, 38, 1) 100%);
min-height: 60px;
border-radius: 25px;
border-radius: 0px 0px 37px 34px;
box-shadow: #938D94 7px 1px 5px;
}
.leftbar {
width: 50%;
background: #EB593C;
min-height: 605px;
float: left;
border-radius: 4px;
border: 3px dashed #282827;
}
.rightbar {
width: 47%;
background: #221E1D;
min-height: 595px;
float: left;
padding: 5px;
border: 2px solid #EB593C;
box-shadow: #938D94 5px 5px 5px;
}
#submit,
#clear {
border-radius: 25px;
}
input:focus {
border: 1px solid #FF9933;
}
#media screen and (max-width: 700px) {
.leftbar,
.rightbar {
float: none;
}
.headerbar.top h1 {
margin-left: 50px;
text-align: center;
float: left;
}
and here is my HTML page very simple
<!DOCTYPE html>
<html>
<head>
<title>My web app</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="mystyle2.css" rel="stylesheet"/>
<script>
var studentsArray = [];
var selectedIndex = -1;
function init() {
document.getElementById("tablerows").innerHTML = "";
if (localStorage.studentsRecord) {
studentsArray = JSON.parse(localStorage.studentsRecord);
for (var i = 0; i < studentsArray.length; i++) {
prepareTableCell(i, studentsArray[i].course, studentsArray[i].name, studentsArray[i].profesor, studentsArray[i].subject);
}
}
}
function onRegisterPressed() {
if(validate()){
var course = document.getElementById("course").value;
var name = document.getElementById("name").value;
var profesor = document.getElementById("profesor").value;
var subject = document.getElementById("subject").value;
var stuObj = {course: course, name: name, profesor: profesor, subject: subject};
if (selectedIndex === -1) {
studentsArray.push(stuObj);
} else {
studentsArray.splice(selectedIndex, 1, stuObj);
}
localStorage.studentsRecord = JSON.stringify(studentsArray);
init();
onClarPressed();
}else{
}
}
function prepareTableCell(index, course, name, profesor, subject) {
var table = document.getElementById("tablerows");
var row = table.insertRow();
var courseCell = row.insertCell(0);
var nameCell = row.insertCell(1);
var profesorCell = row.insertCell(2);
var subjectCell = row.insertCell(3);
var actionCell = row.insertCell(4);
courseCell.innerHTML = course;
nameCell.innerHTML = name;
profesorCell.innerHTML = profesor;
subjectCell.innerHTML = subject;
actionCell.innerHTML = '<button id="edit" onclick="onEditPressed(' + index + ')">Edit</button><br/><button id="delete" onclick="deleteTableRow(' + index + ')">Delete</button>';
}
function deleteTableRow(index) {
studentsArray.splice(index, 1);
localStorage.studentsRecord = JSON.stringify(studentsArray);
init();
}
function onClarPressed() {
selectedIndex = -1;
document.getElementById("course").value = "";
document.getElementById("name").value = "";
document.getElementById("profesor").value = "";
document.getElementById("subject").value = "Math";
document.getElementById("submit").innerHTML = "Register";
}
function onEditPressed(index) {
selectedIndex = index;
var stuObj = studentsArray[index];
document.getElementById("course").value = stuObj.course;
document.getElementById("name").value = stuObj.name;
document.getElementById("profesor").value = stuObj.profesor;
document.getElementById("subject").value = stuObj.subject;
document.getElementById("submit").innerHTML = "Update";
}
function validate(){
var errors = [];
var re = /^[\w]+$/;
var id = document.getElementById("course");
if(id.value==="" ){
errors.push("Course name is empty");
}else if(id.value.length<3){
errors.push("Course name is to shoort");
}else if(!re.test(id.value)){
errors.push("Input contains invalid characters");
}
var name = document.getElementById("name");
var regEx = /^[a-zA-Z ]+$/;
if(name.value===""){
errors.push("Name cannot be empty");
}else if(!regEx.test(name.value)){
errors.push("Name contains invalid characters");
}
var profesor = document.getElementById("profesor");
if(profesor.value===""){
errors.push("Professor field cannot be empty");
}else if(!regEx.test(profesor.value)){
errors.push("Professor field contains invalid characters");
}
if(errors.length>0){
var message = "ERRORS:\n\n";
for(var i = 0;i<errors.length;i++){
message+=errors[i]+"\n";
}
alert(message);
return false;
}
return true;
}
</script>
</head>
<body onload="init()">
<header class="headerbar top"><h1>ITEC3506: Assignment#2</h1></header>
<aside class="leftbar">
<div>
<fieldset>
<label for="course"><span>Course Name</span></label>
<input type="text" placeholder="enter name of course" id="course">
</fieldset>
<fieldset>
<label for="name">Your Name</label>
<input type="text" placeholder="enter your name" id="name">
</fieldset>
<fieldset>
<label for="profesor">Course Professor</label>
<input type="text" placeholder="enter course Professor" id="profesor">
</fieldset>
<fieldset>
<label for="subject">Subject</label>
<select id="subject">
<option value="Math">Math</option>
<option value="Physics">Physics</option>
<option value="Chemistry">Chemistry</option>
<option value="English">English</option>
<option value="CS">CS</option>
</select>
</fieldset>
<fieldset>
<label for="submit"> </label>
<button id="submit" onclick="onRegisterPressed()">Submit</button>
<button id="clear" onclick="onClarPressed()">Clear</button>
</fieldset>
</div>
</aside>
<aside class="rightbar">
<table id="regtable">
<thead>
<tr>
<th>Course</th>
<th>Student</th>
<th>Professor</th>
<th>Subject</th>
<th>Action</th>
</tr>
</thead>
<tbody id="tablerows">
</tbody>
</table>
</aside>
<footer class="headerbar bottom"></footer>
</div>
</body>
</html>
My question is how can I transform this code into a responsive site.
Everything is resizing normally, except I cannot seem to resize my table and form. Could somebody help me?
A few things going on here.
First, you don't have a set width on a few of your fields, so change:
fieldset{
border: 0px dotted red;
width: 400px;
margin: 0 auto;
}
to:
fieldset{
border: 0px dotted red;
width: 400px;
margin: 0 auto;
max-width: 100%;
}
Also change .headerbar from width: 988px; to width: 100%;.
For responsive frameworks, you need to ensure that you never have a set a fixed width without ensuring there is a max-width attached to it, otherwise your content size will never drop below the size of your fixed width.
Second, I noticed the following:
.leftbar{
width: 50%;
background: #EB593C;
min-height: 605px;
float: left;
border-radius: 4px;
border: 3px dashed #282827;
}
You didn't specifically call this out, but when I check your code in a smaller view, I notice that your width: 50%; is causing the backgrounds to look off, which does not seem to be your intention. I would recommend adding .leftbar { width: 100%; } as well as .rightbar { width: 100%; } inside of #media screen and (max-width:700px){
That just leaves the table. Tables do not automatically break down, so are generally not something we want to use when developing a responsive site, but of course sometimes there is no getting around this.
There are a few ways to tackle the issue with the table. One is to set the table to display:block; and apply overflow-x: scroll; to it inside of your #media screen and (max-width:700px){, which will allow the user to scroll left/right when viewing it from smaller screens. Another is to use one of the various Javascript plugins that can achieve this.
Hope this helps get you on the right track. Best of luck!
Do not set width for these
input,select{/*width: 400px;*/}
fieldset{/*width: 400px;*/}
If you are setting width obviously you cannot obtain a responsive layout

Categories

Resources