Note that there are some explanatory texts on larger screens.

plurals
  1. POHTML ─ Python dictionary from form-subelement via CherryPy
    text
    copied!<pre><code># ! /usr/bin/env python # -*- coding: utf-8 -*- # image_slide.py """ Python 2.7.3 Cherrypy 3.2.2 """ </code></pre> <p>When an HTML form is submitted to a Python function, the values are sent within one dictionary. For some subelements in an HTML form, I want to POST an additional nested dictionary, within that form dictionary. The question is, if there is an HTML tag or such a thing, which Python would interpret as opening for a new dictionary. So far I tried naming the <code>&lt;td&gt;</code> or an invisible <code>&lt;fieldset&gt;</code>, but of course it isn't as simple. And nested forms aren't possible either. </p> <p>What I have is a form, which contains a few text inputs and a table with a selection of associated items.</p> <pre><code>_____ the entire form __________________________________________________________ | | | beverage: coffee | | time of day: morning | | temperature: hot | | color: brown | | taste: full-bodied | | | | Ingredients: | | ________________________________________________________________________ | | | | | | | | | | &lt;IMAGE_1&gt; | &lt;IMAGE_2&gt; | &lt;IMAGE_3&gt; | &lt;IMAG| | | | | | | | | | | filename: coffee | filename: sugar | filename: milk | filename:| | | | x select item | x select item | x select item | x select | | | |___________________|___________________|___________________|__________| | | |_____________________________&lt;scrollbar&gt;______________________________| | | | | &lt; OK &gt; | |______________________________________________________________________________| </code></pre> <p>Following are three simple pseudo-code snippets to explain the gist. </p> <ul> <li><p>Content of one form entry: </p> <pre><code>beverages = { 'coffee': { 'beverage': 'coffee', 'time of day': 'morning', 'temperature': 'hot', 'color': 'brown', 'taste': 'full-bodied', } } ingredients = { 'coffee': [ 'coffee', 'sugar', 'milk', 'cinnamon', ], } </code></pre></li> <li><p>Top part of the form : </p> <pre><code>yield(u''' &lt;form action="..." method="POST"&gt; &lt;table&gt; ''') for key, value in beverages['coffee'].items(): yield(u''' &lt;tr&gt; &lt;td&gt; {key}: &lt;/td&gt; &lt;td&gt; &lt;input type="text" name="{key}" value="{value}"&gt;&lt; /td&gt; &lt;/tr&gt; '''.format(locals(),) </code></pre></li> <li><p>Bottom part of the form : </p> <pre><code>""" This hole bottom part already shall be in a dictionary named 'ingredients'. For each loop pass, I'd like a sub-dictionary, named by its loop pass. I used the fictional tag &lt;SPECIAL_SUB_DICT&gt;, to open a new dictionary. """ yield(u''' &lt;/table&gt; &lt;SPECIAL_SUB_DICT name="ingredients"&gt; &lt;table style="overflow-x: scroll"&gt; &lt;tr&gt; ''') for index, name in enumerate(ingredients['coffee']): yield(u''' &lt;td&gt; &lt;SPECIAL_SUB_DICT name="{index}"&gt; &lt;img src="..."&gt; &lt;input type="text" name="filename" value="{name}"&gt; &lt;input type="check" name="chosen_one" value="{index}"&gt; select item &lt;/SPECIAL_SUB_DICT&gt; &lt;/td&gt; '''.format(locals(),) yield(u''' &lt;/tr&gt; &lt;/table&gt; &lt;/SPECIAL_SUB_DICT&gt; &lt;input type="submit" name="submit" value="OK"&gt; &lt;/form&gt; ''') </code></pre></li> </ul> <h2>Conclusion</h2> <p>The problem is, without some sort of <code>&lt;SPECIAL_SUB_DICT&gt;</code> tag, I can't easily rename single ingredients. For example, if I'd like to change the filename from 'milk' to 'hole cream milk'. The way I do it now is, to add the current loop pass to the input name, like this: </p> <p><code>'&lt;input type="text" name="filename_{index}" value="{name}"&gt; '.format(locals(),)</code> </p> <p>Then, within the receiving function, I can check which key starts with 'filename_' and update all of them: </p> <pre><code>for key, values in kwargs: if key startswith('filename_'): ingredients['coffee'][key[9:]] = value </code></pre> <p>It would be much nicer, if I just could iterate <code>kwargs['ingredients']</code>:</p> <pre><code>for key, values in kwargs['ingredients'].items(): ingredients['coffee'][key] = value[filename] </code></pre> <p>I'm asking, because a <code>&lt;SPECIAL_SUB_DICT&gt;</code> tag would be much closer to my current solution than parsing the table with Python's BeautifulSoup. And of course I want to know it. After all, with BeautifulSoup I'd probably be done by now.</p> <p><strong>EDIT 1:</strong> </p> <p>This runs with the web application framework CherryPy.<br> Maybe there's a way it could handle such a request.<br> Though I dont't think, that it would offer something off-standard.</p> <p><strong>EDIT 2:</strong> </p> <p>Given, that the form-dictionary starts in the URL with a question mark, I don't think a sub-dictionary is possible, because I don't know of any dictionary closing character. The closest thing I could come up with is using a hidden input named 'index', and zip() it with the text input named 'filename'. <a href="https://stackoverflow.com/questions/1893332/html-table-of-forms/1893346#1893346">This answer</a>, unfortunately for PHP, got me in the right direction. </p> <pre><code>'&lt;input type="hidden" name="index" value="{index}"&gt; '.format(locals(),) '&lt;input type="text" name="filename" value="{name}"&gt; '.format(locals(),) for key, values in zip(kwargs['index'], kwargs['filename']): ingredients['coffee'][key] = value </code></pre> <p>However, this wouldn't work for the delete button, which I planed to add to each ingredient. Since only the submit input can carry the index, and its value is used to display the button's unicode symbol, I again have to append the index to the name. </p> <p>Then, the only thing I can think of, is a form for each ingredient and the top part of the formular, instead of one large form for everything. Though I don't know if that would be good for the performance, if the list of ingredients becomes too long.</p> <p>As a visual trick comes a background image to mind, to replace the value, which then transparently, can be used according to its name. <a href="https://stackoverflow.com/questions/11772326/submit-button-image/11772584#11772584">This answer</a> and its corresponding question was helpful to get it working. </p> <p>But nothing of this is an answer to my question.<br> I'm still missing the one solution for all inputs,<br> like multiple forms, just more elegant. </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload