I'm trying to add an image url string to a visitor's Badge property in a database. I have a page where I'm calling an instance of a visitor from a database and then formatting some info from the visitor, screenshotting it, and generating an image url. OnGetAsync works fine, however, I cannot get the url to post to the server during OnPostAsync. I've narrowed the issue down to just the form tag, since when I try to post the data using the form tag method=post, the instance of the visitor is lost, so ModelState is invalid (when form tag is removed, the url is generated, so I know it's not that BadgeDataUrl is null). Why is the visitor instance resetting? I've been searching through other posts, but I'm not seeing anyone with a similar reset problem. I've also tried setting the visitor again in OnPostAsync, but ModelState is still invalid because it sees the properties of the visitor as null (which is strange because when I add a watch for the properties, the data shows up correctly-I'm not sure why ModelState is invalid then).
RegistrationSuccess.cshtml.cs
public async Task<IActionResult> OnGetAsync(string visitorId)
{
if (visitorId == null)
{
return NotFound();
}
Visitor = await _context.Visitor.FirstOrDefaultAsync(m => m.ID.ToString() == visitorId);
if (Visitor == null)
{
return NotFound();
}
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
//Badge processing
var base64Badge = BadgeDataUrl.Split(",")[1];
var binaryBadge = Convert.FromBase64String(base64Badge);
System.IO.File.WriteAllBytes("Badge.jpg", binaryBadge);
Visitor.FutureBadge = BadgeDataUrl;
_context.Attach(Visitor).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!VisitorExists(Visitor.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("/Visitors/RegistrationSuccess");
}
private bool VisitorExists(int id)
{
return _context.Visitor.Any(e => e.ID == id);
}
RegistrationSuccess.cshtml
#page "{visitorId}"
#model VisitorManagementSystem.Pages.Visitors.RegistrationSuccessModel
#{
}
#{
ViewData["Title"] = "Success";
}
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>HTML TO IMAGE</title>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
<script type="text/javascript">
function downloadimage() {
var container = document.getElementById("htmltoimage");; // full page
html2canvas(container, { allowTaint: true }).then(function (canvas) {
var badgeData = canvas.toDataURL("image/jpeg");
$('#BadgeDataUrl').val(badgeData);
});
}
</script>
<style>
#htmltoimage {
width: 65%;
margin: auto;
}
</style>
</head>
<body>
<form method="post">
<br />
<div id="htmltoimage">
<div id="badge" style=" box-sizing: border-box; background-color: white; border: 2px solid black; margin: 50px; padding: 0px; width: 10.15cm; height: 6.096cm">
<div style="text-align:center; float:left; padding:0; float:left; vertical-align:top; background-color:red; color:white; font-family:Arial; font-size:25px; width:10.06cm">
<label>VISITOR</label>
</div>
<div style="float:left">
<img style="margin-left:18px; margin-top:13px; border:1px solid black; width: 3.2cm; height:2.4cm" src="#Model.Visitor.Picture" alt="Visitor Picture" />
<div style="text-align:left; margin-left:15px; margin-top:9px; line-height:0.8; font-size:13px; padding:5px;">
<label>CCI Host:</label><br>
<label id="destinationlabel">#Model.Visitor.Destination</label><br><br />
</div>
</div>
<div style="float:right; margin-top:3px; margin-right:7px; margin-bottom:0px; font-family: Arial; vertical-align:top">
<label id="datelabel">#Model.Visitor.DateCheckedIn.ToShortDateString()</label>
</div>
<div style="float:left; line-height:0.8; vertical-align:top">
<div style="font-size:45px; margin-top: 30px; line-height:0.1; margin-bottom:5px; margin-left:20px; margin-right:0; font-weight: bold;">#Model.Visitor.FirstName</div><br />
<div style="font-size:45px; margin-top: 5px; margin-bottom:10px; margin-left:20px; margin-right:0; font-weight: bold;">#Model.Visitor.LastName</div>
<label id="companynamelabel" style="font-size:18px; margin-left: 20px">#Model.Visitor.CompanyName</label><br>
<label id="titlelabel" style="font-size:18px; margin-left:20px">#Model.Visitor.CompanyTitle</label>
</div>
<div style="padding: 0px; margin: 0px; position: absolute; bottom: 0; left: 0; width: 10.05cm; background-color: red; color: white; font-family: Arial; font-size: 15px; text-align: right">
<label id="bottomredbar"></label>
</div>
</div>
</div>
<button type="submit" onclick="downloadimage()" class="clickbtn" id="downloadButton">Download/Print Badge</button><br />
<div>
#*This is here just to check if the url is generating*#
<input asp-for="#Model.BadgeDataUrl">
</div>
</form>
</body>
I'm a novice, so I appreciate any help!
Edit
Registration.cshtml.cs without ModelState validation:
public class RegistrationSuccessModel : PageModel
{
[BindProperty]
public Visitor Visitor { get; set; }
[BindProperty]
public string BadgeDataUrl { get; set; }
private readonly VisitorManagementSystem.Data.VisitorManagementSystemContext _context;
public RegistrationSuccessModel(VisitorManagementSystem.Data.VisitorManagementSystemContext context)
{
_context = context;
}
public async Task<IActionResult> OnGetAsync(string visitorId)
{
if (!string.IsNullOrEmpty(visitorId))
{
Visitor = _context.Set<Visitor>().FirstOrDefault(i => i.ID.ToString() == visitorId);
}
return Page();
}
public async Task<IActionResult> OnPostAsync(string visitorId)
{
Visitor = _context.Set<Visitor>().FirstOrDefault(i => i.ID.ToString() == visitorId);
var base64Badge = BadgeDataUrl.Split(",")[1];
var binaryBadge = Convert.FromBase64String(base64Badge);
System.IO.File.WriteAllBytes("Badge.jpg", binaryBadge);
Visitor.FutureBadge = BadgeDataUrl;
_context.Attach(Visitor).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!VisitorExists(Visitor.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("/Visitors/RegistrationSuccess");
}
private bool VisitorExists(int id)
{
return _context.Visitor.Any(e => e.ID == id);
}
}
Visitor value set in OnGet method instead of global. So you could not keep it in another request. Besides, you use BindProperty and this attribute is used to bind the value from form in your scenario.
But you use label element which cannot be bound to backend. One way is that you can get elements value by using jquery and post them by ajax(This will be a bit complex if you want to do anything when post back). The other way is to set hidden input for each property.
If you using type="submit" input, it will not hit onclick event. You need change to type="button".
The reference for html2canvas.js makes an error in my project. So I change to:
<script src="https://cdn.jsdelivr.net/npm/html2canvas#1.1.4/dist/html2canvas.min.js"></script>
Here is a whole working demo:
Registration.cshtml:
<head>
<script src="https://cdn.jsdelivr.net/npm/html2canvas#1.1.4/dist/html2canvas.min.js"></script>
<script type="text/javascript">
function downloadimage() {
var container = document.getElementById("htmltoimage");; // full page
html2canvas(container, { allowTaint: true }).then(function (canvas) {
var badgeData = canvas.toDataURL("image/jpeg");
$('#BadgeDataUrl').val(badgeData);
$('form').submit(); //add this...
});
}
</script>
</head>
<body>
<form method="post"> //add hidden input to make form data post successfully....
<input asp-for="Visitor.Destination" hidden />
<input asp-for="Visitor.DateCheckedIn" hidden />
<input asp-for="Visitor.FirstName" hidden />
<input asp-for="Visitor.LastName" hidden />
<input asp-for="Visitor.CompanyName" hidden />
<input asp-for="Visitor.CompanyTitle" hidden />
<input asp-for="Visitor.Picture" hidden />
<br />
<div id="htmltoimage">
<div id="badge" style=" box-sizing: border-box; background-color: white; border: 2px solid black; margin: 50px; padding: 0px; width: 10.15cm; height: 6.096cm">
<div style="text-align:center; float:left; padding:0; float:left; vertical-align:top; background-color:red; color:white; font-family:Arial; font-size:25px; width:10.06cm">
<label>VISITOR</label>
</div>
<div style="float:left">
<img style="margin-left:18px; margin-top:13px; border:1px solid black; width: 3.2cm; height:2.4cm" src="#Model.Visitor.Picture" alt="Visitor Picture" />
<div style="text-align:left; margin-left:15px; margin-top:9px; line-height:0.8; font-size:13px; padding:5px;">
<label>CCI Host:</label><br>
<label id="destinationlabel">#Model.Visitor.Destination</label><br><br />
</div>
</div>
<div style="float:right; margin-top:3px; margin-right:7px; margin-bottom:0px; font-family: Arial; vertical-align:top">
<label id="datelabel">#Model.Visitor.DateCheckedIn.ToShortDateString()</label>
</div>
<div style="float:left; line-height:0.8; vertical-align:top">
<div style="font-size:45px; margin-top: 30px; line-height:0.1; margin-bottom:5px; margin-left:20px; margin-right:0; font-weight: bold;">#Model.Visitor.FirstName</div><br />
<div style="font-size:45px; margin-top: 5px; margin-bottom:10px; margin-left:20px; margin-right:0; font-weight: bold;">#Model.Visitor.LastName</div>
<label id="companynamelabel" style="font-size:18px; margin-left: 20px">#Model.Visitor.CompanyName</label><br>
<label id="titlelabel" style="font-size:18px; margin-left:20px">#Model.Visitor.CompanyTitle</label>
</div>
<div style="padding: 0px; margin: 0px; position: absolute; bottom: 0; left: 0; width: 10.05cm; background-color: red; color: white; font-family: Arial; font-size: 15px; text-align: right">
<label id="bottomredbar"></label>
</div>
</div>
</div>
//change here....
<button type="button" onclick="downloadimage()" class="clickbtn" id="downloadButton">Download/Print Badge</button><br />
<div>
<input asp-for="#Model.BadgeDataUrl">
</div>
</form>
</body>
Related
I write a login form but I can't make it correctly in validation with jQuery.
$(document).ready(function() {
$("#form1").validate({
rules: {
username: {
required: true,
minlength: 6
},
password: {
required: true,
minlength: 5
}
},
messages: {
username: {
required: "name is mandatory"
}
}
});
});
.error {
color: red;
}
p {
font-size: 13px;
font-style: arial;
font-align: left;
}
body {
font-family: calibri, arial, sans-serif;
background-color: powderblue;
margin: 0;
padding: 0;
border: 0;
outline: 0;
}
span.password {
float: right;
padding-top: 50px;
}
.login-form {
margin-top: 5%;
margin-bottom: 5%;
position: relative;
width: 390px;
left: 35%;
height: 500px;
border: 6px solid#ff0000;
padding: 10px;
background-color: #00ffff;
}
.login-form h1 {
font-size: 50px;
text-align: center;
text-transform: uppercase;
margin: 40px;
}
.login-form label {
font-size: 29px;
text-align: right margin:45px;
}
.login-form input[type=text],
.login-form input[type=password] {
font-size: 20px;
width: 350px;
padding: 10px;
border: 0;
outline: none;
border-radius: 5px;
}
.login-form button {
font-size: 16px;
color: white;
background-color: green;
font-weight: bold;
padding: 79px;
width: 60%;
margin: 10px 15px;
padding: 8px 6px;
border: 5px;
cursor: pointer;
}
.login-form button:hover {
border: solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="jquery-validation/dist/jquery.validate.min.js">
</script>
<script src="js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.js"></script>
<div class="login-form">
<h1>LOGIN PAGE</h1>
<form action="#" name="form1" id="form1">
<label for="firstname">First Name</label>
<input type="text" name="firstname" id="firstname" placeholder="username"><br>
<br>
<label for="password">Password</label>
<input type="password" name="password" id="password" placeholder="pswd"><br>
<input name="submit" type="submit" id="submit" class="submit" value="Submit">
<span>
<input type="checkbox" id= "remember" name="remember " value="remember me">
<label for ="checkbox" name="checkbox" >Remember me</label>
</span>
<span class="password">Forget <a href="#" >Password ?</a></span>
</form>
</div>
For your use case, HTML5 validation attributes could be used to validate
In the HTML snippet below required, minlength, pattern and max validation attributes were used.
<form action="#" id="formOne" novalidate>
<div class="FormGroup">
<label for="name">Name</label>
<input
type="text"
class="FormGroup__Input"
name="username"
placeholder="username"
data-v-input
minlength="6"
required
/>
<span class="FormGroup__ErrorLabel"></span>
</div>
<div class="FormGroup">
<label for="password">Password</label>
<input
type="number"
name="password"
class="FormGroup__Input"
placeholder="password"
data-v-input
minlength="5"
required
/>
<span class="FormGroup__ErrorLabel"></span>
</div>
<button type="submit">Submit</button>
</form>
Steps to make this form work
put novalidate attribute on the form element to validate inputs using code (javascript).
Each input element should have a name attribute that should be unique to that input
Add data-v-input attribute to each input element you want to be considered for validation by the javascript.
Put your html5 validation rules on the input elements
To show errors, add an element just below the input element. NOTE: The error label should be the next sibling of the input field.
'use strict';
const formNode = document.querySelector("#formOne");
initValidation(formNode, (form, data) => {
alert(JSON.stringify(data, null, 4))
});
function initValidation(formNode, onSubmitHandler){
const validationErrors = [];
const inputs = formNode.querySelectorAll("[data-v-input]");
const selects = formNode.querySelectorAll("[data-v-select]");
formNode.addEventListener("submit", handleSubmit);
inputs.forEach(input => input.addEventListener("blur", handleBlur));
inputs.forEach(input => input.addEventListener("input", handleInput));
function handleSubmit(evt){
evt.preventDefault();
let formData = {};
if(inputs.length > 0){
inputs.forEach(input => {
validateInput(input);
formData[input.name] = input.value;
});
}
if(selects.length > 0){
selects.forEach(select => {
validateInput(select);
formData[select.name] = select.value;
});
}
if(validationErrors.length === 0){
formNode.reset();
onSubmitHandler(formNode, formData);
}
}
function handleBlur(evt){
validateInput(evt.target);
}
function handleInput(evt){
validateInput(evt.target);
}
function validateInput(inputNode){
if(inputNode.validity.valid){
let inputNodeIndex = validationErrors.indexOf(inputNode.name);
validationErrors.splice(inputNode, 1);
renderErrorLabel(inputNode, false);
} else {
validationErrors.push(inputNode.name);
renderErrorLabel(inputNode);
}
}
function renderErrorLabel(node, show = true){
node.nextElementSibling.textContent = show ? node.validationMessage : "";
}
return true;
}
Copy the initValidation function into your javascript file.
To validate your form, evoke initValidation after DOM loads. It takes two arguments.
a form node: a result of document.getElementById or any of the DOM selectors. However, initValidation takes one form node.
a callback that receives the form node as it's first argument and the form's data as the second argument. Whatever you want to do after validation is complete goes in the body of that callback. NOTE: The callback is only called when all validations were passed and there's no error.
I am new to Blazor and trying to set up an address form to use google place autocomplete. I have done this web and mobile before.
I am not sure how to:
Call the javascript from the blazor component.
Populate the address fields from the selected address.
Save the data in the fields to the backend.
I was able to get working with the code below. For the complete solution see github repo. Here is the demo site.
\Shared\_Host.cshmtl
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOURAPIKEYI&libraries=places"></script>
</head>
\wwwroot\js\serverSideScripts.js
window.initAutocomplete = () => {
let autocomplete;
let address1Field;
let address2Field;
let postalField;
fillInAddress = (autocomplete) => {
// Get the place details from the autocomplete object.
const place = autocomplete.getPlace();
let address1 = "";
let postcode = "";
// Get each component of the address from the place details,
// and then fill-in the corresponding field on the form.
// place.address_components are google.maps.GeocoderAddressComponent objects
// which are documented at http://goo.gle/3l5i5Mr
if (place) {
for (const component of place.address_components) {
const componentType = component.types[0];
switch (componentType) {
case "street_number": {
address1 = `${component.long_name} ${address1}`;
break;
}
case "route": {
address1 += component.short_name;
break;
}
case "postal_code": {
postcode = `${component.long_name}${postcode}`;
break;
}
case "postal_code_suffix": {
postcode = `${postcode}-${component.long_name}`;
break;
}
case "locality":
document.querySelector("#locality").value = component.long_name;
break;
case "administrative_area_level_1": {
document.querySelector("#state").value = component.short_name;
break;
}
case "country":
document.querySelector("#country").value = component.long_name;
break;
}
}
address1Field.value = address1;
postalField.value = postcode;
// After filling the form with address components from the Autocomplete
// prediction, set cursor focus on the second address line to encourage
// entry of subpremise information such as apartment, unit, or floor number.
address2Field.focus();
}
}
address1Field = document.querySelector("#ship-address");
address2Field = document.querySelector("#address2");
postalField = document.querySelector("#postcode");
// Create the autocomplete object, restricting the search predictions to
// addresses in the US and Canada.
autocomplete = new google.maps.places.Autocomplete(address1Field, {
componentRestrictions: { country: ["us", "ca"] },
fields: ["address_components", "geometry"],
types: ["address"],
});
address1Field.focus();
// When the user selects an address from the drop-down, populate the
// address fields in the form.
autocomplete.addListener("place_changed", function () { fillInAddress(autocomplete) });
}
\Pages\GoogleAutoComplete.razor
#page "/AddressAutocompleteForm"
#inject IJSRuntime JSRuntime
<title>Place Autocomplete Address Form</title>
<style type="text/css">
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
body {
font-family: "Roboto", sans-serif;
font-size: 18px;
color: #686868;
}
form {
display: flex;
flex-wrap: wrap;
align-items: center;
max-width: 400px;
padding: 20px;
}
input {
width: 100%;
height: 1.2rem;
margin-top: 0;
padding: 0.5em;
border: 0;
border-bottom: 2px solid gray;
font-family: "Roboto", sans-serif;
font-size: 18px;
}
input:focus {
border-bottom: 4px solid black;
}
input[type="reset"] {
width: auto;
height: auto;
border-bottom: 0;
background-color: transparent;
color: #686868;
font-size: 14px;
}
.title {
width: 100%;
margin-block-end: 0;
font-weight: 500;
}
.note {
width: 100%;
margin-block-start: 0;
font-size: 12px;
}
.form-label {
width: 100%;
padding: 0.5em;
}
.full-field {
flex: 400px;
margin: 15px 0;
}
.slim-field-left {
flex: 1 150px;
margin: 15px 15px 15px 0px;
}
.slim-field-right {
flex: 1 150px;
margin: 15px 0px 15px 15px;
}
.my-button {
background-color: #000;
border-radius: 6px;
color: #fff;
margin: 10px;
padding: 6px 24px;
text-decoration: none;
}
.my-button:hover {
background-color: #666;
}
.my-button:active {
position: relative;
top: 1px;
}
</style>
<!-- Note: The address components in this sample are based on North American address format. You might need to adjust them for the locations relevant to your app. For more information, see
https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-addressform
-->
<form id="address-form" action="" method="get" autocomplete="off">
<p class="title">Sample address form for North America</p>
<p class="note"><em>* = required field</em></p>
<label class="full-field">
<!-- Avoid the word "address" in id, name, or label text to avoid browser autofill from conflicting with Place Autocomplete. Star or comment bug https://crbug.com/587466 to request Chromium to honor autocomplete="off" attribute. -->
<span class="form-label">Deliver to*</span>
<input id="ship-address"
name="ship-address"
required
autocomplete="off" />
</label>
<label class="full-field">
<span class="form-label">Apartment, unit, suite, or floor #</span>
<input id="address2" name="address2" />
</label>
<label class="full-field">
<span class="form-label">City*</span>
<input id="locality" name="locality" required />
</label>
<label class="slim-field-left">
<span class="form-label">State/Province*</span>
<input id="state" name="state" required />
</label>
<label class="slim-field-right" for="postal_code">
<span class="form-label">Postal code*</span>
<input id="postcode" name="postcode" required />
</label>
<label class="full-field">
<span class="form-label">Country/Region*</span>
<input id="country" name="country" required />
</label>
<button type="button" class="my-button">Save address</button>
<!-- Reset button provided for development testing convenience.
Not recommended for user-facing forms due to risk of mis-click when aiming for Submit button. -->
<input type="reset" value="Clear form" />
</form>
#functions {
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await JSRuntime.InvokeVoidAsync("initAutocomplete");
}
}
}
I have a csv file that I load into an 11 column html table. The data displays as expected except there is a very narrow column on the far right. There is also an extra blank row at the bottom. I have made dozens of adjustments to the width percentages but the little column on the right prevails. I haven't tried to eliminate the extra row on the bottom because I don't know what to try. See CSS code.
<title>CSV to HTML5</title>
<style type="text/css">
table {
width: 850px;
display: block;
margin-left: auto;
margin-right: auto;
border: 1px solid black;
border-collapse: collapse;
}
th {
text-align: center;
padding: 6px;
border: 1px solid black;
border-collapse: collapse;
}
tr {
height: 24px;
border: 1px solid black;
}
tr:nth-child(even) {
background-color: #00FFFF;
}
td {
font-family: Arial, Verdana;
font-size: 0.8em;
font-weight: 700;
}
td {
border: 1px solid black;
cellpadding: 3px;
}
td:nth-child(1) {
width: 4%;
text-align: center;
}
td:nth-child(2) {
width: 6%;
text-align: left;
padding-left: 5px;
}
td:nth-child(3) {
width: 14%;
text-align: left;
padding-left: 5px;
}
td:nth-child(4) {
width: 14%;
text-align: left;
padding-left: 5px;
}
td:nth-child(5) {
width: 18%;
text-align: left;
padding-left: 5px;
}
td:nth-child(6) {
width: 6%;
padding-left: 5px;
}
td:nth-child(7) {
width: 5%;
text-align: center;
}
td:nth-child(8) {
width:8%;
text-align: center;
}
td:nth-child(9) {
width: 8%;
text-align: center;
}
td:nth-child(10) {
width: 8%;
text-align: center;
}
td:nth-child(11) {
width:8%;
text-align: center;
</style>
</head>
<body>
<div>
<div>
<legend>
<h1 id="clubname" style="text-align:center"></h1>
<h2 id="racename" style="text-align:center"></h2>
<h3 id="racedate" style="text-align:center"></h3>
</legend>
</div>
<div id="output">
</div>
<div id="myDiv" class="container">
<hr>
<form>
<div class="form-group">
<input type="text" class="form-control" id="inp_clubname" placeholder="Club Name" size="24" required>
<input type="text" class="form-control" id="inp_racename" placeholder="Race Name" size="24" required>
<input type="date" class="form-control" id="inp_racedate" placeholder="Date Name" size="24" required>
<label for="csvFileInput">CSV File: </label>
<input type="file" id="csvFileInput" onchange=accept=".csv" size="35" required>
<input type="button" class="btn btn-primary" onclick="generate()" value="Generate" />
</div>
</form>
<hr>
</div>
</div>
<footer>
<p style="text-align:center">©: Klexy Soft</p>
</footer>
<script type="text/javascript">
function generate() {
console.log('generate called')
//copy text from form to headings
ids = ["clubname", "racename", "racedate"]
for (i in ids) {
value = document.getElementById('inp_' + ids[i]).value
document.getElementById(ids[i]).innerHTML = value
}
files = document.getElementById('csvFileInput').files
// Check for the various File API support.
if (window.FileReader) {
// FileReader are supported.
var reader = new FileReader();
// Read file into memory as UTF-8
reader.readAsText(files[0]);
// Handle errors load
reader.onload = loadHandler;
reader.onerror = errorHandler;
} else {
alert('FileReader is not supported in this browser.');
}
}
function loadHandler(event) {
var csv = event.target.result;
processData(csv);
}
function processData(csv) {
var allTextLines = csv.split(/\r\n|\n/);
var lines = [];
for (var i = 0; i < allTextLines.length; i++) {
var data = allTextLines[i].split(',');
lines.push(data);
}
//console.log(lines);
drawOutput(lines);
}
function errorHandler(evt) {
if (evt.target.error.name == "NotReadableError") {
alert("Canno't read file !");
}
}
function drawOutput(lines) {
//Clear previous data
document.getElementById("output").innerHTML = "";
var table = document.createElement("table");
for (var i = 0; i < lines.length; i++) {
var row = document.createElement("TR");
table.appendChild(row)
for (var j = 0; j < lines[i].length; j++) {
// first row is header
cell = document.createElement(i == 0 ? "TH" : "TD");
row.appendChild(cell)
cell.appendChild(document.createTextNode(lines[i][j]));
}
}
document.getElementById("output").appendChild(table);
document.getElementById("myDiv").style.visibility = "hidden";
}
console.log('initialized')
</script>
</body>
csv file
PL,Sail#,Yacht,Type,Skipper,Club,Rtg,Finish,Elapsed,Cor'ted, 1st +,
1,1234,Boat Name,42MkII,Name,GYC,115,14:10:53,02:00:53,01:46:42,00:00:00,
2,1234,Boat Name,4000,Name,GYC,107,14:16:29,02:06:29,01:53:17,00:06:35,
3,1234,Boat Name,Catalina36MKII,Name,GYC,144,14:26:34,02:16:34,01:58:48,00:12:06,
4,1234,Boat Name,42,Name,GYC,131,14:26:37,02:16:37,02:00:28,00:13:46,
5,1234,Boat Name,Mark3,Name,GYC,218,14:52:01,02:42:01,02:15:08,00:28:26,
6,1234,Boat Name,Nonsuch 30C,Name,GYC,156,14:54:43,02:44:43,02:25:29,00:38:47,
7,1234,Boat Name,KP44,Name,GYC,168,15:25:50,03:15:50,02:55:07,01:08:25,
One of the problems I was having was the java script, function drawOutput(lines) { and the codes that perform the function, generates the table and adds an extra blank row at the bottom, I guess waiting for another line of data. By adding one more line to the java script function code, the very last line, I was able to remove the extra empty row.
document.getElementById("output").appendChild(table).deleteRow(-1);
Hey I am making a website and have recently seen some problems With css. My header div Works great maybe because I have styled it With Width 100%. But my main and side div seems to have some problems with the size. I have a Width of 1288px on my main id and when I checked it it is way less. I want my side div to be 30% of the Width of the page and the main div to be 70% of the page. How can I do this?
Here is my php code:
<?php
$tjener = "localhost";
$brukernavn = "root";
$passord = "";
$database = "searchengine";
$connection = mysqli_connect($tjener,$brukernavn,$passord,$database) or die("could not connect");
$connection->set_charset("utf8");
$output = "";
//collect
if(isset($_POST["q"])) {
$searchq = $_POST["q"];
$searchq = mysqli_real_escape_string($connection,$searchq);
$searchq = htmlspecialchars($searchq);
$query = mysqli_query($connection,"SELECT * FROM products WHERE vareNavn LIKE '%$searchq%' OR desci LIKE '%$searchq%'");
$count = mysqli_num_rows($query);
if($count == 0) {
$output = "There was no search results.";
} else {
while ($row = mysqli_fetch_array($query)) {
$id = $row['vareNr'];
$vareNavn = $row['vareNavn'];
$desci = $row['desci'];
$output .= "<h1>" . $vareNavn . "</h1><p> " . $desci . "</p><br/>";
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="main.css">
<script>
function active(){
var Search = document.getElementById("search");
if(search.value == "Search..."){
search.value = "";
search.placeholder = "Search...";
}
}
function inactive(){
var Search = document.getElementById("search");
if(search.value == ""){
search.value = "Search...";
search.placeholder = "";
}
}
</script>
</head>
<body>
<div id="header">
<div id ="searchBar">
<form action="main.php" method= "post">
<input type="text" id="search" name="q" placeholder="" value="Search..." autocomplete="off" onMouseDown="active();" onBlur="inactive();"/><input type="submit" id="searchButton" value="Search"/>
</form>
</div>
</div>
<div id="main">
<div id="oppstart">
<h1>Newly commenced webstore</h1>
</div>
<div id="klokkeMer">
<h2>Watches</h2>
</div>
<div id="div1">
</div>
<div id="div2">
</div>
<div id="div3">
</div>
<?php
print($output);
?>
</div>
<div id="side">
</div>
</body>
</html>
and here is my css code:
body {
font-family: arial;
}
h1 {
margin: 20px 0px 0px 0px;
padding:0;
}
p {
margin: 0;
padding:0;
}
#header {
width:100%; /* Full lengde*/
background-color:#1F2A40;
height:100px; /* 150px */
position:absolute;
top:0px;
left:0px;
}
#search {
border: 1px solid #1F2A40;
border-right:none;
font-size:16px;
padding:10px;
outline:none;
width:700px;
-webkit-border-top-left-radius:10px;
-webkit-border-bottom-left-radius:10px;
-moz-border-radius-topleft:10px;
-moz-border-radius-bottomleft:10px;
border-top-left-radius:10px;
border-bottom-left-radius:10px;
}
#searchButton {
border: 1px solid #1F2A40;
padding:10px;
font-size:16px;
background-color:#ff9933;
font-weight:bold;
color:#1F2A40;
cursor:pointer;
outline:none;
-webkit-border-top-right-radius:10px;
-webkit-border-bottom-right-radius:10px;
-moz-border-radius-topright:10px;
-moz-border-radius-bottomright:10px;
border-top-right-radius:10px;
border-bottom-right-radius:10px;
}
#searchButton:hover {
background-color:#F5870A;
}
#main {
position:absolute;
top:100px;
background-color:red; // change to white when website is done
width:1288px;
height:800px;
left:300px;
}
#side {
position:absolute;
top:100px;
background-color:orange; // change to white when website is done
width:300px;
left:0px;
height:800px;
}
#searchBar {
position:absolute;
width:800px;
top:8px;
left:250px;
/* border:1px solid red; */
}
#div1 {
position:absolute;
width:100px;
top:200px;
left:300px;
border:1px solid black;
height:100px;
background-color:purple;
}
#div2 {
}
#div3 {
}
Try using percentages for your main and side widths instead of pixels
#side{
width: 30%;
}
#main{
width: 70%;
}
So what I would do is to scrap most of this css, and use Bootstrap
This way you get a clean and easy set of tools to use troughout your webpage.
You include the following in your header:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
After this, then you use this code:
<div id="side" class="col-md-3">
Sidebar
</div>
<div id="main" class="col-md-9 col-md-offset-3">
<div id="oppstart">
<h1>Newly commenced webstore</h1>
</div>
<div id="klokkeMer">
<h2>Watches</h2>
</div>
<div id="div1">
</div>
<div id="div2">
</div>
<div id="div3">
</div>
<?php
print($output);
?>
</div>
See it in action here on jsfiddle
It might not have your exact dimentions, however this gives you a structered set of rules for your CSS you can use troughout your website
I have this html tag which reffers to the backButton provided by the WinJS library:
<button data-win-control="WinJS.UI.BackButton"></button>
I want to change its size. How can I do that? I tried using CSS by adding the ID "backButton" and font-size OR width/height properties, like this:
#backButton {
font-size: small;
}
#backButton {
height: 30px;
width: 30px;
}
EDIT: Code added and a picture of what happens when changing the values of width/height of the button.
// For an introduction to the Page Control template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232511
(function () {
"use strict";
WinJS.UI.Pages.define("/pages/anime/anime.html", {
// This function is called whenever a user navigates to this page. It
// populates the page elements with the app's data.
ready: function (element, options) {
// TODO: Initialize the page here.
this.renderAnimeInfo(Identifier.file);
},
unload: function () {
// TODO: Respond to navigations away from this page.
},
updateLayout: function (element) {
/// <param name="element" domElement="true" />
// TODO: Respond to changes in layout.
},
renderAnimeInfo: function (id) {
// Path for the anime data.
var path = "data/animes.json";
// Retrieve the .json.
WinJS.xhr({ url: path }).then(
function (response) {
var json = JSON.parse(response.responseText);
for (var i = 0; i < json.length; i++) {
if (json[i].file == id) {
var animeData = json[i];
break;
}
}
},
function (error) {},
function (progress) {}
);
},
});
})();
.right {
float: right;
}
.left {
float: left;
}
.active {
background-color: blue;
}
#animeDetails {
background: red;
height: 100%;
width: 300px;
float: left;
}
#animeInfo {
display: -ms-grid;
height: 100%;
width: calc(100% - 300px);
float: right;
}
#navbar {
-ms-grid-row: 1;
padding: 20px 25px;
}
#navbar .right button {
margin-right: 4px;
}
#navbar input {
width: 150px;
}
#details {
-ms-grid-row: 2;
padding: 0 25px;
text-align: justify;
white-space: pre-line;
}
#details h3 {
width: 100%;
padding: 5px 0;
border-bottom: 1px solid #bebebe;
margin-bottom: 0;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>anime</title>
<link href="anime.css" rel="stylesheet" />
<script src="anime.js"></script>
</head>
<body>
<div id="animeDetails"></div>
<div id="animeInfo">
<div id="navbar">
<div class="left">
<button class="left" data-win-control="WinJS.UI.BackButton"></button>
<h3>Back</h3>
</div>
<div class="right">
<button type="button" class="active">Details</button>
<button type="button">Episodes</button>
<button type="button">Characters</button>
<button type="button">Staff</button>
<input type="search" placeholder="Search" />
</div>
</div>
<div id="details">
<div id="synopsis">
<h3>Synopsis</h3>
<span>
</span>
</div>
</div>
</div>
</body>
When using the width/height properties, what happens is that the button does resize to the specified value, but the icon inside (which is not a background) doesn't. http://i.imgur.com/lMqmL0G.png
Possibly you have to set display: inline-block to button because the width of an element with display: inline (the default for buttons) is exactly the same as its content because it only takes up the space needed to display its contents so try with:
With id selector
#backButton {
height: 30px;
width: 30px;
display: inline-block;
}
<button id="backButton" data-win-control="WinJS.UI.BackButton"></button>
With style inline
<button data-win-control="WinJS.UI.BackButton" style="width: 30px; height: 30px; display: inline-block"></button>
Try to set the styles to child element .win-back
#backButton .win-back{
/*---styles---*/
}
You haven't given your button an ID. The CSS does not know what tag to link to.
<button id="backButton" data-win-control="WinJS.UI.BackButton"></button>
edit: you may find the following reference useful CSS Selectors