I want to call a JS function on load of cq dialog to validate if a field already has something if so, disable it from the edition. I have tried with validation but it is called after the users interact with the field, I need a way to do it before when is being loaded. Is it possible?
<id
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="ID"
validation="is_empty" // DO THIS WHEN IS LOADED
name="./id"
required="{Boolean}true"/>
I can think of a way to achieve this using cq.authoring.dialog clientlib and jQquery
Create a clientlib with categories as cq.authoring.dialog. Scripts in this clientlib are loaded only in the author instance.
Add a class to the text field using the granite:class attribute, this is to hook onto the textfield using script in the above clientlib
<id
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="ID"
granite:class="readonlySelector"
name="./id"
required="{Boolean}true"/>
You will have to include the below namespace in dialog.xml to usegranite:class.
xmlns:granite="http://www.adobe.com/jcr/granite/1.0"
Notice the class name registered above in the DOM
Use one of the OOTB granite event listeners like foundation-contentloaded to fire the script on initialization of the dialog. You could probably use a more narrower event, check out granite documentation for more events
Use the Coral UI Textfield documentation to find out supported attributes. disabled and readonly are supported. Place this code in the cq.authoring.dialog clientlib.
$(document).on('foundation-contentloaded', function (e) {//event fires when dialog loads
var $textField = $('.readonlySelector');
if ($textField.val()) {//truthy check
$textField.prop('disabled', true);//Greys the field
$textField.prop('readonly', true);
}
})
Grayed and disabled
Related
I have web page with two textboxes on it. Upon clicking on the first, I have a bootstrap modal that displays with a searchable treeview. You click an item in the treeview, the modal closes, and the selection appears in the textbox. Works perfectly!
Now I have decided that for the other textbox I want to do the same thing. The only difference is the modal has a different title, and the source data for the modal treeview comes from a different endpoint. All the other javascript to support searching and highlighting within a treeview, opening and closing a modal, etc, is the same.
To get it to work, I duplicated all html for the modals and the js code and just changed the ID's to avoid clashes between the two. I cannot live with myself for doing this!
So in the end, I have some js and html that work together as a component that I want to reuse on a page among several textboxes or whatever type of widget I may create. How can I design my app so I can share this code and not duplicate it all over the page?
I think webcomponents is the way to go. You could create a component that receives the id and other needed data as parameters and then create instances of it...
There is a lot to unpack in this question. High level, to achieve what you're asking with JS…
You could:
Build a method that accepts an event object (or jQuery event object) as its argument; and handles extracting extracting data from the attributes of that element, setting the title, AJAXing the treeview, and returning the selection/setting the text box value
embed the unique data in data-attributes on each text box
set the click event listener to pass the event.target element, with its unique data- attributes to the method
Markup:
<input type="text" id="foo" data-endpoint="/path/to/endpoint_1" data-title="Modal Foo" value="" />
JS
function on_click_modal_spawning_textbox( event ) {
// get the salient data from the `data-` attributes on the `event.target`
// do modal stuff, programmatically replace the modal title, AJAX treeview, et cetera…
}
// assuming you're using jQuery, otherwise this would be a vanilla `.addEventListener()`
$( document ).on( 'click', 'input[ data-endpoint ]', on_click_modal_spawning_textbox );
I am somewhat familiar with HTML, CSS and JavaScript and have written some small apps using Angular and Ionic.
Now I am working with IBM BPM Coach Views and tries to make a simple Coach View
with an input field (bound to a string variable) and a button.
I would like to have the button disabled (in BPM language: read only) as long as
the field is empty, but when the user starts to type anything in the field, the button should become enabled. I have bound the visibility of the button to another string variable.
I have searched around and it seems I cannot find any simple examples of controlling visibility based on keypress events in BPM.
All I have seen are examples with Dojo components and Dijit widgets and currently that is a bit above my head. I would expect there must be some (relatively) simple way of doing it with some 20-40 lines of JavaScript in either the “Inline JavaScript” section or in one (or more) of the “Event Handlers” on the Behavior tab in the Coach View Designer in IBM BPM 8.5.6.
(it opens in a browser window because my Coach View runs in a Client Side Human Service).
Does anyone have such a simple example.
I would suggest you following approach.
Create one custom coach view (lets say CV1).
Within CV1 drag ibm bpm provided input text CV (give control id name as "inputText").
Within CV1 drag ibm bpm provided button CV (give control id name as "button").
Within inline JS or load event of CV1 write following code.
// get input text elment
var inputText = dojo.query("data-viewid['inputText']",this.context.element);
var button = dojo.query("data-viewid['button']",this.context.element);
//make button as disabled by default
button.setAttribute('disabled', true);
//key press event on input text
inputText.on("keydown", function(event) {
//Write your custom logic on key press
button.setAttribute('disabled', false);
});
What you are trying to achieve is validation script in "Data Change" tab of coach but if you want using events, use onInput or onChange even of input text coach view
if(me.getData()){
${viewId_of_button}.setEnabled(true);
}
else ${viewId_of_button}.setEnabled(false);
Product keeps updated, so look for code best for your version.
Note- if you use onChange, user may have to click outside the input field to trigger change event.
I have fields where multiple extra fields can be added after the page loads (think education & work experience fields on job resumes). I am using this.
I can add a datepicker on the first field, but subsequent added fields do not access the datepicker, despite being cloned/essential duplicates of the original. I'm guessing that the datepicker only intializes on page load or for only one class on the page.
So on a page I initialize the datepicker:
$('.input-append.date').datepicker();
for a block of form code encapsulated by this class. OK for initial page load; and also OK if there is an error and the page reloads multiple fields previously input(there is a datepicker for all fields returned with any error). However, with another js function that adds new fields to the form, additional new fields do not have access to the datepicker. I do not see how to do this now, perhaps someone with more experience/wisdom can provide me a hint.
EDIT:
Simple enough: I simply added:
$('.input-append.date').datepicker();
to the code calling the new field. As to being the optimal solution I do not know, anyone who specializes in js can comment on that, and there are many other similar questions here I found once I expanded my search terms. However, good enough for me now in what I'm doing.
For elements which are being added on fly use data-provide="datepicker" attribute. It will be initialized lazily. For example if an input field is coming up in an ajax response and loaded in a container div. So in this case:
<input type="text" data-provide="datepicker" />
so when when you will load this ajax response it in cotainer div like
$('#container-div').html(ajax_response);
this will work.
In the same way if you are creating an element through jquery and appending it to some container (I think this is happening in your case), for example you have a function that creates textbox and append it to some container div and this function is called on click event of some element let's say it's button. Again data-provide attribute is the solution to this problem. For example
function createTextBox(){
var t = $('<input>').attr('data-provide','datepicker');
$('#container-div').append(t);
}
And this function is called on click event of some button like in this way:
$(document).ready(function(){
$('#someBtn).click(createTextBox);
});
In short whether that dynamic element is coming in ajax response as a string or being created through jquery, just use data-provide attribute to set bootstrap datepicker. Because in this case datepicker is initialized lazily in Bootstrap fashion.
I am using ryanfait.com custom form elements to change the appearance of my dropdown lists in my .net web application. Everything works fine except for .net postbacks on dropdown lists. Having looked at the javascript code for custom work elements I have noticed that the onchange event is overwritten:
if(!inputs[a].getAttribute("disabled")) {
inputs[a].onchange = Custom.choose;
} else {
inputs[a].previousSibling.className = inputs[a].previousSibling.className += " disabled";
}
If I comment out the above code the autopostback works but for other dropdownlists which do not require an autopostback the input value now does not change. Is there a way I can get this working for both scenarios? On ryanfait.com he says:
onChange and other JavaScript events
This script utilizes JavaScript's onChange and other events. Because these events can only be used once, if you want to add more functions to an event, you will need to call them from inside my script.
But I can't work out if I can somehow trigger the autopostback event?
Any help would be very much appreciated!
The easiest way do this is to add a a standard asp:dropdownlist with autopostback, preview your page and then view source, find the list in the HTML source and copy the onChange property. this is what you need to call client side to post the page back.
eg.
onchange="javascript:setTimeout('__doPostBack(\'ddlHolidayType\',\'\')', 0)"
Hopefully a quick one...
I need to fire the uncheckAll event in the click event of a separate button on my page, I have tried the following:
$('.masterProviderOrgsListBox').multiselect().uncheckAll();
but this isnt a recognised method. I basically want to fire the same method that is fired when you click the "Uncheck All" box in the header.
I was previously doing this:
$('.masterProviderOrgsListBox option:selected').removeAttr("selected");
but this removes the selections on the actual multiselect rather than the jQuery UI widget.
Couldnt find anything in the documentation, any ideas?
Methods
After an instance has been initialized, interact with it by calling
any of these methods:
// example: $("#multiselect").multiselect("method_name");
...which can be found in the widgets documentation under Methods
$("#multiselect").multiselect("uncheckAll");
1) first, you need to set default value of the control.
jQuery('#multiselect').val("");
2) Then, execute below code to reset the control.
jQuery('#multiselect').multiselect("refresh");
$("#multiselectoption:selected").removeAttr("selected");
$("#multiselect").multiselect('refresh');
refresh should be call after clearing the drop down.