We help IT Professionals succeed at work.

Could you point what must to be adjusted at this view code to avoid the form beeing submited if the modal's textbox is empty?

Eduardo Fuerte
on
Hi Experts


Could you point what must to be adjusted at this view's code to avoid the form beeing submited if the modal's textbox is empty?

Accordingly with:


<?

<div class='row'>
    <br/>
    <div class="well well-lg text-center">
        <h1>Fotos</h1>
    </div>
</div>

<input type='hidden' id='pagina' value='1'/>

<div class="container">
    <div class="row">
    
          <!--div class="panel panel-primary"-->
          <div class="panel panel-default">
          
            <div class="panel-body">
                <div class=" col-md-12 col-sm-12"> 
                      <div class='row'>
                      
                         <div class="col-sm-12 col-md-6">
                          <div class="btn-group" role="group">
                            <button type="button" class="btn btn-primary" onclick="Xxxxx.vitrine.minhasfotos();">
                              <i class="fas fa-video" aria-hidden="true"></i> Minhas Fotos
                            </button>
                          </div>
                        </div>
                        
                         <div class="col-sm-12 col-md-3">
                          <div class="btn-group" role="group">
                            <button type="button" class="btn btn-primary" onclick="Xxxxx.vitrine.todasfotos();">
                              <i class="fas fa-video" aria-hidden="true"></i> Todas as Fotos
                            </button>
                          </div>
                        </div>
                          
                         <div class="col-sm-12 col-md-3">
                          <div class="btn-group" role="group">
                            <button type="button" class="btn btn-primary" onclick="Xxxxx.vitrine.novo();">
                              <i class="fas fa-video" aria-hidden="true"></i> Enviar Foto
                            </button>
                          </div>
                        </div>
                          
                      </div>  
                      
                  </div>
            </div>
        </div>
    </div>
</div>

<div class='row' id="lista"></div>

  <div class='row'>
    <div id="midiaList">
      @include('vitrines.fotos')
    </div>
  </div>


<!-- Modal -->
<div class="modal fade" id="mEditor" tabindex="-1" role="dialog" aria-labelledby="mEditorLabel">
  <div class="modal-dialog modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title" id="mEditorLabel">Nova Foto</h4>
      </div>
      <div class="modal-body row">
            <input type='hidden' value="0" id='id' name='id'>

            <div class='col-md-7'>
  
                <div class='col-md-12 form-group'>
                    <label for='title'>Título</label>
                    <input type='text' id='title' name='title' class='form-control'/>
                </div>

                <div class='col-md-12 form-group'>
                    <label for='description'>Descrição</label>
                    <input type='text' id='description' name='description' class='form-control'/>
                </div>
                
            </div>

            <div id='box-video' class='col-md-5 text-center'>
            
                <img id='srcVitrine' src=''>
                

                <div class='col-md-12 form-group'>
                    <label for='titulo'>URL (Foto/ Imagem):</label>
                    <div class="input-group">
                        <input type='text' id='url' name='url' disabled class='form-control'/>
                        <span class="input-group-btn">
                            <button class="btn btn-primary" type="button" onclick='Xxxxx.vitrine.subirVideo();'><i class="fa fa-camera"></i></button>
                        </span>
                        <input type='file' id='file' name='file' style='display:none;'/>
                    </div>
                </div>
            </div>
      </div>

      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal"><i class="fas fa-times" aria-hidden="true"></i> Fechar</button>
        
		
		<button type="button"  id="btnSubmit" class="btn btn-primary" onclick="Xxxxx.vitrine.salvar();"><i class="fas fa-hdd" aria-hidden="true"></i> Salvar</button>
      
	  
	  </div>
    </div>
   
  </div>
</div>

