Change datatable row controls dynamically - dynamic

I have a datatable in which I add rows dynamically after user clicks on add button. Now my requirement is I dynamically add 2 textboxes and a save button. Once the user clicks on Save button the value entered in the textboxes needs to be save as a label, and the Save button text turned to edit.
If the user clicks edit button, the label needs to be changed to textboxes again and edit button text changed to Save.
Following is my code so far:
function addNewRow() {
$('#addRow').on('click', function () {
t.row.add([
'<input type="text" class="form-control">',
'<input type="text" class="form-control">',
'<button type="button" class="btn green btn-xs select-row" data-id="7" data-includeTax="N">Save</button>'
]).draw();
});
}
var t;
$(document).ready(function () {
t = $('#datatable').DataTable();
});
Any suggestions on the same. Actually the fields are going to be lot more then this, but just want guidance and what should be the approach for this?.
Thanks In Advance!!!.

You can do like this to solve your issue:
$(document).ready(function () {
t = $('#datatable').DataTable();
$('#addRow').on('click', function () {
t.row.add([
'<input type="text" class="form-control text1">',
'<input type="text" class="form-control text2">',
'<button type="button" class="btn green btn-xs select-row save_btn" data-id="7" data-includeTax="N">Save</button>'
]).draw();
});
$('body').on('click', '.save_btn', function (e) {
e.preventDafault();
var _this = $(this);
$.ajax({
type: 'post',
url: 'your url',
data: { 'text1' : $(this).closest('tr').find('.text1').val(), 'text2' : $(this).closest('tr').find('.text2').val() },
dataType : 'json',
})
.done(function (data) {
_this.text('Edit');
_this.addClass('edit_btn');
_this.removeClass('save_btn');
});
return false;
});
$('body').on('click', '.edit_btn', function () {
_this.text('Save');
_this.addClass('save_btn');
_this.removeClass('edit_btn');
});
});

Related

Laravel ajax my column id is not being shown by console.log

Demonstration on how my catagory_id is being read (console.log each time I press the edit button)
$(document).on('click','.edit_category',function (e) {
e.preventDefault();
var cat_id = $(this).val();
console.log(cat_id);
});
My problem is when I try to output the an array shown at the consoles by clicking the edit button (testing purposes)
Not sure how I still get the 404 as the category_id is already defined in the table
blade:
<td>
<button type="button" value="${cat.category_id}" class="edit_category btn btn-outline-secondary"><i class="fas fa-edit"></i> Edit</button>
<button type="button" value="${cat.category_id}" class="delete_category btn btn-outline-secondary"><i class="fas fa-trash"></i> Delete</button>
</td>
ajax:
$(document).on('click','.edit_category',function (e) {
e.preventDefault();
var cat_id = $(this).val();
// console.log(cat_id);
$('#editCategoryModal').modal('show');
$.ajax({
type: "GET",
url: "/bbr-category-configuration-edit/"+cat_id,
success: function (response) {
console.log(response);
}
});
});
controller:
public function edit($category_id) {
$category_edit = HmsBbrCategory::find($category_id);
if ($category_edit)
{
return response()->json([
'status'=>200,
'status'=>$category_edit,
]);
}
else
{
return response()->json([
'status'=>404,
'status'=>'Category Not Found',
]);
}
}
model:
public $timestamps = false;
protected $table = 'hms_bbr_category';
route:
Route::get('/bbr-category-configuration', [BBRCategoryConfigurationController::class,'index']);
Route::get('/bbr-category-configuration-data', [BBRCategoryConfigurationController::class,'fetchcategory']);
Route::post('/bbr-category-configuration', [BBRCategoryConfigurationController::class,'store']);
Route::get('/bbr-category-configuration-edit/{category_id}', [BBRCategoryConfigurationController::class,'edit']);
any advice or input would be appreciated, thankyou

How to get selected value from drop down list in VueJs?

I have one textbox and one dropdownlist here. The dropdownlist list and textbox event works. My problem is how do I get the selected value of the dropdownlist on keyup event? I have google it. It looks different from vanilla javascript approach. I tried to add v-model in the select tag but once I have added it, the dropdownlist no longer works.
new Vue({
el: "#app",
data() {
return {
currency_from_amount: 0,
currencyFromOptions: [],
selected: ''
};
},
methods: {
convert: function(event) {
debugger
}
},
mounted() {
axios
.get("https://openexchangerates.org/api/currencies.json")
.then(response => (this.currencyFromOptions = response.data))
.catch(error => {
console.log(error);
})
.finally(() => (this.loading = false));
}
});
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
<div id="app">
<input class="form-control" type="number" name="currency_from_amount" id="currency_from_amount" v-model="currency_from_amount" #keyup="convert">
<select class="form-control" name="currency_from_code" id="currency_from_code">
<option v-for="(value,key) in currencyFromOptions" :value="key">{{ value }}</option>
</select>
</div>
To set the selected variable, add a change handler as below
<select class="form-control" name="currency_from_code" id="currency_from_code" #change="onSelected($event)">
Write a method as below
onSelected:function(event){
this.selected = event.target.value;
}
Once you set this variable,you can use the same in keyup event

How to update Image in vue

