Edit API Dropdown - forms

I populated the country list in my select option and when I click on country in user menu data save successfully and afterward while updating the user field the country name is not showing/or the old list from api loads this happens in laravel 08
Code to populate select option
document.addEventListener('DOMContentLoaded', () => {
const selectDrop = document.querySelector('#countries');
// const selectDrop = document.getElementById('countries');
fetch('https://restcountries.com/v3.1/all').then(res => {
return res.json();
}).then(data => {
let output = "";
data.forEach(country => {
console.log(country.name.common)
output += `<option value="${country.name.common}">${country.name.common}</option>`;
})
selectDrop.innerHTML = output;
}).catch(err => {
console.log(err);
})
});
here is my controller
public function update(Request $request){
try{
$user= User::data_update($request);
return view ('profile_edit', ['user'=>$user]);
}catch (\Exception $exception){
return $exception;
}
}
here is my model
public static function data_update($user1)
{
$user = self::user_data();
$user->name = $user1['name'];
$user->email = $user1['email'];
$user->phone = $user1['phone'];
$user->gender = $user1['gender'];
$user->country = $user1['country'];
$status = $user->save();
return $user;
}
here is my blade
<div class="col-sm-9 text-secondary">
<select id="countries" name="country">
<option value="{{$user->country}}" selected ></option>
</select>
</div>

Related

In angular, when a page is opened in edit mode using query params, value in dropdown is not coming in mat select

customer_name is not displayed in dropdown.
In .ts file, in ngOnInit() I have used query params to open a page in edit mode.
ngOnInit(): void {
this.addInvoiceItem();
this.route.queryParams.subscribe((params) => {
if (params._id === undefined) {
this.isEdit = true;
console.log(this.isEdit);
} else {
this._id = params._id;
this.service.fetchInvoiceById(this._id).subscribe((data) => {
this.invoice = data;
console.log(this.invoice.customer_details);
this.customerService
.fetchCustomerById(this.invoice.customer_details)
.subscribe((data) => {
this.invoice.customer_details = data;
console.log(this.invoice.customer_details);
});
});
}
this.customerService.fetchAllCustomers().subscribe((data) => {
this.custList = data;
console.table(this.custList);
});
this.availService.fetchAllCustomers().subscribe((data) => {
this.servicesList = data;
console.table(this.servicesList);
});
});
}
In console.log(this.invoice.customer_details) I can see customer_name in debug. But in display customer_name is not coming.
In html file,
<mat-select
name="customer_details"
[(ngModel)]="invoice.customer_details"
#customer_details="ngModel"
(selectionChange)="updateAddress()"
required
[displayWith]="displayCustomer"
>
<mat-option
*ngFor="let cust of custList"
[value]="cust"
required
>
{{ cust.customer_name }}
</mat-option>
</mat-select>

L.DomUtil.get() modifiers don't update HTML data

