Yii2: How to detect ActiveForm validation on submit - ajax

We have a form that includes fields Hours and Days. Either hours or days must be specified, but not both. We're using a modal form, Ajax and custom validation rules and all is working fine to ensure one or other is specified and valid when completing the form. However, the time to check at least one or other is specified is when the form is submitted.
The problem is how to differentiate between "normal" validation performed on a field-by-field basis and validation performed on submit. Is there a way to detect when the form is submitted (validateOnSubmit) as opposed to when the form data is posted for validation while it's being entered (validateOnChange)?
This can be checked on final model validation, but at that point it's a standard request so the form is rendered normally instead of updating the modal form.

I found the answer: conditional required rules:
[['days'], 'required', 'message' => 'Days or Hours?',
'when' => function($model) { return is_null($model->hours );},
'whenClient' => "function (attribute, value){ return $('#downtime-hours').val() == '';}",
],
[['hours'], 'required', 'message' => 'Hours or Days?',
'when' => function($model) { return is_null($model->days); },
'whenClient' => "function (attribute, value){ return $('#downtime-days').val() == '';}",
],

Related

TYPO3 7.6 - is there any way to Override TYPES?

I am using user defined render types to add HTML Code or funktionlity to Dropdowns, ets. But can I also override text fields?
Example:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1476278844] = [
'nodeName' => 'myNewSelect',
'priority' => 40,
'class' => \WFP2\MyExt\Form\Element\NewSelectElement::class,
];
In this class I derive from SelectMultipleSideBySideElement and now I can use the render method and Change the return of it.
But How to do this on other fields, which do not have a render type?
regards
n00n

Focus on the form field after submit

How can I focus on a particular form field after a form submission?
Things already tried:
1.
dispatch(focus('fieldRefName'))
2.
componentWillReceiveProps = (nextProps) => {
if (nextProps.submitting) {
this.refs.fieldRefname.focus()
}
}
I also want to clean the form too after submission.
redux-form version: 3.0.12
The focus() action has no effect on the DOM. It's a reaction to the onFocus event from the DOM. You will need to use this.refs.myField.focus().
To clean the form, after submit...
<form onSubmit={this.props.handleSubmit(values => {
return doSubmit(values).then(() => this.props.reset())
}}>
...
</form>

Possible Callbacks for observer_form

Can anyone tell me which are the possible observer_form callbacks? I am working on an old Rails application which I have migrated from Rails 2 to Rails 3. Application contains observers like field_observer and form_observer.
I want to add a condition when a form gets submitted by a user through this form and if the condition satisfied then only send Ajax request otherwise terminate the request.
I want to do something like this:
<%= observe_form lrv.simple_form_id,
:before => "Element.show('big_spinner')",
:failure => "alert('Failed AJAX update.')",
:complete => "Element.hide('big_spinner')",
:condition => "CallerMethod.show_event_confirmation(#{confirmation_required?(lrv)})",
:url => { :action => :update, lodging_group_reservation: true }
-%>
I have tried condition but it works only with link_to_remote and not working with observer_form.
I have tried submit observer but it throws error like
TypeError: $(...) is null
var elements = $(form).getElementsByTagName('*'),
This is may be because I have added different ID but it is required because there are many forms on this page.

How to determine if there were validation errors after calling (Kendo) grid.SaveChanges() in javascript

I call grid.SaveChanges() in my javascript function. The grid is using inline editing mode.
My problem is if there were some client side validation errors for example invalid date format, then I must not execute some DOM operations. Unfortunately grid.SaveChanges() has no return value and searching for keyword 'valid' in grid documentation page has no result. (Teleport to Kendo Grid API documentation)
So: How can I determine if there was validation errors after SaveChanges() or the data was successfully sync-ed with the persistent store?
Thx in advance
I'm assuming that you are using the MVC wrappers but calling grid.SaveChanges() as part of your script. Since you're using inline editing mode, that means you're using Ajax. If those assumptions are correct, then when you call SaveChanges() your controller action specified in the wrapper is executed. If you hook into the .Error event you can execute whatever script needs to be executed (even if that's just setting a variable that you check in the other parts of your script). Have a look at the Ajax Editing portion of Getting Started on Kendo's website. Your Razor code will look similar to the following (some of this is extraneous, I pulled it out of production code and modified slightly):
#(Html.Kendo().Grid(Model)
.Name("Grid")
.Columns(cols =>
{
cols.Bound(p => p.ColumnA);
})
.Editable(edit => edit.Enabled(true).Mode(GridEditMode.InCell))
.DataSource(ds => ds
.Ajax()
.AutoSync(false)
.Model(model =>
{
model.Id(p => p.ColumnId);
})
// Configure RU -->
.Read(read => read.Action("_MyRead", "MyController").Data("additionalData"))
.Update(update => update.Action("_MyUpdate", "MyController").Data("additionalData"))
//.ServerOperation(false)
.Batch(true)
.Events(events => events
.Error("onError")
)
)
// <-- Configure RU
.Pageable(page => page.PageSizes(new int[] { 10, 25, 50, 100 }).Enabled(true))
.Groupable(group => group.Enabled(true))
.Filterable(filter => filter.Enabled(true).Extra(false))
.Sortable(sort => sort.Enabled(true).SortMode(GridSortMode.SingleColumn).AllowUnsort(true))
.Navigatable(nav => nav.Enabled(true))
.Resizable(resizing => resizing.Columns(true))
.Reorderable(reorder => reorder.Columns(true))
)
Then your onError script will look like this:
function onError(e, status) {
if (e.errors) {
var message = "The following errors have occurred and changes will be discarded:\n";
$.each(e.errors, function (key, value) {
if (value.errors) {
message += value.errors.join("\n");
}
});
alert(message);
var grid = $("#Grid").data("kendoGrid");
grid.cancelChanges();
}
}

