how to add input field in react-bootstrap-table2 - react-bootstrap-table

I want to upload a file using react-bootstrap-table but in cell, I am unable to select a file.
Column code:
{
dataField: 'evidenceRef',
text: 'Evidence Ref',
formatter: dataFormatter,
}
formatter code snippet :
function dataFormatter(cell, row) {
return (<div>
<input type="file" multiple="multiple" id="file" onChange={(e)=> showFile(e.target.files[0])} value={selectedFile}/>
<p>{cell}</p>
</div>)
};

Related

input value should update on span value changes once file uploads

After uploading an image file, I want the <input>'s value to reflect my <span> value. However, only after I click the <a> tag does the <input> change its value, not automatically on the <span>'s change as desired.
I want the <span>-change to update the <input>'s value.
<input
v-model="data.filename"
class="input"
type="text"
placeholder
readonly
/>
<b-upload v-model="file">
<span class="ss" v-if="file">{{ file.name }}</span>
<a class="button is-orange has-text-white" #click="valuedata">
<span>Upload</span>
</a>
</b-upload>
export default {
data() {
return {
file: null,
data: {
filename: ''
},
}
},
methods: {
valuedata() {
this.data.filename = this.file.name
}
}
}
The screenshot above shows the results after file upload/selection. While the <span>'s value updates correctly, the <input>'s value however remains the same. Its value updates only after clicking the anchor tag.
The b-upload component has an input event that is fired when a file is selected:
You could add an input-handler that sets data.filename to the selected file's name:
<b-upload #input="onFileSelected">
export default {
methods: {
onFileSelected(file) {
this.data.filename = file.name
}
}
}
demo

Validate submitted form and display errors gracefully

I am trying to validate user submitted form and display meaningful errors, but I have a lot of problems. First of all, my form (event_form.ejs):
<% if (typeof errors !== 'undefined') { %>
<div class="message"><%= errors %></div>
<% } %>
<form method="POST" action="/submit-create-event" id="create-event">
<input type="text" class="title" name="title" placeholder="title">
<input type="text" class="date" autocomplete="off" name="date" placeholder="date">
<select class="type" name="type">
<option value="road">Road</option>
<option value="mtb">MTB</option>
</select>
<input type="text" class="city" name="city" placeholder="city">
<select class="level" name="level">
<option value="beginner">Beginner</option>
<option value="advanced">Advanced</option>
<option value="pro">Pro</option>
</select>
<input type="text" class="start-time timepicker" autocomplete="off" data-time-format="H:i" name="startTime" placeholder="start time">
<input type="text" class="start_location" name="startLocation" placeholder="start location">
<input type="text" class="distance" name="distance" placeholder="distance">
<input type="submit" class="create-event-submit">
</form>
On submit, in my eventController.js I have function to handle submit.
//Helper function to handle event form submit.
module.exports.submitEventForm = function(req, res) {
const event = new eventModel.event({
title: req.body.title,
date: req.body.date,
type: req.body.type,
city: req.body.city,
level: req.body.level,
start_time: req.body.startTime,
start_location: req.body.startLocation,
distance: req.body.distance
});
event.save(function(err, data) {
if (err) {
console.log(err);
//I tried this, kinda works but pretty sure a bad practice
res.render('forms/create_event_form', {errors: err})
} else {
res.render('status/success');
}
});
};
As you can see, on event.save() if I have errors, I console.log() them at the moment. What I tried doing was rendering once again my event creation form and displaying errors (as visible in my .ejs file). Pretty sure it should not be done like that.
This is my model file with one validator
var mongoose = require('mongoose')
var validate = require('mongoose-validator')
var Schema = mongoose.Schema;
var titleValidator = [
validate({
validator: 'isAlphanumeric',
message: 'Title should be alphanumeric'
})
]
var eventSchema = new Schema({
title: {type: String, required: true, validate: titleValidator},
date: {type: String },
type: {type: String },
city: {type: String },
level: {type: String },
start_time: {type: String },
start_location: {type: String },
distance: {type: Number },
});
var Event = mongoose.model('Event', eventSchema);
module.exports.eventSchema = eventSchema;
module.exports.event = Event;
I created titleValidator, and if my form fails, it prints out something like this:
My questions is: How can I properly send my validator message to the template and display it? How to handle multiple messages once more validators are created, as errors are not returned in array manner, meaning I cannot loop through them?
Kinda found a solution. To make error messages more readable and usable, I used Mongoose error helper. It prints out all error messages neatly. However, when getting package via npm there is a bug in code and a pull request is created for a solution, but was never merged. Just make that minor change manually.
I couldn't find another way of rendering the same form with errors, so I sticked to this:
event.save(function(err) {
if (err) {
res.render('forms/create_event_form', {errors: errorHelper(err, next)});
} else {
res.render('status/success');
}
});
and in my .ejs template I print out errors as follows:
<% if (typeof errors !== 'undefined') {
errors.forEach(function(err) { %>
<div class="message"><%= err %></div>
<% })} %>
Hope this helps someone, cheers.