<script>
  var jqXHRData;
  $(document).ready(function() {
    
    var pars = {
        _token:$('input[name="_token"]').val()
    };

       var resultImageUpload = function (data) {
        if (!data.result.erro) {
            localizacao = data.result.retorno.localizacao;
            $('#url').val(localizacao);
            
            $('#srcVitrine').attr('src', localizacao);


            return false;
        } else {
          xxx.openModalCustom("Erro",'Erro ao subir vídeo.', "Entendi", "error");
          return false;
        }
        else
        {

// ---- ADJUST ---This function is called but even returning false the form is submited with success 
            $(function() {  
                $('#btnSubmit').click(function() {  
                    var txt = $('#title');  
                    if (txt.val() != null && txt.val() != '') {  
                        alert('you entered text ' + txt.val())  
                    } else {  
                        alert('Please enter text')  
                        return false;   
                    }  
                })  
            });  
       
        }
    
    };

    var failImageUpload = function (data) {
          if (data.files[0].error) {
              Xxxxx.openModalCustom("Erro",'Erro ao subir vídeo.', "Entendi", "error");
              return false;
          }
    };

    Xxxxx.InitFileUpload("file", "/vitrine/salvarVitrine", pars, resultImageUpload, failImageUpload);

   // Limpa a Modal
   $(".modal").on("hidden.bs.modal", function(){
        $(".modal-body input").val("")
    });


    $("#file").change(function () {
        if (jqXHRData) {
            jqXHRData.submit();
        }
        return false;
    });
  })
</script>
@endsection

Open in new window



Thanks in advance.
Comment
Watch Question

Eduardo FuerteDeveloper and Analyst

Author

Commented:
Hi

By "submited" I mean the modal form content is saved without errors, even with empty text.
SILVER EXPERT
Most Valuable Expert 2018
Distinguished Expert 2019

Commented:
Hey Eduardo,

Firstly, you seem to have 2 bindings for the click on your button. One is inline:

onclick="Xxxxx.vitrine.salvar();

And one is attached through jQuery:

$('#btnSubmit').click(function() {

Unless you have very specific reasons for doing it (and you know what you're doing), pick one and remove the other (personally, I'd go with the jQuery approach to keep Javascript out of your HTML)

The one atached through jQuery looks wrong for a couple of reasons, and if you check your console, you'll likely see errors (so it's very likely that it's not even being bound to your button). Firstly, you have 2 else statements:

if (!data.result.erro) {
    ...
} else {
    ...
} else {
    // you bind the click event in here, but it's ever going to be called.
}

Open in new window

Secondly, you've got 2 document ready fuctions - one inside the other. The first one is the normal way of writing it:

$(document).ready(function() {

and the second is the shorthand way of writing it:

$(function() {

They both do exectly the same thing, so the second one is redundant as you're already in the dom ready event handler. You don't need the second one!

Now, to stop a event handler dead in it's tracks (i.e. your validation fails) you have a couple of options. For your inline function, your need to return false from your function and then return the result of the function from your handler:

onclick="return Xxxxx.vitrine.salvar();">

function Xxxxx.vitrine.salvar() {
   ...
   // to stop the click event from firing:
   return false;
}

Open in new window

To stop a jQuery bound event, the easiest way is to pass the event object into the handler and call preventDefault() on it:

$('#btnSubmit').click(function(e) {  <-- NOTICE HOW WE PASS IN THE EVENT OBJECT
    var txt = $('#title');  
    if (txt.val() != null && txt.val() != '') {  
        alert('you entered text ' + txt.val())  
    } else {  
        //prevent the handler from continuing
        e.preventDefault();
        alert('Please enter text')
    }  
})

Open in new window

Eduardo FuerteDeveloper and Analyst

Author

Commented:
Hi Chris


The reason there's 02 buttons is:

The 1st one is to save an image file on a storage area (Azure)

The 2nd one saves the other informations  (title/ description/ url of the saved image file) to a database table (Vitrine).

 I really don't know if that is a good implementation.

I'm going to better study your reply.
SILVER EXPERT
Most Valuable Expert 2018
Distinguished Expert 2019

Commented:
Hey Eduardo,

I'm not talking about 2 different buttons. I'm talking about 1 button that has 2 bindings (2 different click handlers on the same button). You have this in your code:

<button type="button"  id="btnSubmit" ... onclick="Xxxxx.vitrine.salvar();">

And you have this in your jQuery:

$('#btnSubmit').click(function() {
Eduardo FuerteDeveloper and Analyst

Author

Commented:
This part

$('#btnSubmit').click(function() {

Open in new window



was added by me at the original script attempting to avoid save empty data at textbox...
SILVER EXPERT
Most Valuable Expert 2018
Distinguished Expert 2019

Commented:
The fact that you have 2 event handlers is part of your problem

In your jQuery event handler, you are returing false in the hope that it will stop the form being submitted - it won't do that because while you may have stopped the jQuery click handler, your other handler Xxxxx.vitrine.salvar() will still fire.
Eduardo FuerteDeveloper and Analyst

Author

Commented:
So I have to consider just one handler for the operation as a whole isn't it?

Better reading your previous reply...
SILVER EXPERT
Most Valuable Expert 2018
Distinguished Expert 2019

Commented:
Hey Eduardo,

I would recommend just having one, yes. If you have more than one, then it just complicates your code. In your example, where you have 2:

<button type="button"  id="btnSubmit" ... onclick="Xxxxx.vitrine.salvar();">

$('#btnSubmit').click(function() {

You have a problem with priority. Basically your Xxxxx.vitrine.salvar() will run first, and then the jQuery click() function will run. Now if you add validation to the jQuery code, then your other function has already finished before you've even started your validation.

Like I said, technically you can have 2 handlers if you really want - just make sure you know exactly what you're doing and what order the events are firing in, otherwise you will have problems. I wouldn't recommend it.
BRONZE EXPERT

Commented:
Hi,

Don't forget to have the server side validation as Javascript validation can be bypassed easily.

What I usually do is to remove space if any before and after any content, so if user just click on space bar and enter nothing it will catch it as empty...
Otherwise it may be considered as filled but it is not...
Eduardo FuerteDeveloper and Analyst

Author

Commented:
Hi

Really the solution implemented was by server side validation by using Laravel's validate at Controller (called by jquery ajax)

  public function save(Request $request) {
      $url = $request->input('url');
      $description = $request->input('description');

      $this->validate($request, [
        'url'=>'required',
        'description'=>'required',
      ],
      [
        'url.required'=>'Necessary to choose a photo.',
        'description.required'=>'Necessary to provide a description.',
      ]
      );

      $x = new xxx;
      $x->url = $url;
      $x->description = $description;
      $x->approved = null;
      $x->created_by = Auth::user()->id;
      $x->created_at = now();
      $x->updated_at = now();
      $x->save();

      $resultado=new Resultado(false,"Sxxx",null);

      return response()->json($resultado);
    }

Open in new window

BRONZE EXPERT

Commented:
Hi,

I'm using trim() to remove the empty space before and after the value https://www.php.net/manual/en/function.trim.php 
trim($thetext);

Open in new window

Then I check if the value is empty or not
if ($thetext == " " ) then echo message...

Open in new window



To test just tapp the space bar a few time, no text, then save it should alert that is empty.
SILVER EXPERT
Most Valuable Expert 2018
Distinguished Expert 2019

Commented:
Laravel's Validate class will take care of all the trim / whitespace issues automatically, so there's no need to be doing all that stuff manually.
Developer and Analyst
Commented:

As pointed above based on informations I get here.

SILVER EXPERT
Most Valuable Expert 2018
Distinguished Expert 2019

Commented:
Hey Eduardo,

So what was the answer. You've accepted your own comment as the solution, but that doesn't really make any sense.
Eduardo FuerteDeveloper and Analyst

Author

Commented:
The solution implemented:

  public function save(Request $request) {
      $url = $request->input('url');
      $description = $request->input('description');

      $this->validate($request, [
        'url'=>'required',
        'description'=>'required',
      ],
      [
        'url.required'=>'Necessary to choose a photo.',
        'description.required'=>'Necessary to provide a description.',
      ]
      );

      $x = new xxx;
      $x->url = $url;
      $x->description = $description;
      $x->approved = null;
      $x->created_by = Auth::user()->id;
      $x->created_at = now();
      $x->updated_at = now();
      $x->save();

      $resultado=new Resultado(false,"Sxxx",null);

      return response()->json($resultado);
    }

Open in new window

SILVER EXPERT
Most Valuable Expert 2018
Distinguished Expert 2019

Commented:
Ahh right.

That doesn't actually stop the form from being submitted as per your question. The form is still submitted to the server where you then carry out the validation. You'll still need to handle the Modal in your Javascript - PHP has no concept of your Modal.
Eduardo FuerteDeveloper and Analyst

Author

Commented:
Hi Chris


Sorry.

My question was poorly formulated.

The real issue was avoid to persist empty data at DB table columns, The frontend approach you presented would be perfectly valid to do that if we continue to implemting it .

Just the backend solution looks easier to get the same effect.