Telerik RadGrid CustomSorting without hitting database?

I tried to post on Telerik forum, but now each time I try to open my thread, I get
"Oops...
It seems there was a problem with our server."
So I posted this question here.
I am pretty new to Telerik and RadGrid. I am trying to modify existing project because client needs custom sorting. There is a data field which may contain numbers or text so it is a string type but sometimes it has to be sorted as numbers. So I went to this link:
http://demos.telerik.com/aspnet-ajax/grid/examples/programming/sort/defaultcs.aspx
and
http://www.telerik.com/help/aspnet-ajax/grdapplycustomsortcriteria.html
The example says:
"With custom sorting turned on, RadGrid will display the sorting icons but it will not actually sort the data."
but it seems it is not enough to add AllowCustomSorting to disable default sorting.
When implementing SortCommand, I noticed that I have to do
e.Canceled = true;
because else default sorting occurs. Why this is not mentioned in the documentation nor example?
But the main question is - inside of SortCommand my RadGrid already has all items loaded. So is there any way to sort them to avoid hitting database? I tried accessing various Items properties of both "object source, GridSortCommandEventArgs e", but all Items are read-only, so I cannot sort them and attach back to the RadGrid.
Thanks for any ideas.
You can set the sortExpression in the OnSelecting event of the objectDatasource and use it in the SelectMethod.
protected void odsGridData_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
e.InputParameters["filterExpression"] = grdMyTasks.MasterTableView.FilterExpression;
//Set the Sort Expression and use this in the Get method
e.InputParameters["sortExpression"] = grdMyTasks.MasterTableView.SortExpressions.GetSortString();
e.Arguments.StartRowIndex = grdMyTasks.CurrentPageIndex;
e.Arguments.MaximumRows = grdMyTasks.PageSize;
}
This way you can perform custom sort and pass on the data to the RadGrid.
Hope this helps.
Here is an example of some code I use that does not hit the database. I'm using MVC 3 with the Razor view engine. Notice the Ajax binding. Don't forget to add using Telerik.Web.Mvc.UI and annotate the "Post" methods in your controller with [GridResult] and to return GridModel to get the Json resultset.
using Telerik.Web.Mvc;
[GridAction]
public ActionResult AjaxGridSelect()
{
return View(new GridModel(db.lm_m_category));
}
Here is the index.cshtml (razor engine), the key is the Ajax binding.
#model IEnumerable<LinkManagerAdmin.Dal.lm_r_category>
#using Telerik.Web.Mvc.UI
#(Html.Telerik().Grid(Model)
.Name("Grid")
.DataKeys(keys => keys.Add(c => c.category_id ))
.DataBinding(dataBinding => dataBinding.Ajax()
.Select("AjaxGridSelect", "CategoryTree")
.Insert("GridInsert", "CategoryTree", new { GridEditMode.PopUp, GridButtonType.ImageAndText })
.Update("GridUpdate", "CategoryTree", new { GridEditMode.InLine, GridButtonType.ImageAndText })
.Delete("GridDelete", "CategoryTree", new { GridEditMode.InLine, GridButtonType.ImageAndText }))
.Columns(columns =>
{
columns.Bound(p => p.category_name).Width(150);
columns.Bound(p => p.status_cd).Width(100);
columns.Command(commands =>
{
commands.Edit().ButtonType(GridButtonType.ImageAndText);
commands.Delete().ButtonType(GridButtonType.ImageAndText);
}).Width(180).Title("Commands");
})
.Editable(editing => editing.Mode(GridEditMode.InLine))
.Pageable(paging => paging.PageSize(50)
.Style(GridPagerStyles.NextPreviousAndNumeric)
.Position(GridPagerPosition.Bottom))
.Sortable(o => o.OrderBy(sortcol =>
{
sortcol.Add(a => a.category_name);
sortcol.Add(a => a.add_date);
})
.Filterable()
.Groupable()
.Selectable())

Resources