Membaca isi file text dan memasukkan ke input box dengan cakePHP dan jQuery
Sebenarnya mau nyari yang AJAX aja tapi dapat yang pake CakePHP. tapi coba dipelajari dulu. ada ide?
Here's how to upload files in CakePHP using jQuery.
First, make sure you download jQuery 1.2.2 or greater plus the jQuery Form plugin. Place them in the
webroot/js
folder and link them in your layout file:
<?=$javascript->link(array('jquery.js','jquery.form.js'));?>
Now, in this example, I have a table named "Stories” in thedatabase. For each Story, I want to make a text upload option availablein the add and edit views. What will happen is that the user willupload a plain-text file, then Cake will place the contents of the fileinto a
<textarea>
field, allowing the user to easily upload a text file but still be able to edit its contents before saving the Story.In the
views/stories
folder, I've created the
edit.ctp
file. You will need to begin the form using the Form helper. Don't forget to specify the type as
file
so that the
<form>
tag contains the necessary
enctype="multipart/form-data"
attribute for the form submission to work correctly.<h1>Edit Story</h1>
<?=$form->create('Story',array('name'=>'storyEditForm','id'=>'storyEditForm','type'=>'file'));?>
You can put whatever input fields you want in the form. I'm just going to include here the actual uploading part:
<div id="storyTextUpload">
<?=$form->input('Story.text', array('label'=>'Current Text ','rows'=>'15','cols'=>'75'));?>
<?=$form->input('upload_text',array('label'=>'Upload Text File ','type'=>'file'));?>
<?=$form->button('Upload Text',array('onClick'=>'$('#storyEditForm').ajaxSubmit({target: '#storyTextUpload',url: ''.$html->url('/stories/text').''}); return false;'));?>
</div>For the Ajax part of the upload, I'll need to tell jQuery where to update the Ajax request. In this case, it's going to be the
<div>
tag with
id="storyTextUpload"
. Notice that the
onClick
event is written in escaped jQuery Form plugin syntax. It's essentially saying to submit the form with
id="storyEditForm"
and make the update target the element with an id of
"storyTextUpload"
. I've linked the Ajax form submission to a controller action I haven't written yet called "text”.
I can now finish the form with whatever else I want.
<?=$form->end('Submit');?>
All I have to do now is create the text action in the Storiescontroller that will handle the upload and then create a view to beused in the final Ajax returned response.
In the Controller
When the file is chosen and the user clicks the "Upload Text” button, jQuery will submit the whole form to the
text
action in the stories controller because of the URL parameter I wrote in the onClick event.So, in the
controllers/stories_controller.php
file, I need to include the following function:function text() {
if (!$this->data['Story']['upload_text']) { //check for uploaded file in $this->data
$this->set('error','You must select a text (.txt) file before you can upload.');
$this->render('text','ajax');
} else {
$file = new File($this->data['Story']['upload_text']['tmp_name']); //the uploaded file sent by jQuery and parsed by Cake
if ($this->data['Story']['upload_text']['type'] != 'text/plain') {
$this->set('error','You may only upload text (.txt) files.');
$this->render('text','ajax');
} else {
$data = h($file->read()); //read file contents and pass through htmlspecialchars function
$file->close();
$this->set('text',$data);
$this->render('text','ajax');
}
}
}Notice that once the action fetches the file contents, it assigns it to a Cake variable named
$text
to be used in the
views/stories/text.ctp
view.
In the View
In the
views/stories/text.ctp
file, I've included the following code:<? if (!empty($error)): ?>
<?=$form->input('Story.text', array('label'=>'Current Text ','rows'=>'15','cols'=>'75'));?>
<?=$form->input('Story.upload_text',array('label'=>'Upload Text File ','type'=>'file'));?>
<?=$form->button('Upload Text',array('onClick'=>'$('#storyEditForm').ajaxSubmit({target: '#storyTextUpload',url: ''.$html->url('/stories/text').''}); return false;'));?>
<p><?=$error;?></p>
<? else: ?>
<?=$form->input('Story.text',array('label'=>'Current Text ','value'=>$text,'rows'=>'15','cols'=>'75'));?>
<p>Upload successful</p>
<?=$form->input('Story.upload_text',array('label'=>'Upload Text File ','type'=>'file'));?>
<?=$form->button('Upload Text',array('onClick'=>'$('#storyEditForm').ajaxSubmit({target: '#storyTextUpload',url: ''.$html->url('/stories/text').''}); return false;'));?>
<? endif; ?>
That's it... Now this handy set of functions will take a file andupload its contents the plop the contents into a text field which willbe saved to the database after the user clicks the Submit button. Ofcourse you will need to create your own edit/add functions but thismuch will get the file uploaded for you.
A File Transfer Method
Actually getting the data was shown above. But say I wanted to putthe file contents not into a form field but do an actual file transferto the server. This is simple. Instead of putting
$data
into a Cake variable, I could make a new file somewhere on the server like so:$file = new File(WWW_ROOT.'/files/'.intval(rand()).'_text_upload.txt');
$file->write($data);
$file->close();
A Note on Ajax Submissions
The reason why I've used jQuery here is that it is the only Ajaxframework I've been able to find that will serialize the form elementsand actually send to the server as a post variable the
<input type="file">
element. Usually, in PHP, the file is accessible in the
$_FILES
variable, but thanks to Cake, I can get the content moved over much more easily by making use of
$this->data
and the File functions, which you have seen me do. To spare you timetrying to get this to work in Prototype (the Ajax framework that theCake Ajax Helper uses), I hope you'll stick with my example here anduse jQuery. Prototype doesn't serialize file inputs.
Maybe someone could build a jQuery set for the Ajax helper :) Until then, hope this helps.