sSearch and fnServerParams, DataTables.net - datatables

I'm trying to set up some search box / datepickers up outside of the main table, i've done some searching and read that i need to pass my values in fnServerParams with a custom value. So, i do this:
"fnServerParams": function (aoData) {
aoData.push({
"name": "iArchiveYears", "value": $("#ddYears :selected").text()}
, { "name": "iMsgType", "value": $('#msgTypeSearch').val() }
)
},
Which, when viewed in firebug appear fine as can be seen below:
I'm using a click function combined with fnFilter to try and filter bsaed on a specific value for a specific columns, which looks like this :
$('#msgTypeSearch').keyup(function (event) {
event.preventDefault();
oMsgDateDetail.fnFilter(this.value, 4, false, false, false, true);
});
for some reason this isnt filtering at all and i note that the value for the search box appears in sSearch4 - do i therefore need to specifiy fnServerParams at all? i'm not sure, as the date (2011) doesnt appear in the sSearch fields.
Is it possible to filter using fnFilter at all??

oMsgDateDetail.fnFilter(this.value, XX, false, false, false, true);
});
Send a request to the server and sSearch_XX = the value
oMsgDateDetail.fnFilter(this.value);
});
Send a request to the server and sSearch = the value
In server-side, you need to search and send all records.
fnFilter doesn't filter when bServer-side = true.
When bServer-side = false. It search in your local data

Related

Vue JS 2 - dynamic array

I understand with Vue JS 2, you have to declare reactive properties upfront.
However, just wondering how would you do a rest call if the child objects appear depending on a few other conditions. For example:
"abc": {
"tests": [
{
"a1": "xxxx",
"result": null,
"selected": false,
"comment": null
} ...
]
}
Now in this example, what happens if the tests are empty ((null)) in some circumstances?
eg: if you bind it using the v-model xx.xx.abc.tests[1].selected - This wont work as tests[1] is null.
So I tried using Vue.set in mounted function to assign a default value but that did not work. It will be hard to define all these in a static data as then I have to know all the tests before the rest call.
Looking at the Vue warning when accessing nested object the issue is if I do the check for inside
the checkbox (Checkbox is rendered from Spring MVC tag).
<form:checkbox id="xx" path="..Spring MVC Path.." v-if="(xx.xx.abc.tests!=null && xx.xxx.abc.tests[3].selected)" **v-model**="xx.xxx.abc.tests[3].selected"/>
The checkbox does not appear at all. I want it to appear regardless of empty value as it gives users to add the option. Also, the other option of statically declaring it does not work as I don't know want to hard code and define array.
for example that means in case another element is added it is hardcoded into script:
[
{
"testName": String,
"result": String,
"selected": false,
"comment": String
},
{
"testName": String,
"result": String,
"selected": false,
"comment": String
}
]
Basically I need to bind using v-model even if it is null in this case. Tried Vue.set but for some reason did not appear to work.
I guess I am missing something here,any help would be appreciated.
Assume that you have a list of checkbox to render whether the child element is null on not. but you do know the array length, right?
If you do, consider use v-for to render checkboxes (then you’re able to track array item by index) and listening on its change event then assign specific value to specific object when events fire
thanks for the replies. As this was due to rest call not returning all required attributes that was defined in Vue model(As mentioned in question).So I checked that in final section of rest call and if they are empty, created them.
axios
.get(***URL***)
.then(
response => {
this.info = response.data;
this.status.loaded = true;
}
)
.finally(
() => {
*** check and fill missing attributes with default values ***
**Example: this.$set(this.someObject, 'b', 2)
}
)
Reference:
https://v2.vuejs.org/v2/guide/reactivity.html

Setting custom field values on a card with the Trello API

