Привязка загрузки файла к кнопке в таблице, используя идентификатор, переданный из базы данных

#javascript #sql #coldfusion #coldfusion-11 #jasny-bootstrap

#javascript #sql #coldfusion #coldfusion-11 #jasny-bootstrap

Вопрос:

Работаю с некоторым устаревшим кодом и пытаюсь добавить некоторую функциональность. Страница предназначена для загрузки расположения. Внизу страницы находится таблица файлов, связанных с размещением. Эти файлы (вложения) хранятся внутри таблицы в базе данных, и у каждого файла есть свой собственный идентификатор.

Клиент хочет, чтобы в таблицу была добавлена кнопка «заменить» в каждой строке рядом с каждой записью (кнопка загрузки и удаления уже есть). После нажатия открывается форма загрузки файла. Что должно произойти, так это то, что файл, который загружает клиент, должен заменить вложение в таблице на идентификатор. Однако, когда я нажимаю на одну из кнопок «заменить», в верхней части таблицы отображается форма для замены вложения.

Как связать кнопку с формами по идентификатору (переданному через таблицу базы данных)?

Вот таблица … «‘

 <table class="table table-striped table-bordered table-hover table-hover table-full-width">
    <thead>
        <tr>
            <th class="center hidden-xs"></th>
            <th style="display:none;">ID</th>
            <th>File Name</th>
            <th>Figure Name</th>
            <th>Date Uploaded</th>
            <th>Rearrange Order</th>
        </tr>
        </thead>
    <tbody>
    <cfset loopCount = 1 />
    <cfset ids = '' />
    <cfset allowDown = #qAttachments.recordCount# />
    <cfloop query = "qAttachments">
    <cfset ID = "#qAttachments.id#">
    <cfset fileName="#qAttachments.filename#">
    <cfset fileExt=ListLast(fileName,".")>
    <cfset filePath = "/secure/edFiles/edAttachments/ED_#session.module.id#/#url.edID#/#fileName#"><!---removed.pdf--->
        <tr>
            <div id="replaceAtt" style="display: none" >
                <div class="col-md-6">
                  <div class="fileupload fileupload-new" data-provides="fileupload">
                            <div class="input-group">
                                <div class="form-control uneditable-input">
                                    <i class="fa fa-file fileupload-exists"></i>
                                    <span class="fileupload-preview"></span>
                                </div>
                                <div class="input-group-btn">
                                    <div class="btn btn-blue btn-file">
                                        <span class="fileupload-new"><i class="fa fa-folder-open-o"></i> Select file</span>
                                        <span class="fileupload-exists"><i class="fa fa-folder-open-o"></i> Change</span>
                                        <input type="file" id="replaceEDFile" name="replaceEDFile" title="Select File to Replace #ID#">
                                    </div>
                                    <a href="" class="btn btn-blue fileupload-exists" data-dismiss="fileupload">
                                        <i class="fa fa-times"></i> Remove
                                    </a>
                                </div>
                            </div>
                        </div>
                </div>

                <div class="col-md-2">
                    <div class = "btn btn-blue btn-block" value="#ID#" type = "submit" name ="replaceFile"  onClick="location.href='edFormData.cfm?replaceFile=#ID#amp;m=#url.m#amp;edID=#url.edID#amp;#r#amp;ai=#url.ai#'">
                          Upload File <i class = "fa fa-arrow-circle-right" ></i>                                
                    </div>
                </div>
            </div>
        </tr>
        <tr>

            <td class="center hidden-xs">
                <a href="#filePath#"><button type = "button" class="fa" name="download" id="download" value="#ID#" onClick="location.href='edFormData.cfm?download=#ID#amp;m=#url.m#amp;edID=#url.edID##r#amp;ai=#url.ai#'">           <img src="../assets/Icons/viewdoc.png"></button></a>   

                <cfif readonly NEQ "readonly">

                <button type = "button"  class="fa" name="Delete" id="Delete" value ="#ID#" onClick="location.href='edFormData.cfm?del=#ID#amp;m=#url.m#amp;edID=#url.edID##r#amp;ai=#url.ai#'">
                <img src="../assets/Icons/trash-o_ff0400_20.png"></button>

                <button id="replace" type = "button" class ="replace" name="replace" value="#ID#" title="Replace attachment #ID#" >
                 <img src="../assets/Icons/file_replace_000000.png">
                </button>
                </cfif>
            </td>
            <td style="display:none;">#ID#</td>
            <td id="file_#ID#">#qAttachments.filename#</td>
            <td id="figure_#ID#">#qAttachments.figureName#</td>
            <td id="uploaded_#ID#">#qAttachments.uploaded#</td>
            <td>
                <cfif loopCount NEQ 1>
                    <div class = "btn btn-green btn-block" id="moveUP_#ID#">Move Up</div><br />
                </cfif>
                <cfif loopCount NEQ allowDown>
                    <div class = "btn btn-blue btn-block" id="moveDown_#ID#">Move Down</div>
                </cfif>
            </td>
        </tr>

        <cfif loopCount NEQ allowDown>
            <cfset ids = #ids#amp;"#ID#," />
        <cfelse>
            <cfset ids = #ids#amp;"#ID#" />
        </cfif>
        <cfset loopCount=(#loopCount# 1) />
    </cfloop>
    <input type="hidden" id="possibleIDs" value="#ids#" />
</tbody>
</table> 
  

»’

И вот JavaScript …. «‘

 <script>
    $(document).ready(function(){
        $('.replace').click(function(e){        
            e.preventDefault();
            $("#replaceAtt").slideToggle('fast');
        });
});

</script>
  

»’

Комментарии:

1. 1. У вас есть таблицы, divs и Bootstrap, все смешано вместе. Я серьезно удваиваю, что вообще может отображаться. 2. loopCount=(#loopCount# 1) нужно просто выполнить целую кучу кода loopcount

2. На самом деле это код, написанный до того, как я начал работать на этой странице. Это для изменения положения, которое перемещает вложения вверх и вниз по таблице. Это работает нормально и не влияет на то, что я добавляю.

3. Так много разных способов решить эту проблему… вы могли бы добавить атрибут data-id к вашей кнопке replace, который затем извлекается с помощью метода jquery .data() или .attr() . Это дает вам ваш идентификатор, а затем вы можете установить скрытое поле в вашей форме. Просто одна идея.

4. @Redtopia, спасибо за предложение. Я недолго использую JavaScript и все еще изучаю все тонкости. Я попробую это завтра.

5. Когда вы говорите «устаревший», с какими версиями вы работаете?

Ответ №1:

Это скорее обзор кода / комментарий, чем полный ответ. В этом блоке кода многое происходит. Как сказал Джеймс, ваш код смешивает таблицы и divs и создает некоторый Bootstrap. Там много переменных, плавающих без ясности, в какой области они находятся (например, readonly ), и много переменных, которые на самом деле не нужны (например, loopcount и allowDown ). Есть также пара переменных, которым не нужны кавычки и фунты стерлингов (например, <cfset ID = "#qAttachments.filename#"> это может быть просто <cfset ID = qAttachments.ID> ) и пара мест, где переменная URL используется непосредственно в коде. И пара других вещей.

Это устаревший код, поэтому я полностью понимаю. Это то, что есть, и если это код CF11, вероятно, с момента его написания было многое улучшено. Здесь легко быть квотербеком в понедельник утром.

Тем не менее, вы можете значительно сократить то, что вы делаете на этой странице между вашими tbody тегами.

Чтобы немного упростить ситуацию, я опустил большую часть вашего HTML-кода, который вы просматриваете в цикле.

Поскольку вы используете цикл запроса, вам не нужно отслеживать количество циклов, потому что это уже часть результатов запроса в currentRow . И вам не нужно устанавливать allowDown , потому что вы ссылаетесь на него только один раз. Единственное, что вам действительно нужно, это инициализировать, ids чтобы вы могли ListAppend() вместо того, чтобы пытаться выяснить, как обращаться с запятой в конце.

 <cfset ids="">

<cfoutput>

<cfloop query="qAttachments">
    <!--- HTML Display Code In This Block --->
    EXAMPLE: WE ARE ON ID = #id# 
    <!--- Move Buttons --->        
    <cfif currentRow NEQ 1> MOVE UP </cfif>
    <cfif currentRow NEQ qAttachments.recordcount> MOVE DOWN </cfif>
    <br>
    <!--- --->
    <!--- Build ID list for hidden form. --->
    <cfset ids = ListAppend(ids,id)>
</cfloop>

<br>
< hiddenFormInput > possibleIDs = "#ids#" < /hiddenFormInput >

</cfoutput>
  

https://cffiddle.org/app/file ?filepath=870efd11-b974-4905-8d47-9afb41fa2a10/e47a5d00-1a86-4cd9-8996-f256ad72dff5/49648087-5075-48c1-9a96-23d20b6e2d82.cfm

Опять же, это всего лишь концептуальный код для лучшего построения вашего цикла. И на этом примечании, поскольку это CF11, вам было бы намного лучше выполнять цикл с помощью cfsccript, а не cftags. И я бы рекомендовал отделить ваш код CFML от вашего кода отображения, возможно, с помощью функции CF, которая может возвращать набор данных для циклического просмотра на вашем дисплее.

Последнее, что я прокомментирую, — это использование ID в качестве общего имени. Внутри вашего цикла используются 3 разные ID переменные: 1) session.module.id 2) ID из вашего запроса 3) и ID переменная, основанная на запросе вашего цикла ID . В данном конкретном случае вы получаете значения, которые вы намереваетесь, но обычно это плохая идея иметь несколько переменных с одинаковым именем на странице, и ID это легко сделать. Все, что требуется, это изменить порядок вычисления, и это вызовет у вас головную боль, которую может быть трудно отладить.