Creating a map with markers displayed on it. When clicking a marker, this one has to display a Popup. I extended the L.Popup like this
L.InfrastructurePopup = L.Popup.extend({
options: {
template : "<form id='popup-form'>\
<div>\
<label for='problem'>Problem</label>\
<textarea id='problem' rows='4' cols='46' placeholder='Type your text here'></textarea>\
</div>\
<div>\
<label for='solution'>Solution</label>\
<textarea id='solution' rows='4' cols='46' placeholder='Type your text here'></textarea>\
</div>\
<button id='button-submit' class='btn btn-primary' type='button'>Submit</button>\
</form>",
},
setContent: function () {
this._content = this.options.template;
this.update();
return this;
},
initializeForm(layer, callback)
{
var problem = L.DomUtil.get('problem');
problem.textContent = layer.options.problem ? layer.options.problem : "";
problem.addEventListener('change', (e) =>
{
layer.options.problem = problem.value;
});
var solution = L.DomUtil.get('solution');
solution.textContent = layer.options.solution ? layer.options.solution : "";
solution.addEventListener('change', (e) =>
{
layer.options.solution = solution.value;
});
var buttonSubmit = L.DomUtil.get('button-submit');
buttonSubmit.addEventListener('click', (e) =>
{
callback(layer);
});
}
});
L.infrastructurePopup = function (options, source)
{
return new L.InfrastructurePopup(options, source);
};
I linked it into a custom Marker called InfrastructureMarker that has one and only popup , a InfrastructurePopup. So when it calls the openPopup() function it loads the popup on the map [ map.addLayer(popup) ] and give me the correct datas thanks to method initializeForm() that I call after the addLayer(popup) method.
L.Map.include({
openInfrastructurePopup: function (layer, callback)
{
this.closePopup();
layer._popup._isOpen = true;
this.addLayer(layer._popup);
layer._popup.initializeForm(layer, callback);
}
});
L.InfrastructureMarker = L.Marker.extend({
openPopup: function (callback)
{
if (this._popup && this._map && !this._map.hasLayer(this._popup))
{
this._popup.setLatLng(this._latlng);
this._map.openInfrastructurePopup(this, callback);
}
return this;
},
togglePopup: function (callback)
{
if (this._popup)
{
if (this._popup._isOpen)
{
this._popup._isOpen = false;
this.closePopup();
}
else
{
this.openPopup(callback);
}
}
return this;
},
bindPopup: function (callback, options)
{
var anchor = L.point(this.options.icon.options.popupAnchor || [0, 0]);
anchor = anchor.add(L.Popup.prototype.options.offset);
if (options && options.offset)
{
anchor = anchor.add(options.offset);
}
options = L.extend({offset: anchor}, options);
if (!this._popupHandlersAdded)
{
this
.on('click', () => {this.togglePopup(callback)}, this)
.on('remove', this.closePopup, this)
.on('move', this._movePopup, this);
this._popupHandlersAdded = true;
}
this._popup = new L.infrastructurePopup(options, this).setContent();
return this;
},
});
L.infrastructureMarker = function (latlng, options)
{
return new L.InfrastructureMarker(latlng, options);
};
But if I decide to click on one marker, then on another one without closing the first one, it loads the template, but initializeForm(callback) doesn't change the datas. I checked all the datas to know if it was empty or something but everything worked, I absolutely don't know where the problem is. I suppose the popup is not yet set on the DOM before my L.DomUtils.get fire but I shouldn't see undefined elements in console.log when I'm getting them.
I actually found what was happening :
Actually, when the L.map calls its closePopup function , it destroys the layer.
So after that, it creates a new one to display. BUT the remaining HTML from the previous kind of still exists.
So I finally bound exact same Ids to two HTML tags. Heresy !
My solution became what's next :
L.InfrastructurePopup = L.Popup.extend({
setContent: function (layer)
{
var template = "<form id='popup-form'>\
<div>\
<label for='problem'>Problème Identifié</label>\
<textarea id='" + layer._leaflet_id + "-problem' rows='4' cols='46' placeholder='Type your text here'></textarea>\
</div>\
<div>\
<label for='solution'>Solution Proposée</label>\
<textarea id='" + layer._leaflet_id + "-solution' rows='4' cols='46' placeholder='Type your text here'></textarea>\
</div>\
<button id='" + layer._leaflet_id + "-button-submit' class='btn btn-primary' type='button'>Submit</button>\
</form>";
this._content = template;
this.update();
return this;
},
initializeForm: function(layer, callback)
{
console.log(L.DomUtil.get(layer._leaflet_id+'-problem'));
var problem = L.DomUtil.get(layer._leaflet_id + '-problem');
problem.textContent = layer.options.problem ? layer.options.problem : "";
problem.addEventListener('change', (e) =>
{
layer.options.problem = problem.value;
});
var solution = L.DomUtil.get(layer._leaflet_id + '-solution');
solution.textContent = layer.options.solution ? layer.options.solution : "";
solution.addEventListener('change', (e) =>
{
layer.options.solution = solution.value;
});
var buttonSubmit = L.DomUtil.get(layer._leaflet_id + '-button-submit');
buttonSubmit.addEventListener('click', (e) =>
{
callback(layer);
});
}
});
L.infrastructurePopup = function (options, source)
{
return new L.InfrastructurePopup(options, source);
};
Calling setContent when creating my InfrastructurePopup with the layer_id and set it into my template made it work.
I got : '97-problem' or '99-problem' and '97-solution' or '99-solution

