In listing of data form is rendered when any input edited? - laravel-livewire

with livewire 1.3 / alpinejs 2.x.x I make listing of data with filter text
and selection inputs and clicking on “Search” button I need to run search when
“Search” button is clicked.
But search is run when text/selection input lose focus without clicking on “Search” button.
I see it by form's wire:loading block and 1 line in log file, which I trigger in render method
That is not what I need : I need to run render method only clicking on “Search” button.
I tried to use alpinejs, but failed...
In component app/Http/Livewire/Admin/AppNews.php I have:
<?php
namespace App\Http\Livewire\Admin;
use Carbon\Carbon;
use Livewire\Component;
use App\News;
use Livewire\WithPagination;
use Livewire\WithFileUploads;
class AppNews extends Component
{
use WithPagination;
use WithFileUploads;
public $filters = [
'title' => '',
'published' => '',
];
];
public $uploaded_file_name;
public $uploadedImageFilenameData;
public $uploadedNewsImage;
protected $listeners = ['fileUpload' => 'handleFileUpload'];
public $current_news_id;
public $updateMode = 'browse';
public function render()
{
\Log::info('-1 NewsRENDER $this->filters ::' . print_r($this->filters, true));
$news_rows_count = News
::getByTitle($this->filters['title'], true)
->getByPublished($this->filters['published'], true)
->count();
$backend_per_page = Settings::getValue('backend_per_page', CheckValueType::cvtInteger, 20);
$this->emit('app_news_opened', ['mode' => 'browse', 'id' => null]);
$newsPublishedValueArray = SetArrayHeader([['key' => '', 'label' => ' -Select published- ']], News::getNewsPublishedValueArray(true));
$newsDataRows = News
::getByTitle($this->filters['title'], true)
->getByPublished($this->filters['published'], true)
->with('creator')
->orderBy('news.created_at', 'desc')
->paginate($backend_per_page);
$newsDataIds = [];
foreach ($newsDataRows as $nextNews) {
$newsDataIds[] = $nextNews->id;
}
return view('livewire.admin.app-news.container', [
'newsDataRows' => $newsDataRows,
'newsDataIds' => $newsDataIds,
'form' => $this->form,
'news_rows_count' => $news_rows_count,
'newsPublishedValueArray' => $newsPublishedValueArray,
]);
}
and in the template resources/views/livewire/admin/app-news/container.blade.php :
<article class="admin_page_container">
<div class="card form-admin-news">
<div class="card-body card-block">
<div class="spinner-border" role="status" wire:loading>
<span class="sr-only">Loading...</span>
</div>
...
<fieldset class="bordered text-muted p-2 m-2" x-data="{ title: '{{$filters['title']}}', published: '{{$filters['published']}}' ,
publishedItems: <?php print str_replace('"',"'",json_encode( $newsPublishedValueArray) ) ?> } ">
<div> $filters::{{ var_dump($filters) }}</div>
title::<div x-html="title"></div>
published::<div x-html="published"></div>
<legend class="bordered">Filters</legend>
<dl class="block_2columns_md m-0 p-2">
<dt class="key_values_rows_label_13">
<label class="col-form-label" for="temp_filter_title">
By title
</label>
</dt>
<dd class="key_values_rows_value_13" >
<div class="content_with_right_button">
<div
class="content_with_right_button_left_content"
wire:model.lazy="filters.title"
>
<input
class="form-control admin_control_input"
type="text"
x-model="title"
x-on:blur="$dispatch('input', title)"
id="title"
>
</div>
<div class="content_with_right_button_right_button pl-2">
<button class="btn btn-outline-secondary nowrap_block" wire:click="makeSearch( )">
{!! $viewFuncs->showAppIcon('filter') !!}Search
</button>
</div>
</div>
</dd>
</dl>
<dl class="block_2columns_md m-0 p-2">
<dt class="key_values_rows_label_13">
<label class="col-form-label" for="temp_filter_published">
By published
</label>
</dt>
<dd
class="key_values_rows_value_13"
wire:model.lazy="filters.published"
>
<select
x-model="published"
x-on:blur="$dispatch('select', published)"
id="published"
class="form-control editable_field admin_control_input"
>
<template x-for="nextPublishedItem in publishedItems">
<option :value="nextPublishedItem.key" x-text="nextPublishedItem.label"></option>
</template>
</select>
#error('form.published')
<div class="validation_error">{{ clearValidationError($message,['form.'=>'']) }}</div> #enderror
</dd>
</dl>
</fieldset> <!-- Filters -->
...
#endif {{-- #if($updateMode=='browse')--}}
#endif {{-- #if($updateMode=='browse')--}}
#if(count($newsDataRows) > 0)
<div class="table-responsive table-wrapper-for-data-listing" x-data="selectedNewsIdsBoxXData()">
<table>
...
</table>
</div> <!-- <div class="table-responsive table-wrapper-for-data-listing"> -->
#endif {{-- #if(count($newsDataRows) > 0) --}}
#endif {{-- #if($updateMode=='browse') --}}
</div> <!-- <div class="card-body card-block"> -->
</div> <!-- <div class="card"> -->
</article> <!-- page_content_container -->
Which is the valid way?
Modified BLOCK 2:
I try another way with using of alpinejs2 : I try to use it in this case, as when public var of component is changed:
with dispatch methid when button “Search” is clicked
<div class="card form-admin-facilities" x-data="adminFacilitiesComponent()">
...
filter_name: {{$filter_name}}<br>
...
temp_filter_name: <span x-html="temp_filter_name"></span><br>
...
<fieldset class="bordered text-muted p-2 m-2">
<legend class="bordered">Filters</legend>
<div class="content_with_right_button" wire:model.lazy="filter_name">
<div class="content_with_right_button_left_content" >
<input
class="form-control admin_filter_input"
x-model="temp_filter_name"
type="text"
>
</div>
<div class="content_with_right_button_right_button pl-2" >
<button class="btn btn-outline-secondary" #click="$dispatch('input', temp_filter_name)" type="button">Search
</button>
<!-- In more complicated form can be several filter fields : text and select inputs -->
</div>
</div>
</fieldset> <!-- Filters -->
...
<script>
function adminFacilitiesComponent() {
return {
temp_filter_name:'',
and in the component I defined public $filter_name var, which is used in render method :
class Facilities extends Component
{
public $form= [
'name'=>'',
'descr'=> '',
'created_at'=> '',
'is_reopen' => false,
];
public $current_facility_id;
public $filter_name= '';
public $updateMode = 'browse';
public function render()
{
\Log::info( '-1 render Facilities $this->filter_name ::' . print_r( $this->filter_name, true ) );
$this->facility_rows_count = Facility
::getByName($this->filter_name, true)
->count();
$backend_per_page = Settings::getValue('backend_per_page', CheckValueType::cvtInteger, 20);
return view('livewire.admin.facilities.container', [
'facilityDataRows' => Facility
::orderBy('created_at', 'desc')
->getByName($this->filter_name, true)
->paginate($backend_per_page),
'facility_rows_count'=> $this->facility_rows_count
]);
}
But it does not work as I expect : entering value in text input when this input lose focus
form is rendered again. I expected form to be rendered only when I click on “Search” button
and form will be rendered with new entered value. I do not use blur event for text input and
do not understand why the form is rendered when this input lose focus?
Modified BLOCK 3:
Using x-ref= I do :
<div class="content_with_right_button" wire:model.lazy="filter_name">
<div class="content_with_right_button_left_content" >
<input
class="form-control admin_filter_input"
x-model="temp_filter_name"
x-ref="searched"
type="text"
> 1111111
</div>
<div class="content_with_right_button_right_button pl-2" >
<button class="btn btn-outline-secondary nowrap_block" wire:click="makeSearch(this.$refs.searched)" type="button">
Search
</button>
</div>
</div>
But I got error clicking on search button:
VM1983:6 Uncaught TypeError: Cannot read property 'searched' of undefined
at eval (eval at parseOutMethodAndParams (directive.js:55), <anonymous>:6:27)
at _default.parseOutMethodAndParams (directive.js:55)
Looks like it is impossible to use this.$refs. value in
wire:click="makeSearch .
I need to trigger component method
public function makeSearch($search_value='')
{
and send entered value into it.
Looks like the way I tried was invalid.
If there is a valid way?
Thanks!

In your modified block 2, you should use wire:ignore in base div of your AlpineJS component. This will make livewire ignore the component.
<div class="card form-admin-facilities" wire:ignore x-data="adminFacilitiesComponent()">
Your $dispatch() should handle setting the value when you click the button.

In order to make livewire ignore the component just add wire:ignore to your component's div in modified block 2 and then in your dispatch method you can write the logic that happens after clicking the button.

Related

How to Toggle text using Livewire or AlpineJs when according to checkbox status

What I would like to do is:
When the checkbox is checked ---> change text value to "Yes" and store its value to a component variable
When the checkbox is unchecked ---> change text value to "No" and also store its value to a component variable
Below is the example that I excepted to have but this example uses Javascript.
I would like to implement the same behavior using livewire or/and alpinejs.
function myFunction() {
var checkBox = document.getElementById("toogleA");
var text = document.getElementById("text");
if (checkBox.checked == true) {
document.getElementById("text").innerHTML = "YES";
} else {
document.getElementById("text").innerHTML = "NO";
}
}
/* Toggle A */
input:checked~.dot {
transform: translateX(100%);
background-color: #7456e3;
}
/* Toggle B */
input:checked~.dot {
transform: translateX(100%);
background-color: #7456e3;
}
<link href="https://unpkg.com/tailwindcss#^2/dist/tailwind.min.css" rel="stylesheet" />
<!--Start toggle button-->
<div class="flex items-center justify-center w-auto mb-5">
<!-- label -->
<label for="toogleA" class="flex items-center cursor-pointer">
<!-- toggle -->
<div class="relative">
<!-- input -->
<input wire:model="person" id="toogleA" onclick="myFunction()" type="checkbox" name="test" value="person" class="sr-only" />
<!-- line -->
<div class="w-10 h-4 bg-gray-400 rounded-full shadow-inner"></div>
<!-- dot -->
<div class="absolute w-6 h-6 transition bg-white rounded-full shadow dot -left-1 -top-1"></div>
</div>
<div id="text" class="ml-3 font-medium text-gray-700">NON </div>
</div>
</div>
You can achieve this with just Livewire.
Component
class YourComponent extends Component
{
public bool $toggleA = false;
public function render()
{
return view('livewire.your-component');
}
}
Component view
<label for="toggleA">Toggle</label>
<input wire:click="$toggle('toggleA')" type="checkbox" id="toggleA" />
<p>{{ $toggleA ? 'Yes' : 'No' }}</p>
The $toggle function is a special helper in Livewire specifically for toggling the value of boolean properties.

Django 1.9, how to POST multiple select value from html

UPDATE:
I found an answer. Just added this little code at the bottom:
$('#myform').submit(function()
{
$('#dates option').prop('selected', true);
});
I have a tempate:
div class="panel">
<div class="large-12 columns">
<div class="row collapse">
<div class="small-10 columns">
<input class="input-append date fdatepicker" id="date" type="text" name="date" value="" data-date-format="dd/mm/yyyy">
</div>
<div class="small-2 columns">
<input type="button" name="add" id="btn_AddToList" value="dodaj" class="button postfix" />
</div>
</div>
</div>
<br>
<select multiple="multiple" size="10" style="height: auto; width: auto" name="dates" id="dates" tabindex="2">
</select>
</div>
and I add dates to #dates select using this little code:
$('#btn_AddToList').click(function () {
var val = $('#date').val();
$('#dates').append('<option value="'+val+'">' + val + '</option>');
$('#date').val('');
event.preventDefault();
event.stopPropagation();
})
in my view i want to read dates so i thought i would use:
for d in request.POST.getlist('dates'):
if d is not None:
print(d)
But I get None. I tried to use request.POST.getlist('dates[]'): request.POST.get('dates'): but with no success. I am recieving None all the time.
What I am doing wrong?
UPDATE: I found an answer. Just added this little code at the bottom:
$('#myform').submit(function()
{
$('#dates option').prop('selected', true);
});

rails 4 : change state issue with Bootstrap Switch

I have 3 bootstrap switches to handle read/update/create permissions.
They area written as :
<%= f.check_box :allow_read, :data => { :size=>'medium',
'on-color'=>'success', 'on-text'=> "#{t('yes').upcase}",
'off-text'=> "#{t('no').upcase}" } %>
<%= f.check_box :allow_update, :data => { :size=>'medium',
'on-color'=>'success', 'on-text'=> "#{t('yes').upcase}",
'off-text'=> "#{t('no').upcase}" } %>
<%= f.check_box :allow_create, :data => { :size=>'medium',
'on-color'=>'success', 'on-text'=> "#{t('yes').upcase}",
'off-text'=> "#{t('no').upcase}" } %>
and displayed as :
I am trying to use the switchChange.bootstrapSwitch method to change other é switches when one switch is toggled by the user .
When :allow_read is switch OFF , then :allow_update and :allow_create should be switched OFF too...
So I wrote the following js code to handle this case ...
$('input[name="permission[allow_read]"]').on('switchChange.bootstrapSwitch', function(event, state) {
if (event.type == "switchChange" && state == false){
$('input[name="permission[allow_update]"]').bootstrapSwitch('state', false, true); // disallow update
$('input[name="permission[allow_create]"]').bootstrapSwitch('state', false, true); // disallow create
}
});
But it's not working fine ... as it's inserting and OFF text before the switch, however the toggling is performed :
what could be wrong ?
thanks for feedback
--UPDATE ---
forgot to add the generated HTML...
<div class="col-sm-9">
<input name="permission[allow_read]" type="hidden" value="0">
<div class="bootstrap-switch bootstrap-switch-wrapper bootstrap-switch-on bootstrap-switch-medium bootstrap-switch-animate bootstrap-switch-id-permission_allow_read">
<div class="bootstrap-switch-container">
<span class="bootstrap-switch-handle-on bootstrap-switch-success">OUI</span>
<label class="bootstrap-switch-label"> </label>
<span class="bootstrap-switch-handle-off bootstrap-switch-default">NON</span>
<input type="checkbox" value="1" checked="checked" name="permission[allow_read]" id="permission_allow_read">
</div>
</div>
</div>
I guess there is something wrong with html generated by the Rails view helper and Bootstrap switch...
back to a standard html tag , it works correctly
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<p class='col-sm-3 control-label' >READ</p>
<div class="col-sm-9">
<input id="allow_read" name="permission[allow_read]" type="checkbox" value="1" data-size ='medium', data-on-color ='success' data-on-text = "YES" data-off-text = "NO" />
</div>
</div>
</div>
</div>
and similar switches for update and create.... the js script runs very well...

Ajax, Django, Jquery Model Form

Built a successful working ModelForm and its fully functional.
My next step was to add Ajax to it and it also worked out pretty well. The Jquery that I used was 1.3.2 version which is pretty old but it worked.
The problem came up when I tried to add bootstrap 2 DATE fields.
Using CHECKIN & CHECKOUT values that I have added to my form and it worked.
It required higher version of jquery so I used the recent one 1.9.1.
But when I used it my form is working except 1 little issues when I submit the form
and there not filled out required fields it will show me those fields but SUBMIT button is
disabled. When I use jquery 1.3.2 all is working 100% except the 2 fields for Bootstrap
DATEPICKER that requires higher jquery version.
Input Fields in the Form: Departure & Return are Date Picker Fields
I didnt include the Bootstrap Scripts they are same from the Bootsrap site.
When I use:
<script src="/media/js/jquery/1.9.1.jquery.min.js" type="text/javascript"></script>
Departure & Return are Date Picker Fields are Working but after submitting it with empty
other fields - it will show you which fields are required but Submit button is disabled.
If I use:
<script src="/media/js/jquery/1.3.2.jquery.min.js" type="text/javascript"></script>
Form is working with ajax 100% but I cant use Departure & Return are Date Picker Fields
(which give me choice to select date - I have to manually type it).
For reference I used this tutorial.
Look at the Category ModelForm Ajax
My question is I can I achieve this form to be working on 1.9.1 Jquery Version with also Date
picker Fields that I can choosed from the calendar.
At the bottom I am including screenshots.
Here is the code:
MODELS.PY
TRIP_TYPES = (
('one way', 'One Way'),
('round trip', 'Round Trip'),
('multi-leg', 'Multi-Leg'),
)
class Request_Quote(models.Model):
trip_type = models.CharField(max_length=10, choices=TRIP_TYPES, default='one way')
company_name = models.CharField(max_length=200)
individual_name = models.CharField(max_length=200)
phone = models.CharField(max_length=200)
email = models.CharField(max_length=200)
from_country = models.CharField(max_length=200)
to_country = models.CharField(max_length=200)
from_city = models.CharField(max_length=200)
to_city = models.CharField(max_length=200)
departure_date = models.CharField(max_length=200)
return_date = models.CharField(max_length=200)
number_of_passengers = models.CharField(max_length=200)
VIEWS.PY
def quote(request):
if request.method == "POST":
form = Request_QuoteForm(request.POST)
## Handle AJAX ##
if request.is_ajax():
if form.is_valid():
form.save()
# Get a list of Categories to return
quotes = Request_Quote.objects.all().order_by('individual_name')
# Create a dictionary for our response data
data = {
'error': False,
'message': 'Request Quote Added Successfully',
# Pass a list of the 'name' attribute from each Category.
# Django model instances are not serializable
'quotes': [q.individual_name for q in quotes],
}
else:
# Form was not valid, get the errors from the form and
# create a dictionary for our error response.
data = {
'error': True,
'message': "Please try again!",
'trip_type_error': str(form.errors.get('trip_type', '')),
'company_name_error': str(form.errors.get('company_name', '')),
'individual_name_error': str(form.errors.get('individual_name', '')),
'phone_error': str(form.errors.get('phone', '')),
'email_error': str(form.errors.get('email', '')),
'from_country_error': str(form.errors.get('from_country', '')),
'to_country_error': str(form.errors.get('to_country', '')),
'from_city_error': str(form.errors.get('from_city', '')),
'to_city_error': str(form.errors.get('to_city', '')),
'departure_date_error': str(form.errors.get('departure_date', '')),
'return_date_error': str(form.errors.get('return_date', '')),
'number_of_passengers_error': str(form.errors.get('number_of_passengers', '')),
}
# encode the data as a json object and return it
return http.HttpResponse(json.dumps(data))
if form.is_valid():
form.save()
return http.HttpResponseRedirect('/request-quote/')
else:
form = Request_QuoteForm()
quotes = Request_Quote.objects.all().order_by('individual_name')
return render_to_response('quote.html', {'title': 'Request Quote', 'form': form, 'quotes': quotes}, context_instance=RequestContext(request))
TEMPLATES:
<script type="text/javascript">
// prepare the form when the DOM is ready
$(document).ready(function() {
$("#add_cat").ajaxStart(function() {
// Remove any errors/messages and fade the form.
$(".form_row").removeClass('errors');
$(".form_row_errors").html('');
$("#add_cat").fadeTo('slow', 0.33);
$("#add_cat_btn").attr('disabled', 'disabled');
$("#message").addClass('hide');
});
// Submit the form with ajax.
$("#add_cat").submit(function(){
$.post(
// Grab the action url from the form.
"#add_cat.getAttribute('action')",
// Serialize the form data to send.
$("#add_cat").serialize(),
// Callback function to handle the response from view.
function(resp, testStatus) {
if (resp.error) {
// check for field errors
if (resp.trip_type_error != '') {
$("#trip_type_row").addClass('errors');
$("#trip_type_errors").html(resp.trip_type_error);
}
if (resp.company_name_error != '') {
$("#company_name_row").addClass('errors');
$("#company_name_errors").html(resp.company_name_error);
}
if (resp.individual_name_error != '') {
$("#individual_name_row").addClass('errors');
$("#individual_name_errors").html(resp.individual_name_error);
}
if (resp.phone_error != '') {
$("#phone_row").addClass('errors');
$("#phone_errors").html(resp.phone_error);
}
if (resp.email_error != '') {
$("#email_row").addClass('errors');
$("#email_errors").html(resp.email_error);
}
if (resp.from_country_error != '') {
$("#from_country_row").addClass('errors');
$("#from_country_errors").html(resp.from_country_error);
}
if (resp.to_country_error != '') {
$("#to_country_row").addClass('errors');
$("#to_country_errors").html(resp.to_country_error);
}
if (resp.from_city_error != '') {
$("#from_city_row").addClass('errors');
$("#from_city_errors").html(resp.from_city_error);
}
if (resp.to_city_error != '') {
$("#to_city_row").addClass('errors');
$("#to_city_errors").html(resp.to_city_error);
}
if (resp.departure_date_error != '') {
$("#departure_date_row").addClass('errors');
$("#departure_date_errors").html(resp.departure_date_error);
}
if (resp.return_date_error != '') {
$("#return_date_row").addClass('errors');
$("#return_date_errors").html(resp.return_date_error);
}
if (resp.number_of_passengers_error != '') {
$("#number_of_passengers_row").addClass('errors');
$("#number_of_passengers_errors").html(resp.number_of_passengers_error);
}
$("#add_cat").fadeTo('slow', 1);
$("#add_cat_btn").attr('disabled', false);
} else {
// No errors. Rewrite the category list.
$("#categories").fadeTo('fast', 0);
var text = new String();
for(i=0; i<resp.quotes.length ;i++){
var m = resp.quotes[i]
text += "<li>" + m + "</li>"
}
$("#categories").html(text);
$("#categories").fadeTo('slow', 1);
$("#id_trip_type").attr('value', '');
$("#id_company_name").attr('value', '');
$("#id_individual_name").attr('value', '');
$("#id_phone").attr('value', '');
$("#id_email").attr('value', '');
$("#id_from_country").attr('value', '');
$("#id_to_country").attr('value', '');
$("#id_from_city").attr('value', '');
$("#id_to_city").attr('value', '');
$("#id_departure_date").attr('value', '');
$("#id_return_date").attr('value', '');
$("#id_number_of_passengers").attr('value', '');
}
// Always show the message and re-enable the form.
$("#message").html(resp.message);
$("#message").removeClass('hide');
$("#add_cat").fadeTo('slow', 1);
$("#add_cat_btn").attr('disabled', '');
// Set the Return data type to "json".
}, "json");
return false;
});
});
</script>
<div id="content" class="span9" style="">
<h1>Request Quote</h1>
<div id='message'></div>
<form id='add_cat' method='post' action='.'><input type='hidden' name='csrfmiddlewaretoken' value='KblPqgczzMK7skak162xe4aOL6bLot2A' />
<div class='form_row' id='trip_type_row'>
<div class="span2">
<label for="id_trip_type">Trip type</label>
</div>
<div class="span4">
<select id="id_trip_type" name="trip_type">
<option value="one way" selected="selected">One Way</option>
<option value="round trip">Round Trip</option>
<option value="multi-leg">Multi-Leg</option>
</select>
</div>
<div class="span6">
<p id='trip_type_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='company_name_row'>
<div class="span2">
<label for="id_company_name">Company name</label>
</div>
<div class="span4">
<input id="id_company_name" maxlength="200" name="company_name" type="text" />
</div>
<div class="span6">
<p id='company_name_errors' class="form_row_errors" style="color: red;"></p>
</div>
</div>
<div class='form_row' id='individual_name_row'>
<div class="span2">
<label for="id_individual_name">Individual name</label>
</div>
<div class="span4">
<input id="id_individual_name" maxlength="200" name="individual_name" type="text" />
</div>
<div class="span6">
<p id='individual_name_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='phone_row'>
<div class="span2">
<label for="id_phone">Phone</label>
</div>
<div class="span4">
<input id="id_phone" maxlength="200" name="phone" type="text" />
</div>
<div class="span6">
<p id='phone_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='email_row'>
<div class="span2">
<label for="id_email">Email</label>
</div>
<div class="span4">
<input id="id_email" maxlength="200" name="email" type="text" />
</div>
<div class="span6">
<p id='email_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='from_country_row'>
<div class="span2">
<label for="id_from_country">From country</label>
</div>
<div class="span4">
<input id="id_from_country" maxlength="200" name="from_country" type="text" />
</div>
<div class="span6">
<p id='from_country_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='to_country_row'>
<div class="span2">
<label for="id_to_country">To country</label>
</div>
<div class="span4">
<input id="id_to_country" maxlength="200" name="to_country" type="text" />
</div>
<div class="span6">
<p id='to_country_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='from_city_row'>
<div class="span2">
<label for="id_from_city">From city</label>
</div>
<div class="span4">
<input id="id_from_city" maxlength="200" name="from_city" type="text" />
</div>
<div class="span6">
<p id='from_city_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='to_city_row'>
<div class="span2">
<label for="id_to_city">To city</label>
</div>
<div class="span4">
<input id="id_to_city" maxlength="200" name="to_city" type="text" />
</div>
<div class="span6">
<p id='to_city_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='departure_date_row'>
<div class="span2">
<label for="id_departure_date">Departure date</label>
</div>
<div class="span4">
<input id="id_departure_date" maxlength="200" name="departure_date" type="text" />
</div>
<div class="span6">
<p id='departure_date_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='return_date_row'>
<div class="span2">
<label for="id_return_date">Return date</label>
</div>
<div class="span4">
<input id="id_return_date" maxlength="200" name="return_date" type="text" />
</div>
<div class="span6">
<p id='return_date_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='number_of_passengers_row'>
<div class="span2">
<label for="id_number_of_passengers">Number of passengers</label>
</div>
<div class="span4">
<input id="id_number_of_passengers" maxlength="200" name="number_of_passengers" type="text" />
</div>
<div class="span6">
<p id='number_of_passengers_errors' class="form_row_errors"></p>
</div>
</div>
<input id="add_cat_btn" type='submit' value="save">
</form>
</div><!-- End content -->
Screenshots:
These are images with not functional after Submission Form Submit button but Date Picker
Fields are working becasue Jquery 1.9.1 was used:
Screen 1:
Screen 2:
This is an image with not functional Date Picker because Jquery 1.3.2 was used and Submit
Button is enabled after submision:
Thanks for help.
I managed to solve the problem, the problem was with the newest jquery using different variables. Updated the code above with the answer.
Here is the code:
TEMPLATES:
<script type="text/javascript">
// prepare the form when the DOM is ready
$(document).ready(function() {
$("#add_cat").ajaxStart(function() {
// Remove any errors/messages and fade the form.
$(".form_row").removeClass("errors");
$(".form_row_errors").html('');
$("#add_cat").fadeTo('slow', 0.33);
$("#add_cat_btn").attr("disabled", "disabled");
$("#message").addClass('hide');
});
// Submit the form with ajax.
$("#add_cat").submit(function(){
$.post(
// Grab the action url from the form.
"#add_cat.getAttribute('action')",
// Serialize the form data to send.
$("#add_cat").serialize(),
// Callback function to handle the response from view.
function(resp, testStatus) {
$(".form_row").removeClass("errors");
$("#trip_type_errors").html("");
$("#company_name_errors").html("");
$("#individual_name_errors").html("");
$("#phone_errors").html("");
$("#email_errors").html("");
$("#from_country_errors").html("");
$("#to_country_errors").html("");
$("#from_city_errors").html("");
$("#to_city_errors").html("");
$("#departure_date_errors").html("");
$("#return_date_errors").html("");
$("#number_of_passengers_errors").html("");
if (resp.error) {
// check for field errors
if (resp.trip_type_error != '') {
$("#trip_type_row").addClass('errors');
$("#trip_type_errors").html(resp.trip_type_error);
}
if (resp.company_name_error != '') {
$("#company_name_row").addClass('errors');
$("#company_name_errors").html(resp.company_name_error);
}
if (resp.individual_name_error != '') {
$("#individual_name_row").addClass('errors');
$("#individual_name_errors").html(resp.individual_name_error);
}
if (resp.phone_error != '') {
$("#phone_row").addClass('errors');
$("#phone_errors").html(resp.phone_error);
}
if (resp.email_error != '') {
$("#email_row").addClass('errors');
$("#email_errors").html(resp.email_error);
}
if (resp.from_country_error != '') {
$("#from_country_row").addClass('errors');
$("#from_country_errors").html(resp.from_country_error);
}
if (resp.to_country_error != '') {
$("#to_country_row").addClass('errors');
$("#to_country_errors").html(resp.to_country_error);
}
if (resp.from_city_error != '') {
$("#from_city_row").addClass('errors');
$("#from_city_errors").html(resp.from_city_error);
}
if (resp.to_city_error != '') {
$("#to_city_row").addClass('errors');
$("#to_city_errors").html(resp.to_city_error);
}
if (resp.departure_date_error != '') {
$("#departure_date_row").addClass('errors');
$("#departure_date_errors").html(resp.departure_date_error);
}
if (resp.return_date_error != '') {
$("#return_date_row").addClass('errors');
$("#return_date_errors").html(resp.return_date_error);
}
if (resp.number_of_passengers_error != '') {
$("#number_of_passengers_row").addClass('errors');
$("#number_of_passengers_errors").html(resp.number_of_passengers_error);
}
} else {
// No errors. Rewrite the category list.
$("#categories").fadeTo('fast', 0);
var text = new String();
for(i=0; i<resp.quotes.length ;i++){
var m = resp.quotes[i]
text += "<li>" + m + "</li>"
}
$("#categories").html(text);
$("#categories").fadeTo('slow', 1);
$("#id_trip_type").val("");
$("#id_company_name").val("");
$("#id_individual_name").val("");
$("#id_phone").val("");
$("#id_email").val("");
$("#id_from_country").val("");
$("#id_to_country").val("");
$("#id_from_city").val("");
$("#id_to_city").val("");
$("#id_departure_date").val("");
$("#id_return_date").val("");
$("#id_number_of_passengers").val("");
}
// Always show the message and re-enable the form.
$("#message").html(resp.message);
$("#message").removeClass('hide');
$("#add_cat").fadeTo('slow', 1);
$("#add_cat_btn").removeAttr("disabled");//attr('disabled', '');
// Set the Return data type to "json".
}, "json");
return false;
});
});
</script>

knockout.js - modify DOM in current item in list (expand list item subsection) using templates

In this example I want to use knockout.js to allow the "Expand" link to be clicked and have its text changed to "Collapse". I also want to set the make the jobDetails section visible. This is a very general question of how to get knockout.js to specifically modify the DOM of the "current" item in a list using a click handler.
<script type="text/html" id="job-template">
<div class="jobContainer">
<label data-bind="text: JobTitle"></label>
<label data-bind="text: CompanyName"></label>
<div class="jobDetails">
<label data-bind="text: City"></label>
<label data-bind="text: State"></label>
</di>
<div>
<a class="expand" href="#" data-bind="click: ???">Expand</a>
</div>
</div>
</script>
This is very straight forward with KO. Here's a simple way to do it. FYI I had to fix your markup slightly.
<div>
<div class="jobContainer">
<label data-bind="text: JobTitle"></label>
<label data-bind="text: CompanyName"></label>
<div class="jobDetails" data-bind="visible: expanded">
<label data-bind="text: City"></label>
<label data-bind="text: State"></label>
</div>
<div>
<a class="expand" href="#" data-bind="click: toggle, text: linkLabel">Expand</a>
</div>
var viewModel = function() {
this.JobTitle = ko.observable("some job");
this.CompanyName = ko.observable("some company");
this.City = ko.observable("some city");
this.State = ko.observable("some state");
this.someValue = ko.observable().extend({ defaultIfNull: "some default" });
this.expanded = ko.observable(false);
this.linkLabel = ko.computed(function () {
return this.expanded() ? "collapse" : "expand";
}, this);
this.toggle = function () {
this.expanded(!this.expanded());
};
};
http://jsfiddle.net/madcapnmckay/XAzW6/
Hope this helps.