I'm using bootstrap Tokenfield library. I have a case in my project saying that I can edit tokens by clicking, but not typing, I have special form for adding new pills.
Is there a way to disable typing in input form, but still have an access to removing and adding pills by clicking?
You can set showAutocompleteOnFocus for mouse focus so there is not any need to use keyboard for add token or remove token, example code :-
$('#tokenfield').tokenfield({
autocomplete: {
source: ['red','blue','green','yellow','violet','brown','purple','black','white'],
delay: 100
},
showAutocompleteOnFocus: true
});
$("#tokenfield").keydown( function(key) {
return false;
});
I had a similar requirement in a project I'm working on, all the tokens are defined using a form, our requirement dictate that the user could remove a token, but not edit or add new tokens in the input, only using the provided form. My "solution" was a bit hacky: bootstrap-tokenfield adds a new input in the DOM for the user to type text that is ultimately transformed into tokens, you can disable this input and effectively prevent the user for typing new tokens.
By default the new token receive an id with the format id-tokenfield where id is the id of the original input. If no id es provided on the original input then a random number is used instead.
So disabling this input:
$('#search-tokenfield').prop('disabled', 'disabled');
Prevents the user from creating new tokens, while keeping the chance to edit/delete tokens. In my case search is the id of the original input.
You can disable the input with id "tokenfield-tokenfield" after the token is created, and enable it back when it is removed.
$('#tokenfield').on('tokenfield:createdtoken', function (e) {
$('#tokenfield-tokenfield').prop('disabled', true);
});
$('#tokenfield').on('tokenfield:removedtoken', function (e) {
$('#tokenfield-tokenfield').prop('disabled', false);
});
Related
I want to customise invalid fields warning.
I want that user should close the warning instead of automatically disappearing warnings. The reason is suppose there are multiple fields that are required and user clicks on save and got invalid field warning but it disappears after 4-5 second. So user can't see the required fields properly and he have to again click on the save button and check what are those required fields.
I have tried to customise the below default method but it doesn't work for me:-
/web/static/src/js/views/basic/basic_controller.js
_notifyInvalidFields: function (invalidFields) {
var record = this.model.get(this.handle, {raw: true});
var fields = record.fields;
var warnings = invalidFields.map(function (fieldName) {
var fieldStr = fields[fieldName].string;
return _.str.sprintf('<li>%s</li>', _.escape(fieldStr));
});
warnings.unshift('<ul>');
warnings.push('</ul>');
this.do_warn(_t("Invalid fields:"), warnings.join(''));
},
Do anyone have any idea how to change this thing or any other method is used to show this warning?
I have a form master detail for tabular input and with enabledAjaxValidation=true
So far so good, the form validates all the rules and shows the error messages when submitting or changing any value of any control (onchange event). The problem comes when I add controls to the form using ajax, the latter do not behave like the original ones, they do not show the error messages.
The same when do submit with button
I think that
You need to add the newly created/added field to the validation manually for any dynamically created inputs using the yiiActiveForm.add() function.
You havent added the code you are currently using when you click on the button and add a new input to the form via ajax. So what you need to do is when you receive the response and append the input to the form just add the new input using the following code.
Note: Change the form and field attributes accordingly
$('#form-id').yiiActiveForm('add', {
id: 'input-id',
name: 'input-name',
container: '.field-input',
input: '#input-id',
error: '.help-block',
validate: function (attribute, value, messages, deferred, $form) {
yii.validation.required(value, messages, {message: "Validation Message Here"});
}
});
Read more about the activeform valiadation js
Update
If you dont wish to add the validation function manually for every input and you have tabular inputs you can access any of the already created similar field and bind the validation function from it.
For instance in the above example if the the name field is tabular and belongs to the model Contact and you already have a name field populated in the form #contact-0-name you can use the yiActiveForm.find() function to access the attributes of that field and assign the existing validation. see an example below
var fieldAttributes = $("#form-id").yiiActiveForm("find", 'contact-0-name');
$('#form-id').yiiActiveForm('add', {
id: 'contact-1-name',
name: '[1][name]',
container: '.field-name',
input: '#contact-1-name',
error: '.help-block',
validate: fieldAttributes.validate
});
use somthing like below code
error: function(jqXHR,textStatus,errorThrown) {
stopLoader('.modal-content');
$('.csv_errors').show();
if(jqXHR.status==422){
var responseText = $.parseJSON(jqXHR.responseText);
$.each(responseText.errors,function(key,value){
$('.csv_error ul').append('<li>'+value+'</li>');
});
}else{
var responseText = $.parseJSON(jqXHR.responseText);
$('.csv_error ul').append('<li>'+responseText.message+'</li>');
}
}
In Dynamics CRM 2013 is it possible to revert a field changed on a form when a business process error occurs?
For example:
1. User changes a text field on a form from 'abc' to 'xyz'
2. User clicks save
3. CRM pre-operation plugin validates field, 'xyz' not allowed, exception thrown
4. CRM displays business process error to user, 'xyz' is not allowed
5. The value 'xyz' is still shown in the form
The desired behavior we want is 'xyz' to revert to 'abc' in step 5.
You will need to cache the data first. You can do this OnLoad, e.g. by memorizing the entity's attribute values:
function GetInitialAttributeState() {
var preImage = {};
Xrm.Page.data.entity.attributes.forEach(function(field) {
// TODO: for lookup attributes you need to do extra work in order to avoid making merely a copy of an object reference.
preImage[field.getName()] = field.getValue();
});
return preImage;
}
window.preImage = GetInitialAttributeState();
Then you need to perform the save operation through the Xrm.Page.data.save method. Pass a callback function handling errors and resetting the fields, e.g.
Xrm.Page.data.save().then(
function() {
/* Handle success here. */
window.preImage = getInitialAttributeState();
},
function() {
/* Handle errors here. */
Xrm.Page.data.entity.attributes.forEach(function(field) {
if (field.getIsDirty()) {
field.setValue(preImage[field.getName()]);
}
});
});
It is not possible to reset the form's fields this way using the save event, because it kicks in before the actual save operation, never after it.
Why let the user save the record at all?
You could use a Business Ruel to validate the field, and set an error condition against the field for values you don't "like". The error condition will persist and prevent them saving the record until they change the value. The error message can give them some explanation as to why their value is not valid.
Obviously the validation you can do in a Business Rule is limited, but your example does not make it clear on what basis we match "xyz" as a "bad" value.
I need to update entity1 based on creation of entity2 (math calculation)
while the form of entity1 is open.
When I refresh the entity1 form, the field has the old value until I close and open the entity1 form (the caching issue).
I found out that it doesn't fire the Retrieve Plugin. Is there a way to overcome this issue just by refreshing the form?
First and foremost: latest CRM has Xrm.Page.data.refresh() to update form data "automagically" (not to mention the fact that fields self-refresh when changed via plugins).
If upgrading is not an option, I'd setup a "watcher" function like this:
// attach to Form Load event
function keepYourFieldInSync() {
setInterval(function(){
var current = Xrm.Page.getAttribute("yourField");
// Not shown here, basically get the updated value from server
var fetched = fetch_yourField_value_from_OData_or_SOAP();
if(fetched != current){
Xrm.Page.getAttribute("yourField").setValue(fetched);
// if users aren't allowed to set the field by hand, I'd also include this
// and customize the field to be readonly
Xrm.Page.getAttribute("yourField").setSubmitMode("never");
}
}, 1000); // keep it above 500 to avoid killing the browser
}
I use a "trick" like this to recognize status changes in Quotes (another user would activate it while this user was working on the draft) and it works quite well.
I have an input field with a value binding. The binding references a writable computed observable.
The intended behavior is:
a user types some letters: The writable computed should recognize the user is still typing
a user finishes typing: The writable should save the value
However, I only can choose updateValue: 'input' or updateValue: 'keydown', but not both. In the JavaScript code, the writable computed is not able to check which event occurred.
I need this behavior for this reason: if the user is just typing I want to fill an auto-suggestion box and want to bold the already typed letters. For this I need the keydown event. But if the user finishes typing (losing focus) I want to do some verification and then save the entered value.
If I use input the verification is working but the auto-suggestion feature is broken. If I use keydown the user isn't able to type something, because the verification always fails and the user cannot finish typing.
Suppose you have computed named self.inputValue which references to the input field.
You can apply rateLimit extender on perticular computed..
e.g.
self.inputValue = ko.computed(function(){
//perform the required logic
}).extend({ rateLimit: { method: "notifyWhenChangesStop", timeout: 400 } });;
where timeout is in miliseconds. It will hold the updation or notification of value for 400 miliseconds.
This should solve your problem. A small JSFiddle I've made for you : http://jsfiddle.net/rahulrulez/x8jmcpLh/
rateLimit was introduced in KO 3.1.0, if you are using old library then use throttle instead.