Merge branch 'master' into javelin

This commit is contained in:
Rohit Yadav 2013-01-27 05:20:49 -08:00
commit 2fb346ab62
No known key found for this signature in database
GPG Key ID: 484248210EE3D884
12 changed files with 348 additions and 212 deletions

View File

@ -25,6 +25,9 @@
<artifactId>cloudstack</artifactId>
<version>4.1.0-SNAPSHOT</version>
</parent>
<properties>
<mkisofs>mkisofs</mkisofs>
</properties>
<dependencies>
<dependency>
<groupId>log4j</groupId>
@ -167,6 +170,19 @@
</plugins>
</build>
<profiles>
<!-- Debian will never distribute mkisofs due to licensing issues.
Fortunately genisoimage is a work-alike -->
<profile>
<id>genisoimage</id>
<activation>
<file>
<exists>/usr/bin/genisoimage</exists>
</file>
</activation>
<properties>
<mkisofs>genisoimage</mkisofs>
</properties>
</profile>
<profile>
<id>vmware</id>
<activation>
@ -209,7 +225,7 @@
</execution>
</executions>
<configuration>
<executable>mkisofs</executable>
<executable>${mkisofs}</executable>
<workingDirectory>dist</workingDirectory>
<arguments>
<argument>-quiet</argument>

View File

@ -1,25 +1,22 @@
<?xml version='1.0' encoding='utf-8' ?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "cloudstack.ent">
%BOOK_ENTITIES;
]>
<!-- Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<chapter id="offerings">
@ -28,4 +25,5 @@
are discussed in the section on setting up networking for users.</para>
<xi:include href="compute-disk-service-offerings.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="system-service-offerings.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="sys-offering-sysvm.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</chapter>

View File

@ -0,0 +1,75 @@
<?xml version='1.0' encoding='utf-8' ?>
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "cloudstack.ent">
%BOOK_ENTITIES;
]>
<!-- Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<section id="sys-offering-sysvm">
<title>Changing the Default System Offering for System VMs</title>
<para>You can manually change the system offering for a particular System VM. Additionally, as a
&PRODUCT; administrator, you can also change the default system offering used for System
VMs.</para>
<orderedlist>
<listitem>
<para>Create a new system offering.</para>
<para>For more information, see <phrase condition="install"><xref
linkend="creating-system-service-offerings"/></phrase>
<phrase condition="admin">Creating a New System Service Offering</phrase>. </para>
</listitem>
<listitem>
<para>Back up the database:</para>
<programlisting>mysqldump -u root -p cloud | bzip2 > cloud_backup.sql.bz2</programlisting>
</listitem>
<listitem>
<para>Open an MySQL prompt:</para>
<programlisting>mysql -u cloud -p cloud</programlisting>
</listitem>
<listitem>
<para>Run the following queries on the cloud database.</para>
<orderedlist numeration="loweralpha">
<listitem>
<para>In the disk_offering table, identify the original default offering and the new
offering you want to use by default. </para>
<para>Take a note of the ID of the new offering.</para>
<programlisting>select id,name,unique_name,type from disk_offering;</programlisting>
</listitem>
<listitem>
<para>For the original default offering, set the value of unique_name to NULL.</para>
<programlisting># update disk_offering set unique_name = NULL where id = 10;</programlisting>
<para>Ensure that you use the correct value for the ID.</para>
</listitem>
<listitem>
<para>For the new offering that you want to use by default, set the value of unique_name
as follows:</para>
<para>For the default Console Proxy VM (CPVM) offering,set unique_name to
'Cloud.com-ConsoleProxy'. For the default Secondary Storage VM (SSVM) offering, set
unique_name to 'Cloud.com-SecondaryStorage'. For example:</para>
<programlisting>update disk_offering set unique_name = 'Cloud.com-ConsoleProxy' where id = 16;</programlisting>
</listitem>
</orderedlist>
</listitem>
<listitem>
<para>Restart &PRODUCT; Management Server. Restarting is required because the default
offerings are loaded into the memory at startup.</para>
<programlisting>service cloud-management restart</programlisting>
</listitem>
<listitem>
<para>Destroy the existing CPVM or SSVM offerings and wait for them to be recreated. The new
CPVM or SSVM are configured with the new offering. </para>
</listitem>
</orderedlist>
</section>