Комментарии:

1. Кроме того, если скрытый список содержит все значения идентификатора из запроса, то нет необходимости создавать список вручную. Просто используйте ValueList() вне цикла.

2. Спасибо за совет. Ссылки на кнопки перемещения вверх и вниз находятся за пределами опубликованного мной кода. Я полагаю, что человек, который написал это, кодировал вокруг существующего беспорядка, которым является этот файл. Проблема с идентификатором также связана со странным файлом cookie. Это не единственное место на сайте, которое использует session.module.id предполагается, что идентификатор из запроса и переменная ID имеют одно и то же значение. В дальнейшем на новых страницах я буду использовать эти примечания для лучшего построения циклов. Спасибо.

3. @Clark id особенно привлек мое внимание, потому что я когда-то работал над системой, которая использовала id в качестве ключа для каждой таблицы БД, неправильно использовала внешние ключи ( ВООБЩЕ читала) и ссылалась на » id » по всему коду. Я не могу вспомнить, в какой версии программного обеспечения это было изменение, но оно изменило порядок, в котором id выполнялась оценка. Мы имели дело с несколькими таблицами, каждая из которых исчислялась миллионами, и начали получать записи, которые были очень старыми. Нам потребовалась вечность, чтобы понять, что это было потому, что, когда мы думали, что смотрим на t2.id , мы действительно смотрели на t1.id . Это немного сводило с ума. :-/

