Hide elements in a Datatables.net table, based on data in another column - datatables

I have a datatable where I recently changed to using the AJAX data source approach.
It works a treat.
I have added three buttons to the first column (works, no problem) and now I want to conditionally display / hide the third button based on the data in another column. I don't want to display the third button if data: PublishStatus = "No shifts created"
I have looked at: https://datatables.net/examples/basic_init/data_rendering.html
but cannot wrap my head around what is needed to twist it to my situation, since the condition is based on a column other than the one that i am using. I could see how to do it if i was placing the button in the PublishStatus column
"ajax": "dt-data_list_wo.asp?mf=d",
"columns": [
{"data": "GUID" , render : function ( data, type, row, meta ) {
return type === 'display' ?
'<span style="display: inline-block;"><form method="POST" action="requestwo.asp"><input type="hidden" name="itemGUID" value="'+ data +'"/><input type="hidden" name="action" value="wodetails" /><button type="submit" class="btn btn-fill btn-info" style="margin-right: 5px">Details</button></form></span><span style="display: inline-block;"><form method="POST" action="prepub.asp"><input type="hidden" name = "itemguid" value = "' + data + '"><input type="hidden" name="action" value="view" /><input type="hidden" name="backlink" value="listwo.asp"/><button type="submit" class="btn btn-fill btn-warning" style="margin-right: 5px">View RS</button></form></span><span style="display: inline-block;"><form method="POST" action="prepub.asp"><input type="hidden" name = "itemguid" value = "' + data + '"><input type="hidden" name="action" value="publish_shifts" /><button type="submit" class="btn btn-fill btn-danger">Publish</button></form></span>': data;
}},
{ "data": "PublishStatus" },
{ "data": "orgname" },
{ "data": "woref" },
{ "data": "weeknum" },
{ "data": "startdate" },
{ "data": "client_po" },
{ "data": "work_desc" }
],

So, thanks to andrewjames, the solution involved a couple of changes to my original code - i have commented out the parts that prevented it from working and the if clause with row.PublishStatus really did the trick. Made my weekend!
"ajax": "dt-data_list_wo.asp?mf=d",
"columns": [
{"data": "GUID" , render : function ( data, type, row, meta ) {
//return type === 'display' ?
if (row.PublishStatus == "All shifts published" || row.PublishStatus == "No shifts created yet") {
return '<span style="display: inline-block;"><form method="POST" action="requestwo.asp"><input type="hidden" name="itemGUID" value="'+ data +'"/><input type="hidden" name="action" value="wodetails" /><button type="submit" class="btn btn-fill btn-info" style="margin-right: 5px">Details</button></form></span><span style="display: inline-block;"><form method="POST" action="prepub.asp"><input type="hidden" name = "itemguid" value = "' + data + '"><input type="hidden" name="action" value="view" /><input type="hidden" name="backlink" value="listwo.asp"/><button type="submit" class="btn btn-fill btn-warning" style="margin-right: 5px">View RS</button></form></span>'//: data;
} else {
return '<span style="display: inline-block;"><form method="POST" action="requestwo.asp"><input type="hidden" name="itemGUID" value="'+ data +'"/><input type="hidden" name="action" value="wodetails" /><button type="submit" class="btn btn-fill btn-info" style="margin-right: 5px">Details</button></form></span><span style="display: inline-block;"><form method="POST" action="prepub.asp"><input type="hidden" name = "itemguid" value = "' + data + '"><input type="hidden" name="action" value="view" /><input type="hidden" name="backlink" value="listwo.asp"/><button type="submit" class="btn btn-fill btn-warning" style="margin-right: 5px">View RS</button></form></span><span style="display: inline-block;"><form method="POST" action="prepub.asp"><input type="hidden" name = "itemguid" value = "' + data + '"><input type="hidden" name="action" value="publish_shifts" /><button type="submit" class="btn btn-fill btn-danger">Publish</button></form></span>'//: data;
}
}},
{ "data": "PublishStatus" },
{ "data": "orgname" },
{ "data": "woref" },
{ "data": "weeknum" },
{ "data": "startdate" },
{ "data": "client_po" },
{ "data": "work_desc" }
],

Related

Why my vuejs wallpaper calculator doesn't work?

After changing the numbers, for example, in the first or seconde input, the result is false. Only changing the values in gives me the right results.
If I put 40 in the first input and 3 in the seconde one and others I leave the same, the result should be 26.
Please, could you help me.
<body>
<div id="app">
<h1>{{title}}</h1>
<form v-on:submit.prevent>
<span>Довжина стіни, м:</span><br>
<input class="length" type="text" name="length" v-model.text.trim="wall_length"><br>
<span>Висота стіни, м:</span><br>
<input class="heigth" type="text" name="heigth" v-model.text.trim="wall_height"><br>
<hr>
<span>Ширина рулона, м:</span><br>
<select v-model="selected">
<option v-for="key in weight" :value="key">{{key}}</option>
</select><br>
<span>Довжина рулона, м:</span><br>
<input class="length_roll" type="text" name="length_roll" v-model.text.trim="length" maxlength="5"><br>
<span>Повтор малюнка (рапорт), см:</span><br>
<input class="rapport" type="text" name="rapport" v-model.text.trim="rapport"><br><br>
<input type="submit" value="Порахувати" v-on:click="calc">
</form>
<span>{{result}} рулонів шпалер</span>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script>
new Vue({
el : "#app",
data: {
title: "Калькулятор шпалер",
wall_length: 20,
wall_height: 2.75,
weight: [0.53, 1.05],
rapport: 0,
length: 10.05,
selected: 0.53,
polotno_for_room: 0,
polotno_rulon: 0,
result: 0
},
methods: {
calc: function () {
this.polotno_for_room = (this.wall_length + this.wall_height)/ this.selected;
this.polotno_rulon = this.length /(this.wall_height + 0.10);
this.result = Math.ceil(this.polotno_for_room/this.polotno_rulon);
console.log((this.wall_length + this.wall_height)/ this.selected);
console.log(this.polotno_rulon = this.length /(this.wall_height + 0.10));
console.log(Math.ceil(this.polotno_for_room/this.polotno_rulon));
}
}
});
</script>
</body>
Your main problem is that you are using an input with type="text". The result of this is a string. When you start your application, the state of your component is initialised to what you set as data, which makes wall_length and wall_height numbers. The moment you change one of the inputs, the type of these variables changes to a `string.
Due to how javascript works, it will now do string concatenation instead of adding two numbers. It will then convert it back to a number for dividing by whatever this.selected is. The result is that instead of doing dividing 40 + 3 = 43 by this.selected, you are dividing "40" + 3 = 403 by this.selected. Notice the typeof checks I added behind the inputs to showcase this.
new Vue({
el: "#app",
data: {
title: "Калькулятор шпалер",
wall_length: 40,
wall_height: 3,
weight: [0.53, 1.05],
rapport: 0,
length: 10.05,
selected: 0.53,
polotno_for_room: 0,
polotno_rulon: 0,
result: 0
},
methods: {
calc: function() {
this.polotno_for_room = (this.wall_length + this.wall_height) / this.selected;
this.polotno_rulon = this.length / (this.wall_height + 0.10);
this.result = Math.ceil(this.polotno_for_room / this.polotno_rulon);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h1>{{title}}</h1>
<form v-on:submit.prevent>
<span>Довжина стіни, м:</span><br>
<input class="length" type="text" name="length" v-model.text.trim="wall_length"> {{ typeof wall_length }}<br>
<span>Висота стіни, м:</span><br>
<input class="heigth" type="text" name="heigth" v-model.text.trim="wall_height"> {{ typeof wall_height }}<br>
<hr>
<span>Ширина рулона, м:</span><br>
<select v-model="selected">
<option v-for="key in weight" :value="key">{{key}}</option>
</select><br>
<span>Довжина рулона, м:</span><br>
<input class="length_roll" type="text" name="length_roll" v-model.text.trim="length" maxlength="5"><br>
<span>Повтор малюнка (рапорт), см:</span><br>
<input class="rapport" type="text" name="rapport" v-model.text.trim="rapport"><br><br>
<input type="submit" value="Порахувати" v-on:click="calc">
</form>
<span>{{result}} рулонів шпалер</span>
</div>
One of your options is to use parseFloat(..) liberally. It will make sure you are using only numbers in your calculation.
new Vue({
el: "#app",
data: {
title: "Калькулятор шпалер",
wall_length: 40,
wall_height: 3,
weight: [0.53, 1.05],
rapport: 0,
length: 10.05,
selected: 0.53,
polotno_for_room: 0,
polotno_rulon: 0,
result: 0
},
methods: {
calc: function() {
this.polotno_for_room = (parseFloat(this.wall_length) + parseFloat(this.wall_height)) / parseFloat(this.selected);
this.polotno_rulon = parseFloat(this.length) / (parseFloat(this.wall_height) + 0.10);
this.result = Math.ceil(parseFloat(this.polotno_for_room) / parseFloat(this.polotno_rulon));
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h1>{{title}}</h1>
<form v-on:submit.prevent>
<span>Довжина стіни, м:</span><br>
<input class="length" type="text" name="length" v-model.text.trim="wall_length"><br>
<span>Висота стіни, м:</span><br>
<input class="heigth" type="text" name="heigth" v-model.text.trim="wall_height"><br>
<hr>
<span>Ширина рулона, м:</span><br>
<select v-model="selected">
<option v-for="key in weight" :value="key">{{key}}</option>
</select><br>
<span>Довжина рулона, м:</span><br>
<input class="length_roll" type="text" name="length_roll" v-model.text.trim="length" maxlength="5"><br>
<span>Повтор малюнка (рапорт), см:</span><br>
<input class="rapport" type="text" name="rapport" v-model.text.trim="rapport"><br><br>
<input type="submit" value="Порахувати" v-on:click="calc">
</form>
<span>{{result}} рулонів шпалер</span>
</div>

Vue.js radio button not checked by default

I'd like to make default checked on radio buttons inside a v-for loop.
Here is the code:
<ul v-for="p in photos">
<li>
<div>
<div>
<div>
Visibility: {{p.visible}}
</div>
<strong>Visibility setting</strong><br>
<input type="radio" v-model="p.visible" name="visibility" value="all" :checked="p.visible == 'all'"> All <br>
<input type="radio" v-model="p.visible" name="visibility" value="fav" :checked="p.visible == 'fav'"> My favorites <br>
<input type="radio" v-model="p.visible" name="visibility" value="none" :checked="p.visible == 'none'"> No one
</div>
<div><img" v-bind:src="BASE_URL +'/uploads/' + userId + '/'+ p.imgId" /> </div>
</div>
</li>
</ul>
I followed this answer.
While I can see Visibility of each item is being printed, the default radio buttons of each photo are not checked as expected.
Here is the photos array which I receive from the server when the component is created:
[
{
"id" : "5bcebb6efeaea3147b7a22f0",
"imgId" : "12710.png",
"visible" : "all"
},
{
"id" : "5bcebbf0feaea3147b7a22f1",
"imgId" : "62818.png",
"visible" : "fav"
},
{
"id" : "5bcec010feaea3147b7a22f2",
"imgId" : "36740.png",
"visible" : "none"
}
],
What is wrong here and how can I fix it?
Don't use :checked:
v-model will ignore the initial value, checked or selected attributes found on any form elements. It will always treat the Vue instance data as the source of truth. You should declare the initial value on the JavaScript side, inside the data option of your component.
If v-model is the same as value it will return true for that checkbox. Your fixed fiddle:
new Vue({
el: '#app',
data: {
photos: [{
"id": "5bcebb6efeaea3147b7a22f0",
"imgId": "12710.png",
"visible": "all"
},
{
"id": "5bcebbf0feaea3147b7a22f1",
"imgId": "62818.png",
"visible": "fav"
},
{
"id": "5bcec010feaea3147b7a22f2",
"imgId": "36740.png",
"visible": "none"
}
],
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<ul v-for="(p, index) in photos">
<li>
<div>
Visibility: {{p.visible}}
</div>
<strong>Visibility setting</strong><br>
<input type="radio" v-model="photos[index].visible" :name=`visibility-${index}` value="all"> All <br>
<input type="radio" v-model="photos[index].visible" :name=`visibility-${index}` value="fav"> My favorites <br>
<input type="radio" v-model="photos[index].visible" :name=`visibility-${index}` value="none"> No one
</li>
</ul>
</div>
Now each radio group has it's own name, with v-model targeting that group (note the index).

Refresh v-model

I'm developing question paper application.
Once I type a question and hit the "+" button, the question goes to the question paper array and counter increased by one.
The problem is after I hit the "+" button, then also the question which I have entered previously is still in the fields of the UI. Because of I use v-model to bind the data fields.
What I want is a method to clear those previous question data in UI.
This is something similar to reset button function.
<template>
<div>
<div class="container" v-if="counter<=5">
<h2>Question {{counter}}</h2><hr>
<textarea rows="7" cols="75" v-model="question"></textarea><br><br>
1. Answer <input type="text" v-model="answer1"> <input type="radio" name="q1answer" value="1" v-model="correctAnswer"><br><br>
2. Answer <input type="text" v-model="answer2"> <input type="radio" name="q1answer" value="2" v-model="correctAnswer"><br><br>
3. Answer <input type="text" v-model="answer3"> <input type="radio" name="q1answer" value="3" v-model="correctAnswer"><br><br>
4. Answer <input type="text" v-model="answer4"> <input type="radio" name="q1answer" value="4" v-model="correctAnswer"><br>
<hr>
Knowledge Area <select v-model="knowledgeArea">
<option value="Maths">Mathematics</option>
<option value="Language">Language Skills</option>
<option value="gk">General Knowledge</option>
<option value="other">Other</option>
</select><br><br>
<button type="button" class="btn" #click="pushToArray" >
<span class="glyphicon glyphicon-plus"></span></button>
</div>
<div v-if="counter>5">
<button type="button" class="btn btn-primary" #click="onSubmit">Save Question Paper</button>
</div>
</div>
</template>
<script>
import axios from 'axios';
var questionPaper = [];
export default {
data () {
return {
question:'',
answer1:'',
answer2:'',
answer3:'',
answer4:'',
correctAnswer:'',
knowledgeArea:'',
counter:1,
show:true
}
},
methods: {
onSubmit () {
},
pushToArray(){
const formData = {
question: this.question,
correctAnswer: this.correctAnswer,
answer1: this.answer1,
answer2: this.answer2,
answer3: this.answer3,
answer4: this.answer4,
knowledgeArea:this.knowledgeArea
}
this.counter++;
questionPaper.push(formData);
}
}
}
</script>
Create a template data variable to use as a reset. For example
const templateData = {
question:'',
answer1:'',
answer2:'',
answer3:'',
answer4:'',
correctAnswer:'',
knowledgeArea:''
}
export default { // ...
use that to set your initial data
data() {
return {
counter: 1,
show: true,
...templateData
}
}
Now you can easily reset your data in the pushToArray method, eg
questionPaper.push(formData);
Object.assign(this, templateData);

How to get some forms from request?

So, I've this form in server side:
case class Employe(id: Int, name: String)
val myForm = Form(
mapping(
"id" -> number,
"name" -> text
) (Employe.apply) (Employe.unapply)
)
So, in client side I need send three same forms to the server:
<html>
<body>
<div class="employe">
<input type="number" class="employe_id"/>
<input type="text" class="employe_name"/>
</div>
<div class="employe">
<input type="number" class="employe_id"/>
<input type="text" class="employe_name"/>
</div>
<div class="employe">
<input type="number" class="employe_id"/>
<input type="text" class="employe_name"/>
</div>
<input type="button" id="send_button"/>
</body>
</html>
and this data I send to the server via ajax with following code:
var allEmployes = $('.employe');
var addUrl = '/employes/add';
var employesArray = [];
for(var i = 0; i < allEmployes.length; i++) {
var currentRow = $(allEmployes[i]);
var emplId = currentRow.find('.employe_id').val();
var emplName = currentRow.find('employe_name').val();
var employe = {
'id' : emplId,
'name': emplName
};
employesArray.push(employe);
}
$.post(addUrl, { 'employes': employesArray })
.done(function(response){
console.log(response);
})
.fail(function(error){
console.log(error);
});
but, I don't know how to get three same forms from request (in Action of Server side)? Anybody know how to can this?
Thanks in Advance!
In controller change form mapping as
val myForm = Form(
mapping(
"id" -> list(number),
"name" -> list(text)
) (Employe.apply) (Employe.unapply)
)
and in html
<div class="employe">
<input type="number" name="id[0]" />
<input type="text" name="name[0]" />
</div>
<div class="employe">
<input type="number" name="id[1]" />
<input type="text" name="name[1]" />
</div>
<div class="employe">
<input type="number" name="id[2]" />
<input type="text" name="name[2]" />
</div>

DataTables warning: Requested unknown parameter '4' from the data source for row ''

Are Days and days that I'm looking for this problem, but nothing resolved it!
This warning appear after the add of a Student to my Database. The persist of the Data is Ok, so i need to hide this error or adjust it.
So i have a Datables that give me this error:
This is my html code:
<script type="text/javascript">
$(document).ready(function () {
$("#companies").dataTable({
"bServerSide": true,
"sAjaxSource": "/studentiSource",
"bProcessing": true,
"sPaginationType": "full_numbers",
"bJQueryUI": true,
"aoColumns": [
{ "sName": "ID", "mDataProp": null,
"bSearchable": false,
"bSortable": false,
"bVisible": false
},
{ "sName": "NOME",},
{ "sName": "COGNOME"},
{ "sName": "USERNAME"},
{ "sName": "PASSWORD" },
{ "fnRender": function (oObj) {
console.log(oObj);
return '<a href=${pageContext.request.contextPath}/modificaStudente.jsp?id=' + oObj.aData[0] + '>' + 'Gestisci' + '</a>';
}}
]
}).makeEditable({
sUpdateURL : "/updateStudenti" ,
sAddURL: "/studenteServlet",
sDeleteURL: "/deleteStudenti",
fnShowError: function (message, action) {
switch (action) {
case "update":
jAlert(message, "Update failed");
break;
case "delete":
jAlert(message, "Delete failed");
break;
case "add":
$("#lblAddError").html(message);
$("#lblAddError").show();
break;
}
},
fnStartProcessingMode: function () {
$("#processing_message").dialog();
},
fnEndProcessingMode: function () {
$("#processing_message").dialog("close");
}
});
});
And the table is:
<div id="container">
<div id="demo_jui">
<button id="btnAddNewRow" value="Ok">Aggiungi nuovo studente...</button>
<button id="btnDeleteRow" value="cancel">Rimuovi utente selezionato</button>
<div id="processing_message" style="display:none" title="Processing">Attendere.. Caricamento dati in corso</div>
<table id="companies" class="display">
<thead>
<tr>
<th>ID</th>
<th>Nome</th>
<th>Cognome</th>
<th>Username</th>
<th>Password</th>
<th>Dispense</th>
</tr>
</thead>
<tbody >
</tbody>
</table>
</div>
<form id="formAddNewRow" action="#" title="Aggiungi nuovo studente">
<label id="lblAddError" style="display:none" class="error"></label>
<input type="hidden" id="id" name="id" value="-1" rel="0" />
<input type="hidden" value="aggiungi" name="action">
<label for="name">Nome</label><input type="text" name="nome" id="name" class="required" rel="1" />
<br />
<label for="name">Cognome</label><input type="text" name="cognome" id="address" rel="2" />
<br />
<label for="name">Username</label><input type="text" name="username" id="postcode"/>
<br />
<label for="name">Password</label><input type="text" name="password" id="town" rel="3"/>
<br />
</form>
</div>
I'm using Datatables 1.9.4
I cant give you a definitive answer, since you did not include the JSON response from the server.
This message usally means that DataTables is looking at your data source for array position 4 (which is the fifth element -- the password field) and not finding it.
You should make sure that you are returning a response with all the fields specified in the datatables definition, including the password field.
The sixth element of your JSON array doesn't contain the value for key '4' because you're fetching a null value, try to parse your JSON array to http://jsoneditoronline.org/ and you'll see it.