Project

General

Profile

How to save form_for form in database?

Added by Stéphane CHÂTEAU over 2 years ago

This message is a continuation of [[https://www.redmine.org/boards/3/topics/56954]] where I add button on issues list and issue details.
I add informations into issues list and issue details Redmine pages by injected html code into theses pages and it's work fine.

But now, I need to add forms to be able to modify (only modify, not add or delete for the moment) these informations.

In order to create maps and manage georeferenced issues, a "pointes" table allows each Issue to be geolocalized.
This table contains the Id of the Issue, the id of the pointes, a point (postgresql spatial database), a state and various informations.
In order to visualize these coordinates but also to be able to modify the information, several plugins have been developed (allowing to add / delete one or more pointed by FT via rest requests and QGis plugins).
To display checkpoint information, a file has been added in <plugin name>/lib/<plugin name>/view_hook_listeners.rb
This will run the app/views/<plugin name>/issue/_issus_details.html.erb file to inject code into the issue view page and it works fine.

view_hook_listeners.rb:
@require 'redmine'

Rails.logger.info 'Plugin d’affichage du statut de la présence d’une géométrie pour Redmine'

  1. This is the important line.
  2. It requires the file in lib/geometry_status/view_hook_listeners.rb
    require_dependency 'geometry_status/view_hook_listeners'

Redmine::Plugin.register :geometry_status do
name 'Geometry Status plugin'
author 'xxxxxx'
description 'Ceci est le plugin pour l’intégration du status de la géométrie dans Redmine'
version '1.0.0' # Requires the redmine geometry plugin
requires_redmine_plugin :geometry, :version_or_higher => '1.0.0'
end@

view_hook_listeners.rb:
@module GeometryStatus # Voir : http://www.redmine.org/projects/redmine/wiki/Hooks
class Hooks < Redmine::Hook::ViewListener
def view_layouts_base_html_head(context)
stylesheet_link_tag("plugin", :plugin => 'geometry_status') +
javascript_include_tag('plugin', :plugin => 'geometry_status')
end

  1. rewrite select for trackers on issue form // view_issues_show_details_bottom
    def view_issues_show_details_bottom(context={})
    issue = context[:issue]
    project = context[:project]

    html_return = ''
    if project != nil && project.id == 24 && issue != nil # Afficher tous les custom fields : #================================== # html_return = "<hr>" # CustomField.all.each do |custom| # html_return += "<br/>custom id=#{custom.id} / name=#{custom.name}" # custom.possible_values.each do |value| # html_return += "<br/> => #{value}" # end # end # return html_return

    1. id 24 => project.name "Base des défauts"
      pointe = Pointes.where(issue_id: issue.id)
    if pointe.first != nil
      # La géométrie a été trouvée
    html_button_click = "onClick=\"call_qgis('#{issue.id}|#{pointe.first.pointe}')\""
    html_button = "&lt;button class=\"geometry_status_button\" #{html_button_click}&gt;" + image_tag('geometry.png', :plugin => 'geometry_status', :title => "La FT #{issue.id} a une géométrie\nCliquez sur le bouton pour l'ouvrir dans le plugin Redmine sous QGis", :align => "center") + "&lt;/button&gt;"
    html_return = "&lt;hr&gt;&lt;p&gt;#{html_button}&lt;strong class=\"geometry_status_centered_text\"&gt;Géométrie&lt;/strong&gt;&lt;div class=\"wiki\"&gt;&lt;p&gt;La FT a une géométrie => WKT = #{pointe.first.pointe}&lt;/p&gt;&lt;/div&gt;"
    else # La géométrie n'a pas été trouvée
    html_button_click = "onClick=\"call_qgis('#{issue.id}|')\""
    value = CustomField.select('id, name, possible_values').where(name: 'Portée du Défaut').first
    if value # Obligé de mettre dans "#{xxxxxx}" sinon la comparaison ne fonctionne pas !
    portee_du_defaut = "#{issue.custom_value_for(value.id)}"
    if portee_du_defaut == "Général" 
    html_button = "&lt;button class=\"geometry_status_button\" #{html_button_click}&gt;" + image_tag('geometry_none.png', :plugin => 'geometry_status', :title => "La FT #{issue.id} n'a pas de géométrie\nCliquez sur le bouton pour l'ouvrir dans le plugin Redmine sous QGis", :align => "center") + "&lt;/button&gt;"
    html_return = "&lt;hr&gt;&lt;p&gt;#{html_button}&lt;strong class=\"geometry_status_centered_text\"&gt;Géométrie&lt;/strong&gt;&lt;div class=\"wiki\"&gt;&lt;p&gt;La FT générale ne contient pas de géométrie&lt;/p&gt;&lt;/div&gt;"
    elsif portee_du_defaut == "Local"
    html_button = "&lt;button class=\"geometry_status_button\" #{html_button_click}&gt;" + image_tag('geometry_gray.png', :plugin => 'geometry_status', :title => "La FT #{issue.id} n'a pas de géométrie mais elle devrait en avoir une !\nCliquez sur le bouton pour l'ouvrir dans le plugin Redmine sous QGis", :align => "center") + "&lt;/button&gt;"
    html_return = "&lt;hr&gt;&lt;p&gt;#{html_button}&lt;strong class=\"geometry_status_centered_text\"&gt;Géométrie&lt;/strong&gt;&lt;div class=\"wiki\"&gt;&lt;p&gt;La FT locale ne contient pas de géométrie mais elle devrait en avoir une !&lt;/p&gt;&lt;/div&gt;"
    else
    html_return = "&lt;hr&gt;&lt;p&gt;&lt;strong class=\"geometry_status_centered_text\"&gt;Géométrie&lt;/strong&gt;&lt;div class=\"wiki\"&gt;&lt;p&gt;La FT ne contient pas de géométrie. &lt;strong class=\"geometry_unknown_portee_default\"&gt;Attention, la portée du défaut '#{portee_du_defaut}' est inconnue !&lt;/strong&gt;&lt;/p&gt;&lt;/div&gt;"
    end
    end
    end
    end

    html_return
    end
    end
    end@

What I want

The form displaying the information of the points has been injected in javascript in the details page of the Issue and works (the modifications are saved in AJAX). However, in order to obtain a better integration in Redmine I wanted not to use a normal form with form keyword but to do it in rails (otherwise it poses problems of detection of modified fields not saved (or saved) badly supported by Rails since we do not go through the framework):
The following code is placed in a loop, in fact there can be several instances of 'pointed to' by FT, each instance having its own form.

@ <%= form_for :pointe, html: {class: 'geometry_pointe_form'} do |form| >
<
= form.hidden_field :id, value: pointe.id >
<legend><strong><
= l(:geometry_legend_status) ></strong></legend>
<
= form.select(:statut, options_for_select([[l(:geometry_status_new), 1],
[l(:geometry_status_refused), 2],
[l(:geometry_status_accepted), 3],
[l(:geometry_status_to_validated), 4],
[l(:geometry_status_resolved), 5],
[l(:geometry_status_confirmed), 6]
],
pointe.statut)) %>
.... les autres champs .....

<%= form.submit "Submit" >
<
end %>
@

What i get

I get exactly what I want at the display level, of course the code is much more complex.
On the other hand, impossible to know what to put in which file to capture the submit and save the modified information in the database.
I always get "Page not found" when I click on the submit button.

I tried in app/status/controller/pointe_controller.rb to put the following code but without any effect.
And when that doesn't work, we can't say rails help us figure things out.

@class PointeController < ApplicationController
def create
Pointes.create(params[:id])
end

def update
@pointe = Pointes.find(params[:id]]))
if @pointe.update(pointe_params)
redirect_to 'pages/success'
else
redirect_to 'pages/error'
end
end

private
def pointe_params
params.require(:id).permit(:comment, :statut)
end
end@

Here, I spent two days to cleanly port the form that I had made in javascript exclusively, but now I have to save it (these) sacred form (s)!

Thank you for your answers.


Replies (1)

    (1-1/1)