AJAX update div without creating partial - ajax

I have some page:
title = "page"
url = "/page"
layout = "default"
==
function onTest()
{
$this['result'] = 'Test string';
}
==
<!-- AJAX enabled form -->
<form data-request="onTest" data-request-update="mypartial: '#myDiv'"></form>
<!-- Result container -->
<div id="myDiv"></div>
After submitting the form I can get 'result' variable only in partial 'mypartial', where code is: Here is {{ result }}. And this code inserts into #myDiv.
How can I get 'result' variable without creating partial? Why should I create .htm file (partial) for each little AJAX query?

I guess you can easily update your div with id myDiv from server side.
You just need to push markup with proper id #myDiv it will update that Html Element with given ID automatically. [ we do not need to ask for partial or need partial ]
title = "page"
url = "/page"
layout = "default"
==
<?php
function onTest()
{
$result = 'Test string';
return ['#myDiv' => 'New Result: ' . $result];
}
?>
==
<!-- AJAX enabled form -->
<form data-request="onTest">
<button type="submit">Submit Fire Ajax</button>
</form>
<!-- Result container -->
<div id="myDiv">old result</div>
After successful Ajax request markup for myDiv will be
<div id="myDiv">New Result: Test string</div>
Good thing is you do not need to write javascript to update myDiv as part of October Ajax framework it will automatically search #myDiv and update its markup.
When you return an Array for an Ajax api of October Cms
return ['#myDiv' => 'Hello'];
At client side it will automatically search element with id myDiv and if it found it, It will update it with given markup on successful Ajax request, for this example its Hello
If any doubt please comment.

Related

Using data on dispatched event and trigger div

I have a component that dispatches a browser event with an object
// Livewire Component Method
public function passToDashboard($dataId)
{
$data = Model::find($dataId);
$this->dispatchBrowserEvent('show-data', ['data' => $data]);
}
Now on my dashboard blade view i've got
<div class="some-classes" x-data="{dataDisplay:false}">
<div x-show="dataDisplay">
{{-- This is where i want to use the object --}}
{{ $data->title }}
</div>
</div>
<script>
window.addEventListener('show-data', data => {
console.log(data.detail.title); // outputs title just fine
})
</script>
The question is, how to 'unhide' the dataDisplay and how to show it with the passed data? Thanks!
You can listen for these events directly on the element using #event-name.window="dataDisplay = true"
To get the event data, you use the $event variable and it should be under $event.detail.data.title
Use x-text to get the text onto the element. See my full example below.
So in your case:
<div class="some-classes" x-data="{dataDisplay:false, title: ''}" #event-data.window="dataDisplay = true; title = $event.detail.data.title">
<div x-show="dataDisplay">
<h3 x-text="title"></h3>
</div>
</div>
The documentation for this can be found here: https://laravel-livewire.com/docs/2.x/events#browser
Do notice I changed the event name, because it does apparently not work if you start the event name with "show". When I changed to "event-data" or anything else it started working again.

Infinite Scroll on ajax loaded content

I'm doing a WP_Query on let's say page-a.php, that page has a div called target where page-b.php is being loaded into. Page-a is a custom template and page-b is an archive page.
The structure on page A as example:
<body>
<div id="wrap">
<div class="target">
while
<div class="post">
<h1>Title</h1>
<p>Description</p>
</div>
endwhile
<div class="pagination"></div>
</div>
</div>
</body>
On page-b I only include the < post > and < pagination > divs within a regular wp loop.
Now the jQuery:
$(window).load(function() {
$('.target').infinitescroll({
navSelector : ".navigation",
// selector for the paged navigation (it will be hidden)
nextSelector : ".navigation a.next",
// selector for the NEXT link (to page 2)
itemSelector : ".post",
// selector for all items you'll retrieve
debug : true,
loading: {
finishedMsg: '<div class="alert alert-info" style="margin-top:50px"><p class="center">All posts were loaded</p></div>',
img: '',
msg: null,
msgText: "<p style='text-align:center; margin-top:50px;'><i style='font-size:60px; color:#babfc8'class='fa fa-cog fa-spin'></i></p>"
}
}, function(arrayOfNewElems){
$('.post').animate({"opacity":"1","max-height":"150px","padding":"15px 8px"},800, "jswing");
}
);
});
-If I call that script on page-a.php will only work on it, once page-b content is placed on
-If I call on page-a.php and page-b.php it works on first, then when first ajax content is loaded and then (if I apply a new filter) it won't work.
-If I call the script on my ajax response function it will work once, then if I apply another filter and target div refreshes content, I get the
Uncaught TypeError: Cannot call method 'appendTo' of null
div classes called (.target and .post) are present on the page.
What the hell am I doing wrong here. Thanks.
PS: If you need to take a look at the real scripts let me know and I will provide.
I think you need this : http://www.247techblog.com/implement-infinite-scroll-functionality-wordpress-wp-ajax-function/
Just need to call a wp ajax function

