to help teach myself PHP I've tasked myself with updating old mysql_* code with PDO.
This has been going great, and as I've been learning I've been able to greatly reduce the amount of code. However my research has ran into a brick wall in a particular area.
Currently, we have it so projects are recorded in a list view, with a set of 'actions/options' for each project. Each of these actions links to a PHP file which runs a small amount of code then sends you back to the list view.
Here is an example:
function projectComplete(id) {
location.href = "complete.php?id=" + id;
}
<button type="button" class="projectComplete" onclick="projectComplete('<?= htmlentities($row['projectid']); ?>')"></button>
The complete.php file simply contains an SQL update query that sets a column in the record a completed state of '1'.
I originally wanted to ask the question 'what is the best practice for handling this type of interaction' however that may attract opinion based answers which I read is not allowed here.
Instead I will phrase it like this: Is there a way of having all of these 'actions' run in the same page? (ideally able to use buttons rather than forms, due to difficulty in layout styling of forms)
I know that if it used forms, I could simply name each form's submit button differently then run an if statement (the only issue would be passing the id, but I'm sure I could figure that out e.g.
if (isset($_POST['exampleAction'])) { Run the code.. }
Any links to guides/tutorials/similar questions etc would be very much appreciated. As previously stated, I'm self-learning PHP - I know very few 'best practices' and would like to learn more.
One thing you could consider is an MVC pattern, where a page call will run some function based on some parameters. A full-blown MVC framework is probably more than you need for this project, but mimicking the controller dispatching is certainly doable. Something to this effect could work (code untested):
if (isset($_GET['action'])) {
new Actions()->dispatch('action_'.$_GET['action']);
}
class Actions {
public function dispatch($action) {
if (method_exists($this, $action)) {
$this->$action($_GET);
} else {
http_response_code(400);
exit(1);
}
}
// The following functions are examples only!
public function action_Create($parameters) {
// Create database record
}
public function action_Read($parameters) {
// Read database record
}
public function action_Update($parameters) {
// Update database record
}
public function action_Delete($parameters) {
// Delete database record
}
}
Then you'd call (for example) action.php?action=Read&name=foo&author=bar
Related
I just finished localizing my web application using spring boot configuration as a base.
#Bean
public LocaleResolver localeResolver() {
return new CookieLocaleResolver();
}
Due to a requirement one is supposed to be able to change locale/language of the website by pressing a button. Said function is implemented with a little bit of JS and a cookie.
<script>
function updateCookie(lang) {
let name = "org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE"
document.cookie = name+"="+lang
location.reload()
}
</script>
<a onclick="updateCookie('de')" class="flag-icon flag-icon-de mr-2"></a>
The idea is to update said cookie on click of a button and use it throughout the whole application. This works fine until I am trying to call a specific endpoint in my application.
In order to debug my application I use:
window.onload = function () {
alert(document.cookie)
}
Now to my problem:
When User-Testing the application this is the alert-feedback:
org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE=de
Switching to other pages, refreshing, changing language etc. properly resets the cookie with a different value.
When calling a specific endpoint though, I get the following alert:
org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE=de;
org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE=fr
Instead of resetting/changing the existing cookie, a new one is added with the value 'de;'. A seemingly random semicolon is added.
This doesn't happen with endpoints using similar logic and almost identical implementation.
There is no further logic outside the little bit of JS code I've posted and I'm not touching the cookie in the backend.
Unfortunately I'm out of ideas. Any tips/help would be appreciated.
I'm developing my project with Blazor Server-side.
While I develop, I used javascript code to implement things that hard to implement by C#.
However, I'm facing something weird situation. (I guess it is problem for javascript)
Suppose there are 2 users(A, B). When 'A' user do some action that call javascript code, if 'B' user into same page, 'A' users action affects to 'B' user.
I implemented web page that have 3d scene with threejs. As I explained above, when User 'A' move some object with mouse event(mousemove, mousedown..), if User 'B' accesses the same page, 3d objects of B are moved to the location where User 'A' moved.
Originally, when user access to web page I developed, 3d objects's position should be 0,0,0.
My Guess
I don't use prototype or class(use variable and functions globally. I'm new to javascript.. )
Javascript runs on server-side(share resources??, If then, how can I solve it)
I'm guessing the javascript would be problem, but if you have any other opinions, would you please share?
Edited
I've solved this problem using DotNetObjectReference.Create(this);
C#
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
//send created instance to javascript
var dotNetObjRef = DotNetObjectReference.Create(this);
await JSRuntime.InvokeVoidAsync("SetObjectRef", dotNetObjRef);
}
await base.OnAfterRenderAsync(firstRender);
}
[JSInvokable]
public async Task enableSomething(bool bEnable)
{
var something = bEnable;
}
//== before edit
//[JSInvokable]
//public static async Task enableSomethingStatic(bool bEnable)
//{
// var something = bEnable;
//}
Javascript
var objectRef;
function SetObjectRef(ref) {
objectRef = ref;
}
//call c# function
objectRef.invokeMethodAsync("enableSomething", true);
It was problem of 'static' method as I guessed.
If you declare C# method called from javascript as 'static' and this method changes something of UI variable, this method can affect another users.
So I create instance of current page and send it javascript and when I need to call C# methods from javascript, I call methods using created instance.
Is there any problem or issue, please share it.
Sorry for my bad English.
JavaScript runs client side only. I don't see how two windows, let alone two users, would share data.
Almost for sure, the problem is that you are injecting a singleton service-- which means the server will use one instance for all users.
If so, you have two choices:
(1) add logic to your singleton service to incorporate users. (For example, a dictionary with UserID/Property name for key, and a column for Value)
(2) go to Startup.cs and change the suspect singleton service to .AddScoped(), which will create a new instance for each user.
For right now, I think the latter solution will solve your problem immediately. However, don't underestimate the value of Singletons-- they'll be very useful for other things.
We're planning on rebuilding our service at my workplace, creating a RESTful API and such and I happened to stumble on an interesting question: can I make my JS code in a way that it mimics my API design?
Here's an example to illustrate what I mean:
We have dogs, and you can access those dogs doing a GET /dogs, and get info on a specific one by GET /dogs/{id}.
My Javascript code would then be something like
var api = {
dogs : function(dogId) {
if ( dogId === undefined ) {
//request /dogs from server
} else {
//request /dogs/dogId from server
}
}
}
All if fine and dandy with that code, I just have to call api.dogs() or api.dogs(123) and I'll get the info I want.
Now, let's say those dogs have a list of diseases (or whatever, really) which you can fetch via GET /dogs/{id}/disases. Is there a way to modify my Javascript so that the previous calls will remain the same - api.dogs() returns all dogs and api.dogs(123) returns dog 123's info - while allowing me to do something like api.dogs(123).diseases() to list dog 123's diseases?
The simplest way I thought of doing it is by having my methods actually build queries instead of retrieving the data and a get or run method to actually run those queries and fetch the data.
The only way I can think of building something like this is if I could somehow, when executing a function, if some other function is chained to the object, but I don't know if that's possible.
What are your thoughts on this?
I cannot give you a concrete implementation, but a few hints how you could accomplish what you want. It would be interesting to know, what kind of Server and framework you are using.
Generate (Write yourself or autogenerate from code) a WADL describing your Service and then try do generate the Code for example with XSLT
In my REST projects I use swagger, that analyzes some common Java REST Implementation and generates JSON descriptions, that you could use as a base for Your JavaScript API
It can be easy for simple REST Apis but gets complicated as the API divides into complex hierarchies or has a tree structure. Then everything will depend on an exact documentation of your service.
Assuming that your JS application knows of the services provided by your REST API i.e send a JSON or XML file describing the services, you could do the following:
var API = (function(){
// private members, here you hide the API's functionality from the outside.
var sendRequest = function (url){ return {} }; // send GET request
return {
// public members, here you place methods that will be exposed to the public.
var getDog = function (id, criteria) {
// check that criteria isn't an invalid request. Remember the JSON file?
// Generate url
response = sendRequest(url);
return response;
};
};
}());
var diseases = API.getDog("123", "diseases");
var breed = API.getDog("123", "breed");
The code above isn't 100% correct since you still have to deal with AJAX call but it is more or less what you what.
I hope this helps!
I have a DevExpress GridView in my Asp.NET MVC 4 application and want to access row data on the client side via JavaScript. At the moment I am doing the following:
Specify which values should be transmitted to js function ChangeDetailsTab:
function OnGridFocusedRowChanged(s, e) {
s.GetRowValues(s.GetFocusedRowIndex(),
'MOL_REGID;BATCH_NAME;MOL_NAME;MOL_ENTERED_BY;', ChangeDetailsTab);
}
Access values from array received by ChangeDetailsTab:
function ChangeDetailsTab(rowData) {
var molRegId= rowData[0];
var batchName= rowData[1];
var molName= rowData[2];
var molEnteredBy= rowData[3];
}
This approach makes it quite bad to access a large number of values or add/remove values later because the column names have to be specified in one large string (see example 1 line 3).
Has anyone a better solution for this problem?
The client-side GetRowValues is specially designed for this purpose.
I believe it is the best solution.
this is best way,Of course a any way for this,you can called in C# Code,in CustomCallback you can run it,in client side on the javascript you can perform,such
ASPxGridView1.PerformCallback()(ASPxGridView1 has a event that named CustomCallback)with this you without reload page can get value of C# code
in C# Code :
ASPxGridView1.GetRowValues(ASPxGridView1.FocusedRowIndex,"column1","column2",....)
of course you remember that should called this event from java script in client-side
Which method is faster? I'm loading multiple values but it seems slow for some reason.
I'm doing the setup similar to what you have but I have about 25 - 30 values being loaded.
function insuranceselectionchange() {
insuranceselection.GetRowValues(insuranceselection.GetFocusedRowIndex(), 'CarrierName;CarrierAddress;CarrierAddress2')
}
function SetInsuranceValues(values) {
CarrierName.SetText(values[0]);
CarrierAddress.SetText(values[1]);
CarrierAddress2.SetText(values[2]);
}
I just started to investigate mvc on javascript client side (JavaScript MVC). Everything looked great until I got to form submitting :) View part won't do it, that's simple. Event is attached in Controller, so Controller is good place to validate form data, but I'm not sure I want my Controller to know specific server address (were to post my form), so would be great to have a method in Model, but then I don't want my Model to know about my Form (which is actually html structure...).
Well, what do I miss about MVC conception? I am also not sure I want to serialize my form in Controller and then pass it as parameter to my Model. For now, the only option I see to make Model independent is to have JavaScript structure (entity), which will be filled by controller (based on form data) and will be passed to the Model method to be saved on server. Very smplified code:
Info = {
name,
address,
// 15 more properties
...
}
InfoController = {
...
onFormSubmit: function() {
...
info.name = document.getElementById("info-name").value;
info.adress = document.getElementById("info-address").value;
...
InfoModel.save( info );
}
}
InfoModel = {
...
save: function( info ) {
// here some code to setialize info object
// send it to server
...
}
}
But it makes my code too complicated (comparing to simple form serizlization by some side frameworks and just sending it..). What's the right choice?
Just answering my own question. Short answer - yes, I was right with my assumptions ;)
I took a look at JavaScriptMVC, and noticed one simple thing I missed, a simple function can be developed which will create javascript object based on form (they have function called formParams which performs this type of converting). This way my controller is simplified:
InfoController = {
...
onFormSubmit: function() {
...
var info = $infoForm.formParams();
InfoModel.save( info );
}
}
Now it does not look that complicated, and its advantage is that there is one place (model) which knows how to save data (validation; url to send; some other stuff like add this entity to client side 'storage'; firing an event that something new is going to be created; whatever else according to our needs), and if I have one more place, or control flow to perform this operation again I won't write this code again, and it does not depend on presentation (is it form, or just set of inputs, wizard etc.). Also Model becomes quite reusable.
Actually before using this approach we had something similar, but it was not that structured (among different presentations for my application which can run javascript).