Create New Tile Order
For Customer: **hiii**
').addClass('alert alert-danger p-1 rounded-0').hide();
_this.find('.alert').remove();
const rooms_data = [];
let validation_failed = false;
// --- Validation Loop & Data Aggregation ---
$('.room-block').each(function() {
if (validation_failed) return false;
const roomBlock = $(this);
const room_name = roomBlock.find('[name="room_name[]"]').val();
const direct_area = roomBlock.find('[name="direct_area_sqft[]"]').val();
const direct_wall_area = roomBlock.find('[name="direct_wall_area_sqft[]"]').val();
// 1. Room Name Validation
if (!room_name.trim()) {
alert("Please provide a name for all rooms.");
roomBlock.find('[name="room_name[]"]').focus();
validation_failed = true;
return false;
}
const room_l_ft = roomBlock.find('[name="length_ft[]"]').val();
const room_w_ft = roomBlock.find('[name="width_ft[]"]').val();
const room_h_ft = roomBlock.find('[name="height_ft[]"]').val();
// 2. Floor Area Validation
if(parseFloat(direct_area) <= 0 && (!room_l_ft || parseFloat(room_l_ft) <= 0 || !room_w_ft || parseFloat(room_w_ft) <= 0)) {
alert(`Please enter a Direct Floor Area or valid Length (ft) and Width (ft) for room: ${room_name}`);
roomBlock.find('[name="direct_area_sqft[]"]').focus();
validation_failed = true;
return false;
}
// 3. Wall Area Validation: If wall tiles are requested, ensure area calculation data exists.
const hasWallTiles = roomBlock.find('[name="tile_placement[]"][value="wall"]').length > 0;
if (hasWallTiles && parseFloat(direct_wall_area) <= 0 && (!room_h_ft || parseFloat(room_h_ft) <= 0)) {
alert(`Room '${room_name}' requires wall area for wall tiles. Please enter a Direct Wall Area or a valid Height (ft).`);
roomBlock.find('[name="direct_wall_area_sqft[]"]').focus();
validation_failed = true;
return false;
}
// 4. Tile Data Aggregation
const room_tiles = [];
roomBlock.find('.tile-block').each(function() {
const tileBlock = $(this);
// Basic Tile Validation: Cost and Tiles per Box are required
if(!tileBlock.find('[name="tile_cost[]"]').val() || !tileBlock.find('[name="tiles_per_box[]"]').val()) {
alert(`Tile details are incomplete in room: ${room_name}. Please check the tile cost and boxes per tile.`);
validation_failed = true;
return false;
}
room_tiles.push({
// Dimensions and Costing inputs
tile_name: tileBlock.find('[name="tile_name[]"]').val(),
tile_placement: tileBlock.find('[name="tile_placement[]"]').val(),
t_length_ft: tileBlock.find('[name="t_length_ft[]"]').val(),
t_length_in: tileBlock.find('[name="t_length_in[]"]').val(),
t_width_ft: tileBlock.find('[name="t_width_ft[]"]').val(),
t_width_in: tileBlock.find('[name="t_width_in[]"]').val(),
tiles_per_box: tileBlock.find('[name="tiles_per_box[]"]').val(),
cost_basis: tileBlock.find('[name="cost_basis[]"]').val(),
tile_cost: tileBlock.find('[name="tile_cost[]"]').val(),
// Calculated data (stored in data attributes)
tile_area_sqft: tileBlock.data('tile_area_sqft'),
total_boxes: tileBlock.data('total_boxes'),
total_cost: tileBlock.data('total_cost'),
total_tiles: tileBlock.data('total_tiles'),
});
});
if (validation_failed) return false;
// 5. Aggregated Room Data Push
rooms_data.push({
room_name: room_name,
// Dimension Inputs
length_ft: roomBlock.find('[name="length_ft[]"]').val(),
length_in: roomBlock.find('[name="length_in[]"]').val(),
width_ft: roomBlock.find('[name="width_ft[]"]').val(),
width_in: roomBlock.find('[name="width_in[]"]').val(),
height_ft: roomBlock.find('[name="height_ft[]"]').val(),
height_in: roomBlock.find('[name="height_in[]"]').val(),
// Direct Area Inputs (NEW and existing)
direct_area_sqft: direct_area,
direct_wall_area_sqft: direct_wall_area,
// Calculated Areas
floor_area: roomBlock.data('floor_area'),
wall_area: roomBlock.data('wall_area'),
// Tiles Array
tiles: room_tiles
});
});
if (validation_failed) return false;
// 7. Finalize Data for AJAX
// Move the aggregated complex data into the hidden form field
$('#hidden_rooms_data').val(JSON.stringify(rooms_data));
// 8. Send Data via AJAX
_this.find('button').attr('disabled', true);
$.ajax({
url:'../classes/Master.php?f=save_order',
data: new FormData($(this)[0]),
cache: false,
contentType: false,
processData: false,
method: 'POST',
type: 'POST',
dataType: 'json',
error:err=>{
console.log(err)
// Use 'start_load()' and 'end_load()' if defined in your system
alert("An error occurred. Check the console for details.");
_this.find('button').attr('disabled', false);
},
success:function(resp){
if(typeof resp =='object' && resp.status == 'success'){
// Redirect on success
location.replace("./?page=tiles/view_order&id="+resp.id)
}else if(resp.status == 'failed' && resp.msg != ''){
el.text(resp.msg)
_this.prepend(el)
$('html, body').animate({scrollTop: _this.offset().top},'fast');
}else{
alert("An unknown error occurred on the server.");
console.log(resp)
}
_this.find('button').attr('disabled', false);
}
})
})
});