mirror of
https://github.com/Radarr/Radarr.git
synced 2024-11-04 10:02:40 +01:00
more validation
This commit is contained in:
parent
e4c8255d69
commit
488da59143
@ -165,7 +165,7 @@
|
|||||||
<Compile Include="System\SystemModule.cs" />
|
<Compile Include="System\SystemModule.cs" />
|
||||||
<Compile Include="TinyIoCNancyBootstrapper.cs" />
|
<Compile Include="TinyIoCNancyBootstrapper.cs" />
|
||||||
<Compile Include="Update\UpdateModule.cs" />
|
<Compile Include="Update\UpdateModule.cs" />
|
||||||
<Compile Include="Validation\IdValidationRule.cs" />
|
<Compile Include="Validation\RuleBuilderExtensions.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
@ -14,7 +14,7 @@ public class ResourceValidator<TResource> : AbstractValidator<TResource>
|
|||||||
public IRuleBuilderInitial<TResource, TProperty> RuleForField<TProperty>(Expression<Func<TResource, IEnumerable<Field>>> fieldListAccessor, string fieldName)
|
public IRuleBuilderInitial<TResource, TProperty> RuleForField<TProperty>(Expression<Func<TResource, IEnumerable<Field>>> fieldListAccessor, string fieldName)
|
||||||
{
|
{
|
||||||
var rule = new PropertyRule(fieldListAccessor.GetMember(), c => GetValue(c, fieldListAccessor.Compile(), fieldName), null, () => CascadeMode.Continue, typeof(TProperty), typeof(TResource));
|
var rule = new PropertyRule(fieldListAccessor.GetMember(), c => GetValue(c, fieldListAccessor.Compile(), fieldName), null, () => CascadeMode.Continue, typeof(TProperty), typeof(TResource));
|
||||||
rule.PropertyName += "." + fieldName;
|
rule.PropertyName = fieldName;
|
||||||
rule.DisplayName = new StaticStringSource(fieldName);
|
rule.DisplayName = new StaticStringSource(fieldName);
|
||||||
|
|
||||||
AddRule(rule);
|
AddRule(rule);
|
||||||
@ -34,7 +34,4 @@ private static object GetValue(object container, Func<TResource, IEnumerable<Fie
|
|||||||
return resource.Value;
|
return resource.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -30,9 +30,11 @@ public SeriesModule(ISeriesService seriesService, ISeriesStatisticsService serie
|
|||||||
DeleteResource = DeleteSeries;
|
DeleteResource = DeleteSeries;
|
||||||
|
|
||||||
SharedValidator.RuleFor(s => s.QualityProfileId).ValidId();
|
SharedValidator.RuleFor(s => s.QualityProfileId).ValidId();
|
||||||
SharedValidator.RuleFor(s => s.Path).NotEmpty().When(s => String.IsNullOrEmpty(s.RootFolderPath));
|
|
||||||
SharedValidator.RuleFor(s => s.RootFolderPath).NotEmpty().When(s => String.IsNullOrEmpty(s.Path));
|
|
||||||
|
|
||||||
|
PutValidator.RuleFor(s => s.Path).NotEmpty();
|
||||||
|
|
||||||
|
PostValidator.RuleFor(s => s.Path).NotEmpty().When(s => String.IsNullOrEmpty(s.RootFolderPath));
|
||||||
|
PostValidator.RuleFor(s => s.RootFolderPath).NotEmpty().When(s => String.IsNullOrEmpty(s.Path));
|
||||||
PostValidator.RuleFor(s => s.Title).NotEmpty();
|
PostValidator.RuleFor(s => s.Title).NotEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,5 +15,4 @@ public static IRuleBuilderOptions<T, int> IsZero<T>(this IRuleBuilder<T, int> ru
|
|||||||
return ruleBuilder.SetValidator(new EqualValidator(0));
|
return ruleBuilder.SetValidator(new EqualValidator(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -38,8 +38,9 @@
|
|||||||
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
<option name="myValues">
|
<option name="myValues">
|
||||||
<value>
|
<value>
|
||||||
<list size="1">
|
<list size="2">
|
||||||
<item index="0" class="java.lang.String" itemvalue="name" />
|
<item index="0" class="java.lang.String" itemvalue="name" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="validation-name" />
|
||||||
</list>
|
</list>
|
||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<label class="control-label">{{label}}</label>
|
<label class="control-label">{{label}}</label>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="password" name="fields.{{order}}.value"/>
|
<input type="password" name="fields.{{order}}.value" validation-name="{{name}}"/>
|
||||||
{{#if helpText}}
|
{{#if helpText}}
|
||||||
<span class="help-inline">
|
<span class="help-inline">
|
||||||
<i class="icon-question-sign" title="{{helpText}}"/>
|
<i class="icon-question-sign" title="{{helpText}}"/>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<label class="control-label">{{label}}</label>
|
<label class="control-label">{{label}}</label>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" name="fields.{{order}}.value" spellcheck="false"/>
|
<input type="text" name="fields.{{order}}.value" validation-name="{{name}}" spellcheck="false"/>
|
||||||
{{> FormHelpPartial}}
|
{{> FormHelpPartial}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -69,10 +69,13 @@
|
|||||||
return false;
|
return false;
|
||||||
//message.message = 'NzbDrone Server Not Reachable. make sure NzbDrone is running.';
|
//message.message = 'NzbDrone Server Not Reachable. make sure NzbDrone is running.';
|
||||||
}
|
}
|
||||||
else {
|
else if (xmlHttpRequest.status === 400 && ajaxOptions.isValidatedCall) {
|
||||||
message.message = '[{0}] {1} : {2}'.format(ajaxOptions.type, xmlHttpRequest.statusText, ajaxOptions.url);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message.message = '[{0}] {1} : {2}'.format(ajaxOptions.type, xmlHttpRequest.statusText, ajaxOptions.url);
|
||||||
|
|
||||||
window.Messenger().post(message);
|
window.Messenger().post(message);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
@ -2,7 +2,7 @@ define(
|
|||||||
[
|
[
|
||||||
'backbone.validation',
|
'backbone.validation',
|
||||||
'underscore',
|
'underscore',
|
||||||
'jQuery/Validation'
|
'jQuery/jquery.validation'
|
||||||
], function (Validation, _) {
|
], function (Validation, _) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
@ -27,7 +27,10 @@ define(
|
|||||||
var boundHandler = errorHandler.bind(this);
|
var boundHandler = errorHandler.bind(this);
|
||||||
|
|
||||||
this.model.sync = function () {
|
this.model.sync = function () {
|
||||||
self.$el.removeBootstrapError();
|
self.$el.removeAllErrors();
|
||||||
|
|
||||||
|
arguments[2].isValidatedCall = true;
|
||||||
|
|
||||||
return self.originalSync.apply(this, arguments).fail(boundHandler);
|
return self.originalSync.apply(this, arguments).fail(boundHandler);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -71,9 +74,13 @@ define(
|
|||||||
var validationErrors = JSON.parse(response.responseText);
|
var validationErrors = JSON.parse(response.responseText);
|
||||||
|
|
||||||
_.each(validationErrors, function (error) {
|
_.each(validationErrors, function (error) {
|
||||||
view.$el.addBootstrapError(error);
|
view.$el.processServerError(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return this;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -5,8 +5,9 @@ define(
|
|||||||
'marionette',
|
'marionette',
|
||||||
'Quality/QualityProfileCollection',
|
'Quality/QualityProfileCollection',
|
||||||
'Mixins/AsModelBoundView',
|
'Mixins/AsModelBoundView',
|
||||||
|
'Mixins/AsValidatedView',
|
||||||
'Mixins/AutoComplete'
|
'Mixins/AutoComplete'
|
||||||
], function (App, Marionette, QualityProfiles, AsModelBoundView) {
|
], function (App, Marionette, QualityProfiles, AsModelBoundView, AsValidatedView) {
|
||||||
|
|
||||||
var view = Marionette.ItemView.extend({
|
var view = Marionette.ItemView.extend({
|
||||||
template: 'Series/Edit/EditSeriesTemplate',
|
template: 'Series/Edit/EditSeriesTemplate',
|
||||||
@ -49,5 +50,6 @@ define(
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return AsModelBoundView.apply(view);
|
AsModelBoundView.apply(view);
|
||||||
|
return AsValidatedView.apply(view);
|
||||||
});
|
});
|
||||||
|
@ -1,26 +1,29 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
define([
|
define(
|
||||||
'app',
|
[
|
||||||
'marionette',
|
'app',
|
||||||
'Settings/Notifications/DeleteView',
|
'marionette',
|
||||||
'Mixins/AsModelBoundView'],
|
'Settings/Notifications/DeleteView',
|
||||||
function (App, Marionette, DeleteView, AsModelBoundView) {
|
'Mixins/AsModelBoundView',
|
||||||
|
'Mixins/AsValidatedView'
|
||||||
|
], function (App, Marionette, DeleteView, AsModelBoundView, AsValidatedView) {
|
||||||
|
|
||||||
var view = Marionette.ItemView.extend({
|
var view = Marionette.ItemView.extend({
|
||||||
template: 'Settings/Indexers/ItemTemplate',
|
template: 'Settings/Indexers/ItemTemplate',
|
||||||
tagName : 'li',
|
tagName : 'li',
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
'click .x-delete': '_deleteIndexer'
|
'click .x-delete': '_deleteIndexer'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_deleteIndexer: function () {
|
||||||
|
var view = new DeleteView({ model: this.model});
|
||||||
|
App.modalRegion.show(view);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AsModelBoundView.call(view);
|
||||||
|
return AsValidatedView.call(view);
|
||||||
|
|
||||||
_deleteIndexer: function () {
|
|
||||||
var view = new DeleteView({ model: this.model});
|
|
||||||
App.modalRegion.show(view);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return AsModelBoundView.call(view);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Sorting</legend>
|
<legend>Season Folder</legend>
|
||||||
|
|
||||||
<!--TODO: Remove this and move it to Add Series-->
|
<!--TODO: Remove this and move it to Add Series-->
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
define(
|
|
||||||
[
|
|
||||||
'jquery'
|
|
||||||
], function ($) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
$.fn.addBootstrapError = function (error) {
|
|
||||||
var input = this.find('[name]').filter(function () {
|
|
||||||
return this.name.toLowerCase() === error.propertyName.toLowerCase();
|
|
||||||
});
|
|
||||||
|
|
||||||
var controlGroup = input.parents('.control-group');
|
|
||||||
if (controlGroup.find('.help-inline').length === 0) {
|
|
||||||
controlGroup.find('.controls').append('<span class="help-inline error-message">' + error.errorMessage + '</span>');
|
|
||||||
}
|
|
||||||
|
|
||||||
controlGroup.addClass('error');
|
|
||||||
|
|
||||||
return controlGroup.find('.help-inline').text();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
$.fn.removeBootstrapError = function () {
|
|
||||||
|
|
||||||
this.removeClass('error');
|
|
||||||
|
|
||||||
return this.parents('.control-group').find('.help-inline.error-message').remove();
|
|
||||||
};
|
|
||||||
|
|
||||||
});
|
|
52
UI/jQuery/jquery.validation.js
Normal file
52
UI/jQuery/jquery.validation.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
define(
|
||||||
|
[
|
||||||
|
'jquery'
|
||||||
|
], function ($) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
$.fn.processServerError = function (error) {
|
||||||
|
|
||||||
|
var validationName = error.propertyName.toLowerCase();
|
||||||
|
|
||||||
|
var input = this.find('[name]').filter(function () {
|
||||||
|
return this.name.toLowerCase() === validationName;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if (input.length === 0) {
|
||||||
|
input = this.find('[validation-name]').filter(function () {
|
||||||
|
return $(this).attr('validation-name').toLowerCase() === validationName;
|
||||||
|
});
|
||||||
|
|
||||||
|
//still not found?
|
||||||
|
if (input.length === 0) {
|
||||||
|
this.addFormError(error);
|
||||||
|
console.error('couldn\'t find input for ' + error.propertyName);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var controlGroup = input.parents('.control-group');
|
||||||
|
controlGroup.find('.controls').append('<span class="help-inline error-message">' + error.errorMessage + '</span>');
|
||||||
|
|
||||||
|
controlGroup.addClass('error');
|
||||||
|
|
||||||
|
return controlGroup.find('.help-inline').text();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$.fn.processClientError = function (error) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.addFormError = function (error) {
|
||||||
|
this.find('.control-group').parent().prepend('<div class="alert alert-error validation-error">'+ error.errorMessage +'</div>')
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.removeAllErrors = function () {
|
||||||
|
this.find('.error').removeClass('error');
|
||||||
|
this.find('.validation-error').remove();
|
||||||
|
return this.find('.help-inline.error-message').remove();
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user