In this piece of code:
var disable = { inputLabelBox : false, nodeIpInput: false, checkBox: false};
var checkDeviceNameExists = function(devices, form) {
return devices.some(function(element) {
nameExists = deviceNameMap(form, element);
if (nameExists) {
form.address.$setViewValue(nameExists);
form.address.$render();
if (!disable.checkBox || !disable.nodeIpInput) {
disable.checkBox = true;
disable.nodeIpInput = true;
checkBox.checked = false;
}
console.log(disable.checkBox);
return true;
} else {
return false;
}
});
}
Everything works out as it should, but I can't get the expect(disable.checkBox).toBe(true); to work. I get Expected false to be true instead. I have verified the console.log(disable.checkBox); is true. Any suggestions?
beforeEach(function() {
form = {};
form.label = {};
form.address = jasmine.createSpyObj("address", ["$setValidity", "$setViewValue", "$render"]);
form.$setValidity = jasmine.createSpy("$setValidity");
disable = { inputLabelBox : false, nodeIpInput: false, checkBox: false};
});
it("It should populate ip address because Vip label pre-exists", function() {
form.label.$viewValue = "myvip";
FormDeviceExistSvc.checkDeviceExists(form, "checkForVips");
expect(VipSvc.getVips).toHaveBeenCalled();
expect(form.address.$setViewValue).toHaveBeenCalledWith("10.11.11.1");
expect(disable.checkBox).toBe(true);
});
it("It should populate ip address because Vip label pre-exists", function() {
form.label.$viewValue = "myvip";
FormDeviceExistSvc.checkDeviceExists(form, "checkForVips");
expect(VipSvc.getVips).toHaveBeenCalled();
expect(form.address.$setViewValue).toHaveBeenCalledWith("10.11.11.1");
expect(FormDeviceExistSvc.disable.checkBox).toBe(true);
expect(FormDeviceExistSvc.disable.nodeIpInput).toBe(true);
expect(FormDeviceExistSvc.checkBox.checked).toBe(false);
});
I needed to use full service name FormDeviceExistSvc to access the value FormDeviceExistSvc.disable.checkBox.
Also, note: In testing, you only want to test what is public, not private. So... anything from the service that is return {} can be tested.
Related
I'm using code I found online to convert a standard option set field to a checkbox in MS CRM 2015 online. It keeps giving me the above error.
Here is the code:
function MultiPickList3(param1, param2, param3,param4,param5)
{
try
{
var fn = arguments.callee.toString().match(/function\s+([^\s\(]+)/);
if (param1==null || param2==null)
{
alert("Error: Parameter missing. \n Format: <optionset fieldname> , <option value text field> , [<option header>], [<select color>] , [<deselect color>] , \n ["+"Function="+fn[1]+"]" );
return true;
}
var tparamtype=Xrm.Page.data.entity.attributes.get(param1).getAttributeType();
if (tparamtype!="optionset")
{ alert (param1+"(first parameter) should be of type optionset \n"+"[function="+fn[1]+"]");
return true;
}
var tparamtype=Xrm.Page.data.entity.attributes.get(param2).getAttributeType();
if (tparamtype!="memo")
{ alert (param2+"(second parameter) should be of type memo (text with mutiline) \n[function="+fn[1]+"]");
return true;
}
var plOptions=param1;
var plText=param2;
var plMenuItem="View Selected List";
var SelectedList_orig = crmForm.all[plText];
var FullList=crmForm.all[plOptions];
var SelCtr=-1;
var new_selColor="orange";
var new_deSelColor="white";
if (param4!=null)
new_selColor=param4;
if (param5!=null)
new_deSelColor=param5;
var SelectedList =SelectedList_orig.value.split("\r\n");
crmForm.all[plText].style.display="none";
if(FullList!=null && SelectedList!=null)
{
initColor();
if (param3!=null && param3!="")
{
plMenuItem=param3;
}
else
{
plMenuItem=FullList.options[0].text;
changeColor("grey",0);
}
for (var ctr=0; ctr<SelectedList.length;ctr++)
{
selCtr=SelectedIndex(SelectedList[ctr]);
if (selCtr >-1)
{
changeColor(new_selColor,selCtr);
}
}
}
function SelectedIndex(selectedText)
{
var FullListText;
for (var ctr1=0; ctr1<FullList.options.length;ctr1++)
{
FullListText=FullList.options[ctr1].text;
if ( FullListText==selectedText)
{
return ctr1;
}
}
return -2;
}
crmForm.all[plOptions].attachEvent('onchange', OnChangePL);
function OnChangePL()
{
var SelCtr=-1;
var sel=crmForm.all[plOptions].SelectedText;
if (sel==plMenuItem)
return;
SelCtr=SelectedIndex(sel);
var SelColor="grey";
SelColor=crmForm.all[plOptions][SelCtr].style.backgroundColor;
if (SelColor==new_selColor)
{
changeColor(new_deSelColor,SelCtr);
saveChanges(sel,selCtr,"del");
}
else
{
changeColor(new_selColor, SelCtr);
saveChanges(sel,selCtr,"add");
}
}
function saveChanges(p_selText,p_SelCtr,p_mode)
{
switch(p_mode)
{
case "add":
SelectedList.push(p_selText);
break;
case "del":
for (var ctr2=0;ctr2<SelectedList.length;ctr2++)
{
if (SelectedList[ctr2]==p_selText)
{
SelectedList.splice(ctr2,1);
break;
}
}
break;
}
Xrm.Page.getAttribute(plText).setValue(SelectedList.join("\r\n"));
}
function initColor()
{
for (var ctr3=0; ctr3<FullList.options.length;ctr3++)
{ changeColor(new_deSelColor, ctr3); }
}
function changeColor(newColor, newCtr)
{
crmForm.all[plOptions][newCtr].style.backgroundColor=newColor;
}
}
catch (e)
{ alert (e.description);}
}
param2 takes the field "new_textholder" which is a multiline text field. It's defined on the form and I have checked to make sure I am writing it correctly.
What could be the problem?
Thank you!!
This error is likely coming from the crmForm.all[plText] line. I'm guessing your org is recent enough that support for the old 4.0 api is no longer present, which would mean that the all object is no longer available, which would give you that error (plText is set to the value of param2). You might be able to modify this code to work on your 2015 form, but I don't have a 2015 org available to me at the moment so I can't say for sure.
Project: jsp + AngularJS
I have a modal, where I already pass some info to my Java controller via POST (ajax), it works fine.
But, I inserted a new component and I do not know how to receive my selected list of the picklist component, check image to understand:
For example, I have there fields I pass via POST to my java controller and works fine:
$scope.cadastraCertificado = function() {
$http.post('/boxmlV2/cadastrocertificado/salvaCertificado', {
urlCertificado : $scope.certificadoIncluirAlterar.urlCertificado,
dataValidadeCertificado : $scope.certificadoIncluirAlterar.dataValidadeCertificado.toString(),
senhaCertificado : $scope.certificadoIncluirAlterar.senhaCertificado
//picklist????????
}).then(function(response) {
$scope.sucesso();
}, function(response) {
});
};
But I do not know how to receive data from my list selected in the picklist component, the ones from the right side.
How can I do that?
My picklist:
<div class="form-group">
<label class="control-label col-md-3">Empresas:</label>
<div class="col-md-9">
<select ng-model="corvo" multiple="multiple" class="multi-select" id="my_multi_select1" name="my_multi_select1[]">
<option ng-repeat="c in clientes" value="{{c.idCliente}}" ng-click="atribuirUm($index, c)">{{c.razaoSocial}}</option>
<option selected ng-repeat="c2 in clientes2" value="{{c2.idCliente}}" ng-click="limparUm($index, c2)">{{c2.razaoSocial}}</option>
</select>
</div>
</div>
$scope.corvo will contain an array with the IDs (the values) of the selected elements, so you can just send that array:
$http.post('/boxmlV2/cadastrocertificado/salvaCertificado', {
urlCertificado : $scope.certificadoIncluirAlterar.urlCertificado,
dataValidadeCertificado : $scope.certificadoIncluirAlterar.dataValidadeCertificado.toString(),
senhaCertificado : $scope.certificadoIncluirAlterar.senhaCertificado,
corvo: $scope.corvo
}).then(function(response) {
$scope.sucesso();
}, function(response) {
});
I assume you are sending JSON data, otherwise you have to serialize it to a string, for example using $scope.corvo.join(',').
This is how my js looks like after working ok:
BoxApp.controller("CadastroCertificadoController", function($scope, $http) {
$scope.clientes = {};
$scope.listaEmpresas = [];
$scope.iniciar = function() {
$http.get('/boxmlV2/cadastrocertificado').success(function(response) {
$scope.clientes = response;
});
};
$scope.iniciar();
/**
* Trabalhando o componente picklist
*/
$scope.clientes2 = [];
$scope.atribuirUm = function(index, c) {
var cliente = {};
cliente.idCliente = c.idCliente;
cliente.razaoSocial = c.razaoSocial;
$scope.clientes2.push(cliente);
$scope.clientes.splice(index, 1);
}
$scope.limparUm = function(index, c2) {
$scope.clientes2.splice(index, 1);
$scope.clientes.push(c2);
}
/**
* Trecho para validar o form ao submeter.
*/
$scope.submitted = false;
$scope.submitForm = function(form, clientes2) {
$scope.listaEmpresas = $scope.clientes2;
$scope.submitted = true;
if (form.$valid) {
$scope.cadastraCertificado();
}
};
/**
* Requisição POST (ajax)
*/
$scope.cadastraCertificado = function() {
var dados = {
urlCertificado : $scope.certificadoIncluirAlterar.urlCertificado,
strDataValidadeCertificado : $scope.certificadoIncluirAlterar.strDataValidadeCertificado.toString(),
senhaCertificado : $scope.certificadoIncluirAlterar.senhaCertificado,
listaEmpresas : $scope.listaEmpresas
};
$http.post('/boxmlV2/cadastrocertificado/salvarCertificado', dados).then(function(response) {
}, function(response) {
$scope.sucesso();
});
};
$scope.sucesso = function() {
$scope.closeMyPopup();
$scope.iniciar();
};
$scope.closeMyPopup = function() {
$(myModal_autocomplete).modal('hide');
};
});
I'm trying to somehow dynamically use i18next translations together with Knockout.js, but I cant figure out how.
Neither a custom Knockout binding or the i18next jQuery plugin seems to work with observable values.
A demo of what I'm trying to achieve can be found here: http://jsfiddle.net/rdfx2/1/
A workaround is something like this, but I'd rather avoid that, if possible:
<div data-bind="text: translate('key', observable)"></div>
self.translate = function (key, value) {
return i18next.t(key, {
"var": value
});
};
Thanks,
I'm not very familiar with i18next, so I might be using i18next incorrectly, but you could easily achieve this by creating a bindingHandler. A very simple version of such a bindingHandler, which supports passing optional options, could look like:
ko.bindingHandlers['translatedText'] = {
update: function(element, valueAccessor, allBindings){
var key = ko.unwrap(valueAccessor());
var options = ko.toJS(allBindings.get('translationOptions') || {});
var translation = i18n.t(key, options);
element.innerText = translation;
}
};
Given the following i18next initialization code:
i18n.init({
lng: "en",
debug: true,
resStore: {
en: {
translation: {
'myTextKey': 'My translated value is "__value__"',
'otherTextKey': 'This is just a text which does not use options'
}
}
}
});
You could use it with the following HTML:
<input type="text" data-bind="value: input, valueUpdate: 'afterkeydown'"/>
<div data-bind="translatedText: 'myTextKey', translationOptions: { value: input }"></div>
<div data-bind="translatedText: 'otherTextKey'"></div>
And the following view model:
function ViewModel(){
this.input = ko.observable();
}
ko.applyBindings(new ViewModel);
I have saved the above code to a jsfiddle which you can find at http://jsfiddle.net/md2Hr/
I've updated the code to support translating HTML attributes as well.
Here is a working demo: http://jsfiddle.net/remisture/GxEGe/
HTML
<label>HTML/text</label>
<textarea data-bind="i18n: 'key', i18n-options: {var: input}"></textarea>
<label>Attribute</label>
<input type="text" data-bind="i18n: '[placeholder]key', i18n-options: {var: input}" />
JS
define(['knockout', 'i18next'], function (ko, i18n) {
ko.bindingHandlers.i18n = {
update: function (element, valueAccessor, allBindings) {
var key = ko.unwrap(valueAccessor()),
options = ko.toJS(allBindings.get('i18n-options') || {}),
translation,
parts,
attr;
// Check whether we are dealing with attributes
if (key.indexOf('[') === 0) {
parts = key.split(']');
key = parts[1];
attr = parts[0].substr(1, parts[0].length - 1);
}
translation = i18n.t(key, options);
if (attr === undefined) {
// Check whether the translation contains markup
if (translation.match(/<(\w+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/)) {
//noinspection InnerHTMLJS
element.innerHTML = translation;
} else {
// Check whether the translation contains HTML entities
if (translation.match(/&(?:[a-z]+|#x?\d+);/gi)) {
//noinspection InnerHTMLJS
element.innerHTML = translation;
} else {
// Treat translation as plain text
element.innerText = translation;
}
}
} else {
// Add translation to given attribute
element.setAttribute(attr, translation);
}
}
};
});
KO config:
var language = ko.observable('');
ko.i18n = function(key) {
return ko.computed(function() {
if (language() != null) {
return i18n.t(key, {
lng : language()
});
} else {
return "";
}
}, key);
};
view-model:
var labels = {
aboutUs: ko.i18n('app:labels.aboutUs'),
contactUsBtn: ko.i18n('app:labels.contactUsBtn') }
view:
<span data-bind="text: labels.aboutUs">
Thanks for a great example, #robert.westerlund!
I slightly modified your example to better fit my needs:
ko.bindingHandlers['i18n'] = {
update: function (element, valueAccessor, allBindings) {
var key = ko.unwrap(valueAccessor()),
options = ko.toJS(allBindings.get('i18n-options') || {}),
translation = i18next.t(key, options);
// Check whether the translation contains markup
if (translation.match(/<(\w+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/)) {
element.innerHTML = translation;
} else {
// Check whether the translation contains HTML entities
if (translation.match(/&(?:[a-z]+|#x?\d+);/gi)) {
element.innerHTML = translation;
} else {
// Treat translation as plain text
element.innerText = translation;
}
}
}
};
I have the following html:
<div ng-show=showMarketingNav>
...
</div>
<div ng-show=showProductsNav>
...
</div>
<div ng-show=showSettingsNav>
...
</div>
What I want to do is to easily be able to hide all but one of the divs from another controller. I thought I could be clever and do the following:
var subNavMenuDisplays = {
Marketing: $scope.showMarketingNav,
Products: $scope.showProductsNav,
Settings: $scope.showSettingsNav
}
$rootScope.hideContextMenu = function () {
for (var category in subNavMenuDisplays) {
subNavMenuDisplays[category] = false;
}
}
$rootScope.setContextMenu = function (name) {
$rootScope.hideContextMenu();
subNavMenuDisplays[name] = true;
}
but this obviously does not work as $scope.showMarketingNav etc. will be passed as value, not reference.
The following works, but is not exactly nice to work with:
$rootScope.hideContextMenu = function () {
$scope.showMarketingNav = false;
$scope.showProductsNav = false;
$scope.showSettingsNav = false;
}
$rootScope.setContextMenu = function (name) {
$rootScope.hideContextMenu();
if (name == "Marketing") {
$scope.showMarketingNav = true;
}
if (name == "Products") {
$scope.showProductsNav = true;
}
if (name == "Settings") {
$scope.showSettingsNav = true;
}
}
Is there a way to grab $scope.showMarketingNav by reference, or another clever way around this?
I'd prefer not using eval to concatenate variable names.
You can place an object on the $scope and then toggle it dynamically:
$scope.show = {};
$rootScope.setContextMenu = function (name) {
$scope.show = {};
$scope.show[name] = true;
}
And the Html:
<div ng-show="show.Marketing">
...
</div>
<div ng-show="show.Products">
...
</div>
<div ng-show="show.Settings">
...
</div>
Here's a plunker demonstrating the change.
You can assign simple updater functions in that object:
Marketing: function(val) { $scope.showMarketingNav = val },
Products: function(val) { $scope.showProductsNav = val},
Settings: function(val) { $scope.showSettingsNav = val}
Then call it:
subNavMenuDisplays[name](true);
I have created an object where i need to assign some variables(parameters) and when the object is called, the variables(parameters) change. Here is my code:
var Modal = {
init: function () {
contact1: "";
contact2: "";
aboutus1: "";
aboutus2: "";
privacy1: "";
privacy2: "";
terms1: "";
terms2: "";
$(".modaltrigger").removeAttr("target");
$(".modaltrigger").click(function () {
if ($(this).is("#contact")) {
$('#primary_url').attr('href', contact1);
$('#secondary_url').attr('href', contact2);
} else if ($(this).is("#aboutus")) {
$('#primary_url').attr('href', aboutus1);
$('#secondary_url').attr('href', aboutus2);
} else if ($(this).is("#termsconditions")) {
$('#primary_url').attr('href', terms1);
$('#secondary_url').attr('href', terms2);
} else if ($(this).is("#privacy")) {
$('#primary_url').attr('href', privacy1);
$('#secondary_url').attr('href', privacy2);
}
});
}
};
I am trying to initialize the object above, and it does not work:
Modal.init(
contact1: "http:www.test1.com";
contact2: "http:www.test2.com";
aboutus1: "http:www.test3.com";
aboutus2: "http:www.test4.com";
privacy1: "http:www.test5.com";
privacy2: "http:www.test6.com";
terms1: "http:www.test7.com";
terms2: "http:www.test8.com"
);
it is Done like this way,
i Guess this is what you want to do.
var Modal = {
init: function (args) {
//then access your values like this
contact1= args.contact1;
contact2 = args.contact2;
..........
.........
.........
}
}
And to initiate this method you have write as
Modal.init({
contact1:"contact str",
contact2:"contact str",
.....
.....
lastitem : "last str"
});