Dijit validator question within dynamically created validationbox , please help - dojo

I'm now trying to do a dynamically created table line , with dijit button, validation box.
The button id and textbox id is generate by index number, so how can my Validation box validator can know which line of validationbox is calling the validator?
Should I make the validator : testcall , being validator : function () {testcall(this.id)}, ????
function createNewRow() {
var tablebodyname = "RPDetailbody" ;
var mytablebody = document.getElementById(tablebodyname);
var thetabletr = document.createElement('tr');
var thetabletd1 = document.createElement('td');
var thetabletd2 = document.createElement('td');
var thetabletd3 = document.createElement('td');
var thisButton = new dijit.form.Button({
label : thelineindex ,
id : "I_del_butt"+thelineindex,
name : "I_del_butt"+thelineindex,
onClick : function() {
document.getElementById(tablebodyname).removeChild(thetabletr);
}
}).placeAt( thetabletd1 ) ;
var thisNumberTextBox = new dijit.form.NumberTextBox({
id : "I_seq_no"+thelineindex ,
name : "I_seq_no"+thelineindex ,
value : thelineindex+1 ,
required : "true",
maxLength : 2,
size : 2 ,
style : "width: 2em;",
missingMessage : "Every line must have sequence number"}).placeAt(thetabletd2) ;
var thisValidationTextBox1 = new dijit.form.ValidationTextBox({
id : "I_pig_code"+thelineindex ,
name : "I_pig_code"+thelineindex ,
type : "text" ,
required : "true",
maxLength : 3,
size : 3,
style : "width: 5em;",
validator : testcall ,
missingMessage : "Must have pigment code" }).placeAt(thetabletd3) ;
thetabletr.appendChild(thetabletd1);
thetabletr.appendChild(thetabletd2);
thetabletr.appendChild(thetabletd3);
mytablebody.appendChild(thetabletr);
thelineindex ++ ;
}
<tbody id="RPDetailbody">
<td><div id="delplace"></div></td>
<td><div id="seqplace"></div></td>
<td><div id="pigcodeplace"></div></td>
</tr>
</tbody>
However I've try to make it as javascript function call to my validator , but I found in the form submittion , using form.isValid() to verify all information can pass validation, it always returns fail !
Here are my validator :
function testcall ( thebtnID ) {
var strlen = thebtnID.length ;
var resultAreaID = "I_pigment_name"+ thebtnID.substring(10, strlen) ;
var pigcode = dijit.byId(thebtnID );
var bNoNameFound = ( "Error" == pigcode.get( "state" ) ) ? false:true;
var query = "thePig=" + encodeURI(pigcode.value );
if( "" == pigcode.value ) {
// for some required=true is not kicking in, so we are forcing it.
bNoNameFound = false;
pigcode._setStateClass();
} else {
if( false == pigcode._focused ) {
console.log( "Checking Pigment..." );
dojo.xhrPost({
url: 'ValidatePigmentInput.php',
handleAs: 'text',
postData: query ,
load: function( responseText ) {
if ( responseText == "no record!" ) {
// setting the state to error since the pigment is already taken
bNoNameFound = false;
pigcode.set( "state", "Error" );
//pigcode.displayMessage( "The Pigment dosen't exist..." );
document.getElementById(resultAreaID).innerHTML = "The Pigment dosen't exist...";
// used to change the style of the control to represent a error
pigcode._setStateClass();
} else {
if ( responseText == "pigment BANNED!" ) {
bNoNameFound = false;
pigcode.set( "state", "Error" );
document.getElementById(resultAreaID).innerHTML = "Pigment BANNED! Please don't use it!";
pigcode._setStateClass();
} else {
bNoNameFound = true;
pigcode.set( "state", "" );
document.getElementById(resultAreaID).innerHTML = responseText;
pigcode._setStateClass();
}
}
},
error: function(responseText) {
document.getElementById(resultAreaID).innerHTML = "Error";
}
});
}
}
return bNoNameFound;
}