View File

@ -1371,6 +1371,7 @@ CREATE TABLE `cloud`.`alert` (
`last_sent` DATETIME NULL COMMENT 'Last time the alert was sent',
`resolved` DATETIME NULL COMMENT 'when the alert status was resolved (available memory no longer at critical level, etc.)',
PRIMARY KEY (`id`),
INDEX `last_sent` (`last_sent` DESC),
CONSTRAINT `uc_alert__uuid` UNIQUE (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@ -77,6 +77,8 @@ ALTER TABLE `cloud`.`inline_load_balancer_nic_map` DROP COLUMN load_balancer_id;
ALTER TABLE upload ADD uuid VARCHAR(40);
ALTER TABLE async_job modify job_cmd VARCHAR(255);
ALTER TABLE `cloud`.`alert` ADD INDEX `last_sent` (`last_sent` DESC) ;
-- populate uuid column with db id if uuid is null
UPDATE `cloud`.`account` set uuid=id WHERE uuid is NULL;
UPDATE `cloud`.`alert` set uuid=id WHERE uuid is NULL;

View File

@ -16,11 +16,13 @@
# under the License.
try:
from common import grammar
import re
from marvin.cloudstackAPI import *
from marvin import cloudstackAPI
except ImportError, e:
pass
import sys
print "ImportError", e
sys.exit(1)
completions = cloudstackAPI.__all__
@ -43,9 +45,12 @@ def main():
completing commands and help docs. This reduces the overall search and
cache_miss (computation) complexity from O(n) to O(1) for any valid cmd.
"""
pattern = re.compile("[A-Z]")
verbs = list(set([x[:pattern.search(x).start()] for x in completions
if pattern.search(x) is not None]).difference(['cloudstack']))
# datastructure {'verb': {cmd': ['api', [params], doc, required=[]]}}
cache_verbs = {}
for verb in grammar:
for verb in verbs:
completions_found = filter(lambda x: x.startswith(verb), completions)
cache_verbs[verb] = {}
for api_name in completions_found:

View File

@ -26,6 +26,7 @@ try:
import logging
import os
import pdb
import re
import shlex
import sys
import time
@ -38,7 +39,7 @@ try:
from prettytable import PrettyTable
from common import __version__, config_file, config_fields
from common import grammar, precached_verbs
from common import precached_verbs
from marvin.cloudstackConnection import cloudConnection
from marvin.cloudstackException import cloudstackAPIException
from marvin.cloudstackAPI import *
@ -71,12 +72,12 @@ class CloudMonkeyShell(cmd.Cmd, object):
ruler = "="
config_file = config_file
config_fields = config_fields
grammar = grammar
# datastructure {'verb': {cmd': ['api', [params], doc, required=[]]}}
cache_verbs = precached_verbs
def __init__(self, pname):
def __init__(self, pname, verbs):
self.program_name = pname
self.verbs = verbs
if os.path.exists(self.config_file):
config = self.read_config()
else:
@ -102,11 +103,9 @@ class CloudMonkeyShell(cmd.Cmd, object):
logger.debug("Loaded config fields:\n%s" % self.config_fields)
cmd.Cmd.__init__(self)
# Update config if config_file does not exist
if not os.path.exists(self.config_file):
config = self.write_config()
# Enable history support
try:
if os.path.exists(self.history_file):
readline.read_history_file(self.history_file)
@ -381,13 +380,13 @@ class CloudMonkeyShell(cmd.Cmd, object):
def completedefault(self, text, line, begidx, endidx):
partitions = line.partition(" ")
verb = partitions[0]
rline = partitions[2].partition(" ")
verb = partitions[0].strip()
rline = partitions[2].lstrip().partition(" ")
subject = rline[0]
separator = rline[1]
params = rline[2]
params = rline[2].lstrip()
if verb not in self.grammar:
if verb not in self.verbs:
return []
autocompletions = []
@ -436,7 +435,7 @@ class CloudMonkeyShell(cmd.Cmd, object):
args = args.strip().partition(" ")
key, value = (args[0], args[2])
setattr(self, key, value) # keys and attributes should have same names
self.prompt = self.prompt.strip() + " " # prompt fix
self.prompt = self.prompt.strip() + " " # prompt fix
self.write_config()
def complete_set(self, text, line, begidx, endidx):
@ -513,22 +512,22 @@ class CloudMonkeyShell(cmd.Cmd, object):
def main():
# Create handlers on the fly using closures
self = CloudMonkeyShell
global grammar
for rule in grammar:
def add_grammar(rule):
pattern = re.compile("[A-Z]")
verbs = list(set([x[:pattern.search(x).start()] for x in completions
if pattern.search(x) is not None]).difference(['cloudstack']))
for verb in verbs:
def add_grammar(verb):
def grammar_closure(self, args):
if self.pipe_runner("%s %s" % (rule, args)):
if self.pipe_runner("%s %s" % (verb, args)):
return
try:
args_partition = args.partition(" ")
res = self.cache_verbs[rule][args_partition[0]]
res = self.cache_verbs[verb][args_partition[0]]
cmd = res[0]
helpdoc = res[2]
args = args_partition[2]
except KeyError, e:
self.print_shell("Error: invalid %s api arg" % rule, e)
self.print_shell("Error: invalid %s api arg" % verb, e)
return
if ' --help' in args or ' -h' in args:
self.print_shell(helpdoc)
@ -536,12 +535,12 @@ def main():
self.default("%s %s" % (cmd, args))
return grammar_closure
grammar_handler = add_grammar(rule)
grammar_handler.__doc__ = "%ss resources" % rule.capitalize()
grammar_handler.__name__ = 'do_' + rule
setattr(self, grammar_handler.__name__, grammar_handler)
grammar_handler = add_grammar(verb)
grammar_handler.__doc__ = "%ss resources" % verb.capitalize()
grammar_handler.__name__ = 'do_' + verb
setattr(CloudMonkeyShell, grammar_handler.__name__, grammar_handler)
shell = CloudMonkeyShell(sys.argv[0])
shell = CloudMonkeyShell(sys.argv[0], verbs)
if len(sys.argv) > 1:
shell.onecmd(' '.join(sys.argv[1:]))
else:

View File

@ -39,12 +39,3 @@ config_fields = {'host': 'localhost', 'port': '8080',
'history_file':
os.path.expanduser('~/.cloudmonkey_history')}
# Add verbs in grammar
grammar = ['create', 'list', 'delete', 'update', 'lock',
'enable', 'activate', 'disable', 'add', 'remove',
'attach', 'detach', 'associate', 'disassociate', 'generate', 'ldap',
'assign', 'authorize', 'change', 'register', 'configure',
'start', 'restart', 'reboot', 'stop', 'reconnect',
'cancel', 'destroy', 'revoke', 'mark', 'reset',
'copy', 'extract', 'migrate', 'restore', 'suspend',
'get', 'query', 'prepare', 'deploy', 'upload']

View File

@ -642,12 +642,16 @@
},
vmLimit: {
label: 'label.instance.limits',
isEditable: function(context) {
isEditable: function(context) {
if(context.accounts == undefined)
return false;
else {
if (context.accounts[0].accounttype == roleTypeUser || context.accounts[0].accounttype == roleTypeDomainAdmin) //updateResourceLimits is only allowed on account whose type is user or domain-admin
return true;
else
return false;
}
} }
},
ipLimit: {
label: 'label.ip.limits',

View File

@ -1322,6 +1322,13 @@
networkOfferingObjs = json.listnetworkofferingsresponse.networkoffering;
if (networkOfferingObjs != null && networkOfferingObjs.length > 0) {
for (var i = 0; i < networkOfferingObjs.length; i++) {
if(args.scope=="account-specific" && args.context.zones[0].securitygroupsenabled == true) { //BUG - CLOUDSTACK-1063
var serviceObjArray = networkOfferingObjs[i].name;
if(serviceObjArray == "DefaultSharedNetworkOfferingWithSGService"){
continue;
}
}
//comment out the following 12 lines because of CS-16718
/*

View File

@ -860,8 +860,19 @@
// Previous button
if ($target.closest('div.button.previous').size()) {
var index = $steps.filter(':visible').index();
if (index) showStep(index);
var $step = $steps.filter(':visible');
var $networkStep = $steps.filter('.network');
var index = $step.index();
$networkStep.removeClass('next-use-security-groups');
if (index) {
if (index == $steps.size() - 1 && $networkStep.hasClass('next-use-security-groups')) {
showStep(5);
} else {
showStep(index);
}
}
return false;
}

View File

@ -57,22 +57,80 @@
var fields = $.map(args.form.fields, function(value, key) {
return key;
})
$(fields).each(function() {
var ret = function() {
return $formContainer.dialog({
dialogClass: 'create-form',
closeOnEscape: false,
draggable: false,
width: 400,
title: _l(args.form.title),
open: function() {
if (args.form.preFilter) {
args.form.preFilter({ $form: $form, context: args.context });
}
},
buttons: [
{
text: createLabel ? createLabel : _l('label.ok'),
'class': 'ok',
click: function() {
if (!complete($formContainer)) { return false; }
$('div.overlay').remove();
$('.tooltip-box').remove();
$formContainer.remove();
$(this).dialog('destroy');
$('.hovered-elem').hide();
return true;
}
},
{
text: _l('label.cancel'),
'class': 'cancel',
click: function() {
$('div.overlay').remove();
$('.tooltip-box').remove();
$formContainer.remove();
$(this).dialog('destroy');
$('.hovered-elem').hide();
}
}
]
}).closest('.ui-dialog').overlay();
};
var isLastAsync = function(idx) {
for(var i = idx+1; i < $(fields).length ; i++) {
var f = args.form.fields[$(fields).get(i)];
if(f.select || f.dynamic){
return false;
}
}
return true;
};
var isAsync = false;
var isNoDialog = args.noDialog ? args.noDialog : false;
$(fields).each(function(idx, element) {
var key = this;
var field = args.form.fields[key];
var $formItem = $('<div>')
.addClass('form-item')
.attr({ rel: key });
if(field.isHidden != null) {
if (typeof(field.isHidden) == 'boolean' && field.isHidden == true)
$formItem.hide();
else if (typeof(field.isHidden) == 'function' && field.isHidden() == true)
$formItem.hide();
if (typeof(field.isHidden) == 'boolean' && field.isHidden == true)
$formItem.hide();
else if (typeof(field.isHidden) == 'function' && field.isHidden() == true)
$formItem.hide();
}
$formItem.appendTo($form);
//Handling Escape KeyPress events
@ -96,7 +154,7 @@
closeOnEscape: false
}); */
// Label field
var $name = $('<div>').addClass('name')
.appendTo($formItem)
.append(
@ -104,9 +162,10 @@
);
// red asterisk
var $astersikSpan = $('<span>').addClass('field-required').html('*');
$name.find('label').prepend($astersikSpan);
if (field.validation == null || field.validation.required == false) {
var $astersikSpan = $('<span>').addClass('field-required').html('*');
$name.find('label').prepend($astersikSpan);
if (field.validation == null || field.validation.required == false) {
$astersikSpan.hide();
}
@ -169,6 +228,7 @@
// Determine field type of input
if (field.select) {
isAsync = true;
selectArgs = {
context: args.context,
response: {
@ -193,6 +253,10 @@
}
$input.trigger('change');
if((!isNoDialog) && isLastAsync(idx)) {
ret();
}
}
}
};
@ -200,7 +264,7 @@
selectFn = field.select;
$input = $('<select>')
.attr({ name: key })
.data('dialog-select-fn', function(args) {
.data('dialog-select-fn', function(args) {
selectFn(args ? $.extend(true, {}, selectArgs, args) : selectArgs);
})
.appendTo($value);
@ -221,21 +285,21 @@
var dependsOnArgs = {};
$input.find('option').remove();
if (!$target.children().size()) return true;
dependsOnArgs[dependsOn] = $target.val();
selectFn($.extend(selectArgs, dependsOnArgs));
selectFn($.extend(selectArgs, dependsOnArgs));
return true;
});
if (!$dependsOn.is('select')) {
selectFn(selectArgs);
selectFn(selectArgs);
}
} else {
selectFn(selectArgs);
selectFn(selectArgs);
}
} else if (field.isBoolean) {
if (field.multiArray) {
@ -263,7 +327,7 @@
} else {
// This is mainly for IE compatibility
setTimeout(function() {
$input.attr('checked', false);
$input.attr('checked', false);
}, 100);
}
}
@ -277,6 +341,7 @@
});
}
} else if (field.dynamic) {
isAsync = true;
// Generate a 'sub-create-form' -- append resulting fields
$input = $('<div>').addClass('dynamic-input').appendTo($value);
$form.hide();
@ -297,6 +362,9 @@
// Form should be slightly wider
$form.closest(':ui-dialog').dialog('option', { position: 'center',closeOnEscape: false });
if((!isNoDialog) && isLastAsync(idx)) {
ret();
}
}
}
});
@ -308,63 +376,64 @@
if (field.defaultValue) {
$input.val(field.defaultValue);
}
} else if (field.isDatepicker) { //jQuery datepicker
$input = $('<input>').attr({
name: key,
type: 'text'
}).appendTo($value);
} else if (field.isDatepicker) { //jQuery datepicker
$input = $('<input>').attr({
name: key,
type: 'text'
}).appendTo($value);
if (field.defaultValue) {
$input.val(field.defaultValue);
}
if (field.id) {
$input.attr('id', field.id);
}
$input.addClass("disallowSpecialCharacters");
$input.datepicker({dateFormat: 'yy-mm-dd'});
} else if(field.range) { //2 text fields on the same line (e.g. port range: startPort - endPort)
$input = $.merge(
// Range start
$('<input>').attr({
type: 'text',
name: field.range[0]
}),
if (field.defaultValue) {
$input.val(field.defaultValue);
}
if (field.id) {
$input.attr('id', field.id);
}
$input.addClass("disallowSpecialCharacters");
$input.datepicker({dateFormat: 'yy-mm-dd'});
// Range end
$('<input>').attr({
type: 'text',
name: field.range[1]
})
).appendTo(
$('<div>').addClass('range-edit').appendTo($value)
);
$input.wrap($('<div>').addClass('range-item'));
$input.addClass("disallowSpecialCharacters");
} else { //text field
$input = $('<input>').attr({
name: key,
type: field.password || field.isPassword ? 'password' : 'text'
}).appendTo($value);
} else if(field.range) {//2 text fields on the same line (e.g. port range: startPort - endPort)
$input = $.merge(
// Range start
$('<input>').attr({
type: 'text',
name: field.range[0]
}),
if (field.defaultValue) {
$input.val(field.defaultValue);
}
if (field.id) {
$input.attr('id', field.id);
}
// Range end
$('<input>').attr({
type: 'text',
name: field.range[1]
})
).appendTo(
$('<div>').addClass('range-edit').appendTo($value)
);
$input.wrap($('<div>').addClass('range-item'));
$input.addClass("disallowSpecialCharacters");
} else { //text field
$input = $('<input>').attr({
name: key,
type: field.password || field.isPassword ? 'password' : 'text'
}).appendTo($value);
if (field.defaultValue) {
$input.val(field.defaultValue);
}
if (field.id) {
$input.attr('id', field.id);
}
$input.addClass("disallowSpecialCharacters");
}
if(field.validation != null)
if(field.validation != null)
$input.data('validation-rules', field.validation);
else
else
$input.data('validation-rules', {});
var fieldLabel = field.label;
var inputId = $input.attr('id') ? $input.attr('id') : fieldLabel.replace(/\./g,'_');
$input.attr('id', inputId);
$name.find('label').attr('for', inputId);
@ -380,29 +449,32 @@
attachTo: '.form-item'
});
}
/* $input.blur(function() {
console.log('tooltip remove->' + $input.attr('name'));
});*/
});
var getFormValues = function() {
var formValues = {};
$.each(args.form.fields, function(key) {});
};
// Setup form validation
// Setup form validation
$formContainer.find('form').validate();
$formContainer.find('input, select').each(function() {
$formContainer.find('input, select').each(function() {
if ($(this).data('validation-rules')) {
$(this).rules('add', $(this).data('validation-rules'));
}
else {
$(this).rules('add', {});
}
});
$form.find('select').trigger('change');
else {
$(this).rules('add', {});
}
});
$form.find('select').trigger('change');
var complete = function($formContainer) {
var $form = $formContainer.find('form');
var data = cloudStack.serializeForm($form);
@ -429,93 +501,48 @@
$formContainer: $formContainer,
completeAction: complete
};
} else if (!isAsync) {
return ret();
}
return $formContainer.dialog({
dialogClass: 'create-form',
closeOnEscape: false,
draggable: false,
width: 400,
title: _l(args.form.title),
open: function() {
if (args.form.preFilter) {
args.form.preFilter({ $form: $form, context: args.context });
}
},
buttons: [
{
text: createLabel ? createLabel : _l('label.ok'),
'class': 'ok',
click: function() {
if (!complete($formContainer)) { return false; }
$('div.overlay').remove();
$('.tooltip-box').remove();
$formContainer.remove();
$(this).dialog('destroy');
$('.hovered-elem').hide();
return true;
}
},
{
text: _l('label.cancel'),
'class': 'cancel',
click: function() {
$('div.overlay').remove();
$('.tooltip-box').remove();
$formContainer.remove();
$(this).dialog('destroy');
$('.hovered-elem').hide();
}
}
]
}).closest('.ui-dialog').overlay();
},
/**
/**
* to change a property(e.g. validation) of a createForm field after a createForm is rendered
*/
createFormField: {
validation: {
required: {
add: function($formField) {
var $input = $formField.find('input, select');
var validationRules = $input.data('validation-rules');
if(validationRules == null || validationRules.required == null || validationRules.required == false) {
$formField.find('.name').find('label').find('span.field-required').css('display', 'inline'); //show red asterisk
if(validationRules == null)
validationRules = {};
validationRules.required = true;
$input.data('validation-rules', validationRules);
$input.rules('add', { required: true });
}
},
remove: function($formField) {
createFormField: {
validation: {
required: {
add: function($formField) {
var $input = $formField.find('input, select');
var validationRules = $input.data('validation-rules');
if(validationRules != null && validationRules.required != null && validationRules.required == true) {
$formField.find('.name').find('label').find('span.field-required').hide(); //hide red asterisk
delete validationRules.required;
$input.data('validation-rules', validationRules);
var validationRules = $input.data('validation-rules');
if(validationRules == null || validationRules.required == null || validationRules.required == false) {
$formField.find('.name').find('label').find('span.field-required').css('display', 'inline'); //show red asterisk
if(validationRules == null)
validationRules = {};
validationRules.required = true;
$input.data('validation-rules', validationRules);
$input.rules('add', { required: true });
}
},
remove: function($formField) {
var $input = $formField.find('input, select');
var validationRules = $input.data('validation-rules');
if(validationRules != null && validationRules.required != null && validationRules.required == true) {
$formField.find('.name').find('label').find('span.field-required').hide(); //hide red asterisk
delete validationRules.required;
$input.data('validation-rules', validationRules);
$input.rules('remove', 'required');
$formField.find('.value').find('label.error').hide();
}
}
}
}
},
$input.rules('remove', 'required');
$formField.find('.value').find('label.error').hide();
}
}
}
}
},
/**
* Confirmation dialog
*/