Cette fois, nous utiliserons jQuery pour définir le bouton d'envoi afin qu'il ne puisse pas être pressé tant que le formulaire n'est pas rempli et sélectionné.
Partagez des informations et rédigez votre propre mémorandum.
Pour éviter une transmission erronée et améliorer la convivialité.
MacOS 10.15.7 ruby 2.6.5 Ruby on Rails 6.0.0
--JQuery a été installé.
La table User est "Poster", la table Post est "Post", la table Image est "Postée", la table Prefecture est "Prefectural data" et la table Category est "Post category".
La table Prefecture et la table Category utilisent des données de départ.
Posts_controller.rb est en charge de la nouvelle fonction de publication.
posts_controller.rb
class PostsController < ApplicationController
def new
@post = Post.new
@post.build_spot
@post.images.build()
end
def create
@post = Post.new(post_params)
if @post.save
redirect_to root_path, notice: "Le message est terminé"
else
flash.now[:alert] = "S'il vous plaît remplir les champs obligatoires"
@post.images.build()
render :new
end
end
...Une description ci-dessous est omise
.
.
.
private
def post_params
params.require(:post).permit(:title, :content, :prefecture_id, :category_id, images_attributes: [:id, :image, :_destroy]).merge(user_id: current_user.id)
end
Tout d'abord, créez le formulaire en html.
erb:new.html.erb
<%= form_with(model: @post, local: true, multipart: true) do |form| %>
<ul class='formSpace'>
<li class="prefecture">
<label class="labelName" for="Prefecture">Prefecture:</label>
<%= form.collection_select :prefecture_id, Prefecture.all, :id, :name, {include_blank: 'Veuillez sélectionner'}, {class: "prefecture__input", id: 'input01'} %>
</li>
<li class="category">
<label class="labelname" for="category">Category:</label>
<%= form.collection_select :category_id, Category.all, :id, :name, {include_blank: 'Veuillez sélectionner'}, {class: "category__input", id: 'input02'} %>
</li>
<li class="title">
<label class="labelName" for="titleSpace">Title:</label>
<%= form.text_field :title, class: 'title__input', id: "input03", placeholder: "Veuillez entrer un titre" %>
</lil
<li class='newImage'>
<label class="labelName" for="imageSpace">Photo:</label>
<div class="prevContent">
</div>
<div class="labelContent">
<label class="labelBox" for="post_images_attributes_0_image">
<div class="labelBox__text-visible">
Cliquez pour télécharger des fichiers (jusqu'à 5)
</div>
</label>
</div>
<div class="hiddenContent">
<%= form.fields_for :images do |i| %>
<%= i.file_field :image, class: "hiddenField", id: "post_images_attributes_0_image", name: "post[images_attributes][0][image]", type: "file" %>
<%= i.file_field :image, class: "hiddenField", id: "post_images_attributes_1_image", name: "post[images_attributes][1][image]", type: "file" %>
<%= i.file_field :image, class: "hiddenField", id: "post_images_attributes_2_image", name: "post[images_attributes][2][image]", type: "file" %>
<%= i.file_field :image, class: "hiddenField", id: "post_images_attributes_3_image", name: "post[images_attributes][3][image]", type: "file" %>
<%= i.file_field :image, class: "hiddenField", id: "post_images_attributes_4_image", name: "post[images_attributes][4][image]", type: "file" %>
<% end %>
</div>
</li>
<li class='content'>
<label class="labelName" for="contentSpace">Content:</label>
<%= form.text_area :content, class: 'content__input', id: "input05", placeholder: "Merci de saisir un commentaire" %>
</li>
</ul>
<div class='send'>
<%# <%= form.submit "Envoi en cours", class: 'send__btn', id: 'sending', value: "Publier" %>
<input type='submit' id='sending' class='send__btn' value='Publier'>
</div>
<% end %>
new.scss
.formSpace {
height: auto;
}
.labelName {
color: #000000;
}
//Préfectures================================================================
.prefecture {
height: auto;
width: auto;
margin-top: 1vh;
font-size: 1.5vh;
line-height: 1.5;
color: #fff;
&__input {
width: auto;
border: 1px solid #ccc;
background-color: #fff;
border-radius: 5px;
text-align: center;
color: #000000;
}
}
//Catégorie ===============================================
.category {
height: auto;
width: auto;
margin-top: 1vh;
font-size: 1.5vh;
line-height: 1.5;
color: #fff;
&__input {
width: auto;
border: 1px solid #ccc;
background-color: #fff;
border-radius: 5px;
color: #000000;
}
}
//Title===================================================================
.title {
height: auto;
width: auto;
margin-top: 1vh;
font-size: 1.5vh;
line-height: 1.5;
color: #fff;
&__input {
width: 30vw;
border-radius: 5px;
border: 1px solid #ccc;
background-color: #fff;
color: #000000;
margin-left: 25px;
}
}
//Image======================================================================
.newImage {
display: block;
margin: 16px auto 0;
display: flex;
flex-wrap: wrap;
cursor: pointer;
}
.imageLabelName {
color: #fff;
margin-right: 25px;
}
.prevContent {
display: flex;
}
.previewBox {
height: 162px;
width: 112px;
margin: 0 15px 10px 0;
}
.upperBox {
height: 112px;
width: 100%;
img {
width: 112px;
height: 112px;
}
}
.lowerBox {
display: flex;
text-align: center;
}
.deleteBox {
color: #1e90ff;
width: 100%;
height: 50px;
line-height: 50px;
background: #f5f5f5;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.imageDeleteBtn {
background-color: #f5f5f5;
line-height: 4vh;
height: 4vh;
width: 60px;
}
.imageDeleteBtn:hover {
color: rgba($color: #1e90ff, $alpha: 0.7);
}
//Zone de clic du message CSS
.labelContent {
margin-bottom: 10px;
width: 620px;
.labelBox {
display: block;
border: 1px dashed #ccc;
position: relative;
background: #f5f5f5;
width: 100%;
height: 162px;
cursor: pointer;
&__text-visible {
position: absolute;
top: 50%;
left: 16px;
right: 16px;
text-align: center;
font-size: 14px;
line-height: 1.5;
font-weight: bold;
-webkit-transform: translate(0, -50%);
transform: translate(0, -50%);
pointer-events: none;
white-space: pre-wrap;
word-wrap: break-word;
}
}
}
//file_champ css
.hiddenContent {
.hiddenField {
display: none;
}
.hidden-checkbox {
display: none;
}
}
//commentaire====================================================================
.content {
display: flex;
height: auto;
width: auto;
margin-top: 5px;
line-height: 1.5;
font-size: 1.5vh;
&__input {
height: 15vh;
width: 40vw;
border-radius: 5px;
color: #000000;
border: 1px solid #ccc;
background-color: #fff;
margin-left: 0px;
padding: 1vh;
}
}
//Bouton d'envoi=========================================================================
.send {
display: flex;
justify-content: center;
&__btn {
height: 5vh;
width: 25vw;
margin: 50px 0;
border-radius: 20px;
background-color: #87cefa;
border: none;
box-shadow: 0 0 8px gray;
color: #ffffff;
line-height: 1.5;
font-size: 2vh;
font-weight: bold;
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease;
}
:hover {
background-color: #00bfff;
}
.send__btn[disabled] {
background-color: #ddd;
cursor: not-allowed;
}
}
Si vous faites jusqu'à présent, cela ressemblera à ce qui suit.
Cette fois, afin de gérer l'état si le formulaire est saisi ou sélectionné en JavaScript
<%= form.collection_select :prefecture_id, Prefecture.all, :id, :name, {include_blank: 'Veuillez sélectionner'}, {class: "prefecture__input", id: 'input01'} %>
L'id est spécifié sous la forme "id:" input01 ".
De cette façon, id est spécifié pour chaque formulaire, mais cette fois, il est impossible de réutiliser l'id avec le même nom.
Les identifiants sont attribués dans l'ordre sous la forme id = 'input02'
, id =' input03'
...
(Le nom de la classe peut être unifié et réutilisé, mais cette fois, il sera omis.)
Concernant SCSS, il est décrit que la couleur du bouton est modifiée en fonction de l'état activé / désactivé du bouton (classe: send__btn). La gestion de l'état des boutons est gérée à l'aide d'une valeur appelée distabled, qui sera décrite plus loin. S'il n'est pas valide, une valeur appelée distabled sera donnée à l'élément, donc scss
.send__btn[disabled] {
background-color: #ddd;
cursor: not-allowed;
}
Si le bouton est désactivé, la couleur est grisée et le curseur est désactivé.
Après cela, nous déterminerons si le formulaire a été saisi / sélectionné dans le fichier js et décrirons le processus pour activer / désactiver le bouton d'envoi.
Cette fois, nous l'écrirons dans un fichier appelé submit.js.
submit.js
//Empêcher le bouton d'envoi d'être enfoncé jusqu'à ce que le formulaire soit rempli et sélectionné=============================================
$(function() {
//Désactivez d'abord le bouton d'envoi
$('#sending').prop("disabled", true);
//Lors de l'utilisation d'un champ d'entrée pour lequel "input" est défini pour id
$("[id^= input],#post_images_attributes_0_image").change(function () {
//Afin de définir si le champ de saisie est vide, l'état du contenu du formulaire est géré à l'aide d'une variable appelée send.
let send = true;
//id=input~Vérifiez les champs de saisie spécifiés comme&Vérifiez l'image (image avec numéro d'index 0)
$("[id^= input],#post_images_attributes_0_image").each(function(index) {
//Vérifiez le contenu (valeurs) du formulaire dans l'ordre, et si la valeur du formulaire est vide, envoyez=faux
if ($("[id^= input],#post_images_attributes_0_image").eq(index).val() === "") {
send = false;
}
});
//Si tous les formulaires sont remplis(send =Si vrai)
if (send) {
//Activer le bouton d'envoi
$('#sending').prop("disabled", false);
}
//Si même un formulaire est vide(send =Si faux)
else {
//Désactiver le bouton d'envoi
$('#sending').prop("disabled", true);
}
});
});
Envoyer d'abord le bouton
<input type='submit' id='sending' class='send__btn' value='Publier'>
D'autre part, le bouton est désactivé en tant que prop (disabled, false)
.
La méthode prop a le rôle __ de définir une valeur sur l'attribut spécifié.
distabled est un attribut __ qui peut invalider l'élément HTML spécifié.
En l'utilisant en combinaison avec la méthode prop
prop ('disabled', true)» ・ ・ ・ Disable element
prop ('disabled', false)» ・ ・ ・ Activer l'élément
Vous pouvez l'utiliser comme ça.
référence: méthode prop ・ ・ ・ http://js.studio-kingdom.com/jquery/attributes/prop distabled ・ ・ ・ https://persol-tech-s.co.jp/hatalabo/it_engineer/463.html#disabled
prochain,
$("[id^= input],#post_images_attributes_0_image").change(function ()
Il est décrit comme.
La description est "L'événement se déclenche lorsque les valeurs de [id ^ = entrée]
et # post_images_attributes_0_image
changent.
Ce à quoi je voudrais que vous fassiez attention
[id^= input]
C'est la partie de. Cela utilise la méthode de spécification utilisant les attributs de jQuery. Il y a environ quatre façons de spécifier.
Pour la "correspondance de départ", vous pouvez obtenir tous les éléments qui correspondent à la chaîne de caractères au début du nom d'attribut simplement en ajoutant "^" comme "attribut ^ = nom d'attribut".
Dans ce cas, en définissant [id ^ = input]
, l'élément avec id = "input01", id = "input02, ... id =" input05, c'est-à-dire l'élément nommé input dans le nom id Vous pouvez tous les obtenir.
Pour la méthode de spécification utilisant les attributs de jQuery, je me suis référé à cet article. Si vous voulez en savoir plus que la désignation du préfixe, jetez un œil.
continuer,
let send = true;
Est décrit afin de gérer l'état du formulaire à l'aide d'une variable appelée send afin de juger si le champ de saisie est vide. Si c'est vrai, cela signifie que le formulaire est complètement rempli.
$("[id^= input],#post_images_attributes_0_image").each(function(index) {
//Vérifiez le contenu (valeurs) du formulaire dans l'ordre, et si la valeur du formulaire est vide, envoyez=faux
if ($("[id^= input],#post_images_attributes_0_image").eq(index).val() === "") {
send = false;
}
});
Pour, utilisez la méthode each pour extraire les éléments dont l'id est nommé input en fonction du nombre d'éléments. Lors de la récupération, il est nécessaire de définir une fonction de rappel dans l'argument de chaque méthode, spécifiez donc "fonction (index)". En faisant cela, vous pouvez obtenir le numéro d'index et attribuer le numéro d'index à chaque élément extrait.
Dans ce cas, en tant qu'image
0 : id="input01"Des éléments de
1 : id="input02"Des éléments de
2 : id="input03"Des éléments de
3 : id="input04"Des éléments de
4 : id="input05"Des éléments de
Je pense que ça va ressembler à ça.
De plus, # post_images_attributes_0_image
est également ajouté à l'objet cible. Honnêtement,
Lors de la publication de plusieurs images, je ne peux pas définir et spécifier un bon identifiant, je l'ai donc ajouté ici.
(J'apprécierais que vous me disiez s'il y a une autre façon de le faire!)
Après avoir récupéré le numéro d'index avec chaque méthode
if ($("[id^= input],#post_images_attributes_0_image").eq(index).val() === "") {
send = false;
}
Passez au traitement de.
Ici, nous vérifions si le contenu du formulaire pour chacun des éléments extraits est vide.
La méthode eq
est utilisée pour vérifier chacun d'eux.
La méthode eq filtre les éléments actuellement correspondants par numéro d'index.
(site de référence de la méthode eq)
L'élément nommé input dans id est une image dans laquelle le numéro d'index est entré dans l'argument de la méthode eq dans l'ordre car les numéros d'index 0 à 4 sont attribués dans chaque méthode. (Exemple: eq (0), eq (1) ... eq (4))
Utilisez la méthode val pour obtenir la valeur du formulaire (site de référence de la méthode val)
~~ ===" "
signifie que "~~ est vide".
Il valide les éléments extraits un par un et renvoie send = false
si l'un des éléments a une valeur de forme vide.
Dernier
//Si tous les formulaires sont remplis(send =Si vrai)
if (send) {
//Activer le bouton d'envoi
$('#sending').prop("disabled", false);
}
//Si même un formulaire est vide(send =Si faux)
else {
//Désactiver le bouton d'envoi
$('#sending').prop("disabled", true);
}
Pour la part de
Dans le cas de if (send)
(signifiant si send == true), c'est-à-dire lorsque le formulaire est complètement rempli, $ ('# envoi'). Prop (" disabled ", false);
Le bouton d'envoi est activé et prêt à être pressé.
Dans le cas de else
(send == false), c'est-à-dire si même un formulaire est vide, le bouton d'envoi est désactivé sous la forme $ ('# envoi'). Pro (" disabled ", true);
Pour rendre impossible d'appuyer sur.
C'est ça.
Comme je suis débutant, il y a encore beaucoup de parties que je ne comprends pas bien, et honnêtement, je pense qu'il y a beaucoup de prédictions d'amélioration concernant cette implémentation, alors j'apprécierais que vous me disiez s'il existe une meilleure méthode de mise en œuvre. De plus, si vous lisez cet article, je serais très heureux si vous pouviez également obtenir LGTM. Merci de votre collaboration.