How to use <a> instead of a button on express.js post? - javascript

I am using handlebars as my templating engine and I use buttons to call app.post() on my javascript file.
<form method="POST" action="/smo_assessment">
<div class="container" id="div1">
<h3 id="header" align="center">Request Inventory</h3>
<h4 style="color: white">Select the ID of the request you want to make an assesssment</h4>
<table>
<td>
<select class="form-control" style="width: 80px" name="requestID">
{{#each requests}}
<option>{{this.id}}</option>
{{/each}}
</select>
</td>
<td>
<button buttontype="submit" class="btn btn-default" id=btn1>Make Assessment</button>
</td>
</table>
</form>
However, since I am using bootstrap navbar, I need to use a <a> tag instead of a button in order to navigate to a different page.
app.post('/smo_assessment', urlencodedParser, function(req, res){
connection.query('SELECT * FROM requests WHERE id=?', req.body.requestID, function(err, rows, fields){
if(err)
throw err;
else
selectedRequest = rows
res.render('smo_assessment', {assessmentType, data: selectedRequest[0]});
});
});

Try the form.submit() Javascript method:
<form id="theForm" method="POST" action="/smo_assessment">
<div class="container" id="div1">
<h3 id="header" align="center">Request Inventory</h3>
<h4 style="color: white">Select the ID of the request you want to make an assesssment</h4>
<table>
<td>
<select class="form-control" style="width: 80px" name="requestID">
{{#each requests}}
<option>{{this.id}}</option>
{{/each}}
</select>
</td>
<td>
Make Assessment
</td>
</table>
</form>

Add an id to your form and use it into a on-click event:
<form id="myForm">
...
<a class="btn btn-default" onclick="myForm.submit();">Make Assessment</a>
</form>

Related

How to add toast message to a submit button

I am trying to show error messages on toast. I have a form with a submit button as below.
my html form is:
file.html
<form method="post" enctype="multipart/form-data" >
<div class="form-group">
<label>Select Layer Type</label>
<select class="form-control select2" style="width: 100%;">
<option value="vector">Vector Layer</option>
<option value="rasterfile">Raster Image</option>
</select>
</div>
<div class="card-footer"> <button type="submit" class="btn btn-primary toastrDefaultError">Upload File</button></div>
</form>
And js is
$(function () {
$('.select2').select2()
toastr.error('Error...') // I want to display msg from context instead
})
The form action is
menu.html
<li class="nav-item ">
<a href="/fileupload/" class="nav-link">
<i class="nav-icon fas fa-book"></i>
<p> File Upload </p>
</a>
</li>
My python code is
fileupload.py
def file_execution(request):
try:
#something processing
except Exception as Er:
print('Er:',Er)
context['msg'] = 'Some error occured !!'
return render(request,'file.html',context)
urls.py
path('fileupload/', fileupload.file_execution, name='fileupload'),
If I change the button type to type="button", I will get the toastr. How can I add toastr message to my type="submit" button tag.
The click on File Upload menu of menu.html render file.html page.
I want to show the context message in the toastr on submitting the form
You're doing it wrong.
Here you get a toast on button click... no matter what the server answer. No matter if there is a request.
This is not what you want to do.
$(function () {
$('.toastrDefaultError').click(function() {
toastr.error('Error...')
});
})
<button type="submit" class="btn btn-primary toastrDefaultError">Upload File</button>
Change the form to remove the toast
<form method="post" enctype="multipart/form-data" >
<div class="form-group">
<label>Select Layer Type</label>
<select class="form-control select2" style="width: 100%;">
<option value="vector">Vector Layer</option>
<option value="rasterfile">Raster Image</option>
</select>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary">Upload File</button>
</div>
</form>
On submitting, the server do his job and give the same page, with a success message or an error message. I put both in the example but don't code that.
<form method="post" enctype="multipart/form-data" >
<div class="form-group">
<label>Select Layer Type</label>
<select class="form-control select2" style="width: 100%;">
<option value="vector">Vector Layer</option>
<option value="rasterfile">Raster Image</option>
</select>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary">Upload File</button>
</div>
<p class='errorMsg'>There is an error</p>
<p class='successMsg'>There is an error</p>
</form>
Verify everything works correctly, then use this JS
$(function () {
//Find every errorMsg on the page and toast them
$('.errorMsg').each( e => {
const txt = $(e).text();
toastr.error(txt)
})
//Find every successMsg on the page and toast them
$('.successMsg').each( s => {
const txt = $(s).text();
toastr.tost(txt)
})
})

document.getElementById() on a value that is set through a Meteor template

So I've been trying to build a website using Meteor and am quite new with it. I am trying to have javascript that will make use of the values on the page and then create a download from those values. These values differ depending on which page the user is on as the meteor template is loaded with specific information. The way I would think is would work is:
var thing = document.getElementById("tcpout").value;
but when I test this I get "undefined". Now if I don't do .value then do something like
console.log(document.getElementById("tcpout"));
the output in the console is this:
<td id="tcpout"> 50443</td>
where 50443 is the value that I want. Yet I can't seem to figure out how to get that into the javascript. I am using meteor and have tried a few things through meteor's project .js file, but can't seem to figure out how to incorporate dynamic fields into javascript. Essentially I just want to figure out the easiest and best way to work with the mongodb data on the client-side with javascript. Here is the template and the meteor js file.
<template name="profile">
{{#each iotdevice}}
<div class="container" style="margin-top:10px">
<div class="starter-template" align="center">
<h1>{{model}} {{manufacturer}} {{type}}</h1>
<p class="lead"></p>
<table class="table table-bordered">
<thead>
<tr>
<th>Ports</th>
<th>Outgoing</th>
<th>Incoming</th>
</tr>
</thead>
<tbody>
<tr>
<td>TCP</td>
<td id="tcpout"> {{tcpout}}</td>
<td id="tcpin"> {{tcpin}}</td>
</tr>
<tr>
<td>UDP</td>
<td id="udpout"> {{udpout}}</td>
<td id="udpin"> {{udpin}}</td>
</tr>
</tbody>
</table>
<table class="table table-bordered">
<thead>
<tr>
<th colspan="2">Domains</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{domains}}</td>
</tr>
</tbody>
</table>
</div>
<h4 align="center">Select Firewall</h4>
<div align="center">
<button style="margin-bottom:15px" type="button" class="btn btn-outline-danger" onclick="vyosformshow()">
VyOS
</button>
<button style="margin-bottom:15px" type="button" class="btn btn-outline-danger"
onclick="download('test.sh','hello\nworld')">IPTables
</button>
<button style="margin-bottom:15px" type="button" class="btn btn-outline-danger">FreePBX</button>
<button style="margin-bottom:15px" type="button" class="btn btn-outline-danger" onclick="dthings()">IPFire
</button>
<button style="margin-bottom:15px" type="button" class="btn btn-outline-danger">IPCop</button>
</div>
<div id="vyosform" style="display:none">
<form>
<div class="form-row">
<div class="form-group col-md-6">
<label for="exampleInputEmail1">firewall in name</label>
<input class="form-control" id="firein" placeholder="">
</div>
<div class="form-group col-md-6">
<label for="exampleInputPassword1">firewall out name</label>
<input class="form-control" type="text" id="fireout" placeholder="">
</div>
<div class="form-group col-md-6">
<label for="exampleInputPassword1">rule number</label>
<input class="form-control" id="rulenum" placeholder="">
</div>
<div class="form-group col-md-6">
<label for="exampleInputPassword1">device IP address</label>
<input class="form-control" id="ip" placeholder="">
</div>
<div align="center">
<button id="dostuff" class="btn btn-primary" style="margin-bottom:30px">Submit</button>
</div>
</div>
</form>
</div>
</div>
{{/each}}
</template>
JS
if (Meteor.isClient) {
//this code only runs on the client
var directory = Iron.Location.get().path;
var start = directory.lastIndexOf("/");
var stop = directory.search(".html");
var parseddir = directory.slice(start + 1, stop);
var search = directory.slice(start + 1);
var regexsearch = new RegExp(["^", search, "$"].join(""), "i");
console.log(search);
Template.iotprofiler.helpers({
'device': function () {
return DeviceList.find();
}
});
Template.profile.helpers({
'iotdevice': function () {
return DeviceList.find({model: parseddir});
}
});
Template.search.helpers({
'results': function () {
return DeviceList.find({$or: [{model: regexsearch}, {manufacturer: regexsearch}, {type: z}]});
}
});
}

Angular 2 upload Image button is refreshing page

I have a html form with two buttons on it:-
[1] One button is used to upload an image file (.jpg)
[2] and the second one is to submit the form.
The problem is that the upload image button seems to be refreshing the page after the method for uploading the image has completed. Below is my html:-
<div class="m-b-18px">
<div class="col-m-12">
<a (click)="readRecipes()" class="btn btn-primary pull-right">
<span class="glyphicon glyphicon-plus"></span>Read Recipes
</a>
</div>
</div>
<div class="row">
<div class="col-md-12">
<form [formGroup]="create_recipe_form" (ngSubmit)="createRecipe()">
<table class="table table-hover table-responsive table-bordered">
<tr>
<td>
Name
</td>
<td>
<input name="name" formControlName="name" type="text" class="form-control" required />
<div *ngIf="create_recipe_form.get('name').touched && create_recipe_form.get('name').hasError('required')"
class="alert alert-danger">Name is required
</div>
</td>
</tr>
<tr>
<td>
Description
</td>
<td>
<textarea name="description" formControlName="description" class="form-control" required>
</textarea>
<div *ngIf="create_recipe_form.get('description').touched && create_recipe_form.get('description').hasError('required')"
class="alert alert-danger">
Description is required
</div>
</td>
</tr>
<tr>
<td>
Image
</td>
<td>
<input name="selectFile" id="selectFile" type="file" class="form-control btn btn-success" />
<button type="button" class="btn btn-primary" (click)="uploadImage($event)" value="Upload Image">Upload Image</button>
<input type='hidden' id='image_id' name='img_id' value="6" formControlName="image_id" />
</td>
</tr>
<tr>
<td></td>
<td>
<button class="btn btn-primary" type="submit" [disabled]="!create_recipe_form.valid">
<span class="glyphicon glyphicon-plus"></span> Create
</button>
</td>
</tr>
</table>
</form>
</div>
</div>
My code for the uploadImage method is below:-
uploadImage(e) {
let files = this.elem.nativeElement.querySelector('#selectFile').files;
let formData = new FormData();
let file = files[0];
formData.append('selectFile', file, file.name);
this._imageService.uploadImage(formData)
.subscribe(
image => {
console.log(image);
this.addImageIdToHtml(image)
e.preventDefault();
e.stopPropagation();
},
error => console.log(error)
);
}
As soon as the above method has finished running the page appears to refreshing causing my app to go back to the land page. This is not the behaviour I want. What I actually want is the form page to be retained until the Submit form button is pressed. Can anyone help me please?
Use div tags instead of form tag.
Change the button type as button.
<button type="button">Upload Image</button>
Modify the code as follows.
<div class="m-b-18px">
<div class="col-m-12">
<a (click)="readRecipes()" class="btn btn-primary pull-right">
<span class="glyphicon glyphicon-plus"></span>Read Recipes
</a>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div [formGroup]="create_recipe_form" (ngSubmit)="createRecipe()">
<table class="table table-hover table-responsive table-bordered">
<tr>
<td>
Name
</td>
<td>
<input name="name" formControlName="name" type="text" class="form-control" required />
<div *ngIf="create_recipe_form.get('name').touched && create_recipe_form.get('name').hasError('required')"
class="alert alert-danger">Name is required
</div>
</td>
</tr>
<tr>
<td>
Description
</td>
<td>
<textarea name="description" formControlName="description" class="form-control" required>
</textarea>
<div *ngIf="create_recipe_form.get('description').touched && create_recipe_form.get('description').hasError('required')"
class="alert alert-danger">
Description is required
</div>
</td>
</tr>
<tr>
<td>
Image
</td>
<td>
<input name="selectFile" id="selectFile" type="file" class="form-control btn btn-success" />
<button type="button" class="btn btn-primary" (click)="uploadImage($event)" value="Upload Image">Upload Image</button>
<input type='hidden' id='image_id' name='img_id' value="6" formControlName="image_id" />
</td>
</tr>
<tr>
<td></td>
<td>
<button class="btn btn-primary" type="button" [disabled]="!create_recipe_form.valid">
<span class="glyphicon glyphicon-plus"></span> Create
</button>
</td>
</tr>
</table>
</div>
</div>
</div>
You should not upload files on Angular folders like (Assets) , cuz it will recompile every time new file added to Angular environment and that will cause you the page refreshment you didn't want.
If you are using button tag inside the form tag, add type="button" inside the button tag.
<button type="button"></button>
This will work perfectly

Angular2 Javascript Push - Add item to array

I'm building a form in Angular2 which contains a field that is an array of objects. I've so far built the table with a Delete Row button per row and an Add Row button. These use the JavaScript push() and slice() methods.
There is a big bug though:
When adding a new row, the content of the previous rows is deleted.
That is to say, the content of the row is deleted, not the row itself.
Any ideas why?
Component Code:
public addRow(): void {
this.table.push({});
}
public deleteRow(row: object): void {
this.table.splice(this.table.indexOf(row), 1);
}
HTML Template
<form #TimesheetForm="ngForm" (ngSubmit)="saveTimesheet()">
<div class="row">
<div class="col text-right">
<button type="button" class="btn" (click)="addRow()"><i class="fa fa-plus-square" aria-hidden="true"></i> Add Row</button>
</div>
</div>
<table class="table">
<thead>
<td class="table__header">Date</td>
<td class="table__header">Time</td>
<td class="table__header">Actions</td>
</thead>
<tbody>
<tr *ngFor="let row of table">
<td class="table__item">
<input class="input" [(ngModel)]="row.date" name="date">
</td>
<td class="table__item">
<input class="input" [(ngModel)]="row.time" name="time">
</td>
<td class="table__item">
<button type="button" class="btn btn--negative" (click)="deleteRow(row)"><i class="fa fa-times" aria-hidden="true"></i> Delete</button>
</td>
</tr>
<tr *ngIf="school.rows.length == 0">
<td colspan="3">No rows exist yet. Click Add Row to start logging your timesheet.</td>
</tr>
</tbody>
</table>
</div>
<div class="row">
<div class="col">
<button class="btn btn--positive" type="submit"><i aria-hidden="true" class="fa fa-check"></i> Save</button>
</div>
<div class="col text-right">
<button class="btn btn--negative"><i aria-hidden="true" class="fa fa-times"></i> Cancel</button>
</div>
</div>
</form>
With template driven forms, we need to remember that the name attribute needs to be unique, otherwise the fields will be evaluated as the same field. So what your form does now, is not adding new form controls when you add new rows, instead it manipulates the one and same form field. If you were to put something like <pre>{{TimesheetForm.value | json}}</pre> in your template, you can see, that despite pushing new rows, there is only one form control name date and one form control named time.
So what we need to do is to provide an unique name, we can do that by using the index of the items in your table array. So do the following:
<tr *ngFor="let row of table; let i = index">
<td>
<input [(ngModel)]="row.date" name="date{{i}}">
</td>
<td>
<input [(ngModel)]="row.time" name="time{{i}}">
</td>
<!-- more code here -->
</tr>

how to submit a non-form element using angular2

<tbody>
<tr *ngFor="let gasType of staffConfig.gasTypes">
<td class="col-md-3">
<input class="gas-name form-control" type="text" [(ngModel)]="gasType.name" name="gasName"
[disabled]="!isStaffEnabled">
</td>
</tr>
</tbody>
</table>
</div>
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">
<h3 class="panel-title">
<img src="/assets/brand-icon.png">
<span>Brands</span>
</h3>
</div>
<!-- Table -->
<table class="table">
<tbody>
<tr *ngFor="let brand of staffConfig.brands;let i = index;">
<td>
<input class="form-control" type="text" [(ngModel)]="brand.name" name="brands"
[disabled]="!isStaffEnabled">
</td>
</tr>
</tbody>
</table>
</div>
</tab>
<button id="saveChangesBtn" type="button" class="btn btn-primary" disabled>Save Changes</button>
I want to bind the "save" button to a method in the component. So I changed:
<button id="saveChangesBtn" type="button" (ngSubmit)="registerUser(registrationForm.value) class="btn btn-primary" disabled>Save Changes</button>
but then, if that's not a <form> how do I bind the fields to a model?
In other words how can I send these fields to the server?
I have to read them from the component and then assemble an object.
But how can I access the non-form model like registrationForm.value?
If you are using ngModel outside of the <form> you must specify [ngModelOptions]={standalone:true}.
Template
<div class="not-a-form">
<input type="text" [(ngModel)]="model.foo" [ngModelOptions]="{standalone: true}" />
<input type="text" [(ngModel)]="model.bar" [ngModelOptions]="{standalone: true}" />
<button type="button" (click)="save(model)"> Send </button>
</div>
Component
#Component({
selector: 'selector',
...
})
class SomeComponent {
model: any = {};
save(data) {
console.log(data);
}
}

Categories

Resources