I'm a newbie in vue, I need help to update image, I'm using vform, in below onFileSelected function responsible creating and updating image, I'm successfully creating data with image, but now I'm stack in update the image, here is my code with form structure
Form
<form #submit.prevent="editMode ? update() : store()">
<div class="form-group">
<label for="image" class="font-weight-bold">Image</label>
<input class="form-control" type="file"
:class="{ 'is-invalid': form.errors.has('image') }"
name="image" id="image" accept="image/*"
#change="onFileSelected">
<has-error :form="form" field="image"></has-error>
</div>
</form>
I'm storing like this
onFileSelected(event) {
let file = event.target.files[0];
this.form.image = file;
},
store() {
this.$Progress.start();
this.form.busy = true;
this.form.post('/api/students', {
transformRequest: [function (data, headers) {
return objectToFormData(data)
}],
}).then(response => {
//......
}),
My edit code is
edit(student) {
this.editMode = true;
this.clearForm();
this.form.fill(student);
$('#modal').modal('show');
},
update() {
this.$Progress.start();
this.form.busy = true;
this.form.patch('/api/students/' + this.form.id)
.then(response => {
//.........
})
.catch(e => {})
},
I think your issue is that while your data is updating the render is not. For this you can put a key attribute (with some number or id) on the element that contains the image and then inside the update function once updated change the key like: forceReloadKey++ this will force the component to rerender and update.
Like so:
<form :key="reloadKey" #submit.prevent="editMode ? update() : store()">
...
update() {
...
this.reloadKey++
...

Retrieve data attribute value of clicked element with v-for

I've made a datalist which is filled dynamically and it works correctly.
Now, I need listen the click event on the options to retrieve the data-id value and put it as value in the input hidden.
I already tried with v-on:click.native and #click but there is no response in the console.
Any idea? I'm just starting at Vue, hope you can help me.
Edit:
Looks like it doesn't even fire the function. I've tried v-on:click="console.log('Clicked')" but nothing happens.
<input type="hidden" name="id_discipline" id="id_discipline">
<input list="disciplines" id="disciplines-list">
<datalist id="disciplines">
<option
v-for="discipline in disciplines"
:key="discipline.id_discipline"
:data-id="discipline.id_discipline"
v-on:click="updateDisciplineId($event)"
>{{discipline.name}}</option>
</datalist>
methods: {
updateDisciplineId(event) {
console.log('clicked!);
}
},
Using datalist is not suited for what you want to acheive, however there's a workaround with a limitation.
Template:
<template>
<div>
<input
type="text"
name="id_discipline"
v-model="selectedID"
placeholder="Data id value of clicked"
/>
<input
#input="onChange"
list="disciplines"
id="disciplines-list"
class="form-control"
placeholder="Seleccionar disciplina"
/>
<datalist id="disciplines">
<option
v-for="discipline in disciplines"
:key="discipline.id_discipline"
:data-value="discipline.id_discipline"
>{{ discipline.name }}</option
>
</datalist>
</div>
</template>
Script Part:
<script>
export default {
data() {
return {
selectedID: "",
id_discipline: "",
disciplines: [
{
id_discipline: 1,
name: "Yoga"
},
{
id_discipline: 2,
name: "Functional"
}
]
};
},
methods: {
onChange(e) {
this.getID(e.target.value).then(
resposnse => (this.selectedID = resposnse)
);
},
async getID(value) {
let promise = new Promise((resolve, reject) => {
this.disciplines.forEach(item => {
if (item.name === value) resolve(item.id_discipline);
});
});
return await promise;
}
}
};
</script>
Here's a working Sandbox demo.
**Limitation: Discipline name (Yoga, functional) should be unique.

Performing action when clicking off an element

The below code allows me to have a click-to-edit header tag within my application.
I'm looking for the best way to handle exiting editing mode when any other action is performed on the page... either a click or a drag-n-drop.
<validator name="teamSetValidation">
<input id='teamSetName' v-if="isEditingName" type="text" v-model="teamSet.name" class="semi-bold p-t-10 p-b-10 m-l-15 edit-header" v-on:keyup.enter="saveTeamSetName()" v-on:keyup.esc="doneEditing()" v-validate:name.required.maxlength="teamSetRules" :isEditingName="true"/>
<h3 v-else class="semi-bold p-t-10 p-b-10 m-l-15" v-on:click="editing()" :isEditingName="false">{{ teamSet.name }} <span class="fa fa-edit"></span></h3>
<div class="text-small">
<span class="text-danger" v-if="$teamSetValidation.teamSet.name.required">A name is required.</span>
<span class="text-danger" v-if="$teamSetValidation.teamSet.name.maxlength">The name you provided is too long.</span>
</div>
<div class="b-grey b-b m-t-10"></div>
</validator>
Javascript:
var vm = new Vue({
el: '#page',
data: {
// When true, user can edit the teamSet name
isEditingName: false,
teamSet: teamSet,
teamSetRules: {
required: false,
maxlength: 64
}
},
methods: {
editTeamSetName: function () {
alert('editing');
},
saveTeamSetName: function () {
if(this.$teamSetValidation.valid) {
this.doneEditing();
var teamSet = this.teamSet,
self = this;
$.ajax({
url: '/team/'+teamSet.id,
type: 'PATCH',
data: {
'name': teamSet.name
},
error: function(res) {
Messenger().post({
message: 'Unable to save changes',
type: 'error',
hideAfter: 3
});
self.editing();
}
});
}
},
editing: function () {
this.isEditingName = true;
Vue.nextTick(function () {
$('#teamSetName').focus();
});
},
doneEditing: function () {
this.isEditingName = false;
}
}
});
Attaching a blur event to the input should do the trick:
<input id='teamSetName' v-if="isEditingName"
type="text" v-model="teamSet.name"
class="semi-bold p-t-10 p-b-10 m-l-15 edit-header"
v-on:keyup.enter="saveTeamSetName()"
v-on:keyup.esc="doneEditing()"
v-validate:name.required.maxlength="teamSetRules"
:isEditingName="true" v-on:blur="doneEditing()"
/>