I'm using Laravel 5 to generate a form for a warehouse. In Main form you can select which items to get and it should generate a PDF with the items (all info), people to get the items, date and invoice number.
All the information is on a DIV called 'invoice'. How can I send this object to a new view to generates the PDF. I read about 'invoking dompdf via web' to make it more interactive but the documentation is not clear enough or doesn't fit with I'm needing.
This is my current code:
From:
Recibo.js
$('#createPDF').click(function()
{
$htmlData = "data";
$_token = $('[name="_token"]').val();
$.get('recibos/pdf',{ html:$htmlData, _token: $_token })
.done(function(data)
{
console.log('Done PDF!');
});
});
ReciboController.php
public function reciboPDF(Request $request)
{
$data = $request->get('html');
$pdf = \PDF::loadView('create.template.formReciboPDF',compact('data'))->setPaper('letter')->setOrientation('landscape');
return $pdf->stream();
//return view('create.template.formReciboPDF');
}
formReciboPDF.blade.php
<tr>
<td>{{$data}}</td>
<td>Papeleria</td>
<td>Unidad</td>
<td>Grande</td>
<td>La Palma</td>
<td>2342423424234</td>
<td>Bueno</td>
<td>9</td>
</tr>
Instead of trying to capture the HTML can you send the selection parameters to the server and rebuid the page? Then you would just need to feed the generated HTML into dompdf and render. If visual appearance is important you could use hidden checkboxes as the selection mechanism.
If you want to use a shortcut you can capture the HTML using jQuery.contents().
In your second part it looks like you're trying to send your request via AJAX and get back the PDF. While this is technically possible it's more trouble than it's worth. An easier alternative would be to submit a hidden form to a blank window. It would require some minor changes to your HTML/JS but little else, e.g.
$('#createPDF').click(
function() {
$('#html').val($('#invoice').content());
$(this).closest('form').submit();
});
<form method="POST" action="recibos/pdf" target="_blank">
<input type="hidden" name="html" id="html" value="" />
<input type="hidden" name="_token" value="{value from server}" />
<button type="button" id="createPDF">Create PDF</button>
</form>
Related
Is it possible to get Data back from a vue component?
Laravel blade.php code:
...
<div>
<component1></component1>
</div>
...
In component1 is a selectbox which i need (only the selected item/value) in the blade.php
A vue component, when rendered in the browser, is still valid HTML. If you make sure your component is wrapped in a form element and has a valid input element, and the form can be submitted, the PHP endpoint can consume the form’s data without problems. It could look like this:
Layout/view:
<form method="post" action="/blade.php">
<component1></component1>
<button type="submit">Submit form</button>
</form>
Component (<component1/>):
<fieldset>
<input type="checkbox" name="my_option" id="my_option">
<label for="my_option">I have checked this checkbox</label>
</fieldset>
PHP script (blade.php):
echo $_POST["my_option"] // if checked, should print "on"
If you are looking for a JavaScript centered approach, you may want to serialize the form and fetch the endpoint; it could look similar to this:
import serialize from 'form-serialize';
const formData = serialize(form)
fetch(form.action, { method: 'POST' }, body: JSON.stringify(formData) })
.then(response => {
// update page with happy flow
})
.catch(error => {
// update page with unhappy flow
})
Building from an accessible and standardized basis using proper HTML semantics will likely lead to more understandable code and easier enhancements down the road. Good luck!
(Edit: if you require a complete, working solution to your question, you should post more code, both from the Vue app as well as the PHP script.)
I have a button on a page but there is no hyperlink in the button. So I need to submit the form to go to the next page.
HtmlUnit is not waiting till the next page loads. So the nextPage variable is having the current page instead of the next page (intermittently it works if page loads quick enough though). How to resolve this?
Html Page:
<form action="/webapp/NewPage.jsp" id="idForm01" accept-charset="UNKNOWN" onsubmit="return false;"
name="frmNewPageForm" method="post" enctype="application/x-www-form-urlencoded">
<input name="attribute1" type="HIDDEN" value="1">
<input id="attribute2" value="EDIT_ATTRIBUTE2" name="functionalAttribute" type="hidden">
</form>
<table id="idTablePageDetails" class="formTable">
<tbody>
<tr class="formHeaderRow">
<td colspan="4" nowrap="">
Page Details
<a onclick="onClick_newPageButton();return false;" id="newPageButton" title="New Page" href="#" class="smallButton">
<img id="image" border="0" class="smallButtonImg" src="/webapp/image/imageButton.png"></a>
<script type="text/javascript" language="Javascript">
<!--
function onClick_newPageButton() {
buttonAction_newPageButton();
}
function buttonAction_newPageButton() {
if ( allowClick() == true ) { addFormField( "frmNewPageForm", "action", "ACTION_NEW_PAGE" );
if ( document.frmNewPageForm.onsubmit != null ) { document.frmNewPageForm.onsubmit(); }document.frmNewPageForm.submit(); }}
// -->
</script>
</table>
Code I am using to get the next page:
HtmlPage nextPage = (HtmlPage) page.executeJavaScript("document.frmNewPageForm.onsubmit()").getNewPage(); // from onsubmit
Your observation is the result of the today common ajax/async/javascript based one page approach for web applications.
You can use a code pattern like this
... find the clickable element...
myBtn.click();
webClient.waitForBackgroundJavaScript(10000);
HtmlPage resultPage = (HtmlPage) webClient.getCurrentWindow().getEnclosedPage();
After the click you have to wait until the async started javascript is processed. Then you have to get access to the current page (the content of the current window) because the page is usually replaced during the javascript processing.
There is also a method waitForJobsStartingBefore() if you like to have more control over the wait time. Both methods are returning before the given timeframe in case there is no more javascript job pending. For more details have a look at the javadoc and the code.
If you like to have a look at a more sophisticated usage of the api you can have a look at the Wetator (https://www.wetator.org/) source code. A good starting point is the class HtmlUnitBrowser (https://wetator.repositoryhosting.com/trac/wetator_wetator/browser/trunk/wetator/src/org/wetator/backend/htmlunit/HtmlUnitBrowser.java)
Hope that helps.
Why do you do clicks on buttons or execute javascript instead do requests? I think this is more trustworthy
Append any attributes to the form if you need using NameValuePair.
Then Call onSubmit() and then Submit()
HtmlPage nextPage1 = (HtmlPage) page.executeJavaScript("document.frmNewPageForm.onsubmit()").getNewPage(); // from onsubmit
HtmlPage nextPage2 = (HtmlPage) nextPage1.executeJavaScript("document.frmNewPageForm.submit()").getNewPage(); // from submit
I am making a simple put request to my app backend using axios.put();
This all works, I have a button that is binded to vue like #click="submitForm"
However looking around I see that some people still wrap their input fields in forms like those:
<form method="POST" #submit.prevent="onSubmit" action="{{ route('someRoute') }}" id="form-submit">
{{ method_field('PUT') }}
{{ csrf_field() }}
Even if I dont use a form like the one above I get the same result when calling my ajax put request.
Laravel allready adds csfr headers to axios by default in resources/assets/js/bootstrap.js
So is there any reason I still should wrap my inputs in a form like above?
Thanks
Your ajax request doesn't matter if you do your inputs in form tags or not, because the request still sends and receives data from a server.
I would use a form tag because everybody can read the markup much easier and it could be usefull for writing less code in javascript - one example
<form action="" method="">
<div class="form-group">
<label class="control-label">Input</label>
<input type="text" name="input" />
</div>
</form>
$(document).ready(function() {
$('#some-form').on('submit', function() {
var data = $(this).serialize();
... do whatever you want (like ajax call) ...
return false;
});
);
You're using an Ajax request, in which case a standard "form submit" would get prevented. Putting a form around it is not obligatory, especially if you use a button element, which is not a classic form element anyway.
I have a simple form in my tmpl/default.php:
<form id='AddForm' action="<?php echo JRoute::_('index.php?option=com_mycomponent&task=addcam'); ?>" >
<p>
<label for="CamName">Name:
</label>
<input type="text" id="CamName" name="cam_name" />
</p>
<button type='submit' class='submit_cam' name='addcam' value='Add'>Add</button>
<button type='reset' class='cancel_changes' name='cancel_changes' value='Cancel'>Cancel</button>
</form>
In my controller.php file I'm trying to process the values:
function addcam()
{
$add_name=JRequest::getString('cam_name');
$model = &$this->getModel();
$model->AddWebcam($add_name); //send to model to add to DB
}
In my model I just return the result of the query. With this implementation I just get routed to an empty page. I'd like to have it refresh the current page. Typically you do this with action="" but in my case I need it to route to the function called addcam in the controller. Or is there a better way to do this?
A common technique in Joomla when directing to the task is to have that function do a full redirect to a view at the end. This prevents a page refresh from trying to resubmit the data and leads to a cleaner url for the client. To do this, try the following:
function addcam()
{
$add_name=JRequest::getString('cam_name');
$model = &$this->getModel();
$model->AddWebcam($add_name); //send to model to add to DB
JFactory::getApplication()->redirect(JRoute::_(index.php?option=com_mycomponent&view=whatever));
}
Obviously, update the JRoute bit to the url you actually need. You can also include a message if you would like (like "Saved!"): http://docs.joomla.org/JApplication::redirect/1.6
I am writing a function that well keep the user in lightbox images while he adds to cart.
When you click any image it well enlarge using lightbox v2, so when the user clicks the Add image, it will refresh the page. When I asked about it at jcart support they told me to use jquery live, but I dont know how to do that. T tried this code but still nothing is happening:
jQuery(function($) {
$('#button')
.livequery(eventType, function(event) {
alert('clicked'); // to check if it works or not
return false;
});
});
I also used
jQuery(function($) {
$('input=[name=addto')
.livequery(eventType, function(event) {
alert('clicked'); // to check if it works or not
return false;
});
});
yet nothing worked.
for code to create those images http://pasite.org/code/572
I also tried:
function adding(form){
$( "form.jcart" ).livequery('submit', function() {var b=$(this).find('input[name=<?php echo $jcart['item_id']?>]').val();var c=$(this).find('input[name=<?php echo $jcart['item_price']?>]').val();var d=$(this).find('input[name=<?php echo $jcart['item_name']?>]').val();var e=$(this).find('input[name=<?php echo $jcart['item_qty']?>]').val();var f=$(this).find('input[name=<?php echo $jcart['item_add']?>]').val();$.post('<?php echo $jcart['path'];?>jcart-relay.php',{"<?php echo $jcart['item_id']?>":b,"<?php echo $jcart['item_price']?>":c,"<?php echo $jcart['item_name']?>":d,"<?php echo $jcart['item_qty']?>":e,"<?php echo $jcart['item_add']?>":f}
});
return false;
}
and it seems to add to jcart but yet it still refreshes
.live() is to assign handlers to future creating elements. On your site, however, you are re-loading the page so .live would have no bearing. (you are submitting a form)
It sounds like you want to make an ajax request to add the item to the cart and update that display on the site? That would be in the submit of the form and if jcart is dynamically created then yes, live is the answer.
$('.jcart').live('submit', function() {
// aggregate form elements into object and send via ajax
// update the cart on the page, since we haven't reloaded the page the light box is still displayed
});
Regarding comment:
When you send an ajax request, jquery takes an object as an argument. Such as $.post('urlToPostTo.php', { title: 'title of whatever', id: 5 } );
The server sees this the same as:
<form id="myForm" action="uroToPostTo.php" method="POST" >
<input type="text" name="title" value="title of whatever" />
<input type="hidden" name="id" value="5" />
<input type="submit" name="submit" value="submit" />
</form>
So if you were to aggregate the form inputs into an object, there's a few ways (even some jquery plugins to help you out). The primitive way would be:
var $form = $('#myForm'); // instead of finding myForm over and over, cache it as a variable to use
var objToSend = {};
objToSend.title = $form.find('input[name=title]').val();
objTosend.id = $form.find('input[name=id]').val();
$.post( 'urlToPostTo.php', objToSend );
A more Elegant solution is to have something loop through all form elements and put them into an object for you. Plugins like http://docs.jquery.com/Plugins:Forms make that a bit easier.
The end result is the form elements are stuffed into an object to send to your script.