Symfony collection form data is not in post params

Today our user reported that saving his CV does not work, that it does not save his Skills, languages, driving license level, schools and prev. employments.
That is the Collection forms that i use on 2 parts of website (CV and Offers)...
Funny is that we tested it before going live and running live from IE6 to any other newer browser.
Collections is added correctly using "add foobar record" button, when there is any record in DB it appears in edit correctly, when i edit these existing it will be saved, if i remove them than they will be removed.
But when i add new, these new records is not in Form post data. I cant understand if its part of form, html is rendered correctly, why it does not include it in post...
These collections works with Offer entity, saved updated added... no problem. i have checked the controller code, the javascript code, the entity code, the html code, the collection templates, the form types..
Here is DB structure:
here is how i add collection in botz CV and Offer
<div class="tbl">
<div class="row">
<div class="col" style="text-align: center; width: 100%;">Počítačové znalosti</div>
</div>
<div class="divider"></div>
<div class="skills" data="0" data-prototype="{% filter escape %}{% include 'TvarplastTopzamBundle:Collections:SkillCollection.html.twig' with {'form': form.skills.vars.prototype} %}{% endfilter %}">
{% for skill in form.skills %}
<div class="row">
{% include 'TvarplastTopzamBundle:Collections:SkillCollection.html.twig' with {'form': skill} %}
</div>
<script type="text/javascript">$(".skills").data("index", {{ loop.index }});</script>
{% endfor %}
</div>
<div class="row">
<div class="col">
Pridať počítačovú znalosť
</div>
</div>
</div>
Problem cannot be with entity, because if some relation exists in DB that is displayed as collection, and if its edited, it can be changed or removed, and its displayed in post parameters, then entity, form type, cannot be wrong.
but i handle form like this:
public function zivotopisAction(\Symfony\Component\HttpFoundation\Request $request, $showmsg = false) {
if (!$this->get("data")->hasPerm(Role::WORKER, $this->getUser())) {
$message["show"] = true;
$message["text"] = "Nemáte požadované oprávnenia. Stránka nemôže byť zobrazená.";
$message["type"] = "box-red";
return new \Symfony\Component\HttpFoundation\Response($this->renderView("TvarplastTopzamBundle::error.html.twig", array("message" => $message)));
}
$return = array();
$message = array("show" => $showmsg, "type" => "", "text" => "");
if ($message["show"]) {
$message["text"] = "Je nutné vyplniť nasledujúce informácie pre pokračovanie.";
$message["type"] = "box-red";
}
$em = $this->getDoctrine()->getManager();
if (!is_null($this->getUser()->getZivotopis())) {
$zivotopis = $em->getRepository("TvarplastTopzamBundle:Zivotopis")->find($this->getUser()->getZivotopis()->getId());
} else {
$zivotopis = new \Tvarplast\TopzamBundle\Entity\Zivotopis();
}
$originalSkills = new \Doctrine\Common\Collections\ArrayCollection();
if ($zivotopis->getSkills()) {
foreach ($zivotopis->getSkills() as $skill) {
$originalSkills->add($skill);
}
}
$originalLanguages = new \Doctrine\Common\Collections\ArrayCollection();
if ($zivotopis->getLanguages()) {
foreach ($zivotopis->getLanguages() as $language) {
$originalLanguages->add($language);
}
}
$originalDrivingskills = new \Doctrine\Common\Collections\ArrayCollection();
if ($zivotopis->getSkilldriving()) {
foreach ($zivotopis->getSkilldriving() as $skilldriving) {
$originalDrivingskills->add($skilldriving);
}
}
$originalEmployments = new \Doctrine\Common\Collections\ArrayCollection();
if ($zivotopis->getEmployments()) {
foreach ($zivotopis->getEmployments() as $employment) {
$originalEmployments->add($employment);
}
}
$originalSchools = new \Doctrine\Common\Collections\ArrayCollection();
if ($zivotopis->getSchools()) {
foreach ($zivotopis->getSchools() as $school) {
$originalSchools->add($school);
}
}
$form = $this->createForm(new \Tvarplast\TopzamBundle\Form\ZivotopisType(), $zivotopis, array(
'action' => $this->generateUrl('zivotopis'),
));
$form->handleRequest($request);
if ($form->isValid()) {
//var_dump($_POST); die();
foreach ($originalSkills as $skill) {
if (false === $zivotopis->getSkills()->contains($skill)) {
$skill->getZivotopis()->removeElement($zivotopis);
$em->persist($skill);
$em->remove($skill);
}
}
foreach ($originalLanguages as $language) {
if (false === $zivotopis->getLanguages()->contains($language)) {
$language->getZivotopis()->removeElement($zivotopis);
$em->persist($language);
$em->remove($language);
}
}
foreach ($originalDrivingskills as $drivingskill) {
if (false === $zivotopis->getSchools()->contains($drivingskill)) {
$drivingskill->getZivotopis()->removeElement($zivotopis);
$em->persist($drivingskill);
$em->remove($drivingskill);
}
}
foreach ($originalEmployments as $employment) {
if (false === $zivotopis->getEmployments()->contains($employment)) {
$employment->getZivotopis()->removeElement($zivotopis);
$em->persist($employment);
$em->remove($employment);
}
}
foreach ($originalSchools as $school) {
if (false === $zivotopis->getSchools()->contains($school)) {
$school->getZivotopis()->removeElement($zivotopis);
$em->persist($school);
$em->remove($school);
}
}
$zivotopis->upload();
$zivotopis->setBasicUser($this->getUser());
$zivotopis = $form->getData();
$em->persist($zivotopis);
$em->flush();
$message["text"] = ($this->container->get('security.context')->isGranted('ROLE_WORKER') ? "Životopis" : "Profil") . " bol úspešne uložený.";
$message["type"] = "box-yellow";
$message["show"] = true;
}
$return["form"] = $form->createView();
$return["message"] = $message;
return $return;
and my javascript looks like this:
$(document).ready(function() {
$.extend({getDeleteLinkCode: function(div) {
return '<div class="col" style="margin-top: 8px; margin-left: 3px;"><a href="#" style="margin-top: 5px;" >Odstrániť</a></div>';
}});
$.extend({addSubFormSelectChangeListener: function(collectionHolder, formRow, div) {
formRow.find('select' + (!div ? ':first' : '')).on("change", function() {
var org = $(this);
if (collectionHolder.find(!div ? "tr" : "div").size() > 1) {
collectionHolder.find(!div ? "tr" : "div").each(function() {
if (org.val() === $(this).find('select:first').val() && org.attr("id") !== $(this).find("select:first").attr("id")) {
org.parent().parent().remove();
}
});
}
});
}});
$.extend({addSubForm: function(collectionHolder, div) {
var prototype = collectionHolder.data('prototype');
var index = collectionHolder.data('index');
index = (index !== parseInt(index) ? 0 : index);
var form = prototype.replace(/__name__/g, index);
var formRow = $((div ? '<div class="row"></div>' : '<tr></tr>')).append(form);
var removeFormRow = $($.getDeleteLinkCode(div));
formRow.append(removeFormRow);
collectionHolder.data('index', index + 1);
collectionHolder.append(formRow);
removeFormRow.on('click', function(e) {
e.preventDefault();
formRow.remove();
});
$.addSubFormSelectChangeListener(collectionHolder, formRow, div);
}});
function addSubFormItemDeleteLink(collectionHolder, $tagFormLi, div, notag) {
var $removeFormA = $($.getDeleteLinkCode(div));
$tagFormLi.append($removeFormA);
$removeFormA.on('click', function(e) {
e.preventDefault();
$tagFormLi.remove();
});
$.addSubFormSelectChangeListener(collectionHolder, $tagFormLi, div);
}
jQuery.fn.toggleOption = function(show) {
$(this).toggle(show);
if (show) {
if ($(this).parent('span.toggleOption').length) {
$(this).unwrap();
}
} else {
if ($(this).parent('span.toggleOption').length === 0) {
$(this).wrap('<span class="toggleOption" style="display: none;" />');
}
}
};
$.extend({comboFilter: function(inputField, comboBox) {
$("#" + inputField).delayBind("input", function() {
var inputValue = $(this).val().toLowerCase();
var combobox = document.getElementById(comboBox);
$("#" + comboBox).children("span").children("optgroup").each(function() {
$(this).toggleOption(true);
});
optionToSelect = false;
$("#" + comboBox + " option").each(function() {
if ($(this).text().toLowerCase().replace(/<.+?>/g, "").replace(/\s+/g, " ").indexOf(inputValue.replace(/<.+?>/g, "").replace(/\s+/g, " ")) !== -1) {
optionToSelect = $(this);
$(this).toggleOption(true);
} else {
$(this).toggleOption(false);
}
if (optionToSelect !== false) {
$(optionToSelect).select();
}
});
$("#" + comboBox).children("optgroup").each(function() {
if ($(this).children("option").length <= 0) {
$(this).toggleOption(false);
} else {
$(this).toggleOption(true);
}
});
if ($("#" + comboBox).children("optgroup").length <= 0) {
$("#" + comboBox).children("span").children("optgroup").children("option").each(function() {
$(this).parent().toggleOption(true);
});
}
if (inputValue === '') {
combobox[0].selected = true;
$("#" + comboBox).children("span").children("optgroup").each(function() {
$(this).toggleOption(true);
});
}
}, 50);
}});
/* skills */
holderSkills = $('div.skills');
holderSkills.find('div.row').each(function() {
addSubFormItemDeleteLink(holderSkills, $(this), false, false);
});
$(".add_skill_link").on('click', function(e) {
e.preventDefault();
$.addSubForm(holderSkills, true);
});
/* driving */
holderDriving = $('div.skilldriving');
holderDriving.find('div.deletehere').each(function() {
addSubFormItemDeleteLink(holderDriving, $(this), true, true);
});
$(".add_driving_link").on('click', function(e) {
e.preventDefault();
$.addSubForm(holderDriving, true);
});
/* Lang */
holderLanguages = $('div.languages');
holderLanguages.find('div.row').each(function() {
addSubFormItemDeleteLink(holderLanguages, $(this), false, false);
});
$(".add_lang_link").on('click', function(e) {
e.preventDefault();
$.addSubForm(holderLanguages, true);
});
/* Emp */
holderEmployments = $('div.employments');
holderEmployments.find('div.deletehere').each(function() {
addSubFormItemDeleteLink(holderEmployments, $(this), false, false);
});
$(".add_zam_link").on('click', function(e) {
e.preventDefault();
$.addSubForm(holderEmployments);
});
/* Schools */
holderSchools = $('div.schools');
holderSchools.find('div.deletehere').each(function() {
addSubFormItemDeleteLink(holderSchools, $(this), false, false);
});
$(".add_Schools_link").on('click', function(e) {
e.preventDefault();
$.addSubForm(holderSchools);
});
});
Any idea where can the problem be?
Thank you very much
Thanks to Dynamically added form field not showing up in POSTed data
Solved by switching first 2 lines to be {form} first and div the second
i had something like
<div .....>
{form....}
some html
</div>
<div>
htmlhhtml
</div>
</div>
{endform}
That was the reason why browser was not able to read newly added items

Fine Uploader in Form Doesn't Submit Model Data into Controller

I have 2 questions:
1.) I have placed the Fine Uploader in a form and now I'm wondering why I don't see the filled content of the entry fields in my controller. How I can solve that?
2.) How can I do field validations before the upload process fires?
I hope someone can help!
Here is my code:
Model:
public class UploadFileModel
{
[StringLength(100)]
[Display(Name = "* Title:")]
public string Title { get; set; }
[StringLength(300)]
[Display(Name = "Description:")]
public string Description { get; set; }
}
View:
#model mowee.Models.UploadFileModel
<link href="~/Scripts/fineuploader/fineuploader-3.5.0.css" rel="stylesheet" />
#using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { id = "uploadForm", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<fieldset>
<legend>Video Upload</legend>
<ol>
<li>
#Html.LabelFor(m => m.Title)
#Html.TextBoxFor(m => m.Title, new { #Class = "action add", title = "Enter your video/movie title here." })
</li>
<li>
#Html.LabelFor(m => m.Description)
#Html.TextAreaFor(m => m.Description, new Dictionary<string, object> { { "rows", "3" } })
</li>
</ol>
<div id="bootstrapped-fine-uploader"></div>
<script src="~/Scripts/fineuploader/fineuploader-3.5.0.js"></script>
<script>
function createUploader() {
var uploader = new qq.FineUploader({
element: document.getElementById('bootstrapped-fine-uploader'),
multiple: false,
validation: {
sizeLimit: 2147483648 //2GB
},
request: {
endpoint: '/Home/UploadFile'
},
text: {
uploadButton: '<div><i class="icon-upload icon-white"></i>* Upload Video</div>'
},
template: '<div class="qq-uploader span12">' +
'<pre class="qq-upload-drop-area span12"><span>{dragZoneText}</span></pre>' +
'<div id="btnUpload" class="qq-upload-button btn btn-success" style="width: 33%;">{uploadButtonText}</div>' +
'<span class="qq-drop-processing"><span>{dropProcessingText}</span><span class="qq-drop-processing-spinner"></span></span>' +
'<ul class="qq-upload-list" style="margin-top: 10px; text-align: center;"></ul>' +
'</div>',
classes: {
success: 'alert alert-success',
fail: 'alert alert-error',
dropActive: "cssClassToAddToDropZoneOnEnter"
}
});
}
window.onload = createUploader;
</script>
</fieldset>
}
Controller:
[HttpPost]
[AllowAnonymous]
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult UploadFile(string qqfile, UploadFileModel myModel)
{
if (ModelState.IsValid)
{
try
{
HttpPostedFileBase uploadFile = null;
uploadFile = Request.Files[0];
if (uploadFile != null && uploadFile.ContentLength > 0)
{
if (myModel.Title != null || myModel.Description != null)
{
**//but UploadFileModel is null. WHY??????? Anyone an idea what i did wrong???
//write data to DB**
}
}
else
{
ModelState.AddModelError("", "Please choose a video/movie.");
return Json(new { success = false, message = "Please choose a video/movie." }, "application/json");
}
}
catch (Exception ex)
{
ModelState.AddModelError("", "An error occured. Try again.");
mailUtils.SendBugMail(ex, this.HttpContext);
return Json(new { success = false, message = "An error occured during upload. Try again." }, "application/json");
}
return Json(new { success = true, VideoLink = #ViewBag.VideoLink, VideoTranscoded = #ViewBag.Transcoded }, "application/json");//"text/html");
}
return Json(new { success = false, message = "An error occured during upload. Try again." }, "application/json");
}
OK. I figured it out. The params can be set on callback 'onSubmit' with setParams like that:
callbacks: {
onSubmit: function (id, fileName, responseJSON) {
uploader.setParams({
idxTitle: $('#titleId').val(),
idxAuthor: $('#authorId').val(),
idxEmail: $('#emailId').val()
});
},
And it works fine!
Addressing your questions:
You should really have a look at the MVC4 example in the Fine Uploader server-side examples repository. Model your server-side code after this example, and you should be fine. I personally am not an MVC4 developer, but I know the example I have linked to works.
You can make use of onValidate and onValidateBatch callbacks to perform your own validation tasks. Please have a look at the callbacks documentation for more info.

alert() message isn't being called in my form

Firebug is giving me no error messages, but it's not working. The idea is regardless of whether the user picks an option from dropdown or if they type in something in search box, I want the alert() message defined below to alert what the value of the variable result is (e.g. {filter: Germany}). And it doesn't. I think the javascript breaks down right when a new Form instance is instantiated because I tried putting an alert in the Form variable and it was never triggered. Note that everything that pertains to this issue occurs when form.calculation() is called.
markup:
<fieldset>
<select name="filter" alter-data="dropFilter">
<option>Germany</option>
<option>Ukraine</option>
<option>Estonia</option>
</select>
<input type="text" alter-data="searchFilter" />
</fieldset>
javascript (below the body tag)
<script>
(function($){
var listview = $('#listview');
var lists = (function(){
var criteria = {
dropFilter: {
insert: function(value){
if(value)
return handleFilter("filter", value);
},
msg: "Filtering..."
},
searchFilter: {
insert: function(value){
if(value)
return handleFilter("search", value);
},
msg: "Searching..."
}
}
var handleFilter = function(key,value){
return {key: value};
}
return {
create: function(component){
var component = component.href.substring(component.href.lastIndexOf('#') + 1);
return component;
},
setDefaults: function(component){
var parameter = {};
switch(component){
case "sites":
parameter = {
'order': 'site_num',
'per_page': '20',
'url': 'sites'
}
}
return parameter;
},
getCriteria: function(criterion){
return criteria[criterion];
},
addCriteria: function(criterion, method){
criteria[criterion] = method;
}
}
})();
var Form = function(form){
var fields = [];
$(form[0].elements).each(function(){
var field = $(this);
if(typeof field.attr('alter-data') !== 'undefined') fields.push(new Field(field));
})
}
Form.prototype = {
initiate: function(){
for(field in this.fields){
this.fields[field].calculate();
}
},
isCalculable: function(){
for(field in this.fields){
if(!this.fields[field].alterData){
return false;
}
}
return true;
}
}
var Field = function(field){
this.field = field;
this.alterData = false;
this.attach("change");
this.attach("keyup");
}
Field.prototype = {
attach: function(event){
var obj = this;
if(event == "change"){
obj.field.bind("change", function(){
return obj.calculate();
})
}
if(event == "keyup"){
obj.field.bind("keyup", function(e){
return obj.calculate();
})
}
},
calculate: function(){
var obj = this,
field = obj.field,
msgClass = "msgClass",
msgList = $(document.createElement("ul")).addClass("msgClass"),
types = field.attr("alter-data").split(" "),
container = field.parent(),
messages = [];
field.next(".msgClass").remove();
for(var type in types){
var criterion = lists.getCriteria(types[type]);
if(field.val()){
var result = criterion.insert(field.val());
container.addClass("waitingMsg");
messages.push(criterion.msg);
obj.alterData = true;
alert(result);
initializeTable(result);
}
else {
return false;
obj.alterData = false;
}
}
if(messages.length){
for(msg in messages){
msgList.append("<li>" + messages[msg] + "</li");
}
}
else{
msgList.remove();
}
}
}
$('#dashboard a').click(function(){
var currentComponent = lists.create(this);
var custom = lists.setDefaults(currentComponent);
initializeTable(custom);
});
var initializeTable = function(custom){
var defaults = {};
var custom = custom || {};
var query_string = $.extend(defaults, custom);
var params = [];
$.each(query_string, function(key,value){
params += key + ': ' + value;
})
var url = custom['url'];
$.ajax({
type: 'GET',
url: '/' + url,
data: params,
dataType: 'html',
error: function(){},
beforeSend: function(){},
complete: function() {},
success: function(response) {
listview.html(response);
}
})
}
$.extend($.fn, {
calculation: function(){
var formReady = new Form($(this));
if(formReady.isCalculable) {
formReady.initiate();
}
}
})
var form = $('fieldset');
form.calculation();
})(jQuery)
Thank you for anyone who responds. I spent a lot of time trying to make this work.
The initial problem as to why the alert() was not being triggered when Form is instantiated is because, as you can see, the elements property belongs to the Form object, not fieldset object. And as you can see in the html, I place the fields as descendents of the fieldset object, not form.