archive-rails7/app/views/admin/archive_files/_form.html.erb

557 lines
22 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<% # encoding: utf-8 %>
<% content_for :page_specific_css do %>
<%= stylesheet_link_tag "lib/main-forms" %>
<%= stylesheet_link_tag "lib/fileupload" %>
<%= stylesheet_link_tag "lib/main-list" %>
<style type="text/css">
.sort-order-icon{
font-size: 25px;
cursor: move;
}
</style>
<% end %>
<% content_for :page_specific_javascript do %>
<%= javascript_include_tag "lib/bootstrap-fileupload" %>
<%= javascript_include_tag "lib/file-type" %>
<%= javascript_include_tag "lib/module-area" %>
<%= javascript_include_tag "lib/jquery-ui-sortable.min" %>
<% end %>
<%
sort_order = ArchiveSortOrder.first
min_sort_number = sort_order.min_sort_number
max_sort_number = sort_order.max_sort_number
%>
<%#= f.error_messages %>
<style>
#fileupload {
position: relative;
clear: both;
overflow: hidden;
height: 254px;
}
#fileupload #dropzone.drop {
position: absolute;
left: 0;
right: 0;
border: 2px dashed #0088CC;
border-radius: 10px;
color: #0088CC;
background-color: #FFFFFF;
z-index: 0;
}
#fileupload #dropzone {
padding: 30px;
text-align: center;
font-size: 3em;
font-family: 'Raleway';
line-height: 1.2em;
color: #e4e4e4;
}
#fileupload #dropzone.in {
opacity: .7;
z-index: 2;
border-color: #faa732;
color: #faa732;
}
</style>
<!-- Input Area -->
<div class="input-area">
<!-- Module Tabs -->
<div class="nav-name"><strong><%= t(:module) %></strong></div>
<ul class="nav nav-pills module-nav">
<li></li>
<li class="active">
<a href="#basic" data-toggle="tab"><%= t(:basic) %></a>
</li>
<li>
<a href="#status" data-toggle="tab"><%= t(:status) %></a>
</li>
<li>
<a href="#tag" data-toggle="tab"><%= t(:tags) %></a>
</li>
</ul>
<!-- Module -->
<div class="tab-content module-area">
<!-- Basic Module -->
<div class="tab-pane fade in active" id="basic">
<!-- Category -->
<div class="control-group">
<label class="control-label muted"><%= t(:category) %></label>
<div class="controls">
<%= select_category(f, @module_app) %>
</div>
</div>
<!-- Sort -->
<div class="control-group">
<label class="control-label muted"><%= t(:sort_number) %></label>
<div class="controls">
<% extra_data = f.object.new_record? ? {placeholder: f.object.sort_number, title: f.object.sort_number, value: ''} : {} %>
<%= f.number_field :sort_number, extra_data %>
<p class="muted">
<% if sort_order.sort_order %>
<%= t("archive.ascending") %>
<% else %>
<%= t("archive.decending") %>
<% end %>
; <%= t('default') %>: <%= sort_order.get_default_order %>
</p>
<p class="muted"><%= t('archive.min') %>: <%=min_sort_number%>, <%= t('archive.max') %>: <%=max_sort_number%></p>
</div>
</div>
</div>
<!-- Status Module -->
<div class="tab-pane fade" id="status">
<!-- Status -->
<div class="control-group">
<label class="control-label muted"><%= t(:status) %></label>
<div class="controls" data-toggle="buttons-checkbox">
<label class="checkbox inline btn <%= 'active' if @archive_file.is_top? %>">
<%= f.check_box :is_top %> <%= t(:top) %>
</label>
<label class="checkbox inline btn <%= 'active' if @archive_file.is_hot? %>">
<%= f.check_box :is_hot %> <%= t(:hot) %>
</label>
<label class="checkbox inline btn <%= 'active' if @archive_file.is_hidden? %>">
<%= f.check_box :is_hidden %> <%= t(:hide) %>
</label>
</div>
</div>
</div>
<!-- Tag Module -->
<div class="tab-pane fade" id="tag">
<!-- Tag -->
<div class="control-group">
<label class="control-label muted"><%= t(:tags) %></label>
<%= select_tags(f, @module_app) %>
</div>
</div>
</div>
<!-- Language Tabs -->
<div class="nav-name"><strong><%= t(:language) %></strong></div>
<ul class="nav nav-pills language-nav">
<% @site_in_use_locales.each_with_index do |locale, i| %>
<li class="<%= 'active' if i == 0 %>">
<a data-toggle="tab" href=".<%= locale %>"><%= t(locale.to_s) %></a>
</li>
<% end %>
</ul>
<div class="control-group" id="file_link_sort_control" data-migrated="<%= @archive_file.files_links_migrated ? 'true' : 'false' %>">
<label class="control-label muted"><%= t("archive.enable_file_link_sort") %></label>
<div class="controls">
<label class="checkbox">
<%= f.check_box :enable_file_link_sort, id: "enable_file_link_sort_checkbox" %>
<%= t("archive.enable_file_link_sort_hint") %>
</label>
<p class="muted" style="color:#c0392b;"><%= t("archive.disable_file_link_sort_warning") %></p>
<% unless @archive_file.files_links_migrated %>
<p class="muted" style="color:#c0392b;"><%= t("archive.not_migrated_yet_hint") %></p>
<% end %>
</div>
</div>
<!-- Language -->
<div class="tab-content language-area">
<% @site_in_use_locales.each_with_index do |locale, i| %>
<div class="<%= locale %> tab-pane fade <%= ( i == 0 ) ? "in active" : '' %>">
<!-- Title-->
<div class="control-group input-title">
<label class="control-label muted"><%= t(:title) %></label>
<div class="controls">
<%= f.fields_for :title_translations do |f| %>
<%= f.text_field locale, class: "input-block-level", placeholder: t(:title), value: (@archive_file.title_translations[locale] rescue nil) %>
<% end %>
</div>
</div>
<!-- description -->
<div class="control-group input-title">
<label class="control-label muted"><%= t("archive.description") %></label>
<div class="controls">
<%= f.fields_for :description_translations do |f| %>
<%= f.text_area locale, class: "ckeditor input-block-level", placeholder: t("archive.description"), value: (@archive_file.description_translations[locale] rescue nil) %>
<% end %>
</div>
</div>
<!-- urls -->
<div class="control-group input-title">
<label class="control-label muted"><%= t(:link) %></label>
<div class="controls">
<!-- 開關「關閉」時使用:原本的陣列式連結輸入,完全不變 -->
<div class="link_append_target old-style-links" style="<%= @archive_file.enable_file_link_sort ? 'display:none;' : '' %>">
<% I18n.with_locale(locale) do %>
<% f.object.urls.to_a.each_with_index do |url,i| %>
<%= render :partial => "form_link", :locals=>{:f=>f,:locale=>locale,:url=>url,:url_text=>f.object.get_url_text(i,true)} %>
<% end %>
<% end %>
</div>
<a class="trigger btn btn-small btn-primary add_link old-style-links" data-locale="<%=locale%>" style="<%= @archive_file.enable_file_link_sort ? 'display:none;' : '' %>"><i class="icons-plus"></i> <%= t(:add) %></a>
<div class="new-style-links" style="<%= @archive_file.enable_file_link_sort ? '' : 'display:none;' %>">
<% f.object.archive_file_links.select{|l| l.locale == locale.to_s}.each do |archive_file_link| %>
<%= f.fields_for :archive_file_links, archive_file_link do |lf| %>
<%= render :partial => "form_file_link", :locals => {:f=>lf, :locale=>locale, :form_link=>archive_file_link} %>
<% end %>
<% end %>
</div>
<a class="trigger btn btn-small btn-primary add_file_link new-style-links" data-locale="<%=locale%>" style="<%= @archive_file.enable_file_link_sort ? '' : 'display:none;' %>"><i class="icons-plus"></i> <%= t(:add) %></a>
</div>
</div>
<div class="control-group file-link-order-block" style="<%= @archive_file.enable_file_link_sort ? '' : 'display:none;' %>">
<label class="control-label muted"><%= t("archive.file_link_order") %></label>
<div class="controls">
<ul class="file-link-sortable" data-locale="<%= locale %>">
<% f.object.merged_items_for_locale(locale).each do |item| %>
<li class="file-link-sortable-item" data-token="<%= item[:token] %>">
<i class="icons-list-2 sort-order-icon"></i>
<span class="label label-info"><%= item[:type] == 'file' ? t(:file_) : t(:link) %></span>
<%= item[:label] %>
</li>
<% end %>
</ul>
<div class="file-link-sortable-hidden-fields"></div>
<p class="muted"><%= t("archive.file_link_order_hint") %></p>
</div>
</div>
</div>
<% end %>
<!-- File -->
<div class="control-group">
<label class="control-label muted"><%= t(:file_) %></label>
<div class="controls">
<p class="add-btn">
<%= hidden_field_tag 'archive_file_multiple_field_count', @archive_file.archive_file_multiples.count %>
<a id="add_file" class="trigger btn btn-small btn-primary"><i class="icons-plus"></i> <%= t(:add) %></a>
</p>
</div>
</div>
<div class="control-group">
<div class="controls">
<!-- Add -->
<div class="add-target" id="add-target"></div>
<!-- Exist -->
<% if @archive_file && !@archive_file.archive_file_multiples.blank? %>
<div class="exist plugin-sortable">
<% @archive_file.archive_file_multiples.desc(:sort_number).each_with_index do |archive_file_multiple, i| %>
<%= f.fields_for :archive_file_multiples, archive_file_multiple do |f| %>
<%= render :partial => 'form_file', :locals => {:f => f, :i => i,:form_file => archive_file_multiple} %>
<% end %>
<% end %>
<hr>
</div>
<% end %>
<div id="fileupload" ondrop="dropHandler(event);" ondragover="dragOverHandler(event);" ondragleave="(function(){$('#dropzone').removeClass('in');})()">
<div id="dropzone" class="drop">
<div data-icons=""></div>
<%=t("archive.drag_file_to_here")%>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Form Actions -->
<div class="form-actions">
<%= hidden_field_tag 'archive_file[order_source]', '', id: 'archive_file_order_source' %>
<%= hidden_field_tag 'page', params[:page] if !params[:page].blank? %>
<%= f.submit t('submit'), class: 'btn btn-primary' %>
<a href="<%= admin_archive_files_path %>" class="btn"><%= t("archive.back_to_archives") %></a>
</div>
<% content_for :page_specific_javascript do %>
<script>
if (!FileReader.prototype.readAsBinaryString) {
console.log('readAsBinaryString definition not found');
FileReader.prototype.readAsBinaryString = function (fileData) {
var binary = '';
var pk = this;
var reader = new FileReader();
reader.onload = function (e) {
var bytes = new Uint8Array(reader.result);
var length = bytes.byteLength;
for (var i = 0; i < length; i++) {
var a = bytes[i];
var b = String.fromCharCode(a)
binary += b;
}
pk.content = binary;
$(pk).trigger('onload');
}
reader.readAsArrayBuffer(fileData);
}
}
function FileListItems (files) {
var b;
try{
b = new DataTransfer();
}catch(e){
if(window.dataTransfer){
b = window.dataTransfer;
}else{
if(typeof(ClipboardEvent) == "undefined"){ //IE
b = new DataTransfer();
}else{
b = new ClipboardEvent("").clipboardData;
}
}
}
if(b.items){
b.items.clear();
}else{
if(b.files.length != 0 ){
var files_length = b.files.length;
for(var i = files_length - 1;i >= 0;i = i - 1){
delete b.files[i];
}
}
if(b.files.length != 0){
return files
}
}
for (var i = 0, len = files.length; i<len; i++){
if(b.items){
b.items.add(files[i])
}else{
b.files[i] = files[i];
}
}
return b.files
}
function change_files_to_file_field(file_field,files){
var fileupload = $(file_field).parents(".fileupload");
if(fileupload.length > 0){
fileupload.find(".fileupload-preview").text(files[0].name);
}
var files_list = new FileListItems(files)
try{
$(file_field)[0].files = files_list;
}catch(e){console.log(e)}
if($(file_field)[0].files.length == 0){ //Change failed
var file_field_values = [];
var file_reader = new FileReader();
$("[name=\""+$(file_field)[0].name+"\"][type=\"hidden\"]").remove();
var hidden_input = $("<input type=\"hidden\" name=\""+$(file_field)[0].name+"\">");
var hidden_input_values = [];
$(file_field).after(hidden_input);
var files_list_length = files_list.length;
for(var i = 0; i < files_list_length; i++){
var file = files_list[i];
$(file_field)[0].files[i] = file;
file_reader.readAsBinaryString(files_list[i]);
file_reader.onload = (function(hidden_input,file,i,files_list_length) {
return function(e) {
var file_info = {};
file_info["name"] = file.name;
file_info["type"] = file.type;
if (file_reader.result)
file_reader.content = file_reader.result;
file_info["content"] = e ? e.target.result : file_reader.content;
if(Array.isArray(hidden_input_values)){
hidden_input_values.push(file_info);
}
if(i == files_list_length - 1){
if(hidden_input_values.length == 1){
hidden_input_values = hidden_input_values[0];
}
hidden_input.val(JSON.stringify(hidden_input_values));
}
};})(hidden_input,file,i,files_list_length);
file_field_values.push("C:\\fakepath\\" + files_list[i].name);
}
Object.defineProperty($(file_field)[0].files, "length", {
// only returns odd die sides
get: function () {
var length = 0;
while(this[length]){
length++;
}
return length;
}
});
Object.defineProperty($(file_field)[0], "value", {
// only returns odd die sides
get: function () {
return (this.getAttribute('value') ? this.getAttribute('value') : "");
},
set: function(value) {
this.setAttribute('value',value);
}
});
$(file_field)[0].value = file_field_values.join(", ");
}
}
function dragOverHandler(ev) {
document.activeElement.blur();
$(ev.target).addClass("in");
// Prevent default behavior (Prevent file from being opened)
ev.preventDefault();
}
function dropHandler(ev) {
window.ev = ev;
window.dataTransfer = ev.dataTransfer;
// Prevent default behavior (Prevent file from being opened)
ev.preventDefault();
var files = [];
if (ev.dataTransfer.items) {
// Use DataTransferItemList interface to access the file(s)
for (var i = 0; i < ev.dataTransfer.items.length; i++) {
// If dropped items aren't files, reject them
if (ev.dataTransfer.items[i].kind === 'file') {
var file = ev.dataTransfer.items[i].getAsFile();
files.push(file)
}
}
} else {
// Use DataTransfer interface to access the file(s)
for (var i = 0; i < ev.dataTransfer.files.length; i++) {
var file = ev.dataTransfer.files[i];
files.push(file)
}
}
files.forEach(function(file){
var single_file = [file];
var file_field = add_file_field();
change_files_to_file_field(file_field,single_file);
})
window.files = files;
var target = ev.target ? ev.target : ev.srcElement;
$(target).removeClass("in");
}
function add_file_field(){
var self = $('#add_file');
var new_id = $(self).prev().attr('value');
var old_id = new RegExp("new_archive_file_multiples", "g");
var on = $('.language-nav li.active').index();
var le = $('#add-target').children('.start-line').length;
$(self).prev().attr('value', parseInt(new_id) + 1);
$('#add-target').prepend(("<%= escape_javascript(add_attribute 'form_file', f, :archive_file_multiples) %>").replace(old_id, new_id).replace("new_archive_file_sort_order_XXX", parseInt(new_id) + 1));
var file_field = $('#add-target').find("*").eq(0).find("[type=\"file\"]");
$('#add-target').children('.start-line').eq(le).children('.input-append').find('.tab-content').each(function() {
$(self).children('.tab-pane').eq(on).addClass('in active').siblings().removeClass('in active');
});
formTip();
return file_field;
}
$(document).ready(function() {
$(".plugin-sortable").sortable({
update : function(event, ui){
var existingfiles = $(".exist.plugin-sortable div.fileupload")
existingfiles.each(function(i, file){
$(file).find("input.file-sort-number-field").val(existingfiles.length - i);
})
$('#archive_file_order_source').val('file_sort');
}
});
$('.main-forms .add-on').tooltip();
$(document).on('click', '#add_file', add_file_field);
$(document).on('click', '.add_link', function(){
var form_link_url = "<%= escape_javascript(render(:partial => "form_link", :locals=>{:f=>f,:locale=>"new_locale",:url=>nil,:url_text=>nil} )) %>"
var old_locale = new RegExp("new_locale", "g"),
new_locale = $(this).data("locale");
$(this).siblings(".link_append_target").append(form_link_url.replace(old_locale,new_locale));
})
$(document).on('click', '.delete_file, .delete_link', function(){
$(this).parents('.input-prepend').remove();
});
$(document).on('click',"[type='file']",function(){
$("[name=\""+$(this).attr("name")+"\"][type=\"hiiden\"]").remove();
});
$(document).on('click', '.remove_existing_record', function(){
if(confirm("<%= I18n.t(:sure?)%>")){
$(this).children('.should_destroy').attr('value', 1);
$(this).parents('.start-line').hide();
}
});
$(document).on('click', '.remove_existing_link', function(){
if(confirm("<%= I18n.t(:sure?)%>")){
$(this).parents('.input-prepend').remove();
}
});
function toggle_file_link_sort_ui(){
var migrated = $('#file_link_sort_control').data('migrated') === true || $('#file_link_sort_control').data('migrated') === 'true';
if (!migrated){
$('.old-style-links').show();
$('.new-style-links').hide();
$('.file-link-order-block').hide();
return;
}
var checked = $('#enable_file_link_sort_checkbox').is(':checked');
$('.old-style-links').toggle(!checked);
$('.new-style-links').toggle(checked);
$('.file-link-order-block').toggle(checked);
}
toggle_file_link_sort_ui();
$(document).on('change', '#enable_file_link_sort_checkbox', toggle_file_link_sort_ui);
// 合併排序清單:拖曳後,把目前順序寫回 hidden fields 一起送出
$(".file-link-sortable").each(function(){
var $list = $(this);
var locale = $list.data("locale");
function write_hidden_fields(){
var $hidden_container = $list.siblings(".file-link-sortable-hidden-fields");
$hidden_container.empty();
$list.children("li").each(function(){
var token = $(this).data("token");
$hidden_container.append(
$("<input>", {type:"hidden", name:"archive_file[sort_order_list]["+locale+"][]", value: token})
);
});
}
$list.sortable({ update: function(){
write_hidden_fields();
$('#archive_file_order_source').val('merged_list');
}});
write_hidden_fields();
});
// 新式連結:新增一筆
$(document).on('click', '.add_file_link', function(){
var target_locale = $(this).data('locale');
var new_index = 'new_' + new Date().getTime();
var html = "<%= escape_javascript(f.fields_for(:archive_file_links, ArchiveFileLink.new, child_index: 'NEW_INDEX') { |lf| render(partial: 'form_file_link', locals: {f: lf, locale: 'new_locale', form_link: ArchiveFileLink.new}) }) %>";
html = html.replace(/NEW_INDEX/g, new_index).replace(/new_locale/g, target_locale);
$(this).siblings('.new-style-links').append(html);
});
// 新式連結:刪除「這次新增、還沒存檔」的那筆
$(document).on('click', '.delete_file_link', function(){
$(this).parents('.input-prepend').remove();
});
// 新式連結:刪除「已存在」的那筆(標記 should_destroy,交給後端在儲存時真正刪除)
$(document).on('click', '.remove_existing_file_link', function(){
if(confirm("<%= I18n.t(:sure?)%>")){
$(this).find('.should_destroy').val('1');
$(this).hide();
}
});
});
</script>
<% end %>