laravel 4 how to show result at the same page and how to solve circle invoke

I am totally new to laravel, I am now want to use laravel 4.
Suppose I have a page A.php, and it contains a form & a submit button. After I submit the post request to B.php, and in B.php I query data from database.
My question is I want to show my result on B.php , that it is to say the same page of A.php request, how do I write in routes.php.
My code:
master.blade.php
<!DOCTYPE HTML>
<html>
<head>
<metacharset="UTF-8">
<title>course query</title>
</head>
<body>
<div class="container">
#yield('container')
</div>
<h1 class="ret">The result is:
#yield('ret')
<input id="result" type="text"/>
</h1>
</body>
</html>
A.php
#extends('course.master')
#section('container')
<h1>My Courses</h1>
{{Form::open(array('url' => 'csOp'))}}
{{Form::label('course', 'Your course')}}
{{Form::text('course')}}
{{Form::submit('Submit')}}
{{Form::close()}}
#endsection
routes.php
Route::get('course', function(){
return View::make('course.B');
});
Route::post('csOp', function(){
// do something
//$inputCourse = Input::get('course');
//$records = Courses::where('name', '=', $inputCourse)->get();
// how do I return
//return View::make('csOp', $records);
});
As you can see, in A.php I have a form and request to csOp
Form::open(array('url' => 'csOp')
csOp is B.php, and in B.php I query data from db, and now I got the results,
but how can I put result to the page (B.php) itself? That it is to say I want to put the result to
<input id="result" type="text"/>
You know in jquery is easy, how do I use it in laravel 4 ?
And if return to csOp, absolutlly will get an error, it is in a circle. So how can I solve it ?
Thanks very much.
If you want to populate a form based on model contents, i,e. populate form using database data.
So in laravel you can use Form Model Binding. To do so, use the Form::model method. so in your case
Route::post('csOp', function(){
// do something
$inputCourse = Input::get('course');
$records = Courses::where('name', '=', $inputCourse)->get();
// how do I return
return View::make('csOp')->with('records',$records);
});
And your csOp.blade.php
#extends('course.master')
#section('container')
<h1>My Courses</h1>
{{Form::model($records,array('url' => 'csOp'))}}
{{Form::label('course', 'Your course')}}
{{Form::text('course')}}
{{Form::close()}}
#endsection
Now, when you generate a form element, like a text input, the model's value matching the field's name will automatically be set as the field value. So, for example, for a text input named course, the Courses model's course attribute would be set as the value.

Yii ClientSide Validation on Render Partial not Working

I have a Yii form which calls a render partial from another model (team has_many team_members). I want to call via ajax a partial view to add members in team/_form. All works (call, show, save) except for ajax validations (server and client side). If i submit form, member's model isn't validating, even in client side, it's not validating the required fields.
Any clue?
//_form
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'team-form',
'enableAjaxValidation'=>true,
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
'validateOnChange'=>true
),
'htmlOptions' => array('enctype' => 'multipart/form-data'),
)); ?>
//Controller
public function actionMember($index)
{
$model = new TeamMember();
$this->renderPartial('_member',array(
'model'=> $model, 'index'=> $index
)
,false,true
);
}
public function actionCreate()
{
$model=new Team;
$members = array();
if(isset($_POST['Team']))
{
$model->attributes=$_POST['Team'];
if(!empty($_POST['TeamMember'])){
foreach($_POST['TeamMember'] as $team_member)
{
$mem = new TeamMember();
$mem->setAttribute($team_member);
if($mem->validate(array('name'))) $members[]=$mem;
}
}
$this->redirect(array('team/create','id'=>$model->id,'#'=>'submit-message'));
}
$members[]=new TeamMember;
$this->performAjaxMemberValidation($members);
$this->render('create',array(
'model'=>$model,'members'=>$members
));
}
//_member
<div class="row-member<?php echo $index; ?>">
<h3>Member <?php echo $index+1; ?></h3>
<div class="row">
<?php echo CHtml::activeLabel($model, "[$index]name",array('class'=>'member')); ?>
<?php echo CHtml::activeTextField($model, "[$index]name",array('class'=>'member')); ?>
<?php echo CHtml::error($model, "[$index]name");?>
</div>
</div>
ProcessOutput was set to true. No dice.
Switch renderPartial() to render(). No dice.
If you will look at the CActiveForm::run:
$cs->registerCoreScript('yiiactiveform');
//...
$cs->registerScript(__CLASS__.'#'.$id,"jQuery('#$id').yiiactiveform($options);");
Then you will understand that you validation will not work, because you render partial and not the whole page. And these scripts show up at the bottom of the page. So you should solve this by execute these scripts.
After you partial is rendered, try to get activeform script which should be stored at the scipts array:
$this->renderPartial('_member',array('model'=> $model, 'index'=> $index));
$script = Yii::app()->clientScript->scripts[CClientScript::POS_READY]['CActiveForm#team-form'];
after, send it with rendered html to page:
echo "<script type='text/javascript'>$script</script>"
Also remember before you will append recieved html on the page you should include jquery.yiiactiveform.js, if you not already did it(by render another form, or registerCoreScript('yiiactiveform')), on the page from calling ajax request. Otherwise javascript error will raised.
Hope this will help.
Edit:
Sorry I'm not understood that you are render part of form and not the whole. But you validation will not work exactly with the same issue. Because jQuery('#$id').yiiactiveform($options); script was not created for the field.
The actual problem is that the ActiveForm saves its attributes to be validated in the "settings" data attribute. I see you are already using indexes so what you need to add the new elements to this settings object in order for the validation to work. After the ajax response this is what must be done:
//Get the settings object from the form
var settings = $("#form").data('settings');
//Get all the newly inserted elements via jquery
$("[name^='YourModel']", data).each(function(k, v) {
//base attribute skeleton
var base = {
model : 'YourModel',
enableAjaxValidation : true,
errorCssClass : 'error',
status : 1,
hideErrorMessage : false,
};
var newRow = $.extend({
id : $(v).attr('id'),
inputID : $(v).attr('id'),
errorID : $(v).attr('id') + '_em_',
name : $(v).attr('name'),
}, base);
//push it to the settings.attribute object
settings.attributes.push(newRow);
});
//update the form
$("#form").data('settings', settings);
```
This way the ActiveForm will be aware of the new fields and will validate them.
Well, setting processOutput to true in renderPartial (in order to make client validation works on newly added fields) will not help in this case since it will only work for CActiveForm form and you don't have any form in your _member view (only input fields).
A simple way to deal with this kind of problem could be to use only ajax validation, and use CActiveForm::validateTabular() in your controller to validate your team members.

How to update a label from a postback in MVC3/Razor

MVC/Razor/Javascript newbie question:
I have a MVC3/Razor form where the use can select a single product from a drop down list.
<div class="editor-label">
Product
</div>
<div class="editor-field">
#Html.DropDownList("ProductID", (IEnumerable<SelectListItem>)ViewBag.Products, "--Select One--")
#Html.ValidationMessageFor(model => model.ProductID)
</div>
What I then want is to display the price of the selected product on a label just below the drop down list (model property name is Amount).
This should be pretty easy, but I am pretty new at Razor, and know almost nothing about Javascript, so I would appreciate any verbose explanations of how do do it, and how it all hangs together.
Add a div/span under the Dropdown .
#Html.DropDownList("ProductID", (IEnumerable<SelectListItem>)ViewBag.Products, "--Select One--")
<div id="itemPrice"></div>
and in your Script, make an ajax call to one of your controller action where you return the price.
$(function(){
$("#ProductId").change(function(){
var val=$(this).val();
$("#itemPrice").load("#Url.Action("GetPrice","Product")", { itemId : val });
});
});
and have a controller action like this in your Product controller
public string GetPrice(int itemId)
{
decimal itemPrice=0.0M;
//using the Id, get the price of the product from your data layer and set that to itemPrice variable.
return itemPrice.ToString();
}
That is it ! Make sure you have jQuery loaded in your page and this will work fine.
EDIT : Include this line in your page to load jQuery library ( If it is not already loaded),
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
The Amount isn't available to your view when the user selects a product (remember the page is rendered on the server, but actually executes on the client; your model isn't available in the page on the client-side). So you would either have to render in a JavaScript array that contains a lookup of the amount based on the product which gets passed down to the client (so it's available via client-side JavaScript), or you would have to make a callback to the server to retrieve this information.
I would use jQuery to do this.
Here's a simple example of what the jQuery/Javascript code might look like if you used an array.
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
$(document).ready(function() {
// This code can easily be built up server side as a string, then
// embedded here using #Html.Raw(Model.NameOfPropertyWithString)
var list = new Array();
list[0] = "";
list[1] = "$1.00";
list[2] = "$1.25";
$("#ProductID").change(displayAmount).keypress(displayAmount);
function displayAmount() {
var amount = list[($(this).prop('selectedIndex'))];
$("#amount").html(amount);
}
});
</script>
<select id="ProductID" name="ProductID">
<option value="" selected>-- Select --</option>
<option value="1">First</option>
<option value="2">Second</option>
</select>
<div id="amount"></div>
You'll want to spend some time looking at the docs for jQuery. You'll end up using it quite a bit. The code basically "selects" the dropdown and attaches handlers to the change and keypress events. When they fire, it calls the displayAmount function. displayAmount() retrieves the selected index, then grabs the value out of the list. Finally it sets the HTML to the amount retrieved.
Instead of the local array, you could call your controller. You would create an action (method) on your controller that returned the value as a JsonResult. You would do a callback using jquery.ajax(). Do some searching here and the jQuery site, I'm sure you'll find a ton of examples on how to do this.

Resources