Search code examples
javascriptphptwitter-bootstrappopoverx-editable

JS/HTML, conflict between bootstrap popover and editable popup breaks editable save data


I have a PHP (Laravel 5.5) app using bootstrap editable fields and popovers. The popovers work great, and the editable fields also work great, until they're on the same view (blade) as the popovers.

Here's the editable field code in my view:

<a href="#" 
                                    class="assetName" 
                                    data-type="text" 
                                    data-name="split_amount" 
                                    data-url="update-real-row" 
                                    data-pk="{{ $real_split->id }}" 
                                    data-title="Edit Amount" 
                                    data-value="{{$real_split_yours}}">${{number_format($real_split_yours,0)}}
                                    </a></div>

Here's the popover code in my view:

<a href="#RE" 
                                    data-toggle="popover" 
                                    title="<h3> Tax Analysis for {{$real_asset->real_name}} property </h3>" 
                                    data-html="true" 
                                    data-content="{{$table_html}}">
                                    ${{number_format($after_taxes_value,0)}}
                                </a>

I have their supporting JavaScript in a file I include into the view, so the same JavaScript exists in both the working view (editable fields on their own) and the broken view (editable fields when on the same page as the popovers). Here's the included scripts file:

<script>

$(document).ready(function() {

$.fn.editable.defaults.mode = 'popup';
$.fn.editable.defaults.send = "always";

  $.fn.editable.defaults.params = function (params) 
  {
   params._token = $("#_token").data("token");
   return params;
  };

  $.fn.editable.defaults.success = function(response, newValue) 
            {
                //if(!response.success) return response.msg;
                window.location.reload();
            };

$('.assetName').editable({

           ajaxOptions: {
             dataType: 'json',
             type: 'post'
           }

           });
});

$('[data-toggle="popover"]').popover({
                    html: true,
                    trigger: 'manual'
                }).click(function(e) {
                    $(this).popover('show');
                    $('.popover-title').append('<button type="button" class="close">&times;</button>');
                    $('.close').click(function(e){
                        $('[data-toggle="popover"]').popover('hide');
                    });
                    e.preventDefault();
                    placement: 'bottom'
                    });

$('body').on('click', function (e) {
    $('[data-toggle="popover"]').each(function () {
        //the 'is' for buttons that trigger popups
        //the 'has' for icons within a button that triggers a popup
        if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
            $(this).popover('hide');
        }
    });
});

</script>

Here's the controller code that supports the editable field save function that works when no popovers are present:

/**
 * Update the specified resource in storage.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \App\real_property_split  $real_property_split
 * @return \Illuminate\Http\Response
 */
public function updateRow(Request $request, real_property_split $real_property_split)
{
    $pk = $request->input('pk');

    $splitRecord = $real_property_split::findOrFail($pk);

    // get column name
    $col = $request->input('name');

    // get new value
    $value = $request->input('value');

    $splitRecord->$col = $value;
    $splitRecord->save();

    return \Response::json(array('status' => 1));
}

Here's the route that connects the editable field to the controller:

Route::post('split-scenario/update-real-row', 'RealPropertySplitController@updateRow')->middleware('auth');

I can't figure out why the editable field works perfectly, updating the database, until the view also has the popover markup in it.

This is the error I get when a new value is entered into the editable field:

{
"message": "",
"exception": "Symfony\\Component\\HttpKernel\\Exception\\MethodNotAllowedHttpException",
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\RouteCollection.php",
"line": 255,
"trace": [
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\RouteCollection.php",
"line": 242,
"function": "methodNotAllowed",
"class": "Illuminate\\Routing\\RouteCollection",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\RouteCollection.php",
"line": 176,
"function": "getRouteForMethods",
"class": "Illuminate\\Routing\\RouteCollection",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
"line": 612,
"function": "match",
"class": "Illuminate\\Routing\\RouteCollection",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
"line": 601,
"function": "findRoute",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php",
"line": 590,
"function": "dispatchToRoute",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
"line": 176,
"function": "dispatch",
"class": "Illuminate\\Routing\\Router",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php",
"line": 30,
"function": "Illuminate\\Foundation\\Http\\{closure}",
"class": "Illuminate\\Foundation\\Http\\Kernel",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\fideloper\\proxy\\src\\TrustProxies.php",
"line": 56,
"function": "Illuminate\\Routing\\{closure}",
"class": "Illuminate\\Routing\\Pipeline",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 149,
"function": "handle",
"class": "Fideloper\\Proxy\\TrustProxies",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php",
"line": 53,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php",
"line": 30,
"function": "Illuminate\\Routing\\{closure}",
"class": "Illuminate\\Routing\\Pipeline",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 149,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php",
"line": 53,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php",
"line": 30,
"function": "Illuminate\\Routing\\{closure}",
"class": "Illuminate\\Routing\\Pipeline",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 149,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php",
"line": 53,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize.php",
"line": 27,
"function": "Illuminate\\Routing\\{closure}",
"class": "Illuminate\\Routing\\Pipeline",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 149,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php",
"line": 53,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode.php",
"line": 46,
"function": "Illuminate\\Routing\\{closure}",
"class": "Illuminate\\Routing\\Pipeline",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 149,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php",
"line": 53,
"function": "Illuminate\\Pipeline\\{closure}",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php",
"line": 102,
"function": "Illuminate\\Routing\\{closure}",
"class": "Illuminate\\Routing\\Pipeline",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
"line": 151,
"function": "then",
"class": "Illuminate\\Pipeline\\Pipeline",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php",
"line": 116,
"function": "sendRequestThroughRouter",
"class": "Illuminate\\Foundation\\Http\\Kernel",
"type": "->"
},
{
"file": "C:\\xampp\\htdocs\\DS_dev_01\\public\\index.php",
"line": 55,
"function": "handle",
"class": "Illuminate\\Foundation\\Http\\Kernel",
"type": "->"
}
]
}

The error would indicate an incorrect method used to store the editable field edited value, but that can't be as it works perfectly fine when there are no popovers on the page.

If anyone can spot the issue I'd be very grateful. I've been buried in this trying to find the conflict for over a week to no avail.

Thanks in advance.


Solution

  • So I found my issue, and it wasn't a JavaScrip conflict.

    I had a typo in my route for the editable field, so the Ajax return trip with the successfully-changed database value was tripping up and breaking. The reason it worked in the page with just the editable popup was that page's route was fine. The new page with both popover and editable popup had a broken route, nothing wrong with the JavaScript elements.

    Not sure if this helps anyone since my original question was looking for an answer in the wrong place. But someone in the future who is stumped by something like this may find an answer/direction that helps. As ever, the fix is quick and easy when you know/figure out how. However, it can be many days of anguish if you don't.

    Thanks to all who viewed my question.