Vee-Validate custom date validation

I was wondering if there is anyway you can write a custom date validation using vee-validate plugin where the end date cannot be less than the start date? I have looked high and low, and there is nowhere I can find a definite answer to this.
If there is no way to implement this, then I can make do without it, however, right now what I have implemented in my template for my start date is:
<input type="text" id="startDate" name="startDate" class="form-control" v-model="startDate" v-validate="'required|date_format:DD-MM-YYYY'" :class="{'input': true, 'is-danger': errors.has('startDate') }">
<label class="mb-0" for="startDate">Start Date</label>
<span v-show="errors.has('startdate')" class="text-danger"><center>{{ errors.first('startdate') }}</center></span>
My script looks like this:
export default {
name: 'App',
data: () => ({
task: '',
startDate: '',
startTime: '',
endDate: '',
endTime: '',
description: 'test'
}),
methods: {
validateBeforeSubmit() {
this.$validator.validateAll().then((result) => {
if (result) {
// eslint-disable-next-line
alert('Form Submitted!');
return;
}
alert('Correct them errors!');
});
}
}
};
But there is no validation that is showing up. I think I am missing something in my script but I am not sure how to implement the date into there. Any help would be greatly appreciated.
First, it's maybe some typo error but in your template you use startDate and startdate lowercased.
Then, to answer your question, it's possible to define a custom validator with a date comparison with vee-validate.
As your chosen date format "DD-MM-YYYY" is not a valid javascript Date format, the string dates need to be rewritten into a valid format to make it work.
Vue.use(VeeValidate)
new Vue({
el: "#app",
data() {
return {
startDate: '',
endDate: '',
}
},
created() {
let self = this
this.$validator.extend('earlier', {
getMessage(field, val) {
return 'must be earlier than startDate'
},
validate(value, field) {
let startParts = self.startDate.split('-')
let endParts = value.split('-')
let start = new Date(startParts[2], startParts[1] -1, startParts[0]) // month is 0-based
let end = new Date(endParts[2], endParts[1] -1, endParts[0])
return end > start
}
})
},
methods: {
validateBeforeSubmit() {
this.$validator.validateAll().then((result) => {
if (result) {
alert('Form Submitted!');
return;
}
alert('Correct them errors!');
});
}
}
})
.is-danger, .text-danger {
color: red;
}
<script src="https://unpkg.com/vee-validate#2.0.0-rc.19/dist/vee-validate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
<div>
<input type="text" name="startDate" v-model="startDate"v-validate="'required|date_format:DD-MM-YYYY'" :class="{'input': true, 'is-danger': errors.has('startDate') }">
<label class="mb-0" for="startDate">Start Date</label>
<span v-show="errors.has('startDate')" class="text-danger">{{ errors.first('startDate') }}</span>
</div>
<div>
<input type="text" name="endDate" v-model="endDate" v-validate="'required|date_format:DD-MM-YYYY|earlier'" :class="{'input': true, 'is-danger': errors.has('endDate') }">
<label class="mb-0" for="endDate">End Date</label>
<span v-show="errors.has('endDate')" class="text-danger">{{ errors.first('endDate') }}</span>
</div>
<button #click="validateBeforeSubmit">Save</button>
</div>
Note: i put the custom validator inside the created hook for the example but you can put it inside any file you want in your projet. Just import it correctly as the documentation recommends.

Watch date input value and use it with v-model

I tried for 4 days to get a stupid date from the input, that the user selected. Looks probably simple but believe me that I ask here because I run out of solutions.
I have a page/component AddNewEvent and inside this input where the user adds the date and time. I have to get it in my v-model so I can send it back to database.
I use bootstrap 4 input type="datetime-local" to get the date and time. I tried to use some vue plugins for date but all are based on bootstrap 3 and in the project is bootstrap 4.
Inside template:
<div class="form-group">
<label class="eda-form-label" for="event-name">Event Name <span>(Max characters number is 60)</span></label>
<input type="text" class="eda-form-input" v-model="newEvent.eventName">
</div>
<div class="form-group">
<label class="eda-form-label" for="exampleTextarea">Event Description <span>(Max characters number is 2000)</span></label>
<textarea class="eda-form-input" rows="3" v-model="newEvent.description"></textarea>
</div>
<div class="form-group">
<div class="row">
<div class="col-6 ">
<label class="eda-form-label" for="start-time">START TIME</label>
<input class="form-control" type="datetime-local" v-model="dateNow">
</div>{{createdDate(value)}}
<div class="col-6">
<label class="eda-form-label" for="end-time">END TIME</label>
<input class="form-control" type="datetime-local" v-model="dateEnd">
</div>
</div>
</div>
In the script:
data() {
return {
dateNow: '',
value: '',
oldValue: ''
}
},
watch: {
dateNow(val, oldVal) {
this.value = val;
this.oldValue = oldVal;
}
},
methods: {
createEvent(){
axios.post("/event", this.newEvent,
{'headers':{'X-AUTH-TOKEN': localStorage.token}},
{'headers':{'Content-Type': 'application/json'}})
.then((response) => {
alertify.success("Success! You added a new the user");
this.$router.push('/events');
})
.catch((response) => {
alertify.error();
})
},
}
If I use in the input, how is right now, v-model="dateNow" works. I can see when I select date, time am/pm shows me the seleted date. But I have to use it like this
v-model="newEvent.dateNow"
v-model="newEvent.dateEnd"
so I can add it to newEvent and send the whole obj back to database.
createdDate is a function that transforms the date in a real date. It's only for testing, because I have to send the date in ms back to database.
Someone please show me what I do wrong, because I'm not so very advance in vuejs.
First you need to initialize dateNow varable in datetime-locale:
data() {
return {
dateNow: new Date().toLocaleString(),
value: '',
oldValue: ''
}
},
It support this format: "2017-09-18T08:30".
I think this will solve your problem.
And also you need to check Browser compatibility, as it is not supported in IE, Firefox and Safari
or you can try:
<input type="datetime-local" :value="dateValue" #input="updateValue($event.target.value)" >
in script:
data() {
return {
dateValue: new Date().toLocaleString()
};
},
methods: {
updateValue: function(value) {
this.dateValue= value;
this.$emit('input', value);
}
}
Try this

How to get value from YUI3 autocomplete to another input

Using YUI3 and try appending the email part of the search value to another input field.
Everything working fine but don't know how to add the email value to the new input field.
Right now I just appending the value to the body.
Thanks full for any help
Here is my code:
<script type="text/javascript">
YUI().use("autocomplete", "autocomplete-highlighters","autocomplete-filters", "node"
function (Y) {
var anInput= Y.one('#searchUser').plug(Y.Plugin.AutoComplete, {
minQueryLength: 0,
scrollIntoView: true,
circular: false,
activateFirstItem: true,
resultHighlighter: 'phraseMatch',
resultFilters: 'charMatch',
resultListLocator: 'user',
resultTextLocator: function (result_) {
return result_.firstname+ ' ' + result_.lastname+ ' ' + result_.email;
},
source: 'http://localhost:8080/rest/user/jsonp?callback={callback}',
});
anInput.ac.on('select', function (ev) {
Y.one('#email').append('<div>User Email: ' + ev.result.raw.email + '</div>');
});
});
</script>
And here is the HTML:
<input id="searchUser" type="text" class="search" name="searchUser" size="40" value="Enter keywords..." onfocus="if(!this._haschanged){this.value=''};this._haschanged=true;" >
<div id="email">
<input id="email" type="text" name="email" size="40" >
</div>
Here is the problem, I can't get the email value added to the input field
Thanks for any help!
Y.one('#email').set('value', ev.result.raw.email);
https://yuilibrary.com/yui/docs/node/properties.html