Ответ №2:

Я хочу поблагодарить всех, кто прокомментировал и помог в этом. Я знаю, что код в лучшем случае неровный, но когда я начинаю возиться с тем, что уже находится в цикле, что-то где-то еще ломается. Но я выяснил проблему (с помощью коллеги, который намного умнее меня), почему я не мог связать кнопку с div и показать правильную форму загрузки для этой строки таблицы! Это было изображение … да, изображение. Я решил, что JS просто выставит предупреждение об имени идентификатора при нажатии кнопки. После некоторого взлома я иногда заставлял это работать, а в других случаях просто запускал NaN. Ну, с помощью некоторой магии «Проверять элемент» было обнаружено, что он выводит либо идентификатор, либо NaN в зависимости от того, где я нажал на кнопку. Это привело нас к пониманию, что самому изображению нужен идентификатор, потому что оно пыталось быть извлечено при нажатии.

Итак, это то, что я изменил в коде, опубликованном выше:

Сначала я вытащил div, в котором содержалась форма загрузки, из цикла, поэтому мне не нужно заполнять несколько форм, и я могу переключать замены вложений, не перезагружая страницу из-за множества движущихся объектов на экране.

Во-вторых, сама кнопка:

 <button type = "button" class ="replace" name="replace" id="replace_#ID#" value="#ID#" title="Replace #qAttachments.figureName#" >
    <!--- Gave the image an ID, so if it is clicked it can still split properly. --->   
    <img id="replaceImg_#ID#" src="../assets/Icons/file_replace_000000.png">
</button>
  

В-третьих, JavaScript.

 <script>

    $('[id^="replace_"], [id^="replaceImg_"]').click(function(e){

        // Split the ID to get the number (lines up with DB ID).
        var replaceID = e.target.id.split("_")[1];

        // Set this to let the user know which file is being replaced (by figure name).
        var figNameRep = $('#figure_' replaceID).text();

        // If the upload replacement is not showing yet, make it show now.
        if ($('#replaceAtt').css("display") == 'none'){
            $('#replaceAtt').slideToggle("fast");
        }

        // Don't worry about hiding and unhiding, just switch the IDs around as needed.
        $('#figNameReplace').text("Replacing file for Figure Name: "   figNameRep);
        $('#replaceFile').val(replaceID);
    });

    </script>
  

Еще раз спасибо всем за их вклад. Идеи, которые вы все предложили, я попробовал, и хотя я не смог заставить ни одну из них работать (это скорее комментарий к моему собственному мастерству), это научило меня некоторым новым инструментам и методам. Вы, ребята, крутые!