diff options
-rwxr-xr-x | wqflask/base/data_set.py | 52 | ||||
-rwxr-xr-x | wqflask/wqflask/collect.py | 2 | ||||
-rwxr-xr-x | wqflask/wqflask/marker_regression/marker_regression.py | 5 | ||||
-rw-r--r-- | wqflask/wqflask/static/new/javascript/dataset_select_menu.js | 1 | ||||
-rwxr-xr-x | wqflask/wqflask/static/new/javascript/histogram.js | 2 | ||||
-rwxr-xr-x | wqflask/wqflask/static/packages/bootstrap/css/bootstrap.css | 4 | ||||
-rwxr-xr-x | wqflask/wqflask/templates/base.html | 3 | ||||
-rwxr-xr-x | wqflask/wqflask/templates/collections/add.html | 6 | ||||
-rwxr-xr-x | wqflask/wqflask/templates/gsearch_gene.html | 4 | ||||
-rwxr-xr-x | wqflask/wqflask/templates/marker_regression.html | 7 | ||||
-rwxr-xr-x | wqflask/wqflask/templates/search_result_page.html | 87 | ||||
-rwxr-xr-x | wqflask/wqflask/templates/show_trait.html | 48 | ||||
-rwxr-xr-x | wqflask/wqflask/templates/show_trait_details.html | 6 | ||||
-rwxr-xr-x | wqflask/wqflask/templates/show_trait_mapping_tools.html | 2 |
14 files changed, 145 insertions, 84 deletions
diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index c60efe65..e98258f6 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -559,29 +559,39 @@ class DataSet(object): This is not meant to retrieve the data set info if no name at all is passed. """ - - query_args = tuple(escape(x) for x in ( - (self.type + "Freeze"), - str(webqtlConfig.PUBLICTHRESH), - self.name, - self.name, - self.name)) - print("query_args are:", query_args) - - #print(""" - # SELECT Id, Name, FullName, ShortName - # FROM %s - # WHERE public > %s AND - # (Name = '%s' OR FullName = '%s' OR ShortName = '%s') - # """ % (query_args)) try: - self.id, self.name, self.fullname, self.shortname = g.db.execute(""" - SELECT Id, Name, FullName, ShortName - FROM %s - WHERE public > %s AND - (Name = '%s' OR FullName = '%s' OR ShortName = '%s') - """ % (query_args)).fetchone() + if self.type == "ProbeSet": + query_args = tuple(escape(x) for x in ( + str(webqtlConfig.PUBLICTHRESH), + self.name, + self.name, + self.name)) + + self.id, self.name, self.fullname, self.shortname, self.tissue = g.db.execute(""" + SELECT ProbeSetFreeze.Id, ProbeSetFreeze.Name, ProbeSetFreeze.FullName, ProbeSetFreeze.ShortName, Tissue.Name + FROM ProbeSetFreeze, ProbeFreeze, Tissue + WHERE ProbeSetFreeze.public > %s AND + ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id AND + ProbeFreeze.TissueId = Tissue.Id AND + (ProbeSetFreeze.Name = '%s' OR ProbeSetFreeze.FullName = '%s' OR ProbeSetFreeze.ShortName = '%s') + """ % (query_args)).fetchone() + else: + query_args = tuple(escape(x) for x in ( + (self.type + "Freeze"), + str(webqtlConfig.PUBLICTHRESH), + self.name, + self.name, + self.name)) + + self.tissue = "N/A" + self.id, self.name, self.fullname, self.shortname = g.db.execute(""" + SELECT Id, Name, FullName, ShortName + FROM %s + WHERE public > %s AND + (Name = '%s' OR FullName = '%s' OR ShortName = '%s') + """ % (query_args)).fetchone() + except TypeError: print("Dataset {} is not yet available in GeneNetwork.".format(self.name)) pass diff --git a/wqflask/wqflask/collect.py b/wqflask/wqflask/collect.py index c7c1e744..750f4757 100755 --- a/wqflask/wqflask/collect.py +++ b/wqflask/wqflask/collect.py @@ -181,6 +181,8 @@ def collections_new(): if "anonymous_add" in params: AnonCollection().add_traits(params, "Default") return redirect(url_for('view_collection')) + elif "sign_in" in params: + return redirect(url_for('login')) collection_name = params['new_collection'] diff --git a/wqflask/wqflask/marker_regression/marker_regression.py b/wqflask/wqflask/marker_regression/marker_regression.py index 850dfc7f..1c5757a6 100755 --- a/wqflask/wqflask/marker_regression/marker_regression.py +++ b/wqflask/wqflask/marker_regression/marker_regression.py @@ -165,7 +165,10 @@ class MarkerRegression(object): else: self.json_data['chr'].append(str(qtl['chr'])) self.json_data['pos'].append(qtl['Mb']) - self.json_data['lod.hk'].append(str(qtl['lod_score'])) + if self.score_type == "LRS": + self.json_data['lod.hk'].append(str(qtl['lrs_value'])) + else: + self.json_data['lod.hk'].append(str(qtl['lod_score'])) self.json_data['markernames'].append(qtl['name']) #Get chromosome lengths for drawing the interval map plot diff --git a/wqflask/wqflask/static/new/javascript/dataset_select_menu.js b/wqflask/wqflask/static/new/javascript/dataset_select_menu.js index fb9fdcf3..f91504be 100644 --- a/wqflask/wqflask/static/new/javascript/dataset_select_menu.js +++ b/wqflask/wqflask/static/new/javascript/dataset_select_menu.js @@ -94,6 +94,7 @@ $(function() { $('#dataset_info').click(dataset_info); make_default = function() { var holder, item, jholder, _i, _len, _ref; + alert("The current settings are now your default.") holder = {}; _ref = ['species', 'group', 'type', 'dataset']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { diff --git a/wqflask/wqflask/static/new/javascript/histogram.js b/wqflask/wqflask/static/new/javascript/histogram.js index d872a3ba..d26d0c03 100755 --- a/wqflask/wqflask/static/new/javascript/histogram.js +++ b/wqflask/wqflask/static/new/javascript/histogram.js @@ -68,7 +68,7 @@ Histogram.prototype.get_histogram_data = function() { var n_bins; console.log("sample_vals:", this.sample_vals); - n_bins = Math.sqrt(this.sample_vals.length); + n_bins = 2*Math.sqrt(this.sample_vals.length); //Was originally just the square root, but increased to 2*; ideally would be a GUI for changing this this.histogram_data = d3.layout.histogram().bins(this.x_scale.ticks(n_bins))(this.sample_vals); return console.log("histogram_data:", this.histogram_data[0]); }; diff --git a/wqflask/wqflask/static/packages/bootstrap/css/bootstrap.css b/wqflask/wqflask/static/packages/bootstrap/css/bootstrap.css index dd6fa736..4145e73f 100755 --- a/wqflask/wqflask/static/packages/bootstrap/css/bootstrap.css +++ b/wqflask/wqflask/static/packages/bootstrap/css/bootstrap.css @@ -1215,7 +1215,7 @@ a.bg-danger:hover { } .page-header { padding-bottom: 9px; - margin: 20px 0 20px; + margin: 10px 0 10px; border-bottom: 1px solid #eee; } ul, @@ -4674,7 +4674,7 @@ a.list-group-item.active > .badge, margin-left: 3px; } .jumbotron { - margin-bottom: 30px; + margin-bottom: 10px; color: inherit; background-color: #eee; } diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index 75af8ba5..90acd0da 100755 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -83,7 +83,8 @@ <option value="phenotype" {% if type=="phenotype" %}selected{% endif %}>Phenotypes</option> </select> <input class="btn btn-primary form-control col-xs-2" style="width: 100px; margin-top: 15px; margin-left: 10px;" type="submit" value="Search All"> - <input class="form-control col-xs-6" style="width: 980px; margin-top: 15px; margin-left: 10px;" type="text" name="terms" required> + <input class="form-control col-xs-6" style="width: 600px; margin-top: 15px; margin-left: 10px;" type="text" name="terms" required> + <a href="http://www.genenetwork.org"><input class="btn btn-primary form-control col-xs-2" style="width: 175px; margin-top: 15px; margin-left: 50px;" value="Use GeneNetwork 1"></a> </div> </form> </div> diff --git a/wqflask/wqflask/templates/collections/add.html b/wqflask/wqflask/templates/collections/add.html index faee4f78..07fcba22 100755 --- a/wqflask/wqflask/templates/collections/add.html +++ b/wqflask/wqflask/templates/collections/add.html @@ -1,11 +1,12 @@ <div id="myModal"> <div class="modal-header"> <h3>Add to collection</h3> - <p>You have three choices: Use your default collection, create a new named collection, + <p>You have two choices: Create and name a collection, or add the traits to an existing collection.</p> </div> <div class="modal-body"> <form action="/collections/new" data-validate="parsley" id="add_form"> +<!-- <fieldset> <legend>Use your default collection</legend> <span class="help-block">Choose this if you're in a hurry or don't plan on using the collection again.</span> @@ -13,11 +14,12 @@ <button type="submit" name="Default" class="btn">Continue</button> </fieldset> <hr /> +--> <input type="hidden" name="traits" value="{{ traits }}" /> <fieldset> - <legend>Or create a new named collection</legend> + <legend>Create a new named collection</legend> <label>New collection name</label> <input type="text" name="new_collection" placeholder="Name of new collection..." data-trigger="change" data-minlength="5" data-maxlength="50"> diff --git a/wqflask/wqflask/templates/gsearch_gene.html b/wqflask/wqflask/templates/gsearch_gene.html index 6beefb01..c7e50a16 100755 --- a/wqflask/wqflask/templates/gsearch_gene.html +++ b/wqflask/wqflask/templates/gsearch_gene.html @@ -52,8 +52,8 @@ <TD>{{ loop.index }}</TD> <TD>{{ this_trait.dataset.group.species }}</TD> <TD>{{ this_trait.dataset.group.name }}</TD> - <TD>{{ this_trait.dataset.name }}</TD> - <TD>{{ this_trait.dataset.name }}</TD> + <TD>{{ this_trait.dataset.tissue }}</TD> + <TD>{{ this_trait.dataset.fullname }}</TD> <TD><a href="{{ url_for('show_trait_page', trait_id = this_trait.name, dataset = this_trait.dataset.name)}}">{{ this_trait.name }}</a></TD> <TD>{{ this_trait.symbol }}</TD> <TD>{{ this_trait.description_display }}</TD> diff --git a/wqflask/wqflask/templates/marker_regression.html b/wqflask/wqflask/templates/marker_regression.html index 91808fcf..d83730a2 100755 --- a/wqflask/wqflask/templates/marker_regression.html +++ b/wqflask/wqflask/templates/marker_regression.html @@ -34,7 +34,7 @@ <thead> <tr> <th>Index</th> - <th>LOD Score</th> + <th>{{ score_type }}</th> <th>Chr</th> <th>Mb</th> <th>Locus</th> @@ -87,7 +87,10 @@ { "type": "natural" }, { "type": "natural" } ], - "sDom": "ZRtir", + "buttons": [ + 'csv' + ], + "sDom": "RZBtir", "iDisplayLength": -1, "autoWidth": true, "bDeferRender": true, diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 117e2dcd..d0875b71 100755 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -2,8 +2,6 @@ {% block title %}Search Results{% endblock %} {% block css %} <link rel="stylesheet" type="text/css" href="/static/new/packages/DataTables/css/jquery.dataTables.css" /> - <!--<link rel="stylesheet" type="text/css" href="/static/packages/DT_bootstrap/DT_bootstrap.css" />--> - <!--<link rel="stylesheet" type="text/css" href="/static/packages/TableTools/media/css/TableTools.css" />--> <link rel="stylesheet" type="text/css" href="/static/new/packages/DataTables/extensions/dataTables.fixedHeader.css" > <link rel="stylesheet" type="text/css" href="//cdn.datatables.net/fixedcolumns/3.0.4/css/dataTables.fixedColumns.css"> <link rel="stylesheet" type="text/css" href="/static/new/packages/DataTables/extensions/buttons.bootstrap.css" /> @@ -45,12 +43,21 @@ <button class="btn btn-default" id="deselect_all"><span class="glyphicon glyphicon-remove"></span> Deselect All</button> <button class="btn btn-default" id="invert"><span class="glyphicon glyphicon-resize-vertical"></span> Invert</button> <button class="btn btn-default" id="add" disabled><span class="glyphicon glyphicon-plus-sign"></span> Add</button> - <button class="btn btn-default"><span class="glyphicon glyphicon-download"></span> Download Table</button> + <!--<button class="btn btn-default"><span class="glyphicon glyphicon-download"></span> Download Table</button>--> <button id="redraw" class="btn btn-default">Reset Columns</button> <input type="text" id="searchbox" class="form-control" style="width: 200px; display: inline;" placeholder="Search This Table For ..."> <input type="text" id="select_top" class="form-control" style="width: 200px; display: inline;" placeholder="Select Top ..."> <br /> <br /> + <button class="btn btn-default" id="open_options">Open Extra Options</button> + <br /> + <br /> + <div id="extra_options" style="display:none;"> + Min LRS <input type="text" id="min" class="form-control" style="width: 60px; display: inline;"> + Max LRS <input type="text" id="max" class="form-control" style="width: 60px; display: inline;"> + </div> + <br /> + <br /> <div id="table_container"> <table class="table table-hover table-striped" id='trait_table' {% if dataset.type == 'Geno' %}width="400px"{% endif %} style="float: left;"> <thead> @@ -58,7 +65,7 @@ <th style="width: 30px;"></th> {% for header in header_fields %} {% if header == 'Max LRS' %} - <th style="text-align: right;">Max <br>LRS<a href="http://genenetwork.org//glossary.html#L" target="_blank"><sup style="color:#f00"> ?</sup></a></th> + <th style="text-align: right;">Max <br>LRS</th> {% elif header == 'Additive Effect' %} <th style="text-align: right;">Additive<br>Effect<a href="http://genenetwork.org//glossary.html#A" target="_blank"><sup style="color:#f00"> ?</sup></a></th> {% else %} @@ -73,7 +80,7 @@ <TR id="trait:{{ this_trait.name }}:{{ this_trait.dataset.name }}"> <TD><INPUT TYPE="checkbox" NAME="searchResult" class="checkbox trait_checkbox" style="transform: scale(1.5);" VALUE="{{ data_hmac('{}:{}'.format(this_trait.name, this_trait.dataset.name)) }}"> </TD> - <TD>{{ loop.index }}</TD> + <TD align="right">{{ loop.index }}</TD> <TD> <a href="{{ url_for('show_trait_page', trait_id = this_trait.name, @@ -132,8 +139,6 @@ <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/extensions/dataTables.colReorder.js"></script> <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/extensions/dataTables.fixedHeader.js"></script> <script language="javascript" type="text/javascript" src="//cdn.datatables.net/fixedcolumns/3.0.4/js/dataTables.fixedColumns.min.js"></script> - <!--<script language="javascript" type="text/javascript" src="/static/packages/DT_bootstrap/DT_bootstrap.js"></script>--> - <!--<script language="javascript" type="text/javascript" src="/static/packages/TableTools/media/js/TableTools.min.js"></script>--> <script type="text/javascript" charset="utf-8"> function getValue(x) { @@ -150,7 +155,41 @@ } return parseFloat(x); } - + + + function filtering( oSettings, aData, iDataIndex, column) { + var iColumn = column; + if (document.getElementById('min').value){ + var iMin = document.getElementById('min').value * 1; + } else { + var iMin = 0 + } + if (document.getElementById('max').value){ + var iMax = document.getElementById('max').value * 1; + } else { + var iMax = 10000 + } + + var iVersion = aData[iColumn] == "-" ? 0 : aData[iColumn]*1; + if ( iMin === "" && iMax === "" ) + { + return true; + } + else if ( iMin === "" && iVersion < iMax ) + { + return true; + } + else if ( iMin < iVersion && "" === iMax ) + { + return true; + } + else if ( iMin < iVersion && iVersion < iMax ) + { + return true; + } + return false; + } + jQuery.fn.dataTableExt.oSort['cust-txt-asc'] = function (a, b) { var x = getValue(a); var y = getValue(b); @@ -183,13 +222,21 @@ console.time("Creating table"); {% if dataset.type == 'ProbeSet' %} + + jQuery.fn.dataTableExt.afnFiltering.push( + function( oSettings, aData, iDataIndex ) { + return filtering( oSettings, aData, iDataIndex, 7 ); + + } + ); + $('#trait_table').DataTable( { "columns": [ { "type": "natural" }, { "type": "natural" }, { "type": "natural" }, { "type": "natural" }, - { "type": "natural", "width": "30%" }, + { "type": "natural", "width": "40%" }, { "type": "natural", "width": "15%" }, { "type": "natural" }, { "type": "natural" }, @@ -201,7 +248,6 @@ ], "sDom": "RZBtir", "iDisplayLength": -1, - "autoWidth": false, "bDeferRender": true, "bSortClasses": false, "scrollY": "700px", @@ -222,7 +268,10 @@ { "type": "natural", "width": "15%"}, { "type": "natural" } ], - "sDom": "RZtir", + "buttons": [ + 'csv' + ], + "sDom": "RZBtir", "iDisplayLength": -1, "autoWidth": false, "bDeferRender": true, @@ -239,7 +288,10 @@ { "type": "natural" }, { "type": "natural", "width": "40%"} ], - "sDom": "RZtir", + "buttons": [ + 'csv' + ], + "sDom": "RZBtir", "iDisplayLength": -1, "autoWidth": true, "bDeferRender": true, @@ -251,13 +303,18 @@ {% endif %} console.timeEnd("Creating table"); + var table = $('#trait_table').DataTable(); $('#redraw').click(function() { var table = $('#trait_table').DataTable(); table.colReorder.reset() }); - - //new $.fn.dataTable.FixedHeader( table ); - //new $.fn.dataTable.FixedColumns( table ); + + $('#min').keyup( function() { table.draw(); } ); + $('#max').keyup( function() { table.draw(); } ); + + $('#open_options').click( function () { + $('#extra_options').toggle(); + }); }); </script> diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index 6199f931..0709a82f 100755 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -11,8 +11,8 @@ <link rel="stylesheet" type="text/css" href="/static/new/css/d3-tip.min.css" /> <link rel="stylesheet" type="text/css" href="/static/new/packages/nvd3/nv.d3.min.css" /> <link rel="stylesheet" type="text/css" href="/static/new/packages/DataTables/css/jquery.dataTables.css" /> + <link rel="stylesheet" type="text/css" href="/static/new/packages/DataTables/extensions/buttons.bootstrap.css" /> <link rel="stylesheet" type="text/css" href="/static/packages/DT_bootstrap/DT_bootstrap.css" /> - <link rel="stylesheet" type="text/css" href="/static/packages/TableTools/media/css/TableTools.css" /> {% endblock %} {% block content %} <!-- Start of body --> @@ -37,12 +37,6 @@ <input type="hidden" name="temp_uuid" id="temp_uuid" value="{{ temp_uuid }}"> <div class="container"> - <div class="page-header"> - <h1>{{ dataset.group.species.capitalize() }} - - {{ dataset.group.name }} - - {{ this_trait.name_header_fmt }} - </h1> - </div> {% include 'show_trait_details.html' %} <div class="panel-group" id="accordion"> @@ -145,12 +139,14 @@ <script language="javascript" type="text/javascript" src="/static/new/javascript/lod_chart.js"></script> <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/jquery.dataTables.js"></script> + <script language="javascript" type="text/javascript" src="https://cdn.datatables.net/buttons/1.0.0/js/dataTables.buttons.min.js"></script> + <script language="javascript" type="text/javascript" src="https://cdn.datatables.net/buttons/1.0.0/js/buttons.html5.min.js"></script> + <script language="javascript" type="text/javascript" src="https://cdn.datatables.net/buttons/1.0.0/js/buttons.bootstrap.min.js"></script> + <script language="javascript" type="text/javascript" src="/static/new/js_external/jszip.min.js"></script> <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/dataTables.scientific.js"></script> <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/js/dataTables.naturalSort.js"></script> <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/extensions/dataTables.colResize.js"></script> <script language="javascript" type="text/javascript" src="/static/new/packages/DataTables/extensions/dataTables.colReorder.js"></script> - <script language="javascript" type="text/javascript" src="/static/packages/DT_bootstrap/DT_bootstrap.js"></script> - <script language="javascript" type="text/javascript" src="/static/packages/TableTools/media/js/TableTools.min.js"></script> <script type="text/javascript" charset="utf-8"> function getValue(x) { @@ -209,19 +205,10 @@ { "bSortable": false }, { "type": "cust-txt" } ], - "sDom": "RZtir", - "oTableTools": { - "aButtons": [ - "copy", - "print", - { - "sExtends": "collection", - "sButtonText": 'Save <span class="caret" />', - "aButtons": [ "csv", "xls", "pdf" ] - } - ], - "sSwfPath": "/static/packages/TableTools/media/swf/copy_csv_xls_pdf.swf" - }, + "buttons": [ + 'csv' + ], + "sDom": "RZBtir", "iDisplayLength": -1, "autoWidth": false, "bLengthChange": true, @@ -245,19 +232,10 @@ null, { "type": "cust-txt" } ], - "sDom": "RZtir", - "oTableTools": { - "aButtons": [ - "copy", - "print", - { - "sExtends": "collection", - "sButtonText": 'Save <span class="caret" />', - "aButtons": [ "csv", "xls", "pdf" ] - } - ], - "sSwfPath": "/static/packages/TableTools/media/swf/copy_csv_xls_pdf.swf" - }, + "buttons": [ + 'csv' + ], + "sDom": "RZBtir", "iDisplayLength": -1, "autoWidth": false, "bLengthChange": true, diff --git a/wqflask/wqflask/templates/show_trait_details.html b/wqflask/wqflask/templates/show_trait_details.html index 108fcd92..04db915a 100755 --- a/wqflask/wqflask/templates/show_trait_details.html +++ b/wqflask/wqflask/templates/show_trait_details.html @@ -1,4 +1,8 @@ <dl class="dl-horizontal"> + <dt>Species</dt> + <dd>{{ this_trait.dataset.group.species }}</dd> + <dt>Group</dt> + <dd>{{ this_trait.dataset.group.name }}</dd> {% if this_trait.dataset.type == 'ProbeSet' %} <dt>Aliases</dt> <dd>{{ this_trait.alias_fmt }}</dd> @@ -33,7 +37,7 @@ {% if this_trait.dataset.type == 'ProbeSet' %} <dd> {% if this_trait.symbol != None %} - <a href="http://bioinformatics-dev/Getd2g.pl?gene_list={{ this_trait.symbol }}" target="_blank" title="Related descriptive, genomic, clinical, functional and drug-therapy information"> + <a href="http://www.genotation.org/Getd2g.pl?gene_list={{ this_trait.symbol }}" target="_blank" title="Related descriptive, genomic, clinical, functional and drug-therapy information"> Genotation </a> diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html index eea9b295..b9ac80bf 100755 --- a/wqflask/wqflask/templates/show_trait_mapping_tools.html +++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html @@ -35,7 +35,7 @@ <div class="mapping_method_fields form-group"> <label for="mapping_permutations" class="col-xs-2 control-label">Permutations</label> <div style="margin-left: 20px;" class="col-xs-4 controls"> - <input name="num_pylmm" value="" type="text" class="form-control"> + <input name="num_perm_pylmm" value="" type="text" class="form-control"> </div> </div> <div id="permutations_alert" class="alert alert-error alert-warning" style="display:none;"> |