HTMX form submission with a table - flask

I am trying to use the Click to Edit example with HTMX, by using a table.
Each row (<tr>) is a database record that looks like this:
<tr hx-target="this" hx-swap="outerHTML">
<form>
<td><input type="text" name="name" value="{{row.name}}"></td>
<td><input type="text" name="email" value="{{row.email}}"></td>
<td>
<button class="btn" hx-put="/edit/{{row.id}}">Update<buttun>
<button class="btn" hx-get="/view/{{row.id}}">Cancel</button>
</td>
</form>
</tr>
Unfortunately, when I print the request body with request.form.keys on my flask server, I see that that the request is empty ([])
It seems like the button click did not trigger the form submission with all the input fields.
How can I make the button click trigger the form submission with all the fields populated ?

Ah, just remembered: you are working with tables here. Unfortunately tables are super picky about the elements inside them, and I bet form doesn't work where you put it. If you inspect the DOM I bet you'll find that there isn't really a form element in there, so htmx isn't finding it to include the inputs.
You'll need to rework this to include the values in a different way, for example using hx-include.
Something like this:
<tr hx-target="this" hx-swap="outerHTML">
<td><input type="text" name="name" value="{{row.name}}"></td>
<td><input type="text" name="email" value="{{row.email}}"></td>
<td>
<button class="btn" hx-put="/edit/{{row.id}}"
hx-include="closest tr">
Update
<button>
<button class="btn" hx-get="/view/{{row.id}}">Cancel</button>
</td>
</tr>
If you are willing to switch from table rows to divs, the original code you had should work fine.
This is an unfortunate situation where tables are not very flexible.
update: #guettli reminded me that you can include any element and it will include all inputs below it, so you can just use closest tr in your hx-include attribute. Thanks!

Can you post what the request looks like from the chrome or firefox console?
This looks correct, in general.

Related

Passing values from Django template to javascript-ajax function

Now my template displays a table having a link on each row to display more details. Each row passes unique column_name, db_name, schema_name, tablenm combination to get more details.
<td>
<a href="{% url 'moreDetails' column_name=row.colname db_name=row.dbname schema_name=row.schemaname table_name=row.tablenm %} " target="_blank">
Values
</a>
</td>
The above code works , but open a new window for the result set. But, I would like to route it through a javascript(Jquery-django) and capture the result back in Javascript and display the result as a javascript message without refreshing the complete page.
How Can I pass there values (column_name, db_name, schema_name, tablenm) to the java script on the click event
I tried replacing href with button and set a value to it
<td>
<input type="button" value={% row.colname |","| row.dbname |","| row.schemaname |","| row.tablenm %} class="apireq" />
<td>
But seems not working. I welcome any help on this . Thanks In advance
Why not set them as data attributes?
<input type="button" class="apireq"
data-colname="{{row.colname}}"
data-dbname="{{row.dbname}}"
data-schemaname="{{row.schemaname}}"
data-tablenm="{{row.tablenm}}"
/>
Then in your click event handler you will have a reference to the button that generated the event, all you need to to is read the attributes off of it. And they are already parsed out so no worries there too.

View - Controller Issue in CFWheels

I am using CFwheels for a site that I am creating and need to use a nested view. However, when I submit the form on the popup view, the component doesn't seem to work.
Below is some test code that I am using (when I use the view in the popup as an individual page everything works fine).
Is there a specific method to make something like this happen or is something like this unsupported in CFWheels?
global.cfm - Parent View
Add New Client
<div id="createClient" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<cfinclude template="createClient.cfm">
</div>
createClient.cfm - nested view (popup)
<form method="post" action="createClient">
<input type="hidden" name="isPost" value="1" />
<table>
<div class="modal-body">
<tr>
<td>Client Brand Name:</td>
<td><input type="text" name="ClientBrandName" value="" required></td>
</tr>
<tr>
<td>Survey Referral:</td>
<td><input type="text" name="surveyReference" value="" required/></td>
</tr>
Controller of nested view
<cffunction name="createClient">
<cfif isDefined('form.isPost')>
<cfscript>
application.someComponent.someFunction(
CBname = params.clientbrandname,
sRef= params.sreferralid,
sRefname = params.surveyreference
);
</cfscript>
</cfif>
</cffunction>
I'm not directly answering your question, but you're not approaching this in a very 'wheels-y' way.
firstly, all cfwheels form + url params are pushed into the params scope, so generally, we'd be doing structkeyexists(params, "isPost") (or some such) for a start. (that's not to say that the form scope is inaccessible though).
secondly, you might find includePartial() more useful than cfinclude, as you can pass named arguments through.
Ajax/Modal calls are supported in wheels, but I'd wager you're accidentally submitting to the wrong URL; you'd need to strip the layout too.
Have a look at https://github.com/neokoenig/RoomBooking - there's several examples of bootstrap modal windows which may help.

