Coldfusion (обновить массив с помощью CFForm - изменить значения после отправки)
У меня есть простая форма. Значения загружаются из базы данных в массив, а затем отображается вся таблица с использованием тегов cfinput и cfselect, позволяющих редактировать поля. Итак, я надеялся, что смогу изменить любые поля вверх и вниз по отображаемой таблице, а затем нажать SUBMIT и отобразить измененные поля, но ничего не изменилось. Таблица просто возвращается к оригиналу, и изменения в тегах исчезают. Я не хочу, чтобы пользователь обновлял каждое поле отдельно, используя отдельную форму. Я хотел бы, чтобы все страницы обновлялись в одном представлении.
Какие-либо предложения:
<!--- **** LOAD ARRAY FROM DATABASE ********************************** --->
<cfset AssignArray = ArrayNew(2)>
<cfset i=1>
<cfoutput query="getAssignments">
<cfset AssignArray[i][1]="#getAssignments.Assignment#">
<cfset AssignArray[i][2]="#getAssignments.Baylor#">
<cfset i = i + 1>
</cfoutput>
<!--- **** FORM WITH TABLE OF VALUES TO CHANGE ********************************** --->
<table border="0" cellspacing="0">
<caption>Update Assignments</caption>
<cfform name="formData">
<table>
<tr><th>#</th><th>Assignment</th><th>Name</th></tr>
<cfloop from="1" to= "#getAssignments.RecordCount#" index="i">
<tr>
<td class="centercell"><cfoutput>#i#</cfoutput></td>
<td><cfinput class="assignSize" type="text" name="Assignment"
maxlength="70"
value="#AssignArray[i][1]#"></td>
<td><cfselect class="assignFont" name="Name" query="getNames"
display="Name" value="Baylor" selected="#TRIM(AssignArray[i][2])#">
<cfif AssignArray[i][2] neq "">
<option value="">Not Assigned</option>
<cfelse>
<option value="" selected="selected" >Not Assigned</option>
</cfif>
</cfselect>
</td>
</tr>
</cfloop>
</table>
<cfinput class="btnStyle" type="submit" name="submit" value="Update">
</cfform>
<!--- ****DUMP FORM WITH CHANGED VALUES ************************************ --->
<cfif IsDefined ("form.Assignment")>
<cfif IsDefined ("form.submit")>
<table>
<tr><th>#</th><th>Assignment</th><th>Name</th></tr>
<cfloop from="1" to= "#getAssignments.RecordCount#" index="i">
<tr>
<td class="centercell"><cfoutput>#i#</cfoutput></td>
<td><cfoutput>#AssignArray[i][1]#</cfoutput></td>
<td><cfoutput>#AssignArray[i][2]#</cfoutput></td>
</tr>
</cfloop>
</table>
</cfif>
</cfif>
3 ответа
... и именно поэтому я использовал массив, потому что я подумал, что потребует и обновит (sql update) для каждой строки для данных, которые отличаются / уникальны. Я надеялся побить систему, используя массив с помощью cfselect и т. Д., Чтобы все произошло сразу, а затем отправил изменения в массиве обратно в базу данных.
Это не работает таким образом. Массивы CF перестраиваются при каждой загрузке страницы и не сохраняются между запросами. Они существуют только тогда, когда вы генерируете <form>
, Однажды <form>
отправляется обратно клиенту / браузеру, вы отключены от сервера и массивы исчезли. Чтобы получить доступ к новым значениям, введенным пользователем, вы должны обработать отправленные поля FORM (не массив).
В вашем случае вы должны использовать уникальные имена полей. Таким образом, вы можете отслеживать каждую "строку" или "набор" полей. Один из способов сделать это - добавить переменную counter к именам полей. Сохраните количество строк в скрытом поле (вне основного цикла запроса).
<form name="formData" method="post" action="debug.cfm">
<cfoutput query="getAssignments">
row = #currentRow#
Assignment
<input type="text" name="UniqueRecordID_#currentRow#" value="#getAssignments.UniqueRecordID#">
<input type="text" name="Assignment_#currentRow#" value="#getAssignments.Assignment#">
<!--- note: this field should have a more descriptive name --->
<select name="Name_#currentRow#">
<option value="">Not Assigned</option>
<cfloop query="getNames">
<option value="#TheValueCol#" <cfif getNames.TheValueCol eq getAssignments.Baylor>selected="true"</cfif>>
#TheDisplayCol#
</option>
</cfloop>
</select>
<br>
</cfoutput>
<!--- store total number of rows --->
<cfoutput>
<input type="hidden" name="totalRows" value="#getAssignments.recordCount#">
</cfoutput>
<input type="submit" name="submit" value="Update">
</form>
После отправки формы используйте form.totalRows для зацикливания и извлечения значений. Внутри цикла делайте со значениями все, что вам нужно (хранить в базе данных, отображать и т. Д.)
<cfif structKeyExists(FORM, "submit")>
<cfparam name="form.totalRows" default="0">
<cfloop from="1" to="#form.totalRows#" index="variables.row">
<!--- get each set of values --->
<cfset variables.ID = FORM["UniqueRecordID_"& variables.row]>
<cfset variables.assignment = FORM["assignment_"& variables.row]>
<cfset variables.name = FORM["Name_"& variables.row]>
<!--- display changed values (insert them into a db, etc..) --->
<cfoutput>
row [#variables.row#]
id = #variables.id#
assignment = #variables.assignment#
name = #variables.name#<br>
</cfoutput>
</cfloop>
</cfif>
Когда я хочу сделать то, что вы пытаетесь, я организую это примерно так.
Шаг 1 - запустить запрос. Убедитесь, что вы выбрали идентификатор записи.
<cfquery name="MyQuery">
select id, field1, field2, etc
</cfquery>
Шаг 2 - Создайте свою форму. Используйте поле id, чтобы отслеживать, что к чему.
<cfform>
<cfoutput query="MyQuery">
<input type="hidden" name="ExistingField1#id#" Value="#Field1#">
<input name = Field1#id# Value="#Field1#>
etc
</cfform>
Теперь давайте предположим, что форма была отправлена. Ищите изменения и обновляйте, если вы их найдете.
<cfloop list="#form.fieldnames#" index = "ThisField">
<cfif left(ThisField, 6) is "Field1">
<!--- The next line will get the record identifier --->
<cfset ThisId = Right(ThisField, Len(ThisField) - 6)>
<cfif form["Field1#ThisId#"] is not form["ExistingField1#ThisId#"]
or form["Field2#ThisId#"] is not form["ExistingField2#ThisId#"]
etc>
update query goes here
three closing tags go here.
Существуют и другие подробности, такие как проверка отправленных значений, но с этого следует начать.
Вам не нужно копировать ваш запрос в массив? Просто используйте
<cfloop query="getAssignments">
or
<cfoutput query="getAssignments">
Тогда вы можете сравнить непосредственно как в <cfif len(trim(getAssignments.assignment)) GT 0>
или что вам нужно сделать, чтобы это имело смысл для вас.
Я бы также избегал использования <CFFORM>...
это обычно и универсально презирается большинством людей CF. Форма будет отлично работать. используйте jquery, если вам нужны дополнительные спецэффекты.
В случае выше, если вы хотите увидеть, что выбрано, оно будет расположено в области видимости. Другими словами
<cfif structKeyExists(form, 'assignment')>
<cfoutput>
#form.assignsize#
#form.name#
</cfoutput>
</cfif>
Название вашего окна выбора - "имя", которое сбивает с толку. Назовите это как-нибудь проще, например "schoolName".
Уоллес - хорошо, я понимаю, что ты пытаешься сделать, но тебе нужно кое-что. Для начала вам понадобится JavaScript (вероятно), чтобы отслеживать ваши изменения. Во-вторых, вам нужно "назвать" элементы формы чем-то уникальным. Вы будете отправлять форму с такими именами, как "assignment_#schoolid#".
Это то, что вы пытаетесь сделать с вашей переменной #currentrow#, но это ненадежно, потому что она отключена от БД и в конечном итоге испортит ваши данные. Ваш пример, вероятно, нужно будет пересмотреть и начать заново. Эта ссылка может помочь.
http://www.coldfusionmuse.com/index.cfm/2011/1/5/form.loop.update.dataset