Differ between 2 or more click events called from javascript code - javascript-events

var option,
Switch (option)
{
case "A":
document.getElementById("cell").click();
break;
case "B":
document.getElementById("cell").click();
break;
default:
break;
},
clickEventHandlerForCell(event){
//When case A
alert("I am fired from case A");
// When case B
alert("I am fired from case B");
}
A button is clicked from Javascript code. How to send a value to the handler function to tell, from where it was called? I read that there is a method to tell the difference between the real click and fake click. But I couldn't find a question differing 2 fake links.'Pure'Javascript is preferable. Thanks.

What I thought you meant
The event object holds what was clicked. So you can handle the data that way.
function clicked(event) {
console.log(event.target);
console.log(event.target.getAttribute("data-item"));
}
document.getElementById("tab").addEventListener("click", clicked);
var tds = document.getElementsByTagName("td");
tds[0].click();
tds[1].click();
<table id="tab">
<tbody>
<tr>
<td data-item="1">1</td>
<td data-item="2">2</td>
</tr>
</tbody>
</table>
What you actually wanted
function clicked(event) {
console.log(event.target.getAttribute("data-action"));
event.target.removeAttribute("data-action");
}
document.getElementById("tab").addEventListener("click", clicked);
var tds = document.getElementsByTagName("td");
tds[0].setAttribute("data-action", "A");
tds[0].click();
tds[0].setAttribute("data-action", "B");
tds[0].click();
<table id="tab">
<tbody>
<tr>
<td>1</td>
</tr>
</tbody>
</table>

Related

data not displaying in table in vuejs