You can do:
var thisValidationTextBox1 = new dijit.form.ValidationTextBox({
id: "I_pig_code" + thelineindex,
name: "I_pig_code" + thelineindex,
type: "text",
required: "true",
maxLength: 3,
size: 3,
style: "width: 5em;",
missingMessage: "Must have pigment code"
}).placeAt(thetabletd3);
thisValidationTextBox1.validator = function() {
return testcall(thisValidationTextBox1.id);
};
Ie. you need to pass the id to your testcall() function, but also you need to explicitly override the validator property of the widget.
See this in the Dojo reference guide.

Related

lodash : add a new field during a ._map

I have an array of objects of that type:
response.data = [{Name = "name1", Type = "text"}, {Name = "name2", Type = "text"}...]
I am trying to do add and initiate a property to all objects.
I tried:
var newObj = _.map([response.data], function (value) {
return {
value: "property : " + value.Name ,
type: "my type is : " + value.Type,
active : false
};
});
But it does not add the property
Do you know how to do this with lodash?
Because lodash map takes in input as first argument a collection. Your response.data is already a collection and you are wrapping it inside another array ([response.data]).
To fix it, avoid to wrap it:
var newObj = _.map(response.data, function (value) {
return {
value: "property : " + value.Name,
type: "my type is : " + value.Type,
active: false
};
});
Please, consider that JavaScript Array natively has map method, so you do not need lodash. You can write your piece of code in the following way:
var newObj = response.data.map(function (value) {
return {
value: "property : " + value.Name,
type: "my type is : " + value.Type,
active: false
};
});
var newObj = _.map(response.data, function (value) {
return {
value: "property : " + value.Name ,
type: "my type is : " + value.Type,
active : false
};
});

JsonRequestBehaviour.AllowGet Not Working

i am working for JQuery Datatables server side. While creating the json object, to return back, it doesn't allow JsonRequestBehaviour.AllowGet. If code is exactly same what below is, then i am not able to get data in client side.
HTML :
<table class="table table-striped table-bordered table-hover" id="EmployeeTable">
<thead>
<tr>
<th>LastName</th>
</tr>
</thead>
<tbody></tbody>
</table>
JQuery:
$('#EmployeeTable').DataTable({
"processing" : true, // for show progress bar
"serverSide" : true, // for process in server side
"filter" : false, // to disable search box
"orderMulti" : false,// for disable multiple columns at once
"ajax" : {
"url" : "/Employee/GetEmployeeDataTable",
"type" : "post",
"datatype" : "json"
},
"columns" : [
{ "data": "LastName", "orderable": true }
]
});
Server Side:
[HttpPost]
public ActionResult GetEmployeeDataTable()
{
// Get Parameters
//get start(paging start index) and length(page size for paging)
var draw = Request.Form["draw"].FirstOrDefault();
var start = Request.Form["start"].FirstOrDefault();
var length = Request.Form["length"].FirstOrDefault();
//get sort column values
var sortColumn = Request.Form["columns[" + Request.Form["order[0][column]"].FirstOrDefault()+"][name]"].FirstOrDefault();
var sortColumnDir = Request.Form["order[0][dir]"].FirstOrDefault();
int pageSize = length != null ? Convert.ToInt32(length) : 0;
int skip = start != null ? Convert.ToInt32(start) : 0;
int totalRecords = 0;
var employees = getDataService.GetAllEmployees().Select(x => new {
x.LastName
}).ToList();
if(!(string.IsNullOrEmpty(sortColumn) && string.IsNullOrEmpty(sortColumnDir)))
{
employees.OrderBy(x => sortColumn + " " + sortColumnDir);
}
totalRecords = employees.Count();
var data = employees.Skip(skip).Take(pageSize).ToList();
var result = Json(new
{ draw = draw,
recordsFiltered = totalRecords,
recordsTotal = totalRecords,
data = data
});
return result;
}
But if i put like following
var result = Json(new
{ draw = draw,
recordsFiltered = totalRecords,
recordsTotal = totalRecords,
data = data
},JsonRequestBehaviour.AllowGet);
then i can't find this thing in mvc core. Please help me what should i do.
In asp.net core, the Json method does not have an overload which takes JsonRequestBehavior. So you may simply call the Json method with the data you want to pass.
var result = Json(new
{ draw = draw,
recordsFiltered = totalRecords,
recordsTotal = totalRecords,
data = data
});
return result;