How to generate dynamic name for a <td> and pass the name of it to server

I have the following code :
{% for assessments in list_assessments%}
<form action="/test/" method="post">{%csrf_token%}
<tr>
<td>{{assessments.assessment_id}}</td>
<td>{{assessments.name}}</td>
<td>{{assessments.assessment_begin_date}}</td>
<td>{{assessments.assessment_end_date}}</td>
<td>{{assessments.is_active}}</td>
<td>{{assessments.is_complete}}</td>
<td>{{assessments.created_at}}</td>
<td>{{assessments.updated_at}}<br></td>
<td><input type="submit" value="Edit Assessment" /></td>
</tr>
{%endfor%}
</form>
All the data here are dynamically coming.
In this following code, i need to assign an name to assessments.name dynamically, something like
<td name="dynamic_name">{{assessment.name}}</td>.
And on clicking the button "Edit Assessment", i want the dynamic_name to be passed and received my the view.
The idea is each assessment has its own set of parameters. I want to display only the parameters related to the name. So if i could pass the value i would be able to do it.
Any help appreciated.
Your ending **</form>** tag should be before for loop.
{% for assessments in list_assessments%}
<form action="/test/" method="post" name="form-{{ assessments.counter }}">{%csrf_token%}
<tr>
<td>{{assessments.assessment_id}}</td>
<td>{{assessments.name}}</td>
<td>{{assessments.assessment_begin_date}}</td>
<td>{{assessments.assessment_end_date}}</td>
<td>{{assessments.is_active}}</td>
<td>{{assessments.is_complete}}</td>
<td>{{assessments.created_at}}</td>
<td>{{assessments.updated_at}}<br></td>
<td><input type="submit" value="Edit Assessment" /></td>
</tr>
</form>
{%endfor%}
Now, You can get specific block values by form name ( see above code ) in javascript as well as in python.
In Javascript,
form = document.getElementByTagName("form")
elems = form.children("td")
elems will give you all td elements.

Django template input button post problem

I try to post value of input buttons in Django but I couldn't
This is my template
<form id="ReviewRateForm" method="post" action="/review/post/rate/">
<input type="button" hint="V1" title="V" value="1" id="radio{{ forloop.counter }}-1" type="button" name="qid[{{forloop.counter}}]"></input>
<input type="button" hint="V1" title="V" value="2" id="radio{{ forloop.counter }}-1" type="button" name="qid[{{forloop.counter}}]"></input>
<input type="button" hint="V1" title="V" value="1" id="radio{{ forloop.counter }}-1" type="button" name="qid[{{forloop.counter}}]"></input>
</form>
However, when I debug it I couldn't reach the values of that input buttons in my view.
What is the problem or how can I overcome it?
The values can be accessed by the name of the input from request.POST. However, you're dynamically naming the inputs, which is going to make things more complicated when you go to retrieve those values.
Example without taking into consideration the dynamic naming:
quid1 = request.POST.get('quid1')
The problem might be with your browser rather than with django.
If you use the button element in an HTML form, different browsers will submit different values. Internet Explorer will submit the text between the <button> and </button> tags, while other browsers will submit the content of the value attribute.
Update: Oh, you are not using <button> elements, I read too fast. Sorry. Then this answer is not relevant.

Form elements with the same name not accessible using CF MX7

