Defect #42966 » 0002-Replace-autocomplete-input-loading-icon-with-SVG.patch
app/assets/javascripts/application-legacy.js | ||
---|---|---|
748 | 748 |
source: url, |
749 | 749 |
minLength: 2, |
750 | 750 |
position: {collision: "flipfit"}, |
751 |
search: function(){$('#'+fieldId).addClass('ajax-loading');},
|
|
752 |
response: function(){$('#'+fieldId).removeClass('ajax-loading');}
|
|
751 |
search: function(){showAutocompleteLoadingIcon(fieldId)},
|
|
752 |
response: function(){restoreAutocompleteSearchIcon(fieldId)}
|
|
753 | 753 |
}, options)); |
754 | 754 |
$('#'+fieldId).addClass('autocomplete'); |
755 | 755 |
}); |
756 | 756 |
} |
757 | 757 | |
758 |
function showAutocompleteLoadingIcon(fieldId) { |
|
759 |
const input = document.getElementById(fieldId); |
|
760 |
if (!input) return; |
|
761 | ||
762 |
const container = input.closest('p'); |
|
763 |
if (!container) return; |
|
764 | ||
765 |
const svg = container.querySelector('svg.svg-search'); |
|
766 |
if (!svg) return; |
|
767 | ||
768 |
updateSVGIcon(svg, 'loader'); |
|
769 |
svg.classList.remove('svg-search'); |
|
770 |
svg.classList.add('svg-loader'); |
|
771 |
input.classList.add('ajax-loading'); |
|
772 |
} |
|
773 | ||
774 |
function restoreAutocompleteSearchIcon(fieldId) { |
|
775 |
const input = document.getElementById(fieldId); |
|
776 |
if (!input) return; |
|
777 | ||
778 |
const container = input.closest('p'); |
|
779 |
if (!container) return; |
|
780 | ||
781 |
const svg = container.querySelector('svg.svg-loader'); |
|
782 |
if (!svg) return; |
|
783 | ||
784 |
updateSVGIcon(svg, 'search'); |
|
785 |
svg.classList.remove('svg-loader'); |
|
786 |
svg.classList.add('svg-search'); |
|
787 |
input.classList.remove('ajax-loading'); |
|
788 |
} |
|
789 | ||
758 | 790 |
function multipleAutocompleteField(fieldId, url, options) { |
759 | 791 |
function split(val) { |
760 | 792 |
return val.split(/,\s*/); |
... | ... | |
774 | 806 |
minLength: 2, |
775 | 807 |
position: {collision: "flipfit"}, |
776 | 808 |
search: function () { |
777 |
$('#' + fieldId).addClass('ajax-loading');
|
|
809 |
showAutocompleteLoadingIcon(fieldId);
|
|
778 | 810 |
}, |
779 | 811 |
response: function () { |
780 |
$('#' + fieldId).removeClass('ajax-loading');
|
|
812 |
restoreAutocompleteSearchIcon(fieldId);
|
|
781 | 813 |
}, |
782 | 814 |
select: function (event, ui) { |
783 | 815 |
var terms = split(this.value); |
... | ... | |
809 | 841 |
type: 'get', |
810 | 842 |
data: {q: $this.val()}, |
811 | 843 |
success: function(data){ if(targetId) $('#'+targetId).html(data); }, |
812 |
beforeSend: function(){ $this.addClass('ajax-loading'); },
|
|
813 |
complete: function(){ $this.removeClass('ajax-loading'); }
|
|
844 |
beforeSend: function(){ showAutocompleteLoadingIcon(fieldId); },
|
|
845 |
complete: function(){ restoreAutocompleteSearchIcon(fieldId); }
|
|
814 | 846 |
}); |
815 | 847 |
} |
816 | 848 |
}; |
app/assets/stylesheets/application.css | ||
---|---|---|
965 | 965 |
.total-hours span.hours-int { font-size: 120%; } |
966 | 966 | |
967 | 967 |
.autoscroll {overflow-x: auto; padding:1px; margin-bottom: 1.2em; position: relative;} |
968 |
#user_login, #user_firstname, #user_lastname, #user_mail, #my_account_form select, #user_form select { width: 90%; } |
|
968 |
#user_firstname, #user_lastname, #user_mail, #my_account_form select, #user_form select { width: 90%; } |
|
969 |
#user_login { width: calc(90% - 18px); } |
|
969 | 970 | |
970 | 971 |
#workflow_copy_form select { width: 200px; } |
971 | 972 |
table.transitions td.enabled {background: #bfb;} |
... | ... | |
1199 | 1200 |
input#principal_search, input#user_search {width:90%} |
1200 | 1201 |
.roles-selection label {display:inline-block; width:210px;} |
1201 | 1202 | |
1202 |
input.autocomplete { |
|
1203 |
background: #fff url(/search.svg) no-repeat 2px 50%; padding-left:20px !important; |
|
1204 |
} |
|
1205 |
input.autocomplete.ajax-loading { |
|
1206 |
background-image: url(/loading.gif); |
|
1207 |
} |
|
1208 | ||
1209 | 1203 |
.role-visibility {padding-left:2em;} |
1210 | 1204 | |
1211 | 1205 |
.objects-selection { |
app/assets/stylesheets/rtl.css | ||
---|---|---|
230 | 230 |
.attachments_fields input.description {margin-left:0px; margin-right:4px;} |
231 | 231 | |
232 | 232 |
.attachments_fields input.filename {background:url(/attachment.png) no-repeat right 1px top 50%; padding-left:0px; padding-right:18px;} |
233 |
.attachments_fields .ajax-waiting input.filename {background:url(/hourglass-empty.svg) no-repeat right top 50%;} |
|
234 |
.attachments_fields .ajax-loading input.filename {background:url(/loading.gif) no-repeat right top 50%;} |
|
235 | 233 |
.attachments_fields div.ui-progressbar {margin: 2px 8px -5px 0;} |
236 | 234 | |
237 | 235 |
a.remove-upload {background: url(/delete.png) no-repeat right 1px top 50%; padding-left:0px; padding-right:16px;} |
... | ... | |
247 | 245 |
table.members td.name {padding-right: 20px; padding-left:0; } |
248 | 246 |
table.members td.group, table.members td.groupnonmember, table.members td.groupanonymous {background: url(/group.png) no-repeat right 50%;} |
249 | 247 | |
250 |
input.autocomplete { |
|
251 |
background: #fff url(/search.svg) no-repeat right 2px top 50%; padding-left:0px !important; padding-right:20px !important; |
|
252 |
} |
|
253 | ||
254 | 248 |
.role-visibility {padding-right:2em; padding-left:0;} |
255 | 249 | |
256 | 250 |
/***** Flash & error messages ****/ |
app/views/groups/_new_users_form.html.erb | ||
---|---|---|
1 | 1 |
<fieldset class="box"> |
2 | 2 |
<legend><%= label_tag "user_search", l(:label_user_search) %></legend> |
3 |
<p><%= text_field_tag 'user_search', nil %></p> |
|
3 |
<p> |
|
4 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %> |
|
5 |
<%= text_field_tag 'user_search', nil %> |
|
6 |
</p> |
|
4 | 7 |
<%= javascript_tag "observeSearchfield('user_search', null, '#{ escape_javascript autocomplete_for_user_group_path(@group) }')" %> |
5 | 8 | |
6 | 9 |
<div id="users"> |
app/views/issue_relations/_form.html.erb | ||
---|---|---|
11 | 11 |
</div> |
12 | 12 |
<% end %> |
13 | 13 |
<p><%= f.select :relation_type, collection_for_relation_type_select, {}, :onchange => "setPredecessorFieldsVisibility();" %> |
14 |
<%= l(:label_issue) %> #<%= f.text_field :issue_to_id, :value => unsaved_relations_ids, :size => 10 %> |
|
14 |
<span> |
|
15 |
<%= l(:label_issue) %> #<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %><%= f.text_field :issue_to_id, :value => unsaved_relations_ids, :size => 10 %> |
|
16 |
</span> |
|
15 | 17 |
<span id="predecessor_fields" style="display:none;"> |
16 | 18 |
<%= l(:field_delay) %>: <%= f.text_field :delay, :size => 3 %> <%= l(:label_day_plural) %> |
17 | 19 |
</span> |
app/views/issues/_attributes.html.erb | ||
---|---|---|
63 | 63 | |
64 | 64 |
<div class="splitcontentright"> |
65 | 65 |
<% if @issue.safe_attribute? 'parent_issue_id' %> |
66 |
<p id="parent_issue"><%= f.text_field :parent_issue_id, :size => 10, |
|
66 |
<p id="parent_issue"> |
|
67 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %> |
|
68 |
<%= f.text_field :parent_issue_id, :size => 9, |
|
67 | 69 |
:required => @issue.required_attribute?('parent_issue_id'), |
68 |
:onchange => "updateIssueFrom('#{escape_javascript update_issue_form_path(@project, @issue)}', this)" %></p> |
|
70 |
:onchange => "updateIssueFrom('#{escape_javascript update_issue_form_path(@project, @issue)}', this)" %> |
|
71 |
</p> |
|
69 | 72 |
<%= javascript_tag "observeAutocompleteField('issue_parent_issue_id', '#{escape_javascript(auto_complete_issues_path(:project_id => @issue.project, :scope => Setting.cross_project_subtasks, :status => @issue.closed? ? 'c' : 'o', :issue_id => @issue.id))}')" %> |
70 | 73 |
<% end %> |
71 | 74 |
app/views/issues/bulk_edit.html.erb | ||
---|---|---|
146 | 146 |
<% if @safe_attributes.include?('parent_issue_id') && @project %> |
147 | 147 |
<p> |
148 | 148 |
<label for='issue_parent_issue_id'><%= l(:field_parent_issue) %></label> |
149 |
<%= text_field_tag 'issue[parent_issue_id]', '', :size => 10, :value => @issue_params[:parent_issue_id] %> |
|
149 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %> |
|
150 |
<%= text_field_tag 'issue[parent_issue_id]', '', :size => 9, :value => @issue_params[:parent_issue_id] %> |
|
150 | 151 |
<label class="inline"><%= check_box_tag 'issue[parent_issue_id]', 'none', (@issue_params[:parent_issue_id] == 'none'), :id => nil, :data => {:disables => '#issue_parent_issue_id'} %><%= l(:button_clear) %></label> |
151 | 152 |
</p> |
152 | 153 |
<%= javascript_tag "observeAutocompleteField('issue_parent_issue_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project, :scope => Setting.cross_project_subtasks)}')" %> |
app/views/issues/destroy.html.erb | ||
---|---|---|
10 | 10 |
<label><%= radio_button_tag 'todo', 'nullify', false %> <%= l(:text_assign_time_entries_to_project) %></label><br /> |
11 | 11 |
<% end %> |
12 | 12 |
<% if @project %> |
13 |
<span> |
|
13 | 14 |
<label><%= radio_button_tag 'todo', 'reassign', false, :onchange => 'if (this.checked) { $("#reassign_to_id").focus(); }' %> <%= l(:text_reassign_time_entries) %></label> |
15 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %> |
|
14 | 16 |
<%= text_field_tag 'reassign_to_id', params[:reassign_to_id], :size => 6, :onfocus => '$("#todo_reassign").attr("checked", true);' %> |
17 |
</span> |
|
15 | 18 |
<%= javascript_tag "observeAutocompleteField('reassign_to_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project)}')" %> |
16 | 19 |
<% end %> |
17 | 20 |
</p> |
app/views/members/_new_form.html.erb | ||
---|---|---|
1 | 1 |
<fieldset class="box"> |
2 | 2 |
<legend><%= label_tag("principal_search", l(:label_principal_search)) %></legend> |
3 |
<p><%= text_field_tag('principal_search', nil) %></p> |
|
3 |
<p> |
|
4 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %> |
|
5 |
<%= text_field_tag('principal_search', nil) %> |
|
6 |
</p> |
|
4 | 7 |
<%= javascript_tag "observeSearchfield('principal_search', null, '#{ escape_javascript autocomplete_project_memberships_path(@project, :format => 'js') }')" %> |
5 | 8 |
<div id="principals_for_new_member"> |
6 | 9 |
<%= render_principals_for_new_members(@project) %> |
app/views/repositories/_related_issues.html.erb | ||
---|---|---|
32 | 32 |
:remote => true, |
33 | 33 |
:method => :post, |
34 | 34 |
:id => 'new-relation-form', :style => (@issue ? '' : 'display: none;')) do |f| %> |
35 |
<%= l(:label_issue) %> #<%= text_field_tag 'issue_id', '', :size => 10 %> |
|
35 |
<p> |
|
36 |
<%= l(:label_issue) %> # |
|
37 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %> |
|
38 |
<%= text_field_tag 'issue_id', '', :size => 10 %> |
|
39 |
</p> |
|
36 | 40 |
<%= submit_tag l(:button_add) %> |
37 | 41 |
<%= toggle_link l(:button_cancel), 'new-relation-form'%> |
38 | 42 |
<% end %> |
app/views/timelog/_form.html.erb | ||
---|---|---|
11 | 11 |
<% end %> |
12 | 12 | |
13 | 13 |
<p> |
14 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %> |
|
14 | 15 |
<%= f.text_field :issue_id, :size => 6, :required => Setting.timelog_required_fields.include?('issue_id') %> |
15 | 16 |
<span id="time_entry_issue"> |
16 | 17 |
<%= link_to_issue(@time_entry.issue) if @time_entry.issue.try(:visible?) %> |
app/views/timelog/bulk_edit.html.erb | ||
---|---|---|
40 | 40 |
:onchange => "updateBulkEditFrom('#{escape_javascript url_for(:action => 'bulk_edit', :format => 'js')}')" ) %> |
41 | 41 |
</p> |
42 | 42 |
<p> |
43 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %> |
|
43 | 44 |
<label for="time_entry_issue_id"><%= l(:field_issue) %></label> |
44 | 45 |
<%= text_field :time_entry, :issue_id, :size => 6 %> |
45 | 46 |
<label class="inline"><%= check_box_tag 'time_entry[issue_id]', 'none', (@time_entry_params[:issue_id] == 'none'), :id => nil, :data => {:disables => '#time_entry_issue_id'} %><%= l(:button_clear) %></label> |
app/views/users/_form.html.erb | ||
---|---|---|
6 | 6 |
<div class="splitcontentleft"> |
7 | 7 |
<fieldset class="box tabular"> |
8 | 8 |
<legend><%=l(:label_information_plural)%></legend> |
9 |
<p><%= f.text_field :login, :required => true, :size => 25 %></p> |
|
9 |
<p><%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %><%= f.text_field :login, :required => true, :size => 25 %></p>
|
|
10 | 10 |
<p><%= f.text_field :firstname, :required => true %></p> |
11 | 11 |
<p><%= f.text_field :lastname, :required => true %></p> |
12 | 12 |
<p><%= f.text_field :mail, :required => true %></p> |
app/views/watchers/_new.html.erb | ||
---|---|---|
21 | 21 |
<% end %> |
22 | 22 |
<%= hidden_field_tag 'project_id', @project.id if @project %> |
23 | 23 | |
24 |
<p><%= label_tag 'user_search', l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p> |
|
24 |
<p> |
|
25 |
<%= label_tag 'user_search', l(:label_user_search) %><br> |
|
26 |
<%= sprite_icon 'search', icon_only: true, css_class: 'svg-search' %><%= text_field_tag 'user_search', nil %> |
|
27 |
</p> |
|
25 | 28 |
<%= javascript_tag( |
26 | 29 |
"observeSearchfield( |
27 | 30 |
'user_search', |