i have created vue file to display data in frontend. but i'm unable to print 2 tables on same page at same time. only table 2 is displaying data , in first table it shows data for 2 seconds and than disappears. what i'm doing wrong? please help. i am super new in vuejs and have not much knowledge.
here is my index.vue file,
Table 1
<tbody>
<tr
v-show="items && items.length"
v-for="(data, i) in items"
:key="i">
<td></td>
<td></td>
</tr>
and this is function code,
async fetchData1() {
this.$store.state.operations.loading = true;
let currentPage = this.pagination ? this.pagination.current_page : 1;
await this.$store.dispatch("operations/fetchData", {
path: "/api/calldata?page=",
currentPage: currentPage + "&perPage=" + this.perPage,
});
table 2
<tbody>
<tr
v-show="items && items.length"
v-for="(data, i) in items"
:key="i">
<td></td>
<td></td>
</tr>
and here is the function for table 2
async fetchData2() {
this.Loading2 = true
let currentPage = this.Pagination2 ? this.Pagination2.current_page : 1;
await this.$store.dispatch("operations/fetchData", {
path: "/api/datacall/data2?page=",
currentPage: currentPage + "&perPage=" + this.perPage,
});
this.Loading2 = false;
and this are the controller functions
public function index(Request $request)
{
return DataResource::collection(Datamodl::with('user')->where('type',1)->latest()->paginate($request->perPage));
}
public function index2(Request $request)
{
return DataResource::collection(Datamodl::with('user')->where('type',0)->latest()->paginate($request->perPage));
}
And Route ,
Route::get('/calldata/data2', [DataController::class, 'index2']);
Route::apiResource('calldata', DataController::class);
Observation : You are updating same variable which is items for both the tables. Hence, it is overriding the latest items with the old items array.
Solution : Here is the implementation as per my comment.
new Vue({
el: '#app',
data: {
table1Items: null,
table2Items: null
},
mounted() {
this.fetchData1();
this.fetchData2();
},
methods: {
fetchData1() {
this.table1Items = [{
id: 1,
name: 'table 1 alpha'
}, {
id: 2,
name: 'table 1 beta'
}]
},
fetchData2() {
this.table2Items = [{
id: 1,
name: 'table 2 alpha'
}, {
id: 2,
name: 'table 2 beta'
}]
}
}
})
table, th, td {
border: 1px solid black;
margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<table>
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr v-show="table1Items" v-for="(data, i) in table1Items" :key="i">
<td>{{ data.id }}</td>
<td>{{ data.name }}</td>
</tr>
</tbody>
</table>
<table>
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr v-show="table2Items" v-for="(data, i) in table2Items" :key="i">
<td>{{ data.id }}</td>
<td>{{ data.name }}</td>
</tr>
</tbody>
</table>
</div>
you are using same property which is items for both. so second request will changed first items. so in both table same data will visible. you have to store in different state property for different data rendering.
solution :
make another action fetchData2.
call another mutation setItems2. add state propery item2: []. and setItems2 value from this mutation.
render second table like this.
<tr
v-show="items2.length"
v-for="(data, i) in items2"
:key="i">
<td></td>
<td></td>
</tr>
For code quailty:
give proper and related variable name . don't use items1 and items2 like that.
never used v-if/v-show and v-for in same element.for more info
use template first in this senerio.
use the item's unique id instead of the index in the key.
if you take the items default value as [], instead of null, then you only required to check items.length instead of items && items.length. so always use list default value []
if both requests are not dependent on each other then you should use Promise.all() for fetching data concurrently. which saved tremendous time and also in this case you don't require two loading property.

Vue3 + DataTables redraw the table after delete

I have a Vue3 component that renders tables based on model data. Then I add DataTables functionality to the table to be able to filter and sorting data. Everything works fine. But if I click on the delete button I need to send a delete ajax request to the server and then on success redraw the whole table with new data. I tried to use draw() method but it does not work. Deleted rows are still in the table. I don't know if I need to remove the whole table and create it again or there is another solution.
This is the Vue template code.
<template>
<div class="table-responsive">
<table :id="id" class="table table-bordered nowrap" width="100%;">
<thead>
<tr>
<th>id</th>
<th>Title</th>
<th>Visible</th>
<th>User</th>
<th></th>
</tr>
</thead>
<tbody>
<tr v-for="article in articles" :key="article.id">
<td>{{article.id}}</td>
<td>{{article.title}}</td>
<td>{{article.visible}}</td>
<td>{{article.user.name}}</td>
<td>
delete
</td>
</tr>
</tbody>
</table>
</div>
</template>
And this is the deleteArticle() code
deleteArticle(id) {
axios.get( apiRoutes.ARTICLE_DELETE_URL + id )
.then( response => {
this.getArticles();
})
.catch( response => {
console.log(response);
});
},
getArticles()
{
axios.get( apiRoutes.ARTICLES_URL )
.then((response) => {
this.articles = response.data.articles;
this.$nextTick(function() {
this.setDataTable();
});
})
.catch((response) => {
console.log(response);
});
},
setDataTable() {
var table = $('#'+this.id);
if( this.dataTableObject )
{
this.dataTableObject.reload().draw(); // This is the code I need to fix
return;
}
...
},
What is the right flow of this component?

laravel vue send array to backend

I want to send array of id's to backend with one button from vuejs table but i get error 500.
Logic
Check the check boxes
Collect the id's
Send id's to back-end when click on button
update the view
Code
template
<table class="table table-dark table-hover table-bordered table-striped">
<thead>
<tr>
<th class="text-center" width="50">
//the button
<button class="btn btn-outline-danger" #click="withdraw(index)">Withdraw</button>
</th>
<th class="text-center" width="50">#</th>
<th class="text-center">Amount</th>
</tr>
</thead>
<tbody>
<tr v-for="(income,index) in incomes" v-bind:key="index">
<td class="text-center">
//check box input
<input v-if="income.withdraw == '0'" type="checkbox" :id="income.id" :value="income.amount" v-model="checkedNumbers">
</td>
<td class="text-center">{{index+1}}</td>
<td class="text-center">Rp. {{formatPrice(income.amount)}}</td>
</tr>
<tr>
<td colspan="2"></td>
<td>
<span>Withdraw for today, Sum: <br> Rp. {{ formatPrice(sum) }}</span>
</td>
</tr>
</tbody>
</table>
script
export default {
data() {
return {
incomes: [],
checkedNumbers: [],
}
},
computed: {
sum() {
return this.checkedNumbers.reduce(function (a, b) {
return parseInt(a) + parseInt(b);
}, 0);
}
},
methods: {
withdraw(index) {
let checkedids = this.incomes[index]
axios.post(`/api/withdrawbutton/`+checkedids).then(response => {
this.income[index].withdraw = '1'
this.$forceUpdate()
});
}
}
}
route
Route::post('withdrawbutton/{id}', 'IncomeController#withdrawbutton');
controller
public function withdrawbutton($id)
{
$dowithdraw = Income::where('id', $id)->get();
$dowithdraw->withdraw = '1';
$dowithdraw->save();
return response()->json($dowithdraw,200);
}
Any idea where is my mistake and how to fix it?
......................................................................................................................
Don't send the list as a GET parameter, send it as a POST:
let params = {}
params.ids = this.checkedNumbers
axios.post(`/api/withdrawbutton/`, params)
.then(response => {
this.income[index].withdraw = '1'
this.$forceUpdate()
});
Controller
public function withdrawbutton(Request $request)
{
$dowithdraws = Income::whereIn('id', $request->input('ids', []));
$dowithdraws->update(['withdraw' => '1']);
return response()->json($dowithdraws->get(), 200);
}
Route
Route::post('withdrawbutton/', 'IncomeController#withdrawbutton');
And I don't think you need to update anything in the front because you already have them checked (if you want to keep them checked)

Line break in cell jquery-bootgrid

There is a way to make visible a <br> inside a cell using jquery-bootgrid? Because the render of <br> is not visible.
What I understand is that you want to add a line break in your data, something like this,
In the features column I am passing an array and it displays each Item in a separate row using <br>
For this you can create a custom converter,
http://www.jquery-bootgrid.com/Documentation#converters
You can create the converter when initializing the BootGrid Table
var dt = $('#myTable').bootgrid({
//.......... Other Options
converters: {
listDisplay: {
from: function(value) {
return value;
},
to: function(value) {
// Here you can customise value - I have an Array which I join using <br>
value.sort();
value = value.join("<br/>");
return value;
}
}
}
});
Then all you have to do in the Table HTML is set the data-type on the Column heading
<table id="myTable">
<thead>
<tr>
<th data-column-id="Id" data-visible="false" data-identifier="true" data-type="numeric">Id</th>
<th data-column-id="SelectedFeaturesNames" data-type="listDisplay">Features</th>
<!-- Note the data-type on the Features <th> is listDisplay -->
</tr>
</thead>
<tbody></tbody>
</table>
Did it work using that method?
Yes #Dawood Awan ! It worked for me
PHP:
<td>
<?php
$test = ['b', 'a', 'c'];
echo json_encode($test);
?>
</td>
JS:
to: function(value) {
value = JSON.parse(value); //convert received json to js array.
value.sort();
value = value.join("<br/>");
return value;
}

Simple UI testing a button click with karma and qUnit

I have figured out how to test my code with the karma test runner, but I cannot figure out how to test the UI features on a web page.
I have a simple calculator program (calculator.js):
window.onload = function () {
var okResult = /^.*(\+|\*|-|÷)\d$|^\d$|^.*\d((\+|\*|-|÷)|\d)$/,
i, tds = document.getElementsByTagName("td");
var setResult = function (t) {
document.getElementsByTagName("th")[0].innerHTML = t;
};
var appendResult = function (t) {
document.getElementsByTagName("th")[0].innerHTML += t;
};
var getResult = function () {
return document.getElementsByTagName("th")[0].innerHTML;
};
for (i = 0; i < tds.length; i++) {
tds[i].onclick = function () {
var r;
if (this.innerHTML == '=') {
setResult(eval(getResult().replace(/÷+?/g, '/')));
} else if (this.innerHTML == 'clr') {
setResult("0");
} else if (getResult() == '0') {
setResult(this.innerHTML);
} else {
appendResult(this.innerHTML);
}
if (!okResult.test(getResult())) {
r = getResult();
setResult(r.substring(0, r.length - 1));
}
};
}
};
With this simple table in the HTML DOM (calculator/index.html):
<table>
<tr>
<th id="results" colspan="4">0</th>
</tr>
<tr>
<td colspan="3"> </td>
<td>clr</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
<td>9</td>
<td>÷</td>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td>6</td>
<td>*</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>-</td>
</tr>
<tr>
<td>.</td>
<td>0</td>
<td>=</td>
<td>+</td>
</tr>
</table>
I want to test it by triggering click events on the cells found in the DOM. For example (calculator-spec.js):
test("Calculator initially displays 0", function () {
equal( $('td#results').text(), "0", "Initial display is 0" );
});
test("Calculator can add numbers", function () {
$('td:contains("1")').trigger('click');
$('td:contains("+")').trigger('click');
$('td:contains("1")').trigger('click');
$('td:contains("=")').trigger('click');
equal( $('td#results').text(), "2", "Initial display is 0" );
});
I am trying to automate testing with karma, and in my karma.conf.js file I have:
// frameworks to use
frameworks: ['qunit'],
// list of files / patterns to load in the browser
files: [
'http://code.jquery.com/jquery-1.10.2.min.js',
'**/Examples/Calculator/Complete/calculator.js',
'test/calculator/calculator-spec.js',
{pattern: '**/Examples/Calculator/Complete/index.html', watched: false, included: false, served: true}
],
How do I perform UI testing using karma. How can I simulate mouse and keyboard events and check the resulting DOM using either qUnit or jasmine?
I've had to use the DOM elements click method:
$('td:contains("1")')[0].click();

Resources