I have an issue with getting default value of select dropdown.
i have fruits val:
val fruits = List("apple", "banana", "other")
and i render a tr with:
<tr id={ theLine.guid }>
<td>
{
SHtml.ajaxSelect(fruits, Full(fruits(0)),
s => {
mutateLine(theLine.guid) {
l => Line(l.guid, l.name, s, l.note)
}
Noop
})
}
</td>
(...)
on page html is rendered correctly with option selected="selected", but when i try to save it to DB i get empty value of fruit. if i change option to 'other' and then i select it back to 'apple', it saves right value.
i add also a println function to addLine to see what values are in this vector, and there is empty value if i dont change fruit option, so i suppose that it is not problem when i process lines to save it to DB.
can you help me with this?
thanks
Gerard
Before you change your select option, you are not triggering the event that calls your function. The function is bound to onChange and that only gets fired when the value changes.
To fix, you could either: Start with an option like "Select a value". This would require the user to change the item, but is the only way to trigger the onchange.
If you don't want to do that, you could add a button and add your logic to a button click handler that would get called when submitted. Something like this should help - you'll need to bind it to your output, either inline as you provided, or via CSS Selectors:
var selected = Full(fruits(0))
SHtml.ajaxSelect(fruits, selected,
s => {
selected = Full(s)
Noop
})
SHtml.ajaxSubmit("Submit", () => {
mutateLine(theLine.guid) {
l => Line(l.guid, l.name, selected, l.note)
}
})
Related
I'm creating a dynamic page in Wix which goes pretty well. Only struggling with one thing. I want a textfield in a repeater that is linked to a boolean in a database to display one text or another depending on the state of the boolean.
Because you mentioned you're on a dynamic page, I assume your repeater is connected to a dataset. This makes things a little more complicated because you have to wait for the dataset to load. If you would use onItemReady() to set your field values, the dataset would just overwrite them.
You want to do something like this:
$w.onReady(function () {
$w('#dataset1').onReady( () => {
$w('#repeater1').forEachItem( ($w, itemData, index) => {
if(itemData.boolField){
$w('#boolText').text = "Yes Ma'am!";
}
else {
$w('#boolText').text = "No way Jose!";
}
} );
} );
} );
Basically, you wait for the dataset to be ready, then loop through all the items in your repeater using the forEachItem() callback, and reset the value of the text field based on the value in the boolean field.
I wrote a function to update Validator rules on an input if a certain option was selected, using this method (the forms are built using FormGroup):
onValueChanged(data : any) {
let appVIP1 = this.vip1TabForm.get('option1');
let appVIP2 = this.vip2TabForm.get('option2');
let appVIP3 = this.vip3TabForm.get('option3');
//Set required validation if data is 'option3'
if(data != 'option3') {
//Due to initialization errors in UI, need to start with the case
//That there are validations, check to remove them
appVIP1.setValidators([]);
appVIP2.setValidators([]);
appVIP3.setValidators([]);
}
else {
appVIP1.setValidators([Validators.required]);
appVIP2.setValidators([Validators.required]);
appVIP3.setValidators([Validators.required]);
}
}
And I bind that function call to a click event on radio buttons (I initially used the guide from this answer, but the onChange function didn't bind correctly).
This works great, and if the user selects option 1 or 2, the validations are empty, and won't be triggered. If they select option 3, the validations are shown and submission is stopped. However, I run into the problem where the user submits, sees the error, and goes back to change to option 1 or 2. While the validator is cleared, my form still reads as invalid. I have multiple input fields I am validating, so I can't just set the form to valid if the validator is removed this way. How would I go about doing this? Can I remove the has-error for one particular field in the formgroup?
If the correct validators are in place, you can manually call AbstractControl#updateValueAndValidity after they select an option:
this.formBuilder.updateValueAndValidity();
(Where, of course, this.formBuilder is your FormBuilder instance.)
You can also call it on FormElements directly.
This is commonly used to trigger validation after a form element's value has been programmatically changed.
Instead of removing and adding validations. It is more simple to enable and disable fields. You need to add the Validators.required for all required fields. And disable the fields which are not required.
onValueChanged(data : any) {
let appVIP1 = this.vip1TabForm.get('option1');
let appVIP2 = this.vip2TabForm.get('option2');
let appVIP3 = this.vip3TabForm.get('option3');
if(data != 'option3') {
appVIP1.disable();
appVIP2.disable();
appVIP3.disable();
}
else {
appVIP1.enable();
appVIP2.enable();
appVIP3.enable();
}
}
I'm trying to remove buttons in detail view of a Lead if it is alredy converted.
I saw a similar question and it use javascript to hide buttons. I'm trying to obtain same result via php.
This is my view.detail.php in custom\modules\Leads\views\ folder
class LeadsViewDetail extends ViewDetail {
function __construct(){
parent::__construct();
}
function preDisplay() {
parent::preDisplay();
if($this->bean->converted==1) {
echo "hide";
foreach ($this->dv->defs['templateMeta']['form']['buttons'] as $key => $value) {
unset($this->dv->defs['templateMeta']['form']['buttons'][$key]);
}
} else {
echo "show";
}
}
}
Using this code, after a Quick Repair & Rebuilt, I see "hide" or "show" correctly according to the Lead status but buttons are not updated correctly.
If I open a converted Lead after QR&R, I will never see the buttons.
If I open a unconverted Lead after QR&R, I will see the buttons all times.
I'm stuck with this situation. Can anyone explain me where is the problem? How I can solve it?
Every help is very appreciated.
You can probably handle this without extending the ViewDetail by using Smarty logic ("customCode") in custom/modules/Leads/metadata/detailviewdefs.php. It looks like the Convert button is already only rendered when the user has Edit privileges, so it's not a big deal to add one more condition to it...
$viewdefs['Leads']['DetailView']['templateMeta']['form]['buttons'][] = array('customCode' => '
{if $bean->aclAccess("edit") && $bean->converted}
<input title="{$MOD.LBL_CONVERTLEAD_TITLE}"
accessKey="{$MOD.LBL_CONVERTLEAD_BUTTON_KEY}"
type="button"
class="button"
name="convert"
value="{$MOD.LBL_CONVERTLEAD}"
onClick="document.location=\'index.php?module=Leads&action=ConvertLead&record={$fields.id.value}\'" />
{/if}');
Alternatively, if you do have several conditions and they'd get too messy or difficult for Smarty logic to be reasonable, we can combine a small amount of Smarty Logic with the extended ViewDetail.
This except of custom/modules/Leads/metadata/detailviewdefs.php is actually the out-of-the-box file from SugarCRM CE 6.5.24, where it looks like they've actually tried to make this customization easier by supplying a Smarty var $DISABLE_CONVERT_ACTION. For reference, it simply needs the global config variable disable_convert_lead to be set and enabled, but I suspect that this was a relatively new feature not included in earlier versions. Still, it's a good example of using the View to set a simple Smarty variable that we can pivot on:
<?php
$viewdefs['Leads']['DetailView'] = array (
'templateMeta' => array (
'form' => array (
'buttons' => array (
'EDIT',
'DUPLICATE',
'DELETE',
array (
'customCode' => '{if $bean->aclAccess("edit") && !$DISABLE_CONVERT_ACTION}<input title="{$MOD.LBL_CONVERTLEAD_TITLE}" accessKey="{$MOD.LBL_CONVERTLEAD_BUTTON_KEY}" type="button" class="button" onClick="document.location=\'index.php?module=Leads&action=ConvertLead&record={$fields.id.value}\'" name="convert" value="{$MOD.LBL_CONVERTLEAD}">{/if}',
//Bug#51778: The custom code will be replaced with sugar_html. customCode will be deplicated.
'sugar_html' => array(
'type' => 'button',
'value' => '{$MOD.LBL_CONVERTLEAD}',
'htmlOptions' => array(
'title' => '{$MOD.LBL_CONVERTLEAD_TITLE}',
'accessKey' => '{$MOD.LBL_CONVERTLEAD_BUTTON_KEY}',
'class' => 'button',
'onClick' => 'document.location=\'index.php?module=Leads&action=ConvertLead&record={$fields.id.value}\'',
'name' => 'convert',
'id' => 'convert_lead_button',
),
'template' => '{if $bean->aclAccess("edit") && !$DISABLE_CONVERT_ACTION}[CONTENT]{/if}',
),
),
We can combine this $DISABLE_CONVERT_ACTION reference with a custom/modules/Leads/views/view.detail.php like the following to set it based on whatever condition we want:
<?php
require_once('modules/Leads/views/view.detail.php');
class CustomLeadsViewDetail extends LeadsViewDetail {
/*
* while we might normally like to call parent::display() in this method to
* best emulate what the parnts will do, we instead here copy-and-paste the
* parent methods' content because LeadsViewDetail::display() will set the
* DISABLE_CONVERT_ACTION Smarty var differently than we want.
*/
public function display(){
global $sugar_config;
// Example One: Disable Conversion when status is Converted
$disableConvert = ($this->bean->status == 'Converted');
// Example Two: Disable Conversion when there is at lead one related Call
// where the status is Held
$disableConvert = FALSE;
$this->bean->load_relationships('calls');
foreach($this->bean->calls->getBeans() as $call){
if($call->status == 'Held'){
$disableConvert = TRUE;
break; // exit foreach()
}
}
// Example Three: Disable Conversion if the User is in a specific Role, e.g.
// Interns who are great for data entry in Leads but shouldn't be making
// actual sales
global $current_user;
$disableConvert = $current_user->check_role_membership('No Lead Conversions');
// In any of the above examples, once we have $disableConvert set up
// as we want, let the Smarty template know.
$this->ss->assign("DISABLE_CONVERT_ACTION", $disableConvert);
// copied from ViewDetail::display();
if(empty($this->bean->id)) {
sugar_die($GLOBALS['app_strings']['ERROR_NO_RECORD']);
}
$this->dv->process();
echo $this->dv->display();
}
}
I have dropdown like this ,
<%= Html.OptionList("Worktype", new SelectList(new List<SelectListItem>{
new SelectListItem{Text = "--Select One--", Value = "0", Selected=true},
new SelectListItem{Text = "Fulltime", Value = "Full Time"},
new SelectListItem{Text = "Partime", Value = "Part Time"}}, "Value", "Text" )) %>
After selecting either fulltime or parttime it should submit, but because the default select is there, required validation is passing. I want the required validation for below two options. can anyone help me out.
thank you,
michael
SetValue empty instead of 0 for "--Select One--"
new SelectListItem{Text = "--Select One--", Value = string.Empty , Selected=true}
I suggest that you should not be adding optional label in SelectList or as SelectListItem. you have overloads for Html.DropDown and Html.DropDownListFor that would allow you to insert an optional label at the top of your dropdown list. Pleas check my answer to this question.
DO you want to fire any event only in case of full time and part time and in case of select you dont want anything to happen.
If this is what you want
$('#dropdownname').change(function () {
var dropdownValue = $(this).val();
if (dropdownValuetoString().length > 0)
{
Your Code here.........
}
});
dropdownname is the name of dropdown dropdownValue is what I m getting from dropdown list when index is changed.
I was filling the dropdown from a list and I was not using any value field
when u check the dropdownValue for select It will show blank and I m sure ur dropdown select list will always have a name.
Tell me if it helps you else I will try something different
I am using jqgrid in my new project.
In a specific case I need to use a select element in the grid. No problem.
I define the colModel and the column for example like (from wiki)
colModel : [
...
{name:'myname', edittype:'select', editoptions:{value:{1:'One',2:'Two'}} },
...
]
But now when I load my data I would prefer the column "myname" to contain the value 1.
This won't work for me instead it has to contain the value "One".
The problem with this is that the text-part of the select element is in my case localized in the business layer where the colModel is dynamically generated. Also the datatype for the entity which generates the data via EF 4 may not be a string. Then I have to find the correct localized text and manipulate the data result so that the column "myname" does not containt an integer which is typically the case but a string instead with the localized text.
There is no option you can use so that when the data contains the value which match an option in the select list then the grid finds that option and presents the text.
Now the grid presents the value as a text and first when I click edit it finds the matching option and presents the text. When I undo the edit it returns to present the value again.
I started to think of a solution and this is what I came up with. Please if you know a better solution or if you know there is a built in option don't hesitate to answer.
Otherwise here is what I did:
loadComplete: function (data) {
var colModel = grid.getGridParam('colModel');
$.each(colModel, function (index, col) {
if (col.edittype === 'select') {
$.each(grid.getDataIDs(), function (index, id) {
var row = grid.getRowData(id);
var value = row[col.name];
var editoptions = col.editoptions.value;
var startText = editoptions.indexOf(value + ':') + (value + ':').length;
var endText = editoptions.indexOf(';', startText);
if (endText === -1) { endText = editoptions.length; }
var text = editoptions.substring(startText, endText);
row[col.name] = text;
grid.setRowData(id, row);
});
}
});
}
It works and I will leave it like this if nobody comes up with a better way.
You should just include additional formatter:'select' option in the definition of the column. See the documentation for more details.