I am trying to use the new Custom Fields methods of the Trello API to set the value of a custom field on a card.
I've created a custom field of type number. When I make a GET request for the custom field by it's id, it returns this custom field object:
{
"id":"5ab13cdb8acaabe576xxxxx",
"idModel":"54ccee71855b401132xxxxx",
"modelType":"board",
"fieldGroup":"837a643fd25acc835affc227xxxxxxxxxxxxxxxxxxxx",
"name":"Test Number Field",
"pos":16384,
"type":"number"
}
Then when I create a new card in the Trello UI (but do not type in a value in the Test Number Field box) and then GET that card using the customFieldItems=true (as documented here), it returns this card object (irrelevant fields removed):
{
"id": "5ab56e6b62abac194d9xxxxx",
"name": "test1",
"customFieldItems": []
}
Note that since I did not type anything into the Test Number Field box in the UI, the customFieldItems property contains an empty array.
Then if I type in the number 1 in the Test Number Field box in the UI and GET the card again, it returns this (irrelevant fields removed):
{
"id": "5ab56e6b62abac194d9xxxxx",
"name": "test1",
"customFieldItems":
[
{
"id": "5ab570c5b43ed17b2dxxxxx",
"value": {
"number": "1"
},
"idCustomField": "5ab13cdb8acaabe5764xxxxx",
"idModel": "5ab56e6b62abac194d9xxxxx",
"modelType": "card"
}
]
}
I want to be able to set the value of this custom field via API.
When I go to the API documentation for "Setting, updating, and removing the value for a Custom Field on a card," (here) I plug in the following information:
Query Auth
key: (our valid/working Trello API key)
token: (our valid/working Trello API token)
PATH PARAMS
idCard: (ID of the card that the Custom Field value should be set/updated for) 5ab56e6b62abac194d9xxxxx
idCustomField (ID of the Custom Field on the card.): 5ab570c5b43ed17b2dxxxxx
QUERY PARAMS
idCustomField (ID of the Custom Field to which the item belongs.): 5ab13cdb8acaabe576xxxxx
modelType (This should always be card.): card
value (An object containing the key and value to set for the card's Custom Field value. The key used to set the value should match the type of Custom Field defined.): {"number": 2}
When I click Try It, I get the response: 400 Bad Request "Invalid custom field item value."
I've tried the following things:
Switching the two idCustomField values (it's confusing that both the path parameter and query parameter have the same name, implying that they are meant to accept the same value, but then they have different descriptions, and the descriptions are vague/confusing).
Setting both idCustomField values to the same thing (for both of the possible IDs)
Setting the value to 2, {"number": "2"}, {number: 2}, {number: "2"} and more.
No matter what I try, I always get "Invalid custom field item value." This behaves the same way whether the card has a value in the custom field or not.
I'm pretty sure that the idCustomField in the path params is being accepted, because when I change one character, it gives me this error instead: "invalid value for idCustomField".
So I don't know if the "Invalid custom field item value." is referring to the query param idCustomField* or the value.
I also don't know if it makes a difference whether or not the card has an existing value in the custom field, but I want to be able to set the value of this custom field regardless of whether or not it currently has a value in the field.
The live example (using XMLHttpRequest) on the Trello documentation page is wrong. You should use the next example using fetch.
var url = "https://api.trello.com/1/cards/{idCard}/customField/{idCustomField}/item?token={yourToken}&key={yourKey}";
var data = {value: { number: "42" }};
fetch(url, { body: JSON.stringify(data), method: 'PUT', headers: {'content-type': 'application/json'}})
.then((resp) => resp.json())
.then((data) => console.log(JSON.stringify(data, null, 2)))
.catch((err) => console.log(JSON.stringify(err, null, 2)))
This example works. And after trying this, I modified the XMLHttpRequest version and it worked too.
var data = null;
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
console.log(this.responseText);
}
});
data = {value: { number: "3" }}; //added
var json = JSON.stringify(data); //added
xhr.open("PUT", 'https://api.trello.com/1/cards/{idCard}/customField/{idCustomField}/item?key={yourkey}&token={yourtoken}');
xhr.setRequestHeader('Content-type','application/json'); //added
xhr.send(json); //modified
The point is that you should 1) set the request Content-type header to application/json and 2) pass the value via JSON object body.
I tried to edit the live example on the documentation but I it was not possible. I hope they will fix it soon.

How to make jqGrid dynamically populate options list based on row data