Dojo dgrid: Filter data from store with diffrent fields when I click on filter button

I am using 'dgrid/Grid' and dstore/RequestMemory for creating grid and storing data. Now I want to filter data according to values in the fields(see img). I am not sure how to filter data when using simple Dgrid and dstore.
var structure = [{
label : "Value Date",
field : "valueDate"
}, {
id: "currencyCol",
label : "Currency",
field : "currency"
}, {
label : "Nostro",
field : "nostroAgent"
}];
var store= new RequestMemory({
target: 'getReportData',
idProperty: "cashflowId",
headers: structure
});
// Create an instance of OnDemandGrid referencing the store
var grid = new(declare([Grid, Pagination, Selection]))({
collection: store,
columns: structure,
loadingMessage: 'Loading data...',
noDataMessage: 'No results found.',
minRowsPerPage: 50,
}, 'grid');
grid.startup();
on(document.getElementById("filter"), "click", function(event) {
event.preventDefault();
grid.set('collection', store.filter({
**currencyCol: "AED"**
.
.
.
}));
Any help would be appreciated or suggest if I use some diffrent store or grid.
I got the solution for my question. On filter button click I have written all my filtering logic and the final store will set to dgrid:
on(document.getElementById("filter"), "click", function(event) {
var store= new RequestMemory({
target: 'getReportData',
idProperty: "cashflowId",
headers: structure
});
var from=dijit.byId('from').value;
var to=dijit.byId('to').value;
var curr=dijit.byId('currency').value;
var nos=dijit.byId('nostro').value;
var authStatus=dijit.byId('authStatus').value;
var filterStore;
var finalStore=store;
var filter= new store.Filter();
var dateToFindFrom;
var dateToFindTo;
if (from != "" && from !== null) {
var yyyy = from.getFullYear().toString();
var mm = ((from.getMonth()) + 1).toString(); // getMonth() is zero-based
var dd = from.getDate().toString();
if(mm <= 9){
mm= "0" + mm;
}
if(dd <= 9){
dd= "0" + dd;
}
dateToFindFrom =yyyy + mm + dd;
filterStore= filter.gte('valueDate', dateToFindFrom);
finalStore=finalStore.filter(filterStore);
}
if (to != "" && to !== null) {
var yyyy = to.getFullYear().toString();
var mm = ((to.getMonth()) + 1).toString(); // getMonth() is zero-based
var dd = to.getDate().toString();
if(mm <= 9){
mm= "0" + mm;
}
if(dd <= 9){
dd= "0" + dd;
}
dateToFindTo =yyyy + mm + dd;
filterStore= filter.lte('valueDate', dateToFindTo); //.lte('valueDate', dateToFindTo);
finalStore=finalStore.filter(filterStore);
}
if(curr != "" && curr !== null) {
filterStore= filter.eq('currency', curr);
finalStore=finalStore.filter(filterStore);
}
if(nos != "" && nos !== null) {
filterStore= filter.eq('nostroAgent',nos);
finalStore=finalStore.filter(filterStore);
}
if(authStatus != "" && authStatus !== null) {
if (authStatus=='ALL') {
var both= [true, false];
filterStore= filter.in('approved', both);
finalStore=finalStore.filter(filterStore);
} else if (authStatus=='Authorised Only') {
filterStore= filter.eq('approved', true);
finalStore=finalStore.filter(filterStore);
} else if (authStatus=='Unauthorised Only') {
filterStore= filter.eq('approved', false);
finalStore=finalStore.filter(filterStore);
};
};
grid.set('collection', finalStore);
});

Dojo domConstruct.create won't create element on postCreate

I'm new to Dojo and I'm making my first widget to be used in EPiServer CMS.
The widget is supposed to dynamically add contacts when clicking on a button. This means that the only control my templateString has is a button. When clicking on it I call a function that creates all of the other controls that will contain the contact infomation, such as name, email etc. This is working fine, I use domConstruct.create without a problem.
Thing is, when I want to create the existing contacts based on the value that comes from the server I can't manage to use domConstruct.create, it just returns "undefined". I'm making the call in the postCreate event which happens after the DOM is ready. (I've tested this as well). Does anyone have a clue what could be wrong? Like I said creating the controls when clicking on the Add button works like a charm.
The function that throws the error is:
postCreate: function () {
// call base implementation
this.inherited(arguments);
//this._loadContacts(this.value);
var node = domConstruct.create("fieldset", { id: "test" }, "cccp"); //this simple create instruction returns undefined here.
//Bind button
this.connect(this.btnAdd, "onclick", dojo.partial(this._createContact, new Object()));
},
Exactly on the line that does the domConstruct.create. Below is the entire code for the widget:
define([
"dojo/_base/array",
"dojo/_base/connect",
"dojo/_base/declare",
"dojo/_base/lang",
"dojo/dom-construct",
"dojo/on",
"dijit/_CssStateMixin",
"dijit/_Widget",
"dijit/_TemplatedMixin",
"dijit/_WidgetsInTemplateMixin",
"epi/epi",
"epi/shell/widget/_ValueRequiredMixin"
],
function (
array,
connect,
declare,
lang,
domConstruct,
on,
_CssStateMixin,
_Widget,
_TemplatedMixin,
_WidgetsInTemplateMixin,
epi,
_ValueRequiredMixin
) {
var amountContacts = 0;
var contactContainerPrefixName = "contactInfo";
return declare("meridian.editors.StringList", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _CssStateMixin, _ValueRequiredMixin], {
templateString: "<div class=\"dijitInline\">\
<form id=\"cccp\" action=\"\">\
</form>\
<button id=\"btnAdd\" data-dojo-attach-point=\"btnAdd\" type=\"button\" class=\"\">Add Contact</button><br/> \
<span>${helptext}</span>\
</div>",
baseClass: "epiStringList",
helptext: "Place items on separate lines",
intermediateChanges: false,
value: null,
multiple: true,
onChange: function (value) { },
_onChange: function (value) {
this.onChange(value);
},
postCreate: function () {
// call base implementation
this.inherited(arguments);
//this._loadContacts(this.value);
var node = domConstruct.create("fieldset", { id: "test" }, "cccp"); //this simple create instruction returns undefined here.
//Bind button
this.connect(this.btnAdd, "onclick", dojo.partial(this._createContact, new Object()));
},
isValid: function () {
// summary:
// Check if widget's value is valid.
// tags:
// protected, override
return !this.required || lang.isArray(this.value) && this.value.length > 0 && this.value.join() != "";
},
_loadContacts:function(data)
{
for (var i = 0; i < data.length; i++) {
this._createContact(data[i]);
}
},
_createContact:function(data)
{
//increase the number of contacts
amountContacts++;
var contactInfoContainer = contactContainerPrefixName+amountContacts;
//Create container for contact data
var contactInfo = domConstruct.create("fieldset", { id: contactInfoContainer }, "cccp");
//Create container for PROPERTIES
var contactInfoProperties = domConstruct.create("div", {class: "properties"}, contactInfoContainer);
//Name
this._createTextbox("name", data.fullName, "Name", contactInfoProperties, false, false);
/*//Email
this._createTextbox("email", "Email", contactInfoProperties, false);
//Phone 1
this._createTextbox("phoneOne", "Phone 1", contactInfoProperties, true);
//Phone 2
this._createTextbox("phoneTwo", "Phone 2", contactInfoProperties, true);
//Fax
this._createTextbox("fax", "Fax", contactInfoProperties, false);
//Organization
this._createTextbox("organization", "Organization", contactInfoProperties, false);
//Department
this._createTextbox("department", "Department/Unit", contactInfoProperties, false);
//Role
this._createTextbox("role", "Role/Job title", contactInfoProperties, false);*/
//Website
this._createTextbox("website", data.website, "Website", contactInfoProperties, false, false);
//Address
//this._createTextbox("address", "Address", contactInfoProperties, false);
//TLP
this._createTLP_DDL("tlp", "TLP", contactInfoProperties);
//Create container for CATEGORIES
var contactInfoCategories = domConstruct.create("div", { class: "categories" }, contactInfoContainer);
//Categories heading
var p=domConstruct.create("p", { class: "heading" }, contactInfoCategories);
p.innerHTML = "Categories";
//Alert, Warning & Incident Response
this._createCategory("alert", contactInfoCategories, "Alert, Warning & Incident Response");
//Threat
this._createCategory("threat", contactInfoCategories, "Threat");
//Vulnerability
this._createCategory("vulnerability", contactInfoCategories, "Vulnerability");
//Industry
this._createCategory("industry", contactInfoCategories, "Industry");
//Policy
this._createCategory("policy", contactInfoCategories, "Policy");
//R & D
this._createCategory("rd", contactInfoCategories, "R & D");
//Sharing
this._createCategory("sharing", contactInfoCategories, "Sharing");
//Crime
this._createCategory("crime", contactInfoCategories, "Crime");
//SCADA/Process Control
this._createCategory("scada", contactInfoCategories, "SCADA/Process Control");
//Assurance
this._createCategory("assurance", contactInfoCategories, "Assurance");
//Standards
this._createCategory("standards", contactInfoCategories, "Standards");
//Resilience
this._createCategory("resilience", contactInfoCategories, "Resilience");
//Exercises
this._createCategory("exercises", contactInfoCategories, "Exercises");
//Defence
this._createCategory("defence", contactInfoCategories, "Defence");
//Media handling
this._createCategory("media", contactInfoCategories, "Media handling");
//General PoC
this._createCategory("poc", contactInfoCategories, "General PoC");
//Add remove button
var btnRemove = domConstruct.create("input", { type: "button", id: "btnRemove" + amountContacts, value: "Remove"/*,onclick:"_deleteContact(this)"*/ }, contactInfo);
this.connect(btnRemove, "onclick", dojo.partial(this._deleteContact, btnRemove.id));
},
_createTextbox:function(id, textBoxValue, labelText, parent, checkbox, checkboxChecked)
{
var currentId = id+amountContacts;
var textboxContainer = domConstruct.create("div", {class:"form-item"}, parent);
this._createLabel(currentId, textboxContainer, labelText);
//Create textbox and attach update handler
var textbox = domConstruct.create("input", { type: "text", id: currentId, name: currentId }, textboxContainer);
if (textBoxValue)
textbox.value = textBoxValue;
this.connect(textbox, "onchange", this._updateValue);
if (checkbox) {
this._createCheckbox("inline", textboxContainer, currentId + "_24", "24/7?");
}
},
_createTLP_DDL:function(id, labelText, parent)
{
var currentId = id+amountContacts;
var ddlContainer = domConstruct.create("div", { class: "form-item" }, parent);
this._createLabel(currentId, ddlContainer, labelText);
var ddl = domConstruct.create("select", { name: currentId, id: currentId }, ddlContainer);
//Add options
var option1 = domConstruct.create("option", { val: "-1" }, ddl);
option1.innerHTML = "None";
var option1 = domConstruct.create("option", { val: "1" }, ddl);
option1.innerHTML = "Yes";
var option1 = domConstruct.create("option", { val: "0" }, ddl);
option1.innerHTML = "No";
},
_createCategory:function(id, parent, checkboxText)
{
var currentId = id + amountContacts;
var categoryContainer = domConstruct.create("div", { class: "form-item inline" }, parent);
this._createCheckbox("", categoryContainer, currentId, checkboxText);
},
_createLabel:function(forId, container, labelText)
{
var label = domConstruct.create("label", { for: forId }, container);
label.innerHTML = labelText;
},
_createCheckbox:function(labelClass, container, checkboxId, checkboxText){
var labelCheckbox = domConstruct.create("label", { class: labelClass }, container);
//Create checkbox and attach update handler
var checkbox = domConstruct.create("input", { type: "checkbox", id: checkboxId, name: checkboxId }, labelCheckbox);
this.connect(checkbox, "onchange", this._updateValue);
var span = domConstruct.create("span", {}, labelCheckbox);
span.innerHTML = checkboxText;
},
_deleteContact:function(targetBtnId)
{
var userInput = window.confirm("Are you sure you want to delete this contact?");
if (userInput) {
dojo.destroy(contactContainerPrefixName+targetBtnId[targetBtnId.length-1]);
}
},
_updateValue: function () {
//TODO: Delete test data
var contacts = [];
//The amount of contacts can have changed after deletions, so the global variables might not hold the real value
var actualAmountContacts = 0;
for (var i = 1; i <= amountContacts; i++) {
if (this._isValidContact(i)) {
var currentContact = new Object();
currentContact.fullName = this._getValueById("name" + i);
currentContact.website = this._getValueById("website" + i);
contacts[actualAmountContacts] = currentContact;
actualAmountContacts++;
}
}
this._set("value", contacts);
this.onChange(contacts);
},
_getValueById: function (id) {
var node = dojo.byId(id);
var textValue = (node != null) ? node.value : "";
return textValue;
},
_isValidContact:function(itemNumber){
//If there's no name or telephone then it's not a valid contact
return (this._getValueById("name" + itemNumber) != "" || this._getValueById("phoneOne" + itemNumber) != "" || this._getValueById("phoneTwo" + itemNumber) != "");
},
});
});
UPDATE:
After a lot of test I've realized it's not the domConstruct.create statement which causes the error, the problem is that the form element that has "id:cccp" and to which I want to attach the created elements is null at this point. It is defined in the templateString as you can see in the source code but it's still null in the postCreate method. So the question is now, what event gets triggered when the HTML in the templateString is loaded?
In the end I solved the problem, so I write the workaround here and I hope it helps somebody!
I changed the templateString and added the attribute data-dojo-attach-point=\"form\" to the form that was not being found. Then in the postCreate method I accessed the form using this (this.form ), which worked without a problem. The final implementation for the function turned out as follows:
postCreate: function () {
// call base implementation
this.inherited(arguments);
//this._loadContacts(this.value);
var node = domConstruct.create("fieldset", { id: "test" }, this.form); //this simple create instruction returns undefined here.
//Bind button
this.connect(this.btnAdd, "onclick", dojo.partial(this._createContact, new Object()));
},
I still don't understand why dojo.byId("cccp") would return null, but I'm happy I found a workaround that solved the problem. Cheers!

condition editing using .editable(..) datatables

Im new to datatables, and Im having this issue thats bugging me for a while.
for example, I'm trying to edit the 5th column, but I want to disable it for part of the rows..
is it possible? cause I don't seem to find the way..
$('td:eq('5')', oTable.fnGetNodes()).editable('/'+appName+'/GetGenWidgetTableDataServlet',
{
type : 'text',
tooltip: 'Click to Edit',
indicator: 'Saving...',
placeholder : '',
"callback": function( sValue, y ) {
var aPos = oTable.fnGetPosition( this );
oTable.fnUpdate( sValue, aPos[0], aPos[2],true,true );
},
"submitdata": function ( value, settings ) {
debugger
var iPos = oTable.fnGetPosition( this );
var colPos = iPos[2];
iPos = iPos[0];
if(iPos!=null)
{
var aData = oTable.fnGetData( iPos );
var vRowType = aData[0];
var iId = aData[2];
var moduleID = iId.split("$")[0];
var unitID = iId.split("$")[1];
var processID = iId.split("$")[2];
var riskID = iId.split("$")[3];
var controlID = iId.split("$")[4];
}
return {
"Token": idhref,
"moduleID" :moduleID,
"unitID": unitID,
"processID" :processID ,
"riskID": riskID,
"controlID": controlID,
"rowType":vRowType,
"Action": "saveRow",
"columnName": aoCols[colPos]["Id"]
};
},
"height": "25px",
"width": "50px"
}
We use the datatables editable plugin (https://code.google.com/p/jquery-datatables-editable/ ) and it allows you to set a sReadOnlyCellClass. We set that class in the datatable fnRowCallBack function based on the values in the row.
You could set an "editable" class in your fnRowCallBack
oTable = $('#resultTable').dataTable( {
...
"fnRowCallback": function( nRow, aData, iDisplayIndex ) {
if ( aData["something"] == "This row should be editable" )
{
nRow.className = "editable";
}
return nRow;
}
...
});
and modify your selector to
oTable.$('tr.editable td:eq(5)').editable( ...)