I am using Coldfusion MX7 and have a basic form which can have several elements that are dynamically added to the form. They are given the same name and are all checkboxes. An example of the form is as follows:
<form action="index.cfm?action=index.report" method="post" id="reportForm">
<div class="report my">
<ul class="connectWith ui-sortable" id="fieldListSelect" aria-disabled="false">
<li class="field" id="field_profileFn" style="">
<a class="action" id="action_profileFn" href="index.cfm?action=index.filter.profileFn" style="display: block; ">filter</a>
<label for="profileFn">First Name</label>
<input type="checkbox" name="reportItem" id="profileFn" value="profileFn">
</li>
<li class="field" id="field_profileSn" style="">
<a class="action" id="action_profileSn" href="index.cfm?action=index.filter.profileSn" style="display: block; ">filter</a>
<label for="profileSn">Surname</label>
<input type="checkbox" name="reportItem" id="profileSn" value="profileSn">
</li>
<li class="field" id="field_contactDate" style="">
<a class="action" id="action_contactDate" href="index.cfm?action=index.filter.contactDate" style="display: block; ">filter</a>
<label for="contactDate">Contact date</label>
<input type="checkbox" name="reportItem" id="contactDate" value="contactDate">
</li>
</ul>
</div>
</form>
Once the form is posted I get the following through cfdump:
<table class="cfdump_struct">
<tr><th class="struct" colspan="2" onClick="cfdump_toggleTable(this);" style="cursor:hand;" title="click to collapse">struct</th></tr>
<tr><td class="struct" onClick="cfdump_toggleRow(this);" style="cursor:hand;" title="click to collapse">CONTACTDATE_FROM</td>
<td> Thu May 19 2011 00:00:00 GMT+0100 (GMT Daylight Time) </td></tr>
<tr><td class="struct" onClick="cfdump_toggleRow(this);" style="cursor:hand;" title="click to collapse">CONTACTDATE_TO</td>
<td> Thu May 19 2011 00:00:00 GMT+0100 (GMT Daylight Time) </td></tr>
<tr><td class="struct" onClick="cfdump_toggleRow(this);" style="cursor:hand;" title="click to collapse">FIELDNAMES</td>
<td> REPORTITEM[],CONTACTDATE_FROM,CONTACTDATE_TO </td></tr>
<tr><td class="struct" onClick="cfdump_toggleRow(this);" style="cursor:hand;" title="click to collapse">REPORTITEM[]</td>
<td> profileFn,profileSn,contactDate </td></tr>
</table>
The element REPORTITEM[] is reported and in trying to access this as a variable I get:
<cfset testing = form.reportItem[]>
Invalid CFML construct found on line 6 at column 50.
In trying to access the variable in the way I would expect I get the following:
<cfset testing = form.reportItem>
Element REPORTITEM is undefined in FORM.
I have inherited this code and it MUST have worked previously. Coldfusion has not been upgraded (obviously being CF 7 still) and nothing else has changed server side that I can think of.
My questions:
Is this just a limitation of CF7?
This should work right or is this totally wrong?
I am going to have to re-write quite a bit of this code if this just doesn't work, handling this after the data has been posted would be easier to code. Modifying the form will be more effort, so is it possible?
Try doing
<cfset testing = form["reportItem[]"]>
This will fetch the form struct by the key "reportItem[]".
As far as I know, CF7 has no problem with this. In fact, I'm pretty sure that the value of your checkboxes is constructed by the browser, not the webserver or CF.
Here's what I see:
form.variableNamve[]
will not work, because the value is coming back as a comma-delimited list.
You will run into the not defined error if no checkboxes are checked, because if no checkboxes with that name are checked then that variable will not be submitted by the browser, and therefore will not exist in the form scope. You should default this, and there are a couple of ways to do it.
You can create a new struct with the checkbox name as a key, the empty string as the value, then structAppend the form scope on top of it.
You can use the traditional cfparam tag.
You can add a hidden form field with the same name and the empty string as a value to the form. This forces the browser to return the form field, even if no checkboxes are checked.
HTH.
Are you posting through jQuery ajax or using normal submit button. I think jQuery add variablename[] while posting it but there is way to disable it. But in case of submit button I will get checkbox only in form structure only if atleast one checkbox is checked.
In this case always cfparam checkbox name with your default value.