I am using jQrid version 3.8.1 with inline editing and each row in the grid has several dropdown lists to populate. When the user edits the row, I need to do an AJAX query to get the values for each of these lists. I've seen this post regarding how to do that. It appears that the dataUrl and buildSelect features are the standard answer here. There are a few issues I can't figure out though:
The row the user is editing has a value that must be passed into the dataUrl value. For example, say each row contains a field called "SpecialValue" and that for row 1, SpecialValue = 100. The dataUrl field for row 1 would be "http://my.services.com?SpecialValue=100". How do I do that?
Each row in the grid has about 10 select boxes that need to be populated. For efficiency reasons, I don't want to make 10 separate AJAX calls. It would be much better to make one call to get all the data, split it up, and fill each select box accordingly. Is that possible? I tried doing this inside onSelectRow but the grid ended up ignoring the values I put in there (I'm guessing do the ordering of the events that fire when you edit a row).
Edit:
After reading Oleg's answers and working on it more, it's clear to me that using dataUrl and buildSelect are not going to work well for me. The version of jqGrid I'm using doesn't support using dataUrl the way I would need. And even if it did I don't want to send multiple separate requests for each dropdown list.
I've decided to do one request when gridComplete fires to pull all the data needed for all dropdown lists into a single JSON structure. Then when the user selects a row to do inline editing, I will populate each list in the row from that JSON structure (the code below uses the getSelectValuesFromJSON() function for that--I don't give its definition but you can imaging it looks through the structure and gets an appropriate list of values to but in the list box).
I have a few candidate solutions but I'm not 100% happy with either one.
Solution 1:
Inside onSelectRow, I call editRow overriding the on oneditfunc to get the data out of the grid that I need. Assume that the value in Field1 is required to get the values to be put into the list in Field2.
onSelectRow: function (index, status, e) {
jQuery('#my_grid').jqGrid('editRow', index, true, function(rowId) {
var f1Val = $('#my_grid').jqGrid('getCell', index, 'Field1');
var selectVals = getSelectValuesFromJSON(f1Val); //gets data out of previously loaded JSON structure
var select = $('#my_grid').find('tr[id="' + index + '"] td[aria-describedby="my_grid_Field2"] select');
_.each(selectVals, function(selectVal) {
$(select).append($("<option></option>").attr("value", selectVal).text(selectVal));
});
});
}
This works but I'm hesitant about the line
var select = $('#my_grid').find('tr[id="' + index + '"] td[aria-describedby="my_grid_Field2"] select');
which relies on this aria-describedby attribute that I don't know much about. Seems hacky and brittle.
Solution 2:
Make use of beforeSelectRow to dynamically change the model of the Field2 column when the user selects a row.
beforeSelectRow: function(index, e) {
var f1Val = getGridCellValue('#my_grid', index, 'Field1');
var values = getSelectValuesFromJSON(f1Val); //gets data out of previously loaded JSON structure
var valStr = "";
_.each(values, function(value) {
valStr += value + ":" + value + ";"
});
jQuery('#grid_pipes').setColProp('Field2', { editoptions: { value: valStr } });
return true;
}
This also works but I'm not sure about whether or not this is really a good idea. Is it valid to dynamically change the model of a column like that? What if the user has several rows selected at the same time? Isn't there only one model for a column? What would that mean?
To answer some of Oleg's questions, the dataType has been set to a function that uses $.ajax to post data to the server. I think I read that's not the recommended approach anymore. I inherited this code so I'm not sure why it was done that way but it probably won't change unless there is a really compelling reason.
The loadonce boolean is not specified so I guess that means it defaults to false.
Here is an abbreviated version of the column model (nothing terribly out of the ordinary):
colModel: [
{ name: 'PK', index: 'PK', hidden: true, editable: true, sortable: true, search: true },
{ name: 'Field1', index: 'Field1', hidden: true, editable: true, sortable: true, search: true },
{ name: 'Field2', index: 'Field2', sortable: false, editable: true, search: false, edittype: "select", editoptions: {} },
{ name: 'Field3', index: 'Field3', sortable: false, editable: true, search: false, edittype: "select", editoptions: {} },
...
]
You don't wrote which version of jqGrid you use currently, but dataUrl can be defined as callback function with (rowid, value, name) parameters, which have to return the URL which you can build dynamically based on the information. The feature exist starting with v4.5.3 (see the line). You can use getCell, getRowData or getLocalRow inside of the callback to get the data from another columns of the row. Thus you can solve your first problem relatively easy.
You second question seems to me absolutely independent from the first one. It's better to separate such questions in different posts to allow the searching engine better to index the information and so to help other people to find it.
There are no simple way how to solve the second problem, but one can sure suggest a solution, but one have to know much more details what you do and how you do. How you start inline editing (do you use inlineNav, formatter: "actions" or you call editRow directly)? Which version of jqGrid (till version 4.7), free jqGrid or Guriddo jqGrid JS you use? How the columns with selects are defined in colModel? Which datatype you use and whether loadonce: true you use? I recommend you to post separate question with the information.
UPDATE: If you have to use old version of jqGrid then you can't generate dataUrl full dynamically, but because you need to add only SpecialValue=100" part to the URL you can follow the trick which I described in many my old answers (the first one was probably here, but the choice on property names which asked the user could be misunderstood). You can use ajaxSelectOptions.data which will define the data parameters of jQuery.ajax request. The problem only that you can define only one ajaxSelectOptions.data property. So you can add the following jqGrid option:
ajaxSelectOptions: {
data: {
SpecialValue: function () {
var rowid = $myGrid.jqGrid("getGridParam", "selrow");
return $myGrid.jqGrid("getCell", rowid, "SpecialValue");
}
}
}
($myGrid is something like $("#grid"))
UPDATED: You used unknown functions getSelectValuesFromJSON, getLookupValuesFromJSON in the updated part of your question. Both of there seems to use synchronous Ajax request which is not good. Moreover you set editoptions.value for only one Field2 instead of setting all selects.
onSelectRow: function (rowid) {
var $myGrid = $(this);
$.ajax({
url: "someUrl",
dataType: "json";
data: {
specialValue: $myGrid.jqGrid("getCell", rowid, "Field1")
},
success: function (data) {
// for example response data have format:
// { "Field2": ["v1", "v2", ...], "Field3": ["v3", "v4", ...] }
var filed, str;
for (filed in data) {
if (data.hasOwnProperty(filed)) {
str = $.map(data[filed], function (item) {
return item + ":" + item
}).join(";");
$myGrid.jqGrid("setColProp", filed, {
editoptions: {
value: str
}
});
}
}
$myGrid.jqGrid("editRow", rowid, true);
}
});
}
Nevertheless the "Solution 2" is more close to what I would recommend you. It's not really important whether to use onSelectRow or beforeSelectRow. You can make asynchronous Ajax request to the server which returns information for all select which you need. After you get the response from the server (inside of success callback) you can set editoptions.value for all selects and only then you can start editRow. In the way you will be sure that editing of the line will use row specific options in all select.
Some additional remarks. I recommend you to verify gridview: true option in the grid. Additionally I suspect that you fill the grid in not full correct way because you have hidden PK column and you use index instead of rowid as the first parameter of beforeSelectRow and onSelectRow. It's very important to understand that the current implementation of jqGrid always assign id attribute on every row (<tr> element) of the grid. So you have to provide id information in every item of input data. If you want to display the id information to the user (and so to have column in colModel with the primary key) then you should just include key: true property in the column definition. For example you can add key: true to the definition of PK column and so you will have rowid (or index in your case) with the same value like PK. It simplify many parts of code. For example jqGrid send id parameter in the editing request to the server. It's practical to have PK in the request. Moreover if you use repeatitems: false format of jsonReader the you can include id: "PK" in the jsonReader instead of having hidden PK column. It informs jqGrid to get rowid from PK. jqGrid will save PK in id attribute of <tr> and you will don't need to have additional <td style="display:none"> with the same information in the grid.
The last remark. I would strictly recommend you to update the retro version jqGrid 3.8.1 to some more recent version, for example to free jqGrid. Even if you would use no features (like Font Awesome for example) you will have performance advantages, and the look of modern web browsers will looks much better. You should understand the jqGrid 3.8.1 was tested with old (and slow jQuery 1.4.2). The version used with Internet Explorer 8 as the latest IE version (IE9 was published later in March 2011) and it's more oriented on IE6/IE7. The look in modern Chrome/Firefox/Safari can be bad. Is it what you want?

jquery datatable column header not update properly

I try reuse 1 table with different amount of data based on different button click, I able to populate data successfully, but the problem is, the header did not populate correctly, I had debug and see the correct amount of column pass into table, but why it still retain the design from the 1st click? the 1st data from the 1st click have 3 column, but in the 2nd click, it still retain the same 3 column instead of 8 column? how to make the header populate correctly?
I try to destroy and recreate, but the code not working well if declare before the table create, any idea?
//if ($.fn.DataTable.fnIsDataTable($(selector)[0])) {
// $(selector).dataTable.fnClearTable();
// $(selector).dataTable.fnDraw();
//}
var oDataTable = $(selector).dataTable({
"sDom": _sDom,
"sPaginationType": "bootstrap",
"bDestroy": true,
"bServerSide": true,
"bFilter": true,
"bStateSave": true,
"bSort": tools,
"bAutoWidth": false,
"sAjaxSource": source,
"fnServerParams": function (aoData) {
aoData.push({ "name": "sParams", "value": params });
},
"bProcessing": true,
"oLanguage": {
"sLengthMenu": _displayLen
},
"aoColumns": cols
});
1st button click
2nd button click
Ok, found the answer, after fndestroy, I still need to remove header from table before recreate a new set of header
$(selector).find('thead tr th').remove();

Datatables editable - oDeleteParameters get id of selected row

I'm trying to pass additional parameters to the ajax call that is done after selecting a row then clicking delete button. Here's the code I have:
$('#datatable').dataTable( {
"bJQueryUI": true,
"bProcessing": true,
"bServerSide": true,
"bFilter": false,
"iDeferLoading": <%= #count %>,
"sAjaxSource": "redraw",
"fnServerData": fnDataTablesPipeline
}).makeEditable({
sDeleteURL: "delete.rb",
oDeleteParameters:
{
foo: WHAT IS ID
}
});
As you can see, I'm trying to send a parameter foo=ID but I'm not sure how to grab the selected ID of the row.
i have used the following function mentioned in the link below to get the id's of the rows that have been selected and sending them via ajax to the serverside where they get deleted.
hope this solves what you were looking for...
http://datatables.net/